segments.c revision 1618:8c9a4f31d225
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.head) {
60		Listnode	*lnp;
61		Sec_order	*scop;
62
63		dbg_print(lml, MSG_ORIG(MSG_SEG_ORDER));
64		for (LIST_TRAVERSE(&sgp->sg_secorder, lnp, scop)) {
65			dbg_print(lml, MSG_ORIG(MSG_SEG_SECTION),
66			    scop->sco_secname, EC_WORD(scop->sco_index));
67		}
68	}
69}
70
71void
72Dbg_seg_title(Lm_list *lml)
73{
74	if (DBG_NOTCLASS(DBG_C_SEGMENTS))
75		return;
76
77	Dbg_util_nl(lml, DBG_NL_STD);
78	dbg_print(lml, MSG_INTL(MSG_SEG_DESC_INUSE));
79}
80
81void
82Dbg_seg_entry(Ofl_desc *ofl, int ndx, Sg_desc *sgp)
83{
84	if (DBG_NOTCLASS(DBG_C_SEGMENTS))
85		return;
86
87	Dbg_seg_desc_entry(ofl->ofl_lml, ofl->ofl_dehdr->e_machine, ndx, sgp);
88}
89
90/*
91 * Print out the available segment descriptors.
92 */
93void
94Dbg_seg_list(Lm_list *lml, Half mach, List *lsg)
95{
96	Listnode	*lnp;
97	Sg_desc		*sgp;
98	int		ndx = 0;
99
100	if (DBG_NOTCLASS(DBG_C_SEGMENTS))
101		return;
102
103	Dbg_util_nl(lml, DBG_NL_STD);
104	dbg_print(lml, MSG_INTL(MSG_SEG_DESC_AVAIL));
105	for (LIST_TRAVERSE(lsg, lnp, sgp))
106		Dbg_seg_desc_entry(lml, mach, ndx++, sgp);
107}
108
109/*
110 * Print the output section information.  This includes the section header
111 * information and the output elf buffer information.  If the detail flag is
112 * set, traverse the input sections displaying all the input buffers that
113 * have been concatenated to form this output buffer.
114 */
115void
116Dbg_seg_os(Ofl_desc *ofl, Os_desc *osp, int ndx)
117{
118	Lm_list		*lml = ofl->ofl_lml;
119	Listnode	*lnp;
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),
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 (LIST_TRAVERSE(&(osp->os_isdescs), lnp, 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),
163		    EC_XWORD(data->d_size), EC_OFF(data->d_off),
164		    EC_XWORD(data->d_align), file, str);
165	}
166}
167