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
30void
31Elf_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
39void
40Elf_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