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
sym_muldef_title()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
ld_map_out(Ofl_desc * ofl)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
ld_ent_check(Ofl_desc * ofl)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 }
225