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 2009 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 30 #include <stdio.h> 31 #include <string.h> 32 #include "msg.h" 33 #include "_libld.h" 34 35 36 /* 37 * Print a virtual address map of input and output sections together with 38 * multiple symbol definitions (if they exist). 39 */ 40 static Boolean symbol_title = TRUE; 41 42 static void 43 sym_muldef_title() 44 { 45 (void) printf(MSG_INTL(MSG_ENT_MUL_FMT_TIL_0), 46 MSG_INTL(MSG_ENT_MUL_TIL_0)); 47 (void) printf(MSG_INTL(MSG_ENT_MUL_FMT_TIL_1), 48 MSG_INTL(MSG_ENT_MUL_ITM_SYM), 49 MSG_INTL(MSG_ENT_MUL_ITM_DEF_0), 50 MSG_INTL(MSG_ENT_MUL_ITM_DEF_1)); 51 symbol_title = FALSE; 52 } 53 54 void 55 ld_map_out(Ofl_desc *ofl) 56 { 57 Sg_desc *sgp; 58 Is_desc *isp; 59 Sym_avlnode *sav; 60 Aliste idx1; 61 62 (void) printf(MSG_INTL(MSG_ENT_MAP_FMT_TIL_1), 63 MSG_INTL(MSG_ENT_MAP_TITLE_1)); 64 if (ofl->ofl_flags & FLG_OF_RELOBJ) 65 (void) printf(MSG_INTL(MSG_ENT_MAP_FMT_TIL_2), 66 MSG_INTL(MSG_ENT_ITM_OUTPUT), 67 MSG_INTL(MSG_ENT_ITM_INPUT), 68 MSG_INTL(MSG_ENT_ITM_NEW), 69 MSG_INTL(MSG_ENT_ITM_SECTION), 70 MSG_INTL(MSG_ENT_ITM_SECTION), 71 MSG_INTL(MSG_ENT_ITM_DISPMNT), 72 MSG_INTL(MSG_ENT_ITM_SIZE)); 73 else 74 (void) printf(MSG_INTL(MSG_ENT_MAP_FMT_TIL_3), 75 MSG_INTL(MSG_ENT_ITM_OUTPUT), 76 MSG_INTL(MSG_ENT_ITM_INPUT), 77 MSG_INTL(MSG_ENT_ITM_VIRTUAL), 78 MSG_INTL(MSG_ENT_ITM_SECTION), 79 MSG_INTL(MSG_ENT_ITM_SECTION), 80 MSG_INTL(MSG_ENT_ITM_ADDRESS), 81 MSG_INTL(MSG_ENT_ITM_SIZE)); 82 83 for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp)) { 84 Os_desc *osp; 85 Aliste idx2; 86 87 if (sgp->sg_phdr.p_type != PT_LOAD) 88 continue; 89 90 for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) { 91 int os_isdescs_idx; 92 Aliste idx3; 93 94 (void) printf(MSG_INTL(MSG_ENT_MAP_ENTRY_1), 95 osp->os_name, EC_ADDR(osp->os_shdr->sh_addr), 96 EC_XWORD(osp->os_shdr->sh_size)); 97 98 OS_ISDESCS_TRAVERSE(os_isdescs_idx, osp, idx3, isp) { 99 Addr addr; 100 101 /* 102 * Although there seems little point in printing 103 * discarded (empty) sections, especially as 104 * diagnostics under -Dsegments,details are more 105 * informative, continue printing them. There 106 * are user scripts, fragile to say the least, 107 * that grep(1) through load-map output to 108 * discover object requirements. These scripts 109 * don't grep for all input sections types (ie. 110 * .picdata), and have become dependent on null 111 * sections (ie. .text) existing in the 112 * load-map output. 113 */ 114 if (isp->is_flags & FLG_IS_DISCARD) { 115 addr = 0; 116 } else { 117 addr = (Addr) 118 _elf_getxoff(isp->is_indata); 119 if (!(ofl->ofl_flags & FLG_OF_RELOBJ)) 120 addr += isp->is_osdesc-> 121 os_shdr->sh_addr; 122 } 123 124 (void) printf(MSG_INTL(MSG_ENT_MAP_ENTRY_2), 125 isp->is_name, EC_ADDR(addr), 126 EC_XWORD(isp->is_shdr->sh_size), 127 ((isp->is_file != NULL) ? 128 (char *)(isp->is_file->ifl_name) : 129 MSG_INTL(MSG_STR_NULL))); 130 } 131 } 132 } 133 134 if (ofl->ofl_flags & FLG_OF_RELOBJ) 135 return; 136 137 /* 138 * Check for any multiply referenced symbols (ie. symbols that have 139 * been overridden from a shared library). 140 */ 141 for (sav = avl_first(&ofl->ofl_symavl); sav; 142 sav = AVL_NEXT(&ofl->ofl_symavl, sav)) { 143 Sym_desc *sdp = sav->sav_symdesc; 144 const char *name = sdp->sd_name, *ducp, *adcp; 145 APlist *dfiles; 146 Aliste idx; 147 148 if (((dfiles = sdp->sd_aux->sa_dfiles) == NULL) || 149 (aplist_nitems(dfiles) == 1)) 150 continue; 151 152 /* 153 * Files that define a symbol are saved on the `sa_dfiles' list. 154 * Ignore symbols that aren't needed, and any special symbols 155 * that the link editor may produce (symbols of type ABS and 156 * COMMON are not recorded in the first place, however functions 157 * like _init() and _fini() commonly have multiple occurrences). 158 */ 159 if ((sdp->sd_ref == REF_DYN_SEEN) || 160 (sdp->sd_aux && sdp->sd_aux->sa_symspec) || 161 (strcmp(MSG_ORIG(MSG_SYM_FINI_U), name) == 0) || 162 (strcmp(MSG_ORIG(MSG_SYM_INIT_U), name) == 0) || 163 (strcmp(MSG_ORIG(MSG_SYM_LIBVER_U), name) == 0)) 164 continue; 165 166 if (symbol_title) 167 sym_muldef_title(); 168 169 ducp = sdp->sd_file->ifl_name; 170 (void) printf(MSG_INTL(MSG_ENT_MUL_ENTRY_1), demangle(name), 171 ducp); 172 for (APLIST_TRAVERSE(dfiles, idx, adcp)) { 173 /* 174 * Ignore the referenced symbol. 175 */ 176 if (strcmp(adcp, ducp) != 0) 177 (void) printf(MSG_INTL(MSG_ENT_MUL_ENTRY_2), 178 adcp); 179 } 180 } 181 } 182 183 /* 184 * Traverse the entrance criteria list searching for those sections that haven't 185 * been met and print error message. (only in the case of reordering) 186 */ 187 void 188 ld_ent_check(Ofl_desc * ofl) 189 { 190 Ent_desc *enp; 191 Aliste ndx; 192 193 /* 194 * Try to give as much information to the user about the specific 195 * line in the mapfile. If the line contains a file name then 196 * output the filename too. Hence we have two warning lines - 197 * one for criterias where a filename is used and the other 198 * for those without a filename. 199 */ 200 for (ALIST_TRAVERSE(ofl->ofl_ents, ndx, enp)) { 201 const char *file; 202 203 if (((enp->ec_segment->sg_flags & FLG_SG_ORDER) == 0) || 204 (enp->ec_flags & FLG_EC_USED) || (enp->ec_ordndx == 0)) 205 continue; 206 207 208 if (enp->ec_files && 209 ((file = enp->ec_files->apl_data[0]) != NULL)) { 210 eprintf(ofl->ofl_lml, ERR_WARNING, 211 MSG_INTL(MSG_ENT_NOSEC_1), enp->ec_segment->sg_name, 212 enp->ec_name, file); 213 } else { 214 eprintf(ofl->ofl_lml, ERR_WARNING, 215 MSG_INTL(MSG_ENT_NOSEC_2), enp->ec_segment->sg_name, 216 enp->ec_name); 217 } 218 } 219 } 220