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