1bc1f688bSRobert Mustacchi /*
2bc1f688bSRobert Mustacchi
3bc1f688bSRobert Mustacchi Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
4*4d9fdb46SRobert Mustacchi Portions Copyright (C) 2007-2011 David Anderson. All Rights Reserved.
5bc1f688bSRobert Mustacchi
6*4d9fdb46SRobert Mustacchi This program is free software; you can redistribute it
7*4d9fdb46SRobert Mustacchi and/or modify it under the terms of version 2.1 of the
8*4d9fdb46SRobert Mustacchi GNU Lesser General Public License as published by the Free
9*4d9fdb46SRobert Mustacchi Software Foundation.
10bc1f688bSRobert Mustacchi
11*4d9fdb46SRobert Mustacchi This program is distributed in the hope that it would be
12*4d9fdb46SRobert Mustacchi useful, but WITHOUT ANY WARRANTY; without even the implied
13*4d9fdb46SRobert Mustacchi warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14*4d9fdb46SRobert Mustacchi PURPOSE.
15bc1f688bSRobert Mustacchi
16*4d9fdb46SRobert Mustacchi Further, this software is distributed without any warranty
17*4d9fdb46SRobert Mustacchi that it is free of the rightful claim of any third person
18*4d9fdb46SRobert Mustacchi regarding infringement or the like. Any license provided
19*4d9fdb46SRobert Mustacchi herein, whether implied or otherwise, applies only to this
20*4d9fdb46SRobert Mustacchi software file. Patent licenses, if any, provided herein
21*4d9fdb46SRobert Mustacchi do not apply to combinations of this program with other
22*4d9fdb46SRobert Mustacchi software, or any other product whatsoever.
23bc1f688bSRobert Mustacchi
24*4d9fdb46SRobert Mustacchi You should have received a copy of the GNU Lesser General
25*4d9fdb46SRobert Mustacchi Public License along with this program; if not, write the
26*4d9fdb46SRobert Mustacchi Free Software Foundation, Inc., 51 Franklin Street - Fifth
27*4d9fdb46SRobert Mustacchi Floor, Boston MA 02110-1301, USA.
28bc1f688bSRobert Mustacchi
29bc1f688bSRobert Mustacchi */
30bc1f688bSRobert Mustacchi
31bc1f688bSRobert Mustacchi #include "config.h"
32bc1f688bSRobert Mustacchi #include <stdio.h>
33*4d9fdb46SRobert Mustacchi #include "dwarf_incl.h"
34*4d9fdb46SRobert Mustacchi #include "dwarf_alloc.h"
35*4d9fdb46SRobert Mustacchi #include "dwarf_error.h"
36*4d9fdb46SRobert Mustacchi #include "dwarf_util.h"
37*4d9fdb46SRobert Mustacchi #include "dwarfstring.h"
38bc1f688bSRobert Mustacchi #include "dwarf_global.h"
39bc1f688bSRobert Mustacchi
40bc1f688bSRobert Mustacchi
41bc1f688bSRobert Mustacchi #ifdef __sgi /* __sgi should only be defined for IRIX/MIPS. */
42bc1f688bSRobert Mustacchi /* The 'fixup' here intended for IRIX targets only.
43bc1f688bSRobert Mustacchi With a 2+GB Elf64 IRIX executable (under 4GB in size),
44bc1f688bSRobert Mustacchi some DIE offsets wrongly
45bc1f688bSRobert Mustacchi got the 32bit upper bit sign extended. For the cu-header
46bc1f688bSRobert Mustacchi offset in the .debug_pubnames section and in the
47bc1f688bSRobert Mustacchi .debug_aranges section.
48bc1f688bSRobert Mustacchi the 'varp' here is a pointer to an offset into .debug_info.
49bc1f688bSRobert Mustacchi We fix up the offset here if it seems advisable..
50bc1f688bSRobert Mustacchi
51bc1f688bSRobert Mustacchi As of June 2005 we have identified a series of mistakes
52bc1f688bSRobert Mustacchi in ldx64 that can cause this (64 bit values getting passed
53bc1f688bSRobert Mustacchi thru 32-bit signed knothole).
54bc1f688bSRobert Mustacchi */
55bc1f688bSRobert Mustacchi void
_dwarf_fix_up_offset_irix(Dwarf_Debug dbg,Dwarf_Unsigned * varp,char * caller_site_name)56bc1f688bSRobert Mustacchi _dwarf_fix_up_offset_irix(Dwarf_Debug dbg,
57bc1f688bSRobert Mustacchi Dwarf_Unsigned * varp, char *caller_site_name)
58bc1f688bSRobert Mustacchi {
59bc1f688bSRobert Mustacchi
60bc1f688bSRobert Mustacchi Dwarf_Unsigned var = *varp;
61bc1f688bSRobert Mustacchi
62bc1f688bSRobert Mustacchi #define UPPER33 0xffffffff80000000LL
63bc1f688bSRobert Mustacchi #define LOWER32 0xffffffffLL
64bc1f688bSRobert Mustacchi /* Restrict the hack to the known case. Upper 32 bits erroneously
65bc1f688bSRobert Mustacchi sign extended from lower 32 upper bit. */
66bc1f688bSRobert Mustacchi if ((var & UPPER33) == UPPER33) {
67bc1f688bSRobert Mustacchi var &= LOWER32;
68bc1f688bSRobert Mustacchi /* Apply the fix. Dreadful hack. */
69bc1f688bSRobert Mustacchi *varp = var;
70bc1f688bSRobert Mustacchi }
71bc1f688bSRobert Mustacchi #undef UPPER33
72bc1f688bSRobert Mustacchi #undef LOWER32
73bc1f688bSRobert Mustacchi return;
74bc1f688bSRobert Mustacchi }
75*4d9fdb46SRobert Mustacchi #endif /* __sgi */
76bc1f688bSRobert Mustacchi
77*4d9fdb46SRobert Mustacchi static void
dealloc_globals_chain(Dwarf_Debug dbg,Dwarf_Chain head_chain)78*4d9fdb46SRobert Mustacchi dealloc_globals_chain(Dwarf_Debug dbg,
79*4d9fdb46SRobert Mustacchi Dwarf_Chain head_chain)
80*4d9fdb46SRobert Mustacchi {
81*4d9fdb46SRobert Mustacchi Dwarf_Chain curr_chain = 0;
82*4d9fdb46SRobert Mustacchi Dwarf_Chain prev_chain = 0;
83*4d9fdb46SRobert Mustacchi int chaintype = DW_DLA_CHAIN;
84*4d9fdb46SRobert Mustacchi
85*4d9fdb46SRobert Mustacchi curr_chain = head_chain;
86*4d9fdb46SRobert Mustacchi for (; curr_chain; ) {
87*4d9fdb46SRobert Mustacchi void *item = curr_chain->ch_item;
88*4d9fdb46SRobert Mustacchi int itemtype = curr_chain->ch_itemtype;
89*4d9fdb46SRobert Mustacchi
90*4d9fdb46SRobert Mustacchi prev_chain = curr_chain;
91*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg, item,itemtype);
92*4d9fdb46SRobert Mustacchi prev_chain->ch_item = 0;
93*4d9fdb46SRobert Mustacchi curr_chain = curr_chain->ch_next;
94*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg, prev_chain, chaintype);
95*4d9fdb46SRobert Mustacchi }
96*4d9fdb46SRobert Mustacchi }
97bc1f688bSRobert Mustacchi
98bc1f688bSRobert Mustacchi int
dwarf_get_globals(Dwarf_Debug dbg,Dwarf_Global ** globals,Dwarf_Signed * return_count,Dwarf_Error * error)99bc1f688bSRobert Mustacchi dwarf_get_globals(Dwarf_Debug dbg,
100bc1f688bSRobert Mustacchi Dwarf_Global ** globals,
101bc1f688bSRobert Mustacchi Dwarf_Signed * return_count, Dwarf_Error * error)
102bc1f688bSRobert Mustacchi {
103bc1f688bSRobert Mustacchi int res = _dwarf_load_section(dbg, &dbg->de_debug_pubnames,error);
104bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
105bc1f688bSRobert Mustacchi return res;
106bc1f688bSRobert Mustacchi }
107*4d9fdb46SRobert Mustacchi if (!dbg->de_debug_pubnames.dss_size) {
108*4d9fdb46SRobert Mustacchi return DW_DLV_NO_ENTRY;
109*4d9fdb46SRobert Mustacchi }
110bc1f688bSRobert Mustacchi
111*4d9fdb46SRobert Mustacchi res = _dwarf_internal_get_pubnames_like_data(dbg,
112bc1f688bSRobert Mustacchi dbg->de_debug_pubnames.dss_data,
113bc1f688bSRobert Mustacchi dbg->de_debug_pubnames.dss_size,
114bc1f688bSRobert Mustacchi globals,
115bc1f688bSRobert Mustacchi return_count,
116bc1f688bSRobert Mustacchi error,
117bc1f688bSRobert Mustacchi DW_DLA_GLOBAL_CONTEXT,
118bc1f688bSRobert Mustacchi DW_DLA_GLOBAL,
119bc1f688bSRobert Mustacchi DW_DLE_PUBNAMES_LENGTH_BAD,
120bc1f688bSRobert Mustacchi DW_DLE_PUBNAMES_VERSION_ERROR);
121*4d9fdb46SRobert Mustacchi return res;
122bc1f688bSRobert Mustacchi
123bc1f688bSRobert Mustacchi }
124bc1f688bSRobert Mustacchi
125bc1f688bSRobert Mustacchi /* Deallocating fully requires deallocating the list
126bc1f688bSRobert Mustacchi and all entries. But some internal data is
127bc1f688bSRobert Mustacchi not exposed, so we need a function with internal knowledge.
128bc1f688bSRobert Mustacchi */
129bc1f688bSRobert Mustacchi
130bc1f688bSRobert Mustacchi void
dwarf_globals_dealloc(Dwarf_Debug dbg,Dwarf_Global * dwgl,Dwarf_Signed count)131bc1f688bSRobert Mustacchi dwarf_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl,
132bc1f688bSRobert Mustacchi Dwarf_Signed count)
133bc1f688bSRobert Mustacchi {
134bc1f688bSRobert Mustacchi _dwarf_internal_globals_dealloc(dbg, dwgl,
135bc1f688bSRobert Mustacchi count,
136bc1f688bSRobert Mustacchi DW_DLA_GLOBAL_CONTEXT,
137bc1f688bSRobert Mustacchi DW_DLA_GLOBAL, DW_DLA_LIST);
138bc1f688bSRobert Mustacchi return;
139bc1f688bSRobert Mustacchi }
140bc1f688bSRobert Mustacchi
141bc1f688bSRobert Mustacchi void
_dwarf_internal_globals_dealloc(Dwarf_Debug dbg,Dwarf_Global * dwgl,Dwarf_Signed count,int context_DLA_code,int global_DLA_code,int list_DLA_code)142bc1f688bSRobert Mustacchi _dwarf_internal_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl,
143bc1f688bSRobert Mustacchi Dwarf_Signed count,
144*4d9fdb46SRobert Mustacchi int context_DLA_code,
145*4d9fdb46SRobert Mustacchi int global_DLA_code, int list_DLA_code)
146bc1f688bSRobert Mustacchi {
147bc1f688bSRobert Mustacchi Dwarf_Signed i;
148*4d9fdb46SRobert Mustacchi struct Dwarf_Global_Context_s *glcp = 0;
149*4d9fdb46SRobert Mustacchi struct Dwarf_Global_Context_s *lastglcp = 0;
150bc1f688bSRobert Mustacchi
151*4d9fdb46SRobert Mustacchi if(!dwgl) {
152*4d9fdb46SRobert Mustacchi return;
153*4d9fdb46SRobert Mustacchi }
154bc1f688bSRobert Mustacchi for (i = 0; i < count; i++) {
155bc1f688bSRobert Mustacchi Dwarf_Global dgb = dwgl[i];
156bc1f688bSRobert Mustacchi
157*4d9fdb46SRobert Mustacchi if (!dgb) {
158*4d9fdb46SRobert Mustacchi continue;
159bc1f688bSRobert Mustacchi }
160*4d9fdb46SRobert Mustacchi /* Avoids duplicate frees of repeated
161*4d9fdb46SRobert Mustacchi use of contexts (while assuming that
162*4d9fdb46SRobert Mustacchi all uses of a particular gl_context
163*4d9fdb46SRobert Mustacchi will appear next to each other. */
164*4d9fdb46SRobert Mustacchi glcp = dgb->gl_context;
165*4d9fdb46SRobert Mustacchi if (lastglcp != glcp) {
166*4d9fdb46SRobert Mustacchi lastglcp = glcp;
167*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg, glcp, context_DLA_code);
168bc1f688bSRobert Mustacchi }
169*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg, dgb, global_DLA_code);
170*4d9fdb46SRobert Mustacchi }
171*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg, dwgl, list_DLA_code);
172bc1f688bSRobert Mustacchi return;
173bc1f688bSRobert Mustacchi }
174bc1f688bSRobert Mustacchi
175*4d9fdb46SRobert Mustacchi /* Sweeps the complete section. */
176bc1f688bSRobert Mustacchi int
_dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg,Dwarf_Small * section_data_ptr,Dwarf_Unsigned section_length,Dwarf_Global ** globals,Dwarf_Signed * return_count,Dwarf_Error * error,int context_DLA_code,int global_DLA_code,int length_err_num,int version_err_num)177bc1f688bSRobert Mustacchi _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg,
178bc1f688bSRobert Mustacchi Dwarf_Small * section_data_ptr,
179bc1f688bSRobert Mustacchi Dwarf_Unsigned section_length,
180bc1f688bSRobert Mustacchi Dwarf_Global ** globals,
181bc1f688bSRobert Mustacchi Dwarf_Signed * return_count,
182bc1f688bSRobert Mustacchi Dwarf_Error * error,
183*4d9fdb46SRobert Mustacchi int context_DLA_code,
184*4d9fdb46SRobert Mustacchi int global_DLA_code,
185bc1f688bSRobert Mustacchi int length_err_num,
186bc1f688bSRobert Mustacchi int version_err_num)
187bc1f688bSRobert Mustacchi {
188bc1f688bSRobert Mustacchi Dwarf_Small *pubnames_like_ptr = 0;
189*4d9fdb46SRobert Mustacchi Dwarf_Off pubnames_section_offset = 0;
190*4d9fdb46SRobert Mustacchi Dwarf_Small *section_end_ptr = section_data_ptr +section_length;
191bc1f688bSRobert Mustacchi
192bc1f688bSRobert Mustacchi /* Points to the context for the current set of global names, and
193bc1f688bSRobert Mustacchi contains information to identify the compilation-unit that the
194bc1f688bSRobert Mustacchi set refers to. */
195bc1f688bSRobert Mustacchi Dwarf_Global_Context pubnames_context = 0;
196bc1f688bSRobert Mustacchi
197*4d9fdb46SRobert Mustacchi Dwarf_Unsigned version = 0;
198bc1f688bSRobert Mustacchi
199*4d9fdb46SRobert Mustacchi /* Offset from the start of compilation-unit for the current
200bc1f688bSRobert Mustacchi global. */
201bc1f688bSRobert Mustacchi Dwarf_Off die_offset_in_cu = 0;
202bc1f688bSRobert Mustacchi
203bc1f688bSRobert Mustacchi Dwarf_Unsigned global_count = 0;
204bc1f688bSRobert Mustacchi
205bc1f688bSRobert Mustacchi /* Points to the current global read. */
206bc1f688bSRobert Mustacchi Dwarf_Global global = 0;
207bc1f688bSRobert Mustacchi
208bc1f688bSRobert Mustacchi /* Used to chain the Dwarf_Global_s structs for creating contiguous
209bc1f688bSRobert Mustacchi list of pointers to the structs. */
210bc1f688bSRobert Mustacchi Dwarf_Chain curr_chain = 0;
211bc1f688bSRobert Mustacchi Dwarf_Chain prev_chain = 0;
212bc1f688bSRobert Mustacchi Dwarf_Chain head_chain = 0;
213bc1f688bSRobert Mustacchi
214bc1f688bSRobert Mustacchi /* Points to contiguous block of Dwarf_Global's to be returned. */
215bc1f688bSRobert Mustacchi Dwarf_Global *ret_globals = 0;
216*4d9fdb46SRobert Mustacchi int mres = 0;
217bc1f688bSRobert Mustacchi
218bc1f688bSRobert Mustacchi /* Temporary counter. */
219bc1f688bSRobert Mustacchi Dwarf_Unsigned i = 0;
220bc1f688bSRobert Mustacchi
221bc1f688bSRobert Mustacchi if (dbg == NULL) {
222bc1f688bSRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
223bc1f688bSRobert Mustacchi return (DW_DLV_ERROR);
224bc1f688bSRobert Mustacchi }
225bc1f688bSRobert Mustacchi /* We will eventually need the .debug_info data. Load it now. */
226bc1f688bSRobert Mustacchi if (!dbg->de_debug_info.dss_data) {
227bc1f688bSRobert Mustacchi int res = _dwarf_load_debug_info(dbg, error);
228bc1f688bSRobert Mustacchi
229bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
230bc1f688bSRobert Mustacchi return res;
231bc1f688bSRobert Mustacchi }
232bc1f688bSRobert Mustacchi }
233bc1f688bSRobert Mustacchi if (section_data_ptr == NULL) {
234bc1f688bSRobert Mustacchi return (DW_DLV_NO_ENTRY);
235bc1f688bSRobert Mustacchi }
236bc1f688bSRobert Mustacchi pubnames_like_ptr = section_data_ptr;
237bc1f688bSRobert Mustacchi do {
238bc1f688bSRobert Mustacchi Dwarf_Unsigned length = 0;
239bc1f688bSRobert Mustacchi int local_extension_size = 0;
240bc1f688bSRobert Mustacchi int local_length_size = 0;
241bc1f688bSRobert Mustacchi
242bc1f688bSRobert Mustacchi /* Some compilers emit padding at the end of each cu's area.
243*4d9fdb46SRobert Mustacchi pubnames_ptr_past_end_cu records the true area end for the
244*4d9fdb46SRobert Mustacchi pubnames(like) content of a cu.
245*4d9fdb46SRobert Mustacchi Essentially the length in the header and the 0
246bc1f688bSRobert Mustacchi terminator of the data are redundant information. The
247bc1f688bSRobert Mustacchi dwarf2/3 spec does not mention what to do if the length is
248bc1f688bSRobert Mustacchi past the 0 terminator. So we take any bytes left after the 0
249bc1f688bSRobert Mustacchi as padding and ignore them. */
250bc1f688bSRobert Mustacchi Dwarf_Small *pubnames_ptr_past_end_cu = 0;
251bc1f688bSRobert Mustacchi
252bc1f688bSRobert Mustacchi
253bc1f688bSRobert Mustacchi pubnames_context = (Dwarf_Global_Context)
254*4d9fdb46SRobert Mustacchi _dwarf_get_alloc(dbg, context_DLA_code, 1);
255bc1f688bSRobert Mustacchi if (pubnames_context == NULL) {
256*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
257bc1f688bSRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
258*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
259bc1f688bSRobert Mustacchi }
260bc1f688bSRobert Mustacchi /* READ_AREA_LENGTH updates pubnames_like_ptr for consumed
261bc1f688bSRobert Mustacchi bytes. */
262*4d9fdb46SRobert Mustacchi mres = _dwarf_read_area_length_ck_wrapper(dbg,
263*4d9fdb46SRobert Mustacchi &length,&pubnames_like_ptr,&local_length_size,
264*4d9fdb46SRobert Mustacchi &local_extension_size,section_length,section_end_ptr,
265*4d9fdb46SRobert Mustacchi error);
266*4d9fdb46SRobert Mustacchi if (mres != DW_DLV_OK) {
267*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
268*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
269*4d9fdb46SRobert Mustacchi return mres;
270*4d9fdb46SRobert Mustacchi }
271bc1f688bSRobert Mustacchi pubnames_context->pu_length_size = local_length_size;
272*4d9fdb46SRobert Mustacchi pubnames_context->pu_length = length;
273bc1f688bSRobert Mustacchi pubnames_context->pu_extension_size = local_extension_size;
274bc1f688bSRobert Mustacchi pubnames_context->pu_dbg = dbg;
275*4d9fdb46SRobert Mustacchi pubnames_context->pu_pub_offset = pubnames_section_offset;
276bc1f688bSRobert Mustacchi pubnames_ptr_past_end_cu = pubnames_like_ptr + length;
277bc1f688bSRobert Mustacchi
278*4d9fdb46SRobert Mustacchi mres = _dwarf_read_unaligned_ck_wrapper(dbg,
279*4d9fdb46SRobert Mustacchi &version,pubnames_like_ptr,DWARF_HALF_SIZE,
280*4d9fdb46SRobert Mustacchi section_end_ptr,error);
281*4d9fdb46SRobert Mustacchi if (mres != DW_DLV_OK) {
282*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
283*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
284*4d9fdb46SRobert Mustacchi return mres;
285*4d9fdb46SRobert Mustacchi }
286*4d9fdb46SRobert Mustacchi pubnames_context->pu_version = version;
287*4d9fdb46SRobert Mustacchi pubnames_like_ptr += DWARF_HALF_SIZE;
288*4d9fdb46SRobert Mustacchi /* ASSERT: DW_PUBNAMES_VERSION2 == DW_PUBTYPES_VERSION2 */
289*4d9fdb46SRobert Mustacchi if (version != DW_PUBNAMES_VERSION2) {
290*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
291*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
292bc1f688bSRobert Mustacchi _dwarf_error(dbg, error, version_err_num);
293*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
294bc1f688bSRobert Mustacchi }
295bc1f688bSRobert Mustacchi
296bc1f688bSRobert Mustacchi /* Offset of CU header in debug section. */
297*4d9fdb46SRobert Mustacchi mres = _dwarf_read_unaligned_ck_wrapper(dbg,
298*4d9fdb46SRobert Mustacchi &pubnames_context->pu_offset_of_cu_header,
299*4d9fdb46SRobert Mustacchi pubnames_like_ptr,
300*4d9fdb46SRobert Mustacchi pubnames_context->pu_length_size,
301*4d9fdb46SRobert Mustacchi section_end_ptr,error);
302*4d9fdb46SRobert Mustacchi if (mres != DW_DLV_OK) {
303*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
304*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
305*4d9fdb46SRobert Mustacchi return mres;
306*4d9fdb46SRobert Mustacchi }
307*4d9fdb46SRobert Mustacchi
308bc1f688bSRobert Mustacchi pubnames_like_ptr += pubnames_context->pu_length_size;
309bc1f688bSRobert Mustacchi
310bc1f688bSRobert Mustacchi FIX_UP_OFFSET_IRIX_BUG(dbg,
311bc1f688bSRobert Mustacchi pubnames_context->pu_offset_of_cu_header,
312bc1f688bSRobert Mustacchi "pubnames cu header offset");
313*4d9fdb46SRobert Mustacchi mres = _dwarf_read_unaligned_ck_wrapper(dbg,
314*4d9fdb46SRobert Mustacchi &pubnames_context->pu_info_length,
315*4d9fdb46SRobert Mustacchi pubnames_like_ptr,
316*4d9fdb46SRobert Mustacchi pubnames_context->pu_length_size,
317*4d9fdb46SRobert Mustacchi section_end_ptr,error);
318*4d9fdb46SRobert Mustacchi if (mres != DW_DLV_OK) {
319*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
320*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
321*4d9fdb46SRobert Mustacchi return mres;
322*4d9fdb46SRobert Mustacchi }
323bc1f688bSRobert Mustacchi pubnames_like_ptr += pubnames_context->pu_length_size;
324bc1f688bSRobert Mustacchi
325bc1f688bSRobert Mustacchi if (pubnames_like_ptr > (section_data_ptr + section_length)) {
326*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
327*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
328bc1f688bSRobert Mustacchi _dwarf_error(dbg, error, length_err_num);
329bc1f688bSRobert Mustacchi return (DW_DLV_ERROR);
330bc1f688bSRobert Mustacchi }
331bc1f688bSRobert Mustacchi
332bc1f688bSRobert Mustacchi /* Read initial offset (of DIE within CU) of a pubname, final
333bc1f688bSRobert Mustacchi entry is not a pair, just a zero offset. */
334*4d9fdb46SRobert Mustacchi mres = _dwarf_read_unaligned_ck_wrapper(dbg,
335*4d9fdb46SRobert Mustacchi &die_offset_in_cu,
336bc1f688bSRobert Mustacchi pubnames_like_ptr,
337*4d9fdb46SRobert Mustacchi pubnames_context->pu_length_size,
338*4d9fdb46SRobert Mustacchi section_end_ptr,error);
339*4d9fdb46SRobert Mustacchi if (mres != DW_DLV_OK) {
340*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
341*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
342*4d9fdb46SRobert Mustacchi return mres;
343*4d9fdb46SRobert Mustacchi }
344bc1f688bSRobert Mustacchi pubnames_like_ptr += pubnames_context->pu_length_size;
345bc1f688bSRobert Mustacchi FIX_UP_OFFSET_IRIX_BUG(dbg,
346bc1f688bSRobert Mustacchi die_offset_in_cu, "offset of die in cu");
347*4d9fdb46SRobert Mustacchi if (pubnames_like_ptr > (section_data_ptr + section_length)) {
348*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
349*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
350*4d9fdb46SRobert Mustacchi _dwarf_error(dbg, error, length_err_num);
351*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
352*4d9fdb46SRobert Mustacchi }
353bc1f688bSRobert Mustacchi
354bc1f688bSRobert Mustacchi /* Loop thru pairs. DIE off with CU followed by string. */
355*4d9fdb46SRobert Mustacchi if (dbg->de_return_empty_pubnames && die_offset_in_cu == 0) {
356*4d9fdb46SRobert Mustacchi /* Here we have a pubnames CU with no actual
357*4d9fdb46SRobert Mustacchi entries so we fake up an entry to hold the
358*4d9fdb46SRobert Mustacchi header data. There are no 'pairs' here,
359*4d9fdb46SRobert Mustacchi just the end of list zero value. We do this
360*4d9fdb46SRobert Mustacchi only if de_return_empty_pubnames is set
361*4d9fdb46SRobert Mustacchi so that we by default return exactly the same
362*4d9fdb46SRobert Mustacchi data this always returned, yet dwarfdump can
363*4d9fdb46SRobert Mustacchi request the empty-cu records get created
364*4d9fdb46SRobert Mustacchi to test that feature.
365*4d9fdb46SRobert Mustacchi see dwarf_get_globals_header() */
366bc1f688bSRobert Mustacchi global =
367*4d9fdb46SRobert Mustacchi (Dwarf_Global) _dwarf_get_alloc(dbg, global_DLA_code, 1);
368bc1f688bSRobert Mustacchi if (global == NULL) {
369*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
370*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
371bc1f688bSRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
372bc1f688bSRobert Mustacchi return (DW_DLV_ERROR);
373bc1f688bSRobert Mustacchi }
374bc1f688bSRobert Mustacchi global_count++;
375bc1f688bSRobert Mustacchi global->gl_context = pubnames_context;
376*4d9fdb46SRobert Mustacchi global->gl_named_die_offset_within_cu = 0;
377*4d9fdb46SRobert Mustacchi global->gl_name = (Dwarf_Small *)"";
378*4d9fdb46SRobert Mustacchi /* Finish off current entry chain */
379bc1f688bSRobert Mustacchi curr_chain =
380bc1f688bSRobert Mustacchi (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
381bc1f688bSRobert Mustacchi if (curr_chain == NULL) {
382*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
383*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
384*4d9fdb46SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
385*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
386*4d9fdb46SRobert Mustacchi }
387*4d9fdb46SRobert Mustacchi /* Put current global on singly_linked list. */
388*4d9fdb46SRobert Mustacchi curr_chain->ch_itemtype = global_DLA_code;
389*4d9fdb46SRobert Mustacchi curr_chain->ch_item = (Dwarf_Global) global;
390*4d9fdb46SRobert Mustacchi if (head_chain == NULL)
391*4d9fdb46SRobert Mustacchi head_chain = prev_chain = curr_chain;
392*4d9fdb46SRobert Mustacchi else {
393*4d9fdb46SRobert Mustacchi prev_chain->ch_next = curr_chain;
394*4d9fdb46SRobert Mustacchi prev_chain = curr_chain;
395*4d9fdb46SRobert Mustacchi }
396*4d9fdb46SRobert Mustacchi /* There is no next entry, we are at it already */
397*4d9fdb46SRobert Mustacchi } else if (!die_offset_in_cu) {
398*4d9fdb46SRobert Mustacchi /* The section is empty.
399*4d9fdb46SRobert Mustacchi Nowhere to record pubnames_context); */
400*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
401*4d9fdb46SRobert Mustacchi pubnames_context = 0;
402*4d9fdb46SRobert Mustacchi continue;
403*4d9fdb46SRobert Mustacchi }
404*4d9fdb46SRobert Mustacchi while (die_offset_in_cu) {
405*4d9fdb46SRobert Mustacchi int res = 0;
406*4d9fdb46SRobert Mustacchi
407*4d9fdb46SRobert Mustacchi /* Already read offset, pubnames_like_ptr
408*4d9fdb46SRobert Mustacchi now points to the string. */
409*4d9fdb46SRobert Mustacchi global =
410*4d9fdb46SRobert Mustacchi (Dwarf_Global) _dwarf_get_alloc(dbg, global_DLA_code, 1);
411*4d9fdb46SRobert Mustacchi if (global == NULL) {
412*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
413*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
414bc1f688bSRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
415bc1f688bSRobert Mustacchi return (DW_DLV_ERROR);
416bc1f688bSRobert Mustacchi }
417*4d9fdb46SRobert Mustacchi global_count++;
418*4d9fdb46SRobert Mustacchi global->gl_context = pubnames_context;
419*4d9fdb46SRobert Mustacchi global->gl_named_die_offset_within_cu = die_offset_in_cu;
420*4d9fdb46SRobert Mustacchi global->gl_name = pubnames_like_ptr;
421*4d9fdb46SRobert Mustacchi res = _dwarf_check_string_valid(dbg,section_data_ptr,
422*4d9fdb46SRobert Mustacchi pubnames_like_ptr,section_end_ptr,
423*4d9fdb46SRobert Mustacchi DW_DLE_STRING_OFF_END_PUBNAMES_LIKE,error);
424*4d9fdb46SRobert Mustacchi if (res != DW_DLV_OK) {
425*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
426*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
427*4d9fdb46SRobert Mustacchi return res;
428*4d9fdb46SRobert Mustacchi }
429*4d9fdb46SRobert Mustacchi pubnames_like_ptr = pubnames_like_ptr +
430*4d9fdb46SRobert Mustacchi strlen((char *) pubnames_like_ptr) + 1;
431bc1f688bSRobert Mustacchi
432*4d9fdb46SRobert Mustacchi /* Finish off current entry chain */
433*4d9fdb46SRobert Mustacchi curr_chain =
434*4d9fdb46SRobert Mustacchi (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
435*4d9fdb46SRobert Mustacchi if (curr_chain == NULL) {
436*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
437*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
438*4d9fdb46SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
439*4d9fdb46SRobert Mustacchi return (DW_DLV_ERROR);
440*4d9fdb46SRobert Mustacchi }
441bc1f688bSRobert Mustacchi /* Put current global on singly_linked list. */
442bc1f688bSRobert Mustacchi curr_chain->ch_item = (Dwarf_Global) global;
443*4d9fdb46SRobert Mustacchi curr_chain->ch_itemtype = global_DLA_code;
444bc1f688bSRobert Mustacchi if (head_chain == NULL)
445bc1f688bSRobert Mustacchi head_chain = prev_chain = curr_chain;
446bc1f688bSRobert Mustacchi else {
447bc1f688bSRobert Mustacchi prev_chain->ch_next = curr_chain;
448bc1f688bSRobert Mustacchi prev_chain = curr_chain;
449bc1f688bSRobert Mustacchi }
450bc1f688bSRobert Mustacchi
451*4d9fdb46SRobert Mustacchi /* Read offset for the *next* entry */
452*4d9fdb46SRobert Mustacchi mres = _dwarf_read_unaligned_ck_wrapper(dbg,
453*4d9fdb46SRobert Mustacchi &die_offset_in_cu,
454bc1f688bSRobert Mustacchi pubnames_like_ptr,
455*4d9fdb46SRobert Mustacchi pubnames_context->pu_length_size,
456*4d9fdb46SRobert Mustacchi section_end_ptr,error);
457*4d9fdb46SRobert Mustacchi if (mres != DW_DLV_OK) {
458*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
459*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
460*4d9fdb46SRobert Mustacchi return mres;
461*4d9fdb46SRobert Mustacchi }
462bc1f688bSRobert Mustacchi pubnames_like_ptr += pubnames_context->pu_length_size;
463bc1f688bSRobert Mustacchi FIX_UP_OFFSET_IRIX_BUG(dbg,
464*4d9fdb46SRobert Mustacchi die_offset_in_cu, "offset of next die in cu");
465bc1f688bSRobert Mustacchi if (pubnames_like_ptr > (section_data_ptr + section_length)) {
466*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
467*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
468bc1f688bSRobert Mustacchi _dwarf_error(dbg, error, length_err_num);
469*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
470bc1f688bSRobert Mustacchi }
471bc1f688bSRobert Mustacchi }
472bc1f688bSRobert Mustacchi /* ASSERT: die_offset_in_cu == 0 */
473bc1f688bSRobert Mustacchi if (pubnames_like_ptr > pubnames_ptr_past_end_cu) {
474bc1f688bSRobert Mustacchi /* This is some kind of error. This simply cannot happen.
475bc1f688bSRobert Mustacchi The encoding is wrong or the length in the header for
476bc1f688bSRobert Mustacchi this cu's contribution is wrong. */
477bc1f688bSRobert Mustacchi _dwarf_error(dbg, error, length_err_num);
478*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
479*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
480*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
481bc1f688bSRobert Mustacchi }
482bc1f688bSRobert Mustacchi /* If there is some kind of padding at the end of the section,
483bc1f688bSRobert Mustacchi as emitted by some compilers, skip over that padding and
484bc1f688bSRobert Mustacchi simply ignore the bytes thus passed-over. With most
485bc1f688bSRobert Mustacchi compilers, pubnames_like_ptr == pubnames_ptr_past_end_cu at
486bc1f688bSRobert Mustacchi this point */
487*4d9fdb46SRobert Mustacchi {
488*4d9fdb46SRobert Mustacchi Dwarf_Unsigned increment =
489*4d9fdb46SRobert Mustacchi pubnames_context->pu_length_size +
490*4d9fdb46SRobert Mustacchi pubnames_context->pu_length +
491*4d9fdb46SRobert Mustacchi pubnames_context->pu_extension_size;
492*4d9fdb46SRobert Mustacchi pubnames_section_offset += increment;
493*4d9fdb46SRobert Mustacchi }
494bc1f688bSRobert Mustacchi pubnames_like_ptr = pubnames_ptr_past_end_cu;
495*4d9fdb46SRobert Mustacchi } while (pubnames_like_ptr < section_end_ptr);
496bc1f688bSRobert Mustacchi
497bc1f688bSRobert Mustacchi /* Points to contiguous block of Dwarf_Global's. */
498bc1f688bSRobert Mustacchi ret_globals = (Dwarf_Global *)
499bc1f688bSRobert Mustacchi _dwarf_get_alloc(dbg, DW_DLA_LIST, global_count);
500bc1f688bSRobert Mustacchi if (ret_globals == NULL) {
501*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
502*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
503bc1f688bSRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
504*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
505bc1f688bSRobert Mustacchi }
506bc1f688bSRobert Mustacchi
507*4d9fdb46SRobert Mustacchi /* Store pointers to Dwarf_Global_s structs in contiguous block,
508*4d9fdb46SRobert Mustacchi and deallocate the chain. This ignores the various
509*4d9fdb46SRobert Mustacchi headers */
510bc1f688bSRobert Mustacchi curr_chain = head_chain;
511bc1f688bSRobert Mustacchi for (i = 0; i < global_count; i++) {
512bc1f688bSRobert Mustacchi *(ret_globals + i) = curr_chain->ch_item;
513bc1f688bSRobert Mustacchi prev_chain = curr_chain;
514bc1f688bSRobert Mustacchi curr_chain = curr_chain->ch_next;
515*4d9fdb46SRobert Mustacchi prev_chain->ch_item = 0; /* Not actually necessary. */
516bc1f688bSRobert Mustacchi dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
517bc1f688bSRobert Mustacchi }
518bc1f688bSRobert Mustacchi *globals = ret_globals;
519bc1f688bSRobert Mustacchi *return_count = (Dwarf_Signed) global_count;
520bc1f688bSRobert Mustacchi return DW_DLV_OK;
521bc1f688bSRobert Mustacchi }
522bc1f688bSRobert Mustacchi
523bc1f688bSRobert Mustacchi
524*4d9fdb46SRobert Mustacchi /* Given a pubnames entry (or other like section entry)
525bc1f688bSRobert Mustacchi return thru the ret_name pointer
526*4d9fdb46SRobert Mustacchi a pointer to the string which is the entry name. */
527bc1f688bSRobert Mustacchi int
dwarf_globname(Dwarf_Global glob,char ** ret_name,Dwarf_Error * error)528bc1f688bSRobert Mustacchi dwarf_globname(Dwarf_Global glob, char **ret_name, Dwarf_Error * error)
529bc1f688bSRobert Mustacchi {
530bc1f688bSRobert Mustacchi if (glob == NULL) {
531bc1f688bSRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
532bc1f688bSRobert Mustacchi return (DW_DLV_ERROR);
533bc1f688bSRobert Mustacchi }
534bc1f688bSRobert Mustacchi
535bc1f688bSRobert Mustacchi *ret_name = (char *) (glob->gl_name);
536bc1f688bSRobert Mustacchi return DW_DLV_OK;
537bc1f688bSRobert Mustacchi }
538bc1f688bSRobert Mustacchi
539bc1f688bSRobert Mustacchi
540*4d9fdb46SRobert Mustacchi /* Given a pubnames entry (or other like section entry)
541bc1f688bSRobert Mustacchi return thru the ret_off pointer the
542bc1f688bSRobert Mustacchi global offset of the DIE for this entry.
543bc1f688bSRobert Mustacchi The global offset is the offset within the .debug_info
544*4d9fdb46SRobert Mustacchi section as a whole. */
545bc1f688bSRobert Mustacchi int
dwarf_global_die_offset(Dwarf_Global global,Dwarf_Off * ret_off,Dwarf_Error * error)546bc1f688bSRobert Mustacchi dwarf_global_die_offset(Dwarf_Global global,
547bc1f688bSRobert Mustacchi Dwarf_Off * ret_off, Dwarf_Error * error)
548bc1f688bSRobert Mustacchi {
549bc1f688bSRobert Mustacchi if (global == NULL) {
550bc1f688bSRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
551bc1f688bSRobert Mustacchi return (DW_DLV_ERROR);
552bc1f688bSRobert Mustacchi }
553bc1f688bSRobert Mustacchi
554bc1f688bSRobert Mustacchi if (global->gl_context == NULL) {
555bc1f688bSRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
556bc1f688bSRobert Mustacchi return (DW_DLV_ERROR);
557bc1f688bSRobert Mustacchi }
558bc1f688bSRobert Mustacchi
559bc1f688bSRobert Mustacchi *ret_off = (global->gl_named_die_offset_within_cu +
560bc1f688bSRobert Mustacchi global->gl_context->pu_offset_of_cu_header);
561bc1f688bSRobert Mustacchi return DW_DLV_OK;
562bc1f688bSRobert Mustacchi }
563bc1f688bSRobert Mustacchi
564*4d9fdb46SRobert Mustacchi /* Given a pubnames entry (or other like section entry)
565bc1f688bSRobert Mustacchi return thru the ret_off pointer the
566bc1f688bSRobert Mustacchi offset of the compilation unit header of the
567bc1f688bSRobert Mustacchi compilation unit the global is part of.
568bc1f688bSRobert Mustacchi
569bc1f688bSRobert Mustacchi In early versions of this, the value returned was
570bc1f688bSRobert Mustacchi the offset of the compilation unit die, and
571bc1f688bSRobert Mustacchi other cu-local die offsets were faked so adding this to
572bc1f688bSRobert Mustacchi such a cu-local offset got a true section offset.
573bc1f688bSRobert Mustacchi Now things do as they say (adding *cu_header_offset to
574*4d9fdb46SRobert Mustacchi a cu-local offset gets the section offset). */
575bc1f688bSRobert Mustacchi int
dwarf_global_cu_offset(Dwarf_Global global,Dwarf_Off * cu_header_offset,Dwarf_Error * error)576bc1f688bSRobert Mustacchi dwarf_global_cu_offset(Dwarf_Global global,
577bc1f688bSRobert Mustacchi Dwarf_Off * cu_header_offset,
578bc1f688bSRobert Mustacchi Dwarf_Error * error)
579bc1f688bSRobert Mustacchi {
580bc1f688bSRobert Mustacchi Dwarf_Global_Context con = 0;
581bc1f688bSRobert Mustacchi
582bc1f688bSRobert Mustacchi if (global == NULL) {
583bc1f688bSRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
584bc1f688bSRobert Mustacchi return (DW_DLV_ERROR);
585bc1f688bSRobert Mustacchi }
586bc1f688bSRobert Mustacchi
587bc1f688bSRobert Mustacchi con = global->gl_context;
588bc1f688bSRobert Mustacchi
589bc1f688bSRobert Mustacchi if (con == NULL) {
590bc1f688bSRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
591bc1f688bSRobert Mustacchi return (DW_DLV_ERROR);
592bc1f688bSRobert Mustacchi }
593bc1f688bSRobert Mustacchi
594bc1f688bSRobert Mustacchi /* In early libdwarf, this incorrectly returned the offset of the
595bc1f688bSRobert Mustacchi CU DIE. Now correctly returns the header offset. */
596bc1f688bSRobert Mustacchi *cu_header_offset = con->pu_offset_of_cu_header;
597bc1f688bSRobert Mustacchi
598bc1f688bSRobert Mustacchi return DW_DLV_OK;
599bc1f688bSRobert Mustacchi }
600bc1f688bSRobert Mustacchi
601*4d9fdb46SRobert Mustacchi static void
build_off_end_msg(Dwarf_Unsigned offval,Dwarf_Unsigned withincr,Dwarf_Unsigned secsize,dwarfstring * m)602*4d9fdb46SRobert Mustacchi build_off_end_msg(Dwarf_Unsigned offval,
603*4d9fdb46SRobert Mustacchi Dwarf_Unsigned withincr,
604*4d9fdb46SRobert Mustacchi Dwarf_Unsigned secsize,
605*4d9fdb46SRobert Mustacchi dwarfstring *m)
606*4d9fdb46SRobert Mustacchi {
607*4d9fdb46SRobert Mustacchi const char *msg = "past";
608*4d9fdb46SRobert Mustacchi if (offval < secsize){
609*4d9fdb46SRobert Mustacchi msg = "too near";
610*4d9fdb46SRobert Mustacchi }
611*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_u(m,"DW_DLE_OFFSET_BAD: "
612*4d9fdb46SRobert Mustacchi "The CU header offset of %u in a pubnames-like entry ",
613*4d9fdb46SRobert Mustacchi withincr);
614*4d9fdb46SRobert Mustacchi dwarfstring_append_printf_s(m,
615*4d9fdb46SRobert Mustacchi "would put us %s the end of .debug_info. "
616*4d9fdb46SRobert Mustacchi "No room for a DIE there... "
617*4d9fdb46SRobert Mustacchi "Corrupt Dwarf.",(char *)msg);
618*4d9fdb46SRobert Mustacchi return;
619*4d9fdb46SRobert Mustacchi }
620*4d9fdb46SRobert Mustacchi
621*4d9fdb46SRobert Mustacchi
622bc1f688bSRobert Mustacchi /*
623bc1f688bSRobert Mustacchi Give back the pubnames entry (or any other like section)
624bc1f688bSRobert Mustacchi name, symbol DIE offset, and the cu-DIE offset.
625bc1f688bSRobert Mustacchi
626bc1f688bSRobert Mustacchi Various errors are possible.
627bc1f688bSRobert Mustacchi
628bc1f688bSRobert Mustacchi The string pointer returned thru ret_name is not
629bc1f688bSRobert Mustacchi dwarf_get_alloc()ed, so no dwarf_dealloc()
630bc1f688bSRobert Mustacchi DW_DLA_STRING should be applied to it.
631bc1f688bSRobert Mustacchi
632bc1f688bSRobert Mustacchi */
633bc1f688bSRobert Mustacchi int
dwarf_global_name_offsets(Dwarf_Global global,char ** ret_name,Dwarf_Off * die_offset,Dwarf_Off * cu_die_offset,Dwarf_Error * error)634bc1f688bSRobert Mustacchi dwarf_global_name_offsets(Dwarf_Global global,
635bc1f688bSRobert Mustacchi char **ret_name,
636bc1f688bSRobert Mustacchi Dwarf_Off * die_offset,
637bc1f688bSRobert Mustacchi Dwarf_Off * cu_die_offset,
638bc1f688bSRobert Mustacchi Dwarf_Error * error)
639bc1f688bSRobert Mustacchi {
640bc1f688bSRobert Mustacchi Dwarf_Global_Context con = 0;
641bc1f688bSRobert Mustacchi Dwarf_Debug dbg = 0;
642*4d9fdb46SRobert Mustacchi Dwarf_Off cuhdr_off = 0;
643bc1f688bSRobert Mustacchi
644bc1f688bSRobert Mustacchi if (global == NULL) {
645bc1f688bSRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
646bc1f688bSRobert Mustacchi return (DW_DLV_ERROR);
647bc1f688bSRobert Mustacchi }
648bc1f688bSRobert Mustacchi
649bc1f688bSRobert Mustacchi con = global->gl_context;
650bc1f688bSRobert Mustacchi
651bc1f688bSRobert Mustacchi if (con == NULL) {
652bc1f688bSRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
653bc1f688bSRobert Mustacchi return (DW_DLV_ERROR);
654bc1f688bSRobert Mustacchi }
655bc1f688bSRobert Mustacchi
656*4d9fdb46SRobert Mustacchi cuhdr_off = con->pu_offset_of_cu_header;
657bc1f688bSRobert Mustacchi /* The offset had better not be too close to the end. If it is,
658bc1f688bSRobert Mustacchi _dwarf_length_of_cu_header() will step off the end and therefore
659bc1f688bSRobert Mustacchi must not be used. 10 is a meaningless heuristic, but no CU
660bc1f688bSRobert Mustacchi header is that small so it is safe. An erroneous offset is due
661bc1f688bSRobert Mustacchi to a bug in the tool chain. A bug like this has been seen on
662bc1f688bSRobert Mustacchi IRIX with MIPSpro 7.3.1.3 and an executable > 2GB in size and
663bc1f688bSRobert Mustacchi with 2 million pubnames entries. */
664bc1f688bSRobert Mustacchi #define MIN_CU_HDR_SIZE 10
665bc1f688bSRobert Mustacchi dbg = con->pu_dbg;
666bc1f688bSRobert Mustacchi if (dbg == NULL) {
667bc1f688bSRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
668bc1f688bSRobert Mustacchi return (DW_DLV_ERROR);
669bc1f688bSRobert Mustacchi }
670*4d9fdb46SRobert Mustacchi /* Cannot refer to debug_types */
671bc1f688bSRobert Mustacchi if (dbg->de_debug_info.dss_size &&
672*4d9fdb46SRobert Mustacchi ((cuhdr_off + MIN_CU_HDR_SIZE) >= dbg->de_debug_info.dss_size)) {
673*4d9fdb46SRobert Mustacchi dwarfstring m;
674*4d9fdb46SRobert Mustacchi dwarfstring_constructor(&m);
675*4d9fdb46SRobert Mustacchi build_off_end_msg(cuhdr_off,cuhdr_off+MIN_CU_HDR_SIZE,
676*4d9fdb46SRobert Mustacchi dbg->de_debug_info.dss_size,&m);
677*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg, error, DW_DLE_OFFSET_BAD,
678*4d9fdb46SRobert Mustacchi dwarfstring_string(&m));
679*4d9fdb46SRobert Mustacchi dwarfstring_destructor(&m);
680bc1f688bSRobert Mustacchi return (DW_DLV_ERROR);
681bc1f688bSRobert Mustacchi }
682bc1f688bSRobert Mustacchi #undef MIN_CU_HDR_SIZE
683*4d9fdb46SRobert Mustacchi /* If global->gl_named_die_offset_within_cu
684*4d9fdb46SRobert Mustacchi is zero then this is a fake global for
685*4d9fdb46SRobert Mustacchi a pubnames CU with no pubnames. The offset is from the
686*4d9fdb46SRobert Mustacchi start of the CU header, so no die can have a zero
687*4d9fdb46SRobert Mustacchi offset, all valid offsets are positive numbers */
688*4d9fdb46SRobert Mustacchi if (die_offset) {
689*4d9fdb46SRobert Mustacchi if(global->gl_named_die_offset_within_cu) {
690*4d9fdb46SRobert Mustacchi *die_offset = global->gl_named_die_offset_within_cu + cuhdr_off;
691*4d9fdb46SRobert Mustacchi } else {
692*4d9fdb46SRobert Mustacchi *die_offset = 0;
693bc1f688bSRobert Mustacchi }
694*4d9fdb46SRobert Mustacchi }
695bc1f688bSRobert Mustacchi *ret_name = (char *) global->gl_name;
696*4d9fdb46SRobert Mustacchi if (cu_die_offset) {
697*4d9fdb46SRobert Mustacchi /* Globals cannot refer to debug_types */
698*4d9fdb46SRobert Mustacchi int cres = 0;
699*4d9fdb46SRobert Mustacchi Dwarf_Unsigned headerlen = 0;
700bc1f688bSRobert Mustacchi int res = _dwarf_load_debug_info(dbg, error);
701bc1f688bSRobert Mustacchi
702bc1f688bSRobert Mustacchi if (res != DW_DLV_OK) {
703bc1f688bSRobert Mustacchi return res;
704bc1f688bSRobert Mustacchi }
705*4d9fdb46SRobert Mustacchi /* The offset had better not be too close to the end.
706*4d9fdb46SRobert Mustacchi If it is,
707bc1f688bSRobert Mustacchi _dwarf_length_of_cu_header() will step off the end and
708bc1f688bSRobert Mustacchi therefore must not be used. 10 is a meaningless heuristic,
709bc1f688bSRobert Mustacchi but no CU header is that small so it is safe. */
710*4d9fdb46SRobert Mustacchi /* Globals cannot refer to debug_types */
711*4d9fdb46SRobert Mustacchi if ((cuhdr_off + 10) >= dbg->de_debug_info.dss_size) {
712*4d9fdb46SRobert Mustacchi dwarfstring m;
713*4d9fdb46SRobert Mustacchi
714*4d9fdb46SRobert Mustacchi dwarfstring_constructor(&m);
715*4d9fdb46SRobert Mustacchi build_off_end_msg(cuhdr_off,cuhdr_off+10,
716*4d9fdb46SRobert Mustacchi dbg->de_debug_info.dss_size,&m);
717*4d9fdb46SRobert Mustacchi _dwarf_error_string(dbg, error, DW_DLE_OFFSET_BAD,
718*4d9fdb46SRobert Mustacchi dwarfstring_string(&m));
719*4d9fdb46SRobert Mustacchi dwarfstring_destructor(&m);
720bc1f688bSRobert Mustacchi return (DW_DLV_ERROR);
721bc1f688bSRobert Mustacchi }
722*4d9fdb46SRobert Mustacchi cres = _dwarf_length_of_cu_header(dbg, cuhdr_off,true,
723*4d9fdb46SRobert Mustacchi &headerlen,error);
724*4d9fdb46SRobert Mustacchi if(cres != DW_DLV_OK) {
725*4d9fdb46SRobert Mustacchi return cres;
726bc1f688bSRobert Mustacchi }
727*4d9fdb46SRobert Mustacchi *cu_die_offset = cuhdr_off + headerlen;
728*4d9fdb46SRobert Mustacchi }
729bc1f688bSRobert Mustacchi return DW_DLV_OK;
730bc1f688bSRobert Mustacchi }
731bc1f688bSRobert Mustacchi
732*4d9fdb46SRobert Mustacchi
733*4d9fdb46SRobert Mustacchi /* New February 2019 from better dwarfdump printing
734*4d9fdb46SRobert Mustacchi of debug_pubnames and pubtypes.
735*4d9fdb46SRobert Mustacchi For ao the Dwarf_Global records in one pubnames
736*4d9fdb46SRobert Mustacchi CU group exactly the same data will be returned.
737*4d9fdb46SRobert Mustacchi
738*4d9fdb46SRobert Mustacchi */
739*4d9fdb46SRobert Mustacchi int
dwarf_get_globals_header(Dwarf_Global global,Dwarf_Off * pub_section_hdr_offset,Dwarf_Unsigned * pub_offset_size,Dwarf_Unsigned * pub_cu_length,Dwarf_Unsigned * version,Dwarf_Off * info_header_offset,Dwarf_Unsigned * info_length,Dwarf_Error * error)740*4d9fdb46SRobert Mustacchi dwarf_get_globals_header(Dwarf_Global global,
741*4d9fdb46SRobert Mustacchi Dwarf_Off *pub_section_hdr_offset,
742*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *pub_offset_size,
743*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *pub_cu_length,
744*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *version,
745*4d9fdb46SRobert Mustacchi Dwarf_Off *info_header_offset,
746*4d9fdb46SRobert Mustacchi Dwarf_Unsigned *info_length,
747*4d9fdb46SRobert Mustacchi Dwarf_Error* error)
748*4d9fdb46SRobert Mustacchi {
749*4d9fdb46SRobert Mustacchi Dwarf_Global_Context con = 0;
750*4d9fdb46SRobert Mustacchi Dwarf_Debug dbg = 0;
751*4d9fdb46SRobert Mustacchi
752*4d9fdb46SRobert Mustacchi if (global == NULL) {
753*4d9fdb46SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
754*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
755*4d9fdb46SRobert Mustacchi }
756*4d9fdb46SRobert Mustacchi con = global->gl_context;
757*4d9fdb46SRobert Mustacchi if (con == NULL) {
758*4d9fdb46SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
759*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
760*4d9fdb46SRobert Mustacchi }
761*4d9fdb46SRobert Mustacchi dbg = con->pu_dbg;
762*4d9fdb46SRobert Mustacchi if (dbg == NULL) {
763*4d9fdb46SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
764*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
765*4d9fdb46SRobert Mustacchi }
766*4d9fdb46SRobert Mustacchi if(pub_section_hdr_offset) {
767*4d9fdb46SRobert Mustacchi *pub_section_hdr_offset = con->pu_pub_offset;
768*4d9fdb46SRobert Mustacchi }
769*4d9fdb46SRobert Mustacchi if (pub_offset_size) {
770*4d9fdb46SRobert Mustacchi *pub_offset_size = con->pu_length_size;
771*4d9fdb46SRobert Mustacchi }
772*4d9fdb46SRobert Mustacchi if (pub_cu_length) {
773*4d9fdb46SRobert Mustacchi *pub_cu_length = con->pu_length;
774*4d9fdb46SRobert Mustacchi }
775*4d9fdb46SRobert Mustacchi if (version) {
776*4d9fdb46SRobert Mustacchi *version = con->pu_version;
777*4d9fdb46SRobert Mustacchi }
778*4d9fdb46SRobert Mustacchi if(info_header_offset) {
779*4d9fdb46SRobert Mustacchi *info_header_offset = con->pu_offset_of_cu_header;
780*4d9fdb46SRobert Mustacchi }
781*4d9fdb46SRobert Mustacchi if (info_length) {
782*4d9fdb46SRobert Mustacchi *info_length = con->pu_info_length;
783*4d9fdb46SRobert Mustacchi }
784*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
785*4d9fdb46SRobert Mustacchi }
786*4d9fdb46SRobert Mustacchi
787*4d9fdb46SRobert Mustacchi
788*4d9fdb46SRobert Mustacchi /* We have the offset to a CU header.
789bc1f688bSRobert Mustacchi Return thru outFileOffset the offset of the CU DIE.
790bc1f688bSRobert Mustacchi
791bc1f688bSRobert Mustacchi New June, 2001.
792*4d9fdb46SRobert Mustacchi Used by SGI IRIX debuggers.
793*4d9fdb46SRobert Mustacchi No error used to be possible.
794*4d9fdb46SRobert Mustacchi As of May 2016 an error is possible if the DWARF is
795*4d9fdb46SRobert Mustacchi corrupted! (IRIX debuggers are no longer built ...)
796bc1f688bSRobert Mustacchi
797bc1f688bSRobert Mustacchi See also dwarf_CU_dieoffset_given_die().
798*4d9fdb46SRobert Mustacchi
799*4d9fdb46SRobert Mustacchi This is assumed to never apply to data in .debug_types, it
800*4d9fdb46SRobert Mustacchi only refers to .debug_info.
801*4d9fdb46SRobert Mustacchi
802bc1f688bSRobert Mustacchi */
803bc1f688bSRobert Mustacchi
804bc1f688bSRobert Mustacchi /* ARGSUSED */
805bc1f688bSRobert Mustacchi int
dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg,Dwarf_Off in_cu_header_offset,Dwarf_Off * out_cu_die_offset,UNUSEDARG Dwarf_Error * err)806bc1f688bSRobert Mustacchi dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg,
807bc1f688bSRobert Mustacchi Dwarf_Off in_cu_header_offset,
808bc1f688bSRobert Mustacchi Dwarf_Off * out_cu_die_offset,
809*4d9fdb46SRobert Mustacchi UNUSEDARG Dwarf_Error * err)
810bc1f688bSRobert Mustacchi {
811*4d9fdb46SRobert Mustacchi Dwarf_Off headerlen = 0;
812*4d9fdb46SRobert Mustacchi int cres = 0;
813bc1f688bSRobert Mustacchi
814*4d9fdb46SRobert Mustacchi cres = _dwarf_length_of_cu_header(dbg, in_cu_header_offset,true,
815*4d9fdb46SRobert Mustacchi &headerlen,err);
816*4d9fdb46SRobert Mustacchi if (cres != DW_DLV_OK) {
817*4d9fdb46SRobert Mustacchi return cres;
818*4d9fdb46SRobert Mustacchi }
819*4d9fdb46SRobert Mustacchi *out_cu_die_offset = in_cu_header_offset + headerlen;
820*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
821*4d9fdb46SRobert Mustacchi }
822bc1f688bSRobert Mustacchi
823*4d9fdb46SRobert Mustacchi /* The following version new in October 2011, does allow finding
824*4d9fdb46SRobert Mustacchi the offset if one knows whether debug_info or debug_types.
825*4d9fdb46SRobert Mustacchi
826*4d9fdb46SRobert Mustacchi However, it is not accurate in DWARF5 because
827*4d9fdb46SRobert Mustacchi there are two different header lengths (CU and TU)
828*4d9fdb46SRobert Mustacchi in DWARF5 .debug_info. In that case, pretend
829*4d9fdb46SRobert Mustacchi that it's .debug_types (here) and pass is_info zero for
830*4d9fdb46SRobert Mustacchi a TU (as if it was in .debug_types).
831*4d9fdb46SRobert Mustacchi */
832*4d9fdb46SRobert Mustacchi int
dwarf_get_cu_die_offset_given_cu_header_offset_b(Dwarf_Debug dbg,Dwarf_Off in_cu_header_offset,Dwarf_Bool is_info,Dwarf_Off * out_cu_die_offset,UNUSEDARG Dwarf_Error * err)833*4d9fdb46SRobert Mustacchi dwarf_get_cu_die_offset_given_cu_header_offset_b(Dwarf_Debug dbg,
834*4d9fdb46SRobert Mustacchi Dwarf_Off in_cu_header_offset,
835*4d9fdb46SRobert Mustacchi Dwarf_Bool is_info,
836*4d9fdb46SRobert Mustacchi Dwarf_Off * out_cu_die_offset,
837*4d9fdb46SRobert Mustacchi UNUSEDARG Dwarf_Error * err)
838*4d9fdb46SRobert Mustacchi {
839*4d9fdb46SRobert Mustacchi Dwarf_Off headerlen = 0;
840*4d9fdb46SRobert Mustacchi int cres = 0;
841*4d9fdb46SRobert Mustacchi
842*4d9fdb46SRobert Mustacchi cres = _dwarf_length_of_cu_header(dbg, in_cu_header_offset,is_info,
843*4d9fdb46SRobert Mustacchi &headerlen,err);
844*4d9fdb46SRobert Mustacchi if (cres != DW_DLV_OK) {
845*4d9fdb46SRobert Mustacchi return cres;
846*4d9fdb46SRobert Mustacchi }
847*4d9fdb46SRobert Mustacchi *out_cu_die_offset = in_cu_header_offset + headerlen;
848bc1f688bSRobert Mustacchi return DW_DLV_OK;
849bc1f688bSRobert Mustacchi }
850bc1f688bSRobert Mustacchi /* dwarf_CU_dieoffset_given_die returns
851bc1f688bSRobert Mustacchi the global debug_info section offset of the CU die
852bc1f688bSRobert Mustacchi that is the CU containing the given (passed-in) die.
853bc1f688bSRobert Mustacchi This information makes it possible for a consumer to
854bc1f688bSRobert Mustacchi find and print context information for any die.
855bc1f688bSRobert Mustacchi
856bc1f688bSRobert Mustacchi Use dwarf_offdie() passing in the offset this returns
857*4d9fdb46SRobert Mustacchi to get a die pointer to the CU die. */
858bc1f688bSRobert Mustacchi int
dwarf_CU_dieoffset_given_die(Dwarf_Die die,Dwarf_Off * return_offset,Dwarf_Error * error)859bc1f688bSRobert Mustacchi dwarf_CU_dieoffset_given_die(Dwarf_Die die,
860bc1f688bSRobert Mustacchi Dwarf_Off* return_offset,
861bc1f688bSRobert Mustacchi Dwarf_Error* error)
862bc1f688bSRobert Mustacchi {
863bc1f688bSRobert Mustacchi Dwarf_Off dieoff = 0;
864bc1f688bSRobert Mustacchi Dwarf_CU_Context cucontext = 0;
865bc1f688bSRobert Mustacchi
866bc1f688bSRobert Mustacchi CHECK_DIE(die, DW_DLV_ERROR);
867bc1f688bSRobert Mustacchi cucontext = die->di_cu_context;
868*4d9fdb46SRobert Mustacchi dieoff = cucontext->cc_debug_offset;
869bc1f688bSRobert Mustacchi /* The following call cannot fail, so no error check. */
870*4d9fdb46SRobert Mustacchi dwarf_get_cu_die_offset_given_cu_header_offset_b(
871*4d9fdb46SRobert Mustacchi cucontext->cc_dbg, dieoff,
872*4d9fdb46SRobert Mustacchi die->di_is_info, return_offset,error);
873*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
874*4d9fdb46SRobert Mustacchi }
875*4d9fdb46SRobert Mustacchi
876*4d9fdb46SRobert Mustacchi /* We do not want to screw up error in case
877*4d9fdb46SRobert Mustacchi it has something important. So not touching it now. */
dwarf_return_empty_pubnames(Dwarf_Debug dbg,int flag,UNUSEDARG Dwarf_Error * err)878*4d9fdb46SRobert Mustacchi int dwarf_return_empty_pubnames(Dwarf_Debug dbg,
879*4d9fdb46SRobert Mustacchi int flag, UNUSEDARG Dwarf_Error *err )
880*4d9fdb46SRobert Mustacchi {
881*4d9fdb46SRobert Mustacchi if (dbg == NULL) {
882*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
883*4d9fdb46SRobert Mustacchi }
884*4d9fdb46SRobert Mustacchi if (flag && flag != 1) {
885*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
886*4d9fdb46SRobert Mustacchi }
887*4d9fdb46SRobert Mustacchi dbg->de_return_empty_pubnames = (unsigned char)flag;
888bc1f688bSRobert Mustacchi return DW_DLV_OK;
889bc1f688bSRobert Mustacchi }
890