xref: /illumos-gate/usr/src/cmd/sgs/libld/common/ldentry.c (revision 8b891ae8)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
55aefb655Srie  * Common Development and Distribution License (the "License").
65aefb655Srie  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
215aefb655Srie 
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  *	Copyright (c) 1988 AT&T
247c478bd9Sstevel@tonic-gate  *	  All Rights Reserved
257c478bd9Sstevel@tonic-gate  *
261007fd6fSAli Bahrami  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
277c478bd9Sstevel@tonic-gate  */
287c478bd9Sstevel@tonic-gate 
297d732bb0SJohn Levon /*
307d732bb0SJohn Levon  * Copyright (c) 2018, Joyent, Inc.
317d732bb0SJohn Levon  */
327d732bb0SJohn Levon 
337c478bd9Sstevel@tonic-gate #include	<stdio.h>
347c478bd9Sstevel@tonic-gate #include	<string.h>
357c478bd9Sstevel@tonic-gate #include	"msg.h"
367c478bd9Sstevel@tonic-gate #include	"_libld.h"
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate /*
407c478bd9Sstevel@tonic-gate  * Print a virtual address map of input and output sections together with
417c478bd9Sstevel@tonic-gate  * multiple symbol definitions (if they exist).
427c478bd9Sstevel@tonic-gate  */
437c478bd9Sstevel@tonic-gate static Boolean	symbol_title = TRUE;
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate static void
sym_muldef_title()467c478bd9Sstevel@tonic-gate sym_muldef_title()
477c478bd9Sstevel@tonic-gate {
487c478bd9Sstevel@tonic-gate 	(void) printf(MSG_INTL(MSG_ENT_MUL_FMT_TIL_0),
497c478bd9Sstevel@tonic-gate 	    MSG_INTL(MSG_ENT_MUL_TIL_0));
507c478bd9Sstevel@tonic-gate 	(void) printf(MSG_INTL(MSG_ENT_MUL_FMT_TIL_1),
517c478bd9Sstevel@tonic-gate 	    MSG_INTL(MSG_ENT_MUL_ITM_SYM),
527c478bd9Sstevel@tonic-gate 	    MSG_INTL(MSG_ENT_MUL_ITM_DEF_0),
537c478bd9Sstevel@tonic-gate 	    MSG_INTL(MSG_ENT_MUL_ITM_DEF_1));
547c478bd9Sstevel@tonic-gate 	symbol_title = FALSE;
557c478bd9Sstevel@tonic-gate }
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate void
ld_map_out(Ofl_desc * ofl)585aefb655Srie ld_map_out(Ofl_desc *ofl)
597c478bd9Sstevel@tonic-gate {
607c478bd9Sstevel@tonic-gate 	Sg_desc		*sgp;
617c478bd9Sstevel@tonic-gate 	Is_desc		*isp;
627c478bd9Sstevel@tonic-gate 	Sym_avlnode	*sav;
6357ef7aa9SRod Evans 	Aliste		idx1;
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate 	(void) printf(MSG_INTL(MSG_ENT_MAP_FMT_TIL_1),
667c478bd9Sstevel@tonic-gate 	    MSG_INTL(MSG_ENT_MAP_TITLE_1));
677c478bd9Sstevel@tonic-gate 	if (ofl->ofl_flags & FLG_OF_RELOBJ)
687c478bd9Sstevel@tonic-gate 		(void) printf(MSG_INTL(MSG_ENT_MAP_FMT_TIL_2),
697c478bd9Sstevel@tonic-gate 		    MSG_INTL(MSG_ENT_ITM_OUTPUT),
707c478bd9Sstevel@tonic-gate 		    MSG_INTL(MSG_ENT_ITM_INPUT),
717c478bd9Sstevel@tonic-gate 		    MSG_INTL(MSG_ENT_ITM_NEW),
727c478bd9Sstevel@tonic-gate 		    MSG_INTL(MSG_ENT_ITM_SECTION),
737c478bd9Sstevel@tonic-gate 		    MSG_INTL(MSG_ENT_ITM_SECTION),
747c478bd9Sstevel@tonic-gate 		    MSG_INTL(MSG_ENT_ITM_DISPMNT),
757c478bd9Sstevel@tonic-gate 		    MSG_INTL(MSG_ENT_ITM_SIZE));
767c478bd9Sstevel@tonic-gate 	else
777c478bd9Sstevel@tonic-gate 		(void) printf(MSG_INTL(MSG_ENT_MAP_FMT_TIL_3),
787c478bd9Sstevel@tonic-gate 		    MSG_INTL(MSG_ENT_ITM_OUTPUT),
797c478bd9Sstevel@tonic-gate 		    MSG_INTL(MSG_ENT_ITM_INPUT),
807c478bd9Sstevel@tonic-gate 		    MSG_INTL(MSG_ENT_ITM_VIRTUAL),
817c478bd9Sstevel@tonic-gate 		    MSG_INTL(MSG_ENT_ITM_SECTION),
827c478bd9Sstevel@tonic-gate 		    MSG_INTL(MSG_ENT_ITM_SECTION),
837c478bd9Sstevel@tonic-gate 		    MSG_INTL(MSG_ENT_ITM_ADDRESS),
847c478bd9Sstevel@tonic-gate 		    MSG_INTL(MSG_ENT_ITM_SIZE));
857c478bd9Sstevel@tonic-gate 
8657ef7aa9SRod Evans 	for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp)) {
87cce0e03bSab196087 		Os_desc	*osp;
8857ef7aa9SRod Evans 		Aliste	idx2;
890bc07c75Srie 
907c478bd9Sstevel@tonic-gate 		if (sgp->sg_phdr.p_type != PT_LOAD)
917c478bd9Sstevel@tonic-gate 			continue;
927c478bd9Sstevel@tonic-gate 
9357ef7aa9SRod Evans 		for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) {
941dd9d86fSAli Bahrami 			int	os_isdescs_idx;
9557ef7aa9SRod Evans 			Aliste	idx3;
960bc07c75Srie 
977c478bd9Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_ENT_MAP_ENTRY_1),
987c478bd9Sstevel@tonic-gate 			    osp->os_name, EC_ADDR(osp->os_shdr->sh_addr),
997c478bd9Sstevel@tonic-gate 			    EC_XWORD(osp->os_shdr->sh_size));
1007c478bd9Sstevel@tonic-gate 
1011dd9d86fSAli Bahrami 			OS_ISDESCS_TRAVERSE(os_isdescs_idx, osp, idx3, isp) {
1027c478bd9Sstevel@tonic-gate 				Addr	addr;
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate 				/*
1057c478bd9Sstevel@tonic-gate 				 * Although there seems little point in printing
1067c478bd9Sstevel@tonic-gate 				 * discarded (empty) sections, especially as
1077c478bd9Sstevel@tonic-gate 				 * diagnostics under -Dsegments,details are more
1087c478bd9Sstevel@tonic-gate 				 * informative, continue printing them.  There
1097c478bd9Sstevel@tonic-gate 				 * are user scripts, fragile to say the least,
1107c478bd9Sstevel@tonic-gate 				 * that grep(1) through load-map output to
1117c478bd9Sstevel@tonic-gate 				 * discover object requirements.  These scripts
1127c478bd9Sstevel@tonic-gate 				 * don't grep for all input sections types (ie.
1137c478bd9Sstevel@tonic-gate 				 * .picdata), and have become dependent on null
1147c478bd9Sstevel@tonic-gate 				 * sections (ie. .text) existing in the
1157c478bd9Sstevel@tonic-gate 				 * load-map output.
1167c478bd9Sstevel@tonic-gate 				 */
117cce0e03bSab196087 				if (isp->is_flags & FLG_IS_DISCARD) {
1187c478bd9Sstevel@tonic-gate 					addr = 0;
119cce0e03bSab196087 				} else {
120cce0e03bSab196087 					addr = (Addr)
121cce0e03bSab196087 					    _elf_getxoff(isp->is_indata);
1227c478bd9Sstevel@tonic-gate 					if (!(ofl->ofl_flags & FLG_OF_RELOBJ))
123cce0e03bSab196087 						addr += isp->is_osdesc->
124cce0e03bSab196087 						    os_shdr->sh_addr;
1257c478bd9Sstevel@tonic-gate 				}
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_ENT_MAP_ENTRY_2),
1287c478bd9Sstevel@tonic-gate 				    isp->is_name, EC_ADDR(addr),
1297c478bd9Sstevel@tonic-gate 				    EC_XWORD(isp->is_shdr->sh_size),
1307c478bd9Sstevel@tonic-gate 				    ((isp->is_file != NULL) ?
1317c478bd9Sstevel@tonic-gate 				    (char *)(isp->is_file->ifl_name) :
1327c478bd9Sstevel@tonic-gate 				    MSG_INTL(MSG_STR_NULL)));
1337c478bd9Sstevel@tonic-gate 			}
1347c478bd9Sstevel@tonic-gate 		}
1357c478bd9Sstevel@tonic-gate 	}
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate 	if (ofl->ofl_flags & FLG_OF_RELOBJ)
1387c478bd9Sstevel@tonic-gate 		return;
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate 	/*
1417c478bd9Sstevel@tonic-gate 	 * Check for any multiply referenced symbols (ie. symbols that have
1427c478bd9Sstevel@tonic-gate 	 * been overridden from a shared library).
1437c478bd9Sstevel@tonic-gate 	 */
1447c478bd9Sstevel@tonic-gate 	for (sav = avl_first(&ofl->ofl_symavl); sav;
1457c478bd9Sstevel@tonic-gate 	    sav = AVL_NEXT(&ofl->ofl_symavl, sav)) {
146635216b6SRod Evans 		Sym_desc	*sdp = sav->sav_sdp;
14757ef7aa9SRod Evans 		const char	*name = sdp->sd_name, *ducp, *adcp;
14857ef7aa9SRod Evans 		APlist		*dfiles;
14957ef7aa9SRod Evans 		Aliste		idx;
1507c478bd9Sstevel@tonic-gate 
15157ef7aa9SRod Evans 		if (((dfiles = sdp->sd_aux->sa_dfiles) == NULL) ||
152*8b891ae8SRichard Lowe 		    (aplist_nitems(dfiles) <= 1))
15357ef7aa9SRod Evans 			continue;
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate 		/*
15657ef7aa9SRod Evans 		 * Files that define a symbol are saved on the `sa_dfiles' list.
15757ef7aa9SRod Evans 		 * Ignore symbols that aren't needed, and any special symbols
15857ef7aa9SRod Evans 		 * that the link editor may produce (symbols of type ABS and
15957ef7aa9SRod Evans 		 * COMMON are not recorded in the first place, however functions
16057ef7aa9SRod Evans 		 * like _init() and _fini() commonly have multiple occurrences).
1617c478bd9Sstevel@tonic-gate 		 */
1627c478bd9Sstevel@tonic-gate 		if ((sdp->sd_ref == REF_DYN_SEEN) ||
1637d732bb0SJohn Levon 		    (sdp->sd_aux->sa_symspec) ||
1647c478bd9Sstevel@tonic-gate 		    (strcmp(MSG_ORIG(MSG_SYM_FINI_U), name) == 0) ||
1657c478bd9Sstevel@tonic-gate 		    (strcmp(MSG_ORIG(MSG_SYM_INIT_U), name) == 0) ||
1667c478bd9Sstevel@tonic-gate 		    (strcmp(MSG_ORIG(MSG_SYM_LIBVER_U), name) == 0))
1677c478bd9Sstevel@tonic-gate 			continue;
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 		if (symbol_title)
1707c478bd9Sstevel@tonic-gate 			sym_muldef_title();
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate 		ducp = sdp->sd_file->ifl_name;
1735aefb655Srie 		(void) printf(MSG_INTL(MSG_ENT_MUL_ENTRY_1), demangle(name),
1745aefb655Srie 		    ducp);
17557ef7aa9SRod Evans 		for (APLIST_TRAVERSE(dfiles, idx, adcp)) {
1767c478bd9Sstevel@tonic-gate 			/*
1777c478bd9Sstevel@tonic-gate 			 * Ignore the referenced symbol.
1787c478bd9Sstevel@tonic-gate 			 */
1797c478bd9Sstevel@tonic-gate 			if (strcmp(adcp, ducp) != 0)
180cce0e03bSab196087 				(void) printf(MSG_INTL(MSG_ENT_MUL_ENTRY_2),
181cce0e03bSab196087 				    adcp);
1827c478bd9Sstevel@tonic-gate 		}
1837c478bd9Sstevel@tonic-gate 	}
1847c478bd9Sstevel@tonic-gate }
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate /*
1877c478bd9Sstevel@tonic-gate  * Traverse the entrance criteria list searching for those sections that haven't
1887c478bd9Sstevel@tonic-gate  * been met and print error message.  (only in the case of reordering)
1897c478bd9Sstevel@tonic-gate  */
1907c478bd9Sstevel@tonic-gate void
ld_ent_check(Ofl_desc * ofl)1915aefb655Srie ld_ent_check(Ofl_desc * ofl)
1927c478bd9Sstevel@tonic-gate {
1937c478bd9Sstevel@tonic-gate 	Ent_desc	*enp;
19457ef7aa9SRod Evans 	Aliste		ndx;
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate 	/*
1977c478bd9Sstevel@tonic-gate 	 *  Try to give as much information to the user about the specific
1987c478bd9Sstevel@tonic-gate 	 *  line in the mapfile.  If the line contains a file name then
1997c478bd9Sstevel@tonic-gate 	 *  output the filename too.  Hence we have two warning lines -
2007c478bd9Sstevel@tonic-gate 	 *  one for criterias where a filename is used and the other
2017c478bd9Sstevel@tonic-gate 	 *  for those without a filename.
2027c478bd9Sstevel@tonic-gate 	 */
20369112eddSAli Bahrami 	for (APLIST_TRAVERSE(ofl->ofl_ents, ndx, enp)) {
20469112eddSAli Bahrami 		/*
20569112eddSAli Bahrami 		 * No warning if any of the following hold:
20669112eddSAli Bahrami 		 * -	The segment has no entrance criteria requiring
20769112eddSAli Bahrami 		 *	input section sorting (FLG_SG_IS_ORDER not set).
20869112eddSAli Bahrami 		 * -	The entrance criteria was used to place a section.
20969112eddSAli Bahrami 		 * -	The specific entrance criteria does not require sorting
21069112eddSAli Bahrami 		 */
21169112eddSAli Bahrami 		if (((enp->ec_segment->sg_flags & FLG_SG_IS_ORDER) == 0) ||
21257ef7aa9SRod Evans 		    (enp->ec_flags & FLG_EC_USED) || (enp->ec_ordndx == 0))
21357ef7aa9SRod Evans 			continue;
21457ef7aa9SRod Evans 
21557ef7aa9SRod Evans 
21669112eddSAli Bahrami 		if (alist_nitems(enp->ec_files) > 0) {
2171007fd6fSAli Bahrami 			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_ENT_NOSEC_1),
2181007fd6fSAli Bahrami 			    enp->ec_segment->sg_name, enp->ec_is_name);
2197c478bd9Sstevel@tonic-gate 		} else {
2201007fd6fSAli Bahrami 			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_ENT_NOSEC_2),
2211007fd6fSAli Bahrami 			    enp->ec_segment->sg_name, enp->ec_is_name);
2227c478bd9Sstevel@tonic-gate 		}
2237c478bd9Sstevel@tonic-gate 	}
2247c478bd9Sstevel@tonic-gate }
225