1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 1988 AT&T 24 * All Rights Reserved 25 * 26 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. 27 */ 28 29 /* 30 * Copyright (c) 2018, Joyent, Inc. 31 */ 32 33 #include <stdio.h> 34 #include <string.h> 35 #include "msg.h" 36 #include "_libld.h" 37 38 39 /* 40 * Print a virtual address map of input and output sections together with 41 * multiple symbol definitions (if they exist). 42 */ 43 static Boolean symbol_title = TRUE; 44 45 static void 46 sym_muldef_title() 47 { 48 (void) printf(MSG_INTL(MSG_ENT_MUL_FMT_TIL_0), 49 MSG_INTL(MSG_ENT_MUL_TIL_0)); 50 (void) printf(MSG_INTL(MSG_ENT_MUL_FMT_TIL_1), 51 MSG_INTL(MSG_ENT_MUL_ITM_SYM), 52 MSG_INTL(MSG_ENT_MUL_ITM_DEF_0), 53 MSG_INTL(MSG_ENT_MUL_ITM_DEF_1)); 54 symbol_title = FALSE; 55 } 56 57 void 58 ld_map_out(Ofl_desc *ofl) 59 { 60 Sg_desc *sgp; 61 Is_desc *isp; 62 Sym_avlnode *sav; 63 Aliste idx1; 64 65 (void) printf(MSG_INTL(MSG_ENT_MAP_FMT_TIL_1), 66 MSG_INTL(MSG_ENT_MAP_TITLE_1)); 67 if (ofl->ofl_flags & FLG_OF_RELOBJ) 68 (void) printf(MSG_INTL(MSG_ENT_MAP_FMT_TIL_2), 69 MSG_INTL(MSG_ENT_ITM_OUTPUT), 70 MSG_INTL(MSG_ENT_ITM_INPUT), 71 MSG_INTL(MSG_ENT_ITM_NEW), 72 MSG_INTL(MSG_ENT_ITM_SECTION), 73 MSG_INTL(MSG_ENT_ITM_SECTION), 74 MSG_INTL(MSG_ENT_ITM_DISPMNT), 75 MSG_INTL(MSG_ENT_ITM_SIZE)); 76 else 77 (void) printf(MSG_INTL(MSG_ENT_MAP_FMT_TIL_3), 78 MSG_INTL(MSG_ENT_ITM_OUTPUT), 79 MSG_INTL(MSG_ENT_ITM_INPUT), 80 MSG_INTL(MSG_ENT_ITM_VIRTUAL), 81 MSG_INTL(MSG_ENT_ITM_SECTION), 82 MSG_INTL(MSG_ENT_ITM_SECTION), 83 MSG_INTL(MSG_ENT_ITM_ADDRESS), 84 MSG_INTL(MSG_ENT_ITM_SIZE)); 85 86 for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp)) { 87 Os_desc *osp; 88 Aliste idx2; 89 90 if (sgp->sg_phdr.p_type != PT_LOAD) 91 continue; 92 93 for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) { 94 int os_isdescs_idx; 95 Aliste idx3; 96 97 (void) printf(MSG_INTL(MSG_ENT_MAP_ENTRY_1), 98 osp->os_name, EC_ADDR(osp->os_shdr->sh_addr), 99 EC_XWORD(osp->os_shdr->sh_size)); 100 101 OS_ISDESCS_TRAVERSE(os_isdescs_idx, osp, idx3, isp) { 102 Addr addr; 103 104 /* 105 * Although there seems little point in printing 106 * discarded (empty) sections, especially as 107 * diagnostics under -Dsegments,details are more 108 * informative, continue printing them. There 109 * are user scripts, fragile to say the least, 110 * that grep(1) through load-map output to 111 * discover object requirements. These scripts 112 * don't grep for all input sections types (ie. 113 * .picdata), and have become dependent on null 114 * sections (ie. .text) existing in the 115 * load-map output. 116 */ 117 if (isp->is_flags & FLG_IS_DISCARD) { 118 addr = 0; 119 } else { 120 addr = (Addr) 121 _elf_getxoff(isp->is_indata); 122 if (!(ofl->ofl_flags & FLG_OF_RELOBJ)) 123 addr += isp->is_osdesc-> 124 os_shdr->sh_addr; 125 } 126 127 (void) printf(MSG_INTL(MSG_ENT_MAP_ENTRY_2), 128 isp->is_name, EC_ADDR(addr), 129 EC_XWORD(isp->is_shdr->sh_size), 130 ((isp->is_file != NULL) ? 131 (char *)(isp->is_file->ifl_name) : 132 MSG_INTL(MSG_STR_NULL))); 133 } 134 } 135 } 136 137 if (ofl->ofl_flags & FLG_OF_RELOBJ) 138 return; 139 140 /* 141 * Check for any multiply referenced symbols (ie. symbols that have 142 * been overridden from a shared library). 143 */ 144 for (sav = avl_first(&ofl->ofl_symavl); sav; 145 sav = AVL_NEXT(&ofl->ofl_symavl, sav)) { 146 Sym_desc *sdp = sav->sav_sdp; 147 const char *name = sdp->sd_name, *ducp, *adcp; 148 APlist *dfiles; 149 Aliste idx; 150 151 if (((dfiles = sdp->sd_aux->sa_dfiles) == NULL) || 152 (aplist_nitems(dfiles) == 1)) 153 continue; 154 155 /* 156 * Files that define a symbol are saved on the `sa_dfiles' list. 157 * Ignore symbols that aren't needed, and any special symbols 158 * that the link editor may produce (symbols of type ABS and 159 * COMMON are not recorded in the first place, however functions 160 * like _init() and _fini() commonly have multiple occurrences). 161 */ 162 if ((sdp->sd_ref == REF_DYN_SEEN) || 163 (sdp->sd_aux->sa_symspec) || 164 (strcmp(MSG_ORIG(MSG_SYM_FINI_U), name) == 0) || 165 (strcmp(MSG_ORIG(MSG_SYM_INIT_U), name) == 0) || 166 (strcmp(MSG_ORIG(MSG_SYM_LIBVER_U), name) == 0)) 167 continue; 168 169 if (symbol_title) 170 sym_muldef_title(); 171 172 ducp = sdp->sd_file->ifl_name; 173 (void) printf(MSG_INTL(MSG_ENT_MUL_ENTRY_1), demangle(name), 174 ducp); 175 for (APLIST_TRAVERSE(dfiles, idx, adcp)) { 176 /* 177 * Ignore the referenced symbol. 178 */ 179 if (strcmp(adcp, ducp) != 0) 180 (void) printf(MSG_INTL(MSG_ENT_MUL_ENTRY_2), 181 adcp); 182 } 183 } 184 } 185 186 /* 187 * Traverse the entrance criteria list searching for those sections that haven't 188 * been met and print error message. (only in the case of reordering) 189 */ 190 void 191 ld_ent_check(Ofl_desc * ofl) 192 { 193 Ent_desc *enp; 194 Aliste ndx; 195 196 /* 197 * Try to give as much information to the user about the specific 198 * line in the mapfile. If the line contains a file name then 199 * output the filename too. Hence we have two warning lines - 200 * one for criterias where a filename is used and the other 201 * for those without a filename. 202 */ 203 for (APLIST_TRAVERSE(ofl->ofl_ents, ndx, enp)) { 204 /* 205 * No warning if any of the following hold: 206 * - The segment has no entrance criteria requiring 207 * input section sorting (FLG_SG_IS_ORDER not set). 208 * - The entrance criteria was used to place a section. 209 * - The specific entrance criteria does not require sorting 210 */ 211 if (((enp->ec_segment->sg_flags & FLG_SG_IS_ORDER) == 0) || 212 (enp->ec_flags & FLG_EC_USED) || (enp->ec_ordndx == 0)) 213 continue; 214 215 216 if (alist_nitems(enp->ec_files) > 0) { 217 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_ENT_NOSEC_1), 218 enp->ec_segment->sg_name, enp->ec_is_name); 219 } else { 220 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_ENT_NOSEC_2), 221 enp->ec_segment->sg_name, enp->ec_is_name); 222 } 223 } 224 }