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 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include	"msg.h"
29 #include	"_debug.h"
30 #include	"libld.h"
31 
32 
33 /*
34  * Print out a single `segment descriptor' entry.
35  */
36 void
37 Dbg_seg_desc_entry(Lm_list *lml, Half mach, int ndx, Sg_desc *sgp)
38 {
39 	Conv_seg_flags_buf_t	seg_flags_buf;
40 	const char		*str;
41 
42 	if (sgp->sg_name && *sgp->sg_name)
43 		str = sgp->sg_name;
44 	else
45 		str = MSG_INTL(MSG_STR_NULL);
46 
47 	Dbg_util_nl(lml, DBG_NL_STD);
48 	dbg_print(lml, MSG_ORIG(MSG_SEG_NAME), ndx, str);
49 
50 	Elf_phdr(lml, mach, &sgp->sg_phdr);
51 
52 	dbg_print(lml, MSG_ORIG(MSG_SEG_LENGTH), EC_ADDR(sgp->sg_length));
53 	dbg_print(lml, MSG_ORIG(MSG_SEG_FLAGS),
54 	    conv_seg_flags(sgp->sg_flags, &seg_flags_buf));
55 
56 	if (sgp->sg_sizesym && sgp->sg_sizesym->sd_name)
57 		dbg_print(lml, MSG_ORIG(MSG_SEG_SIZESYM),
58 		    Dbg_demangle_name(sgp->sg_sizesym->sd_name));
59 
60 	if (sgp->sg_secorder) {
61 		Aliste		off;
62 		Sec_order	**scopp;
63 
64 		dbg_print(lml, MSG_ORIG(MSG_SEG_ORDER));
65 		for (ALIST_TRAVERSE(sgp->sg_secorder, off, scopp)) {
66 			Sec_order	*scop = *scopp;
67 
68 			dbg_print(lml, MSG_ORIG(MSG_SEG_SECTION),
69 			    scop->sco_secname, EC_WORD(scop->sco_index));
70 		}
71 	}
72 	Dbg_util_nl(lml, DBG_NL_STD);
73 }
74 
75 void
76 Dbg_seg_title(Lm_list *lml)
77 {
78 	if (DBG_NOTCLASS(DBG_C_SEGMENTS))
79 		return;
80 
81 	Dbg_util_nl(lml, DBG_NL_STD);
82 	dbg_print(lml, MSG_INTL(MSG_SEG_DESC_INUSE));
83 }
84 
85 void
86 Dbg_seg_entry(Ofl_desc *ofl, int ndx, Sg_desc *sgp)
87 {
88 	if (DBG_NOTCLASS(DBG_C_SEGMENTS))
89 		return;
90 
91 	Dbg_seg_desc_entry(ofl->ofl_lml, ofl->ofl_dehdr->e_machine, ndx, sgp);
92 }
93 
94 /*
95  * Print out the available segment descriptors.
96  */
97 void
98 Dbg_seg_list(Lm_list *lml, Half mach, List *lsg)
99 {
100 	Listnode	*lnp;
101 	Sg_desc		*sgp;
102 	int		ndx = 0;
103 
104 	if (DBG_NOTCLASS(DBG_C_SEGMENTS))
105 		return;
106 
107 	Dbg_util_nl(lml, DBG_NL_STD);
108 	dbg_print(lml, MSG_INTL(MSG_SEG_DESC_AVAIL));
109 	for (LIST_TRAVERSE(lsg, lnp, sgp))
110 		Dbg_seg_desc_entry(lml, mach, ndx++, sgp);
111 }
112 
113 /*
114  * Print the output section information.  This includes the section header
115  * information and the output elf buffer information.  If the detail flag is
116  * set, traverse the input sections displaying all the input buffers that
117  * have been concatenated to form this output buffer.
118  */
119 void
120 Dbg_seg_os(Ofl_desc *ofl, Os_desc *osp, int ndx)
121 {
122 	Conv_inv_buf_t	inv_buf;
123 	Lm_list		*lml = ofl->ofl_lml;
124 	Listnode	*lnp;
125 	Is_desc		*isp;
126 	Elf_Data	*data;
127 	Shdr		*shdr;
128 
129 	if (DBG_NOTCLASS(DBG_C_SEGMENTS))
130 		return;
131 
132 	dbg_print(lml, MSG_ORIG(MSG_SEC_NAME), ndx, osp->os_name);
133 	Elf_shdr(lml, ofl->ofl_dehdr->e_machine, osp->os_shdr);
134 	dbg_print(lml, MSG_INTL(MSG_EDATA_TITLE));
135 
136 	shdr = osp->os_shdr;
137 	data = osp->os_outdata;
138 	dbg_print(lml, MSG_INTL(MSG_EDATA_ENTRY), MSG_INTL(MSG_STR_OUT),
139 	    EC_ADDR(shdr->sh_addr), conv_elfdata_type(data->d_type, &inv_buf),
140 	    EC_XWORD(data->d_size), EC_OFF(data->d_off),
141 	    EC_XWORD(data->d_align), MSG_ORIG(MSG_STR_EMPTY),
142 	    MSG_ORIG(MSG_STR_EMPTY));
143 
144 	if (DBG_NOTDETAIL())
145 		return;
146 
147 	for (LIST_TRAVERSE(&(osp->os_isdescs), lnp, isp)) {
148 		const char	*file, *str;
149 		Addr		addr;
150 
151 		data = isp->is_indata;
152 
153 		if (isp->is_flags & FLG_IS_DISCARD) {
154 			str = MSG_INTL(MSG_EDATA_IGNSCN);
155 			addr = 0;
156 		} else {
157 			str = MSG_ORIG(MSG_STR_EMPTY);
158 			addr = (Addr)(shdr->sh_addr + data->d_off);
159 		}
160 
161 		if (isp->is_file && isp->is_file->ifl_name)
162 			file = isp->is_file->ifl_name;
163 		else
164 			file = MSG_ORIG(MSG_STR_EMPTY);
165 
166 		dbg_print(lml, MSG_INTL(MSG_EDATA_ENTRY), MSG_INTL(MSG_STR_IN),
167 		    EC_ADDR(addr), conv_elfdata_type(data->d_type, &inv_buf),
168 		    EC_XWORD(data->d_size), EC_OFF(data->d_off),
169 		    EC_XWORD(data->d_align), file, str);
170 	}
171 }
172