ldentry.c revision 1682:79d68fa5aedd
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 2006 Sun Microsystems, Inc.  All rights reserved.
27 * Use is subject to license terms.
28 */
29#pragma ident	"%Z%%M%	%I%	%E% SMI"
30
31#include	<stdio.h>
32#include	<string.h>
33#include	"msg.h"
34#include	"_libld.h"
35
36
37/*
38 * Print a virtual address map of input and output sections together with
39 * multiple symbol definitions (if they exist).
40 */
41static Boolean	symbol_title = TRUE;
42
43static void
44sym_muldef_title()
45{
46	(void) printf(MSG_INTL(MSG_ENT_MUL_FMT_TIL_0),
47		MSG_INTL(MSG_ENT_MUL_TIL_0));
48	(void) printf(MSG_INTL(MSG_ENT_MUL_FMT_TIL_1),
49		MSG_INTL(MSG_ENT_MUL_ITM_SYM),
50		MSG_INTL(MSG_ENT_MUL_ITM_DEF_0),
51		MSG_INTL(MSG_ENT_MUL_ITM_DEF_1));
52	symbol_title = FALSE;
53}
54
55void
56ld_map_out(Ofl_desc * ofl)
57{
58	Listnode *	lnp1, * lnp2, * lnp3;
59	Sg_desc *	sgp;
60	Is_desc *	isp;
61	Sym_avlnode	*sav;
62
63	(void) printf(MSG_INTL(MSG_ENT_MAP_FMT_TIL_1),
64		MSG_INTL(MSG_ENT_MAP_TITLE_1));
65	if (ofl->ofl_flags & FLG_OF_RELOBJ)
66		(void) printf(MSG_INTL(MSG_ENT_MAP_FMT_TIL_2),
67			MSG_INTL(MSG_ENT_ITM_OUTPUT),
68			MSG_INTL(MSG_ENT_ITM_INPUT),
69			MSG_INTL(MSG_ENT_ITM_NEW),
70			MSG_INTL(MSG_ENT_ITM_SECTION),
71			MSG_INTL(MSG_ENT_ITM_SECTION),
72			MSG_INTL(MSG_ENT_ITM_DISPMNT),
73			MSG_INTL(MSG_ENT_ITM_SIZE));
74	else
75		(void) printf(MSG_INTL(MSG_ENT_MAP_FMT_TIL_3),
76			MSG_INTL(MSG_ENT_ITM_OUTPUT),
77			MSG_INTL(MSG_ENT_ITM_INPUT),
78			MSG_INTL(MSG_ENT_ITM_VIRTUAL),
79			MSG_INTL(MSG_ENT_ITM_SECTION),
80			MSG_INTL(MSG_ENT_ITM_SECTION),
81			MSG_INTL(MSG_ENT_ITM_ADDRESS),
82			MSG_INTL(MSG_ENT_ITM_SIZE));
83
84	for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) {
85		Os_desc	**ospp;
86		Aliste	off;
87
88		if (sgp->sg_phdr.p_type != PT_LOAD)
89			continue;
90
91		for (ALIST_TRAVERSE(sgp->sg_osdescs, off, ospp)) {
92			Os_desc *osp = *ospp;
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			for (LIST_TRAVERSE(&(osp->os_isdescs), lnp3, 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)_elf_getxoff(isp->is_indata);
118				    if (!(ofl->ofl_flags & FLG_OF_RELOBJ))
119					addr +=
120					    isp->is_osdesc->os_shdr->sh_addr;
121				}
122
123				(void) printf(MSG_INTL(MSG_ENT_MAP_ENTRY_2),
124				    isp->is_name, EC_ADDR(addr),
125				    EC_XWORD(isp->is_shdr->sh_size),
126				    ((isp->is_file != NULL) ?
127				    (char *)(isp->is_file->ifl_name) :
128				    MSG_INTL(MSG_STR_NULL)));
129			}
130		}
131	}
132
133	if (ofl->ofl_flags & FLG_OF_RELOBJ)
134		return;
135
136	/*
137	 * Check for any multiply referenced symbols (ie. symbols that have
138	 * been overridden from a shared library).
139	 */
140	for (sav = avl_first(&ofl->ofl_symavl); sav;
141	    sav = AVL_NEXT(&ofl->ofl_symavl, sav)) {
142		Sym_desc	*sdp;
143		const char	*name, *ducp, *adcp;
144		List		*dfiles;
145
146		sdp = sav->sav_symdesc;
147		name = sdp->sd_name;
148		dfiles = &sdp->sd_aux->sa_dfiles;
149
150		/*
151		 * Files that define a symbol are saved on the
152		 * `sa_dfiles' list, if the head and tail of
153		 * this list differ there must have been more
154		 * than one symbol definition.  Ignore symbols
155		 * that aren't needed, and any special symbols
156		 * that the link editor may produce (symbols of
157		 * type ABS and COMMON are not recorded in the
158		 * first place, however functions like _init()
159		 * and _fini() commonly have multiple
160		 * occurrances).
161		 */
162		if ((sdp->sd_ref == REF_DYN_SEEN) ||
163		    (dfiles->head == dfiles->tail) ||
164		    (sdp->sd_aux && sdp->sd_aux->sa_symspec) ||
165		    (strcmp(MSG_ORIG(MSG_SYM_FINI_U), name) == 0) ||
166		    (strcmp(MSG_ORIG(MSG_SYM_INIT_U), name) == 0) ||
167		    (strcmp(MSG_ORIG(MSG_SYM_LIBVER_U), name) == 0))
168			continue;
169
170		if (symbol_title)
171			sym_muldef_title();
172
173		ducp = sdp->sd_file->ifl_name;
174		(void) printf(MSG_INTL(MSG_ENT_MUL_ENTRY_1), demangle(name),
175		    ducp);
176		for (LIST_TRAVERSE(dfiles, lnp2, adcp)) {
177			/*
178			 * Ignore the referenced symbol.
179			 */
180			if (strcmp(adcp, ducp) != 0)
181			    (void) printf(MSG_INTL(MSG_ENT_MUL_ENTRY_2), 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 */
190void
191ld_ent_check(Ofl_desc * ofl)
192{
193	Listnode *	lnp;
194	Ent_desc *	enp;
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 (LIST_TRAVERSE(&ofl->ofl_ents, lnp, enp)) {
204		if ((enp->ec_segment->sg_flags & FLG_SG_ORDER) &&
205		    !(enp->ec_flags & FLG_EC_USED) && enp->ec_ndx) {
206			Listnode *	_lnp = enp->ec_files.head;
207
208			if ((_lnp != NULL) && (_lnp->data != NULL) &&
209			    (char *)(_lnp->data) != NULL) {
210				eprintf(ofl->ofl_lml, ERR_WARNING,
211				    MSG_INTL(MSG_ENT_NOSEC_1),
212				    enp->ec_segment->sg_name, enp->ec_name,
213				    (const char *)(_lnp->data));
214			} else {
215				eprintf(ofl->ofl_lml, ERR_WARNING,
216				    MSG_INTL(MSG_ENT_NOSEC_2),
217				    enp->ec_segment->sg_name, enp->ec_name);
218			}
219		}
220	}
221}
222