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