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) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24  */
25 #include	<sgs.h>
26 #include	<stdio.h>
27 #include	<debug.h>
28 #include	<msg.h>
29 
30 void
Elf_syminfo_title(Lm_list * lml)31 Elf_syminfo_title(Lm_list *lml)
32 {
33 	dbg_print(lml, MSG_INTL(MSG_SYMINFO_TITLE));
34 }
35 
36 #define	FLAGSZ	16
37 #define	NDXSZ	10
38 
39 void
Elf_syminfo_entry(Lm_list * lml,Word ndx,Syminfo * sip,const char * name,const char * needed)40 Elf_syminfo_entry(Lm_list *lml, Word ndx, Syminfo *sip, const char *name,
41     const char *needed)
42 {
43 	const char	*bndstr = NULL, *str;
44 	char		flagstr[FLAGSZ], sndxstr[NDXSZ], dndxstr[NDXSZ];
45 	int		flgndx = 0;
46 	Half		flags = sip->si_flags;
47 
48 	if (flags & SYMINFO_FLG_CAP) {
49 		bndstr = MSG_INTL(MSG_SYMINFO_CAP);
50 		flagstr[flgndx++] = 'S';
51 		flags &= ~SYMINFO_FLG_CAP;
52 	}
53 
54 	if (flags & SYMINFO_FLG_DIRECT) {
55 		if (bndstr == NULL) {
56 			if (sip->si_boundto == SYMINFO_BT_SELF)
57 				bndstr = MSG_INTL(MSG_SYMINFO_SELF);
58 			else if (sip->si_boundto == SYMINFO_BT_PARENT)
59 				bndstr = MSG_INTL(MSG_SYMINFO_PARENT);
60 			else
61 				bndstr = needed;
62 		}
63 		flagstr[flgndx++] = 'D';
64 		flags &= ~SYMINFO_FLG_DIRECT;
65 
66 	} else if (flags & SYMINFO_FLG_FILTER) {
67 		bndstr = needed;
68 		flagstr[flgndx++] = 'F';
69 		flags &= ~SYMINFO_FLG_FILTER;
70 
71 	} else if (flags & SYMINFO_FLG_AUXILIARY) {
72 		bndstr = needed;
73 		flagstr[flgndx++] = 'A';
74 		flags &= ~SYMINFO_FLG_AUXILIARY;
75 
76 	} else if (sip->si_boundto == SYMINFO_BT_EXTERN)
77 		bndstr = MSG_INTL(MSG_SYMINFO_EXTERN);
78 	else if (bndstr == NULL)
79 		bndstr = MSG_ORIG(MSG_STR_EMPTY);
80 
81 	if (flags & SYMINFO_FLG_DIRECTBIND) {
82 		flagstr[flgndx++] = 'B';
83 		flags &= ~SYMINFO_FLG_DIRECTBIND;
84 	}
85 	if (flags & SYMINFO_FLG_COPY) {
86 		flagstr[flgndx++] = 'C';
87 		flags &= ~SYMINFO_FLG_COPY;
88 	}
89 	if (flags & SYMINFO_FLG_LAZYLOAD) {
90 		flagstr[flgndx++] = 'L';
91 		flags &= ~SYMINFO_FLG_LAZYLOAD;
92 	}
93 	if (flags & SYMINFO_FLG_NOEXTDIRECT) {
94 		flagstr[flgndx++] = 'N';
95 		flags &= ~SYMINFO_FLG_NOEXTDIRECT;
96 	}
97 	if (flags & SYMINFO_FLG_INTERPOSE) {
98 		flagstr[flgndx++] = 'I';
99 		flags &= ~SYMINFO_FLG_INTERPOSE;
100 	}
101 	if (flags & SYMINFO_FLG_DEFERRED) {
102 		flagstr[flgndx++] = 'P';
103 		flags &= ~SYMINFO_FLG_DEFERRED;
104 	}
105 
106 	/*
107 	 * Did we account for all of the flags?
108 	 */
109 	if (flags)
110 		(void) snprintf(&flagstr[flgndx], FLAGSZ - flgndx,
111 		    MSG_ORIG(MSG_SYMINFO_UNKFLAG), flags);
112 	else
113 		flagstr[flgndx] = '\0';
114 
115 	/*
116 	 * If we've bound to a dependency, determine the dynamic entry index.
117 	 */
118 	if (bndstr == needed) {
119 		(void) snprintf(dndxstr, NDXSZ, MSG_ORIG(MSG_FMT_INDEX),
120 		    sip->si_boundto);
121 		str = dndxstr;
122 	} else
123 		str = MSG_ORIG(MSG_STR_EMPTY);
124 
125 	(void) snprintf(sndxstr, NDXSZ, MSG_ORIG(MSG_FMT_INDEX), ndx);
126 
127 	dbg_print(lml, MSG_INTL(MSG_SYMINFO_ENTRY), sndxstr, flagstr, str,
128 	    bndstr, Elf_demangle_name(name));
129 }
130