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 2010 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include	<stdio.h>
28 #include	"msg.h"
29 #include	"_debug.h"
30 #include	"libld.h"
31 
32 /*
33  * Print out a single `segment descriptor' entry.
34  */
35 void
Dbg_seg_desc_entry(Lm_list * lml,uchar_t osabi,Half mach,int ndx,Sg_desc * sgp,Boolean space_nl)36 Dbg_seg_desc_entry(Lm_list *lml, uchar_t osabi, Half mach, int ndx,
37     Sg_desc *sgp, Boolean space_nl)
38 {
39 	Conv_seg_flags_buf_t	seg_flags_buf;
40 	Aliste			idx;
41 	Sym_desc		*sdp;
42 
43 	if (space_nl)
44 		Dbg_util_nl(lml, DBG_NL_STD);
45 	dbg_print(lml, MSG_ORIG(MSG_SEG_DESC), ndx);
46 	if (sgp->sg_name)
47 		dbg_print(lml, MSG_ORIG(MSG_SEG_NAME), sgp->sg_name);
48 
49 	dbg_print(lml, MSG_ORIG(MSG_SEG_FLAGS),
50 	    conv_seg_flags(sgp->sg_flags, &seg_flags_buf));
51 
52 	Elf_phdr(lml, osabi, mach, &sgp->sg_phdr);
53 
54 	if (sgp->sg_flags & FLG_SG_P_ALIGN)
55 		dbg_print(lml, MSG_ORIG(MSG_SEG_ALIGN),
56 		    EC_ADDR(sgp->sg_align));
57 
58 	if (sgp->sg_flags & FLG_SG_LENGTH)
59 		dbg_print(lml, MSG_ORIG(MSG_SEG_LENGTH),
60 		    EC_ADDR(sgp->sg_length));
61 
62 	if (sgp->sg_flags & FLG_SG_ROUND)
63 		dbg_print(lml, MSG_ORIG(MSG_SEG_ROUND),
64 		    EC_ADDR(sgp->sg_round));
65 
66 	if (aplist_nitems(sgp->sg_sizesym) > 0) {
67 		dbg_print(lml, MSG_ORIG(MSG_SEG_SIZESYM_TITLE));
68 		for (APLIST_TRAVERSE(sgp->sg_sizesym, idx, sdp))
69 			if (sdp->sd_name)
70 				dbg_print(lml, MSG_ORIG(MSG_SEG_SIZESYM),
71 				    Dbg_demangle_name(sdp->sd_name));
72 	}
73 	if (aplist_nitems(sgp->sg_is_order) > 0) {
74 		Aliste		idx;
75 		Ent_desc	*enp;
76 
77 		dbg_print(lml, MSG_ORIG(MSG_SEG_IS_ORDER_TITLE));
78 		for (APLIST_TRAVERSE(sgp->sg_is_order, idx, enp))
79 			dbg_print(lml, MSG_ORIG(MSG_SEG_LIST_ITEM),
80 			    enp->ec_name);
81 	}
82 	if (alist_nitems(sgp->sg_os_order) > 0) {
83 		Aliste		idx;
84 		Sec_order	*scop;
85 
86 		dbg_print(lml, MSG_ORIG(MSG_SEG_OS_ORDER_TITLE));
87 		for (ALIST_TRAVERSE(sgp->sg_os_order, idx, scop))
88 			dbg_print(lml, MSG_ORIG(MSG_SEG_LIST_ITEM),
89 			    scop->sco_secname);
90 	}
91 	if (space_nl)
92 		Dbg_util_nl(lml, DBG_NL_STD);
93 }
94 
95 void
Dbg_seg_title(Lm_list * lml)96 Dbg_seg_title(Lm_list *lml)
97 {
98 	if (DBG_NOTCLASS(DBG_C_SEGMENTS))
99 		return;
100 
101 	Dbg_util_nl(lml, DBG_NL_STD);
102 	dbg_print(lml, MSG_INTL(MSG_SEG_DESC_INUSE));
103 }
104 
105 void
Dbg_seg_entry(Ofl_desc * ofl,int ndx,Sg_desc * sgp)106 Dbg_seg_entry(Ofl_desc *ofl, int ndx, Sg_desc *sgp)
107 {
108 	if (DBG_NOTCLASS(DBG_C_SEGMENTS))
109 		return;
110 
111 	Dbg_seg_desc_entry(ofl->ofl_lml, ofl->ofl_dehdr->e_ident[EI_OSABI],
112 	    ofl->ofl_dehdr->e_machine, ndx, sgp, TRUE);
113 }
114 
115 /*
116  * Print out the available segment descriptors.
117  */
118 void
Dbg_seg_list(Lm_list * lml,uchar_t osabi,Half mach,APlist * apl)119 Dbg_seg_list(Lm_list *lml, uchar_t osabi, Half mach, APlist *apl)
120 {
121 	Aliste		idx;
122 	Sg_desc		*sgp;
123 	int		ndx = 0;
124 
125 	if (DBG_NOTCLASS(DBG_C_SEGMENTS))
126 		return;
127 
128 	Dbg_util_nl(lml, DBG_NL_STD);
129 	dbg_print(lml, MSG_INTL(MSG_SEG_DESC_AVAIL));
130 	for (APLIST_TRAVERSE(apl, idx, sgp))
131 		Dbg_seg_desc_entry(lml, osabi, mach, ndx++, sgp, TRUE);
132 }
133 
134 /*
135  * Print the output section information.  This includes the section header
136  * information and the output elf buffer information.  If the detail flag is
137  * set, traverse the input sections displaying all the input buffers that
138  * have been concatenated to form this output buffer.
139  */
140 void
Dbg_seg_os(Ofl_desc * ofl,Os_desc * osp,int ndx)141 Dbg_seg_os(Ofl_desc *ofl, Os_desc *osp, int ndx)
142 {
143 	Conv_inv_buf_t	inv_buf;
144 	Lm_list		*lml = ofl->ofl_lml;
145 	Aliste		idx;
146 	Is_desc		*isp;
147 	Elf_Data	*data;
148 	Shdr		*shdr;
149 	const char	*empty = MSG_ORIG(MSG_STR_EMPTY);
150 	int		os_isdescs_idx;
151 
152 	if (DBG_NOTCLASS(DBG_C_SEGMENTS))
153 		return;
154 
155 	dbg_print(lml, MSG_ORIG(MSG_SEC_NAME), ndx, osp->os_name);
156 	Elf_shdr(lml, ofl->ofl_dehdr->e_ident[EI_OSABI],
157 	    ofl->ofl_dehdr->e_machine, osp->os_shdr);
158 	dbg_print(lml, MSG_INTL(MSG_EDATA_TITLE));
159 
160 	shdr = osp->os_shdr;
161 	data = osp->os_outdata;
162 	dbg_print(lml, MSG_INTL(MSG_EDATA_ENTRY), MSG_INTL(MSG_STR_OUT),
163 	    EC_ADDR(shdr->sh_addr), conv_elfdata_type(data->d_type, &inv_buf),
164 	    EC_XWORD(data->d_size), EC_OFF(data->d_off),
165 	    EC_XWORD(data->d_align), empty, empty, empty);
166 
167 	if (DBG_NOTDETAIL())
168 		return;
169 
170 	OS_ISDESCS_TRAVERSE(os_isdescs_idx, osp, idx, isp) {
171 		dbg_isec_name_buf_t	buf;
172 		char			*alloc_mem;
173 		const char		*file, *str;
174 		Addr			addr;
175 
176 		data = isp->is_indata;
177 
178 		if (isp->is_flags & FLG_IS_DISCARD) {
179 			str = MSG_INTL(MSG_EDATA_IGNSCN);
180 			addr = 0;
181 		} else {
182 			str = empty;
183 			addr = (Addr)(shdr->sh_addr + data->d_off);
184 		}
185 
186 		if (isp->is_file && isp->is_file->ifl_name)
187 			file = isp->is_file->ifl_name;
188 		else
189 			file = empty;
190 
191 		dbg_print(lml, MSG_INTL(MSG_EDATA_ENTRY), MSG_INTL(MSG_STR_IN),
192 		    EC_ADDR(addr), conv_elfdata_type(data->d_type, &inv_buf),
193 		    EC_XWORD(data->d_size), EC_OFF(data->d_off),
194 		    EC_XWORD(data->d_align), file,
195 		    dbg_fmt_isec_name(isp, buf, &alloc_mem), str);
196 		if (alloc_mem != NULL)
197 			free(alloc_mem);
198 	}
199 }
200