149d3bc91SRichard Lowe /*
249d3bc91SRichard Lowe
307dc1947SRichard Lowe Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
4*4d9fdb46SRobert Mustacchi Portions Copyright (C) 2007-2011 David Anderson. All Rights Reserved.
5*4d9fdb46SRobert 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.
10*4d9fdb46SRobert 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.
15*4d9fdb46SRobert 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.
23*4d9fdb46SRobert 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.
2849d3bc91SRichard Lowe
2907dc1947SRichard Lowe */
3007dc1947SRichard Lowe
3149d3bc91SRichard Lowe #include "config.h"
3249d3bc91SRichard Lowe #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"
3849d3bc91SRichard Lowe #include "dwarf_global.h"
3949d3bc91SRichard Lowe
4007dc1947SRichard Lowe
4107dc1947SRichard Lowe #ifdef __sgi /* __sgi should only be defined for IRIX/MIPS. */
4207dc1947SRichard Lowe /* The 'fixup' here intended for IRIX targets only.
43*4d9fdb46SRobert Mustacchi With a 2+GB Elf64 IRIX executable (under 4GB in size),
4407dc1947SRichard Lowe some DIE offsets wrongly
4507dc1947SRichard Lowe got the 32bit upper bit sign extended. For the cu-header
4607dc1947SRichard Lowe offset in the .debug_pubnames section and in the
4707dc1947SRichard Lowe .debug_aranges section.
4807dc1947SRichard Lowe the 'varp' here is a pointer to an offset into .debug_info.
4907dc1947SRichard Lowe We fix up the offset here if it seems advisable..
50*4d9fdb46SRobert Mustacchi
5107dc1947SRichard Lowe As of June 2005 we have identified a series of mistakes
5207dc1947SRichard Lowe in ldx64 that can cause this (64 bit values getting passed
53*4d9fdb46SRobert Mustacchi thru 32-bit signed knothole).
5407dc1947SRichard Lowe */
5507dc1947SRichard Lowe void
_dwarf_fix_up_offset_irix(Dwarf_Debug dbg,Dwarf_Unsigned * varp,char * caller_site_name)5607dc1947SRichard Lowe _dwarf_fix_up_offset_irix(Dwarf_Debug dbg,
5707dc1947SRichard Lowe Dwarf_Unsigned * varp, char *caller_site_name)
5807dc1947SRichard Lowe {
5907dc1947SRichard Lowe
6007dc1947SRichard Lowe Dwarf_Unsigned var = *varp;
6107dc1947SRichard Lowe
6207dc1947SRichard Lowe #define UPPER33 0xffffffff80000000LL
6307dc1947SRichard Lowe #define LOWER32 0xffffffffLL
64*4d9fdb46SRobert Mustacchi /* Restrict the hack to the known case. Upper 32 bits erroneously
65*4d9fdb46SRobert Mustacchi sign extended from lower 32 upper bit. */
6607dc1947SRichard Lowe if ((var & UPPER33) == UPPER33) {
6707dc1947SRichard Lowe var &= LOWER32;
6807dc1947SRichard Lowe /* Apply the fix. Dreadful hack. */
6907dc1947SRichard Lowe *varp = var;
7007dc1947SRichard Lowe }
7107dc1947SRichard Lowe #undef UPPER33
7207dc1947SRichard Lowe #undef LOWER32
7307dc1947SRichard Lowe return;
7407dc1947SRichard Lowe }
75*4d9fdb46SRobert Mustacchi #endif /* __sgi */
76*4d9fdb46SRobert 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;
8407dc1947SRichard Lowe
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 }
9707dc1947SRichard Lowe
9849d3bc91SRichard Lowe int
dwarf_get_globals(Dwarf_Debug dbg,Dwarf_Global ** globals,Dwarf_Signed * return_count,Dwarf_Error * error)9949d3bc91SRichard Lowe dwarf_get_globals(Dwarf_Debug dbg,
10007dc1947SRichard Lowe Dwarf_Global ** globals,
10107dc1947SRichard Lowe Dwarf_Signed * return_count, Dwarf_Error * error)
10249d3bc91SRichard Lowe {
10307dc1947SRichard Lowe int res = _dwarf_load_section(dbg, &dbg->de_debug_pubnames,error);
10449d3bc91SRichard Lowe if (res != DW_DLV_OK) {
10549d3bc91SRichard Lowe return res;
10649d3bc91SRichard Lowe }
107*4d9fdb46SRobert Mustacchi if (!dbg->de_debug_pubnames.dss_size) {
108*4d9fdb46SRobert Mustacchi return DW_DLV_NO_ENTRY;
109*4d9fdb46SRobert Mustacchi }
11049d3bc91SRichard Lowe
111*4d9fdb46SRobert Mustacchi res = _dwarf_internal_get_pubnames_like_data(dbg,
11207dc1947SRichard Lowe dbg->de_debug_pubnames.dss_data,
11307dc1947SRichard Lowe dbg->de_debug_pubnames.dss_size,
114*4d9fdb46SRobert Mustacchi globals,
11507dc1947SRichard Lowe return_count,
11607dc1947SRichard Lowe error,
11707dc1947SRichard Lowe DW_DLA_GLOBAL_CONTEXT,
11807dc1947SRichard Lowe DW_DLA_GLOBAL,
11907dc1947SRichard Lowe DW_DLE_PUBNAMES_LENGTH_BAD,
12007dc1947SRichard Lowe DW_DLE_PUBNAMES_VERSION_ERROR);
121*4d9fdb46SRobert Mustacchi return res;
12249d3bc91SRichard Lowe
12307dc1947SRichard Lowe }
12449d3bc91SRichard Lowe
12507dc1947SRichard Lowe /* Deallocating fully requires deallocating the list
12607dc1947SRichard Lowe and all entries. But some internal data is
12707dc1947SRichard Lowe not exposed, so we need a function with internal knowledge.
12807dc1947SRichard Lowe */
12907dc1947SRichard Lowe
13007dc1947SRichard Lowe void
dwarf_globals_dealloc(Dwarf_Debug dbg,Dwarf_Global * dwgl,Dwarf_Signed count)13107dc1947SRichard Lowe dwarf_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl,
13207dc1947SRichard Lowe Dwarf_Signed count)
13307dc1947SRichard Lowe {
13407dc1947SRichard Lowe _dwarf_internal_globals_dealloc(dbg, dwgl,
13507dc1947SRichard Lowe count,
13607dc1947SRichard Lowe DW_DLA_GLOBAL_CONTEXT,
13707dc1947SRichard Lowe DW_DLA_GLOBAL, DW_DLA_LIST);
13807dc1947SRichard Lowe return;
13907dc1947SRichard Lowe }
14007dc1947SRichard Lowe
14107dc1947SRichard Lowe 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)14207dc1947SRichard Lowe _dwarf_internal_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl,
14307dc1947SRichard Lowe Dwarf_Signed count,
144*4d9fdb46SRobert Mustacchi int context_DLA_code,
145*4d9fdb46SRobert Mustacchi int global_DLA_code, int list_DLA_code)
14607dc1947SRichard Lowe {
14707dc1947SRichard Lowe Dwarf_Signed i;
148*4d9fdb46SRobert Mustacchi struct Dwarf_Global_Context_s *glcp = 0;
149*4d9fdb46SRobert Mustacchi struct Dwarf_Global_Context_s *lastglcp = 0;
15007dc1947SRichard Lowe
151*4d9fdb46SRobert Mustacchi if(!dwgl) {
152*4d9fdb46SRobert Mustacchi return;
153*4d9fdb46SRobert Mustacchi }
15407dc1947SRichard Lowe for (i = 0; i < count; i++) {
15507dc1947SRichard Lowe Dwarf_Global dgb = dwgl[i];
15649d3bc91SRichard Lowe
157*4d9fdb46SRobert Mustacchi if (!dgb) {
158*4d9fdb46SRobert Mustacchi continue;
159*4d9fdb46SRobert 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);
16807dc1947SRichard Lowe }
169*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg, dgb, global_DLA_code);
17007dc1947SRichard Lowe }
171*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg, dwgl, list_DLA_code);
17207dc1947SRichard Lowe return;
17349d3bc91SRichard Lowe }
17449d3bc91SRichard Lowe
175*4d9fdb46SRobert Mustacchi /* Sweeps the complete section. */
17649d3bc91SRichard Lowe 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)17749d3bc91SRichard Lowe _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg,
17807dc1947SRichard Lowe Dwarf_Small * section_data_ptr,
17907dc1947SRichard Lowe Dwarf_Unsigned section_length,
18007dc1947SRichard Lowe Dwarf_Global ** globals,
18107dc1947SRichard Lowe Dwarf_Signed * return_count,
18207dc1947SRichard Lowe Dwarf_Error * error,
183*4d9fdb46SRobert Mustacchi int context_DLA_code,
184*4d9fdb46SRobert Mustacchi int global_DLA_code,
18507dc1947SRichard Lowe int length_err_num,
18607dc1947SRichard Lowe int version_err_num)
18749d3bc91SRichard Lowe {
18807dc1947SRichard Lowe 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;
19149d3bc91SRichard Lowe
192*4d9fdb46SRobert Mustacchi /* Points to the context for the current set of global names, and
193*4d9fdb46SRobert Mustacchi contains information to identify the compilation-unit that the
194*4d9fdb46SRobert Mustacchi set refers to. */
19507dc1947SRichard Lowe Dwarf_Global_Context pubnames_context = 0;
19649d3bc91SRichard Lowe
197*4d9fdb46SRobert Mustacchi Dwarf_Unsigned version = 0;
19849d3bc91SRichard Lowe
199*4d9fdb46SRobert Mustacchi /* Offset from the start of compilation-unit for the current
200*4d9fdb46SRobert Mustacchi global. */
20107dc1947SRichard Lowe Dwarf_Off die_offset_in_cu = 0;
20249d3bc91SRichard Lowe
20349d3bc91SRichard Lowe Dwarf_Unsigned global_count = 0;
20449d3bc91SRichard Lowe
20549d3bc91SRichard Lowe /* Points to the current global read. */
20607dc1947SRichard Lowe Dwarf_Global global = 0;
20749d3bc91SRichard Lowe
208*4d9fdb46SRobert Mustacchi /* Used to chain the Dwarf_Global_s structs for creating contiguous
209*4d9fdb46SRobert Mustacchi list of pointers to the structs. */
21007dc1947SRichard Lowe Dwarf_Chain curr_chain = 0;
21107dc1947SRichard Lowe Dwarf_Chain prev_chain = 0;
21207dc1947SRichard Lowe Dwarf_Chain head_chain = 0;
21349d3bc91SRichard Lowe
21449d3bc91SRichard Lowe /* Points to contiguous block of Dwarf_Global's to be returned. */
21507dc1947SRichard Lowe Dwarf_Global *ret_globals = 0;
216*4d9fdb46SRobert Mustacchi int mres = 0;
21749d3bc91SRichard Lowe
21849d3bc91SRichard Lowe /* Temporary counter. */
21907dc1947SRichard Lowe Dwarf_Unsigned i = 0;
22049d3bc91SRichard Lowe
22149d3bc91SRichard Lowe if (dbg == NULL) {
22207dc1947SRichard Lowe _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
22307dc1947SRichard Lowe return (DW_DLV_ERROR);
22449d3bc91SRichard Lowe }
22549d3bc91SRichard Lowe /* We will eventually need the .debug_info data. Load it now. */
22607dc1947SRichard Lowe if (!dbg->de_debug_info.dss_data) {
22707dc1947SRichard Lowe int res = _dwarf_load_debug_info(dbg, error);
22807dc1947SRichard Lowe
22907dc1947SRichard Lowe if (res != DW_DLV_OK) {
23007dc1947SRichard Lowe return res;
23149d3bc91SRichard Lowe }
23249d3bc91SRichard Lowe }
23349d3bc91SRichard Lowe if (section_data_ptr == NULL) {
23407dc1947SRichard Lowe return (DW_DLV_NO_ENTRY);
23549d3bc91SRichard Lowe }
23649d3bc91SRichard Lowe pubnames_like_ptr = section_data_ptr;
23749d3bc91SRichard Lowe do {
23807dc1947SRichard Lowe Dwarf_Unsigned length = 0;
23907dc1947SRichard Lowe int local_extension_size = 0;
24007dc1947SRichard Lowe int local_length_size = 0;
24107dc1947SRichard Lowe
242*4d9fdb46SRobert 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
246*4d9fdb46SRobert Mustacchi terminator of the data are redundant information. The
247*4d9fdb46SRobert Mustacchi dwarf2/3 spec does not mention what to do if the length is
248*4d9fdb46SRobert Mustacchi past the 0 terminator. So we take any bytes left after the 0
249*4d9fdb46SRobert Mustacchi as padding and ignore them. */
25049d3bc91SRichard Lowe Dwarf_Small *pubnames_ptr_past_end_cu = 0;
25107dc1947SRichard Lowe
25207dc1947SRichard Lowe
25307dc1947SRichard Lowe pubnames_context = (Dwarf_Global_Context)
254*4d9fdb46SRobert Mustacchi _dwarf_get_alloc(dbg, context_DLA_code, 1);
25507dc1947SRichard Lowe if (pubnames_context == NULL) {
256*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
25707dc1947SRichard Lowe _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
258*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
259*4d9fdb46SRobert Mustacchi }
260*4d9fdb46SRobert Mustacchi /* READ_AREA_LENGTH updates pubnames_like_ptr for consumed
261*4d9fdb46SRobert 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;
27007dc1947SRichard Lowe }
27107dc1947SRichard Lowe pubnames_context->pu_length_size = local_length_size;
272*4d9fdb46SRobert Mustacchi pubnames_context->pu_length = length;
27307dc1947SRichard Lowe pubnames_context->pu_extension_size = local_extension_size;
27407dc1947SRichard Lowe pubnames_context->pu_dbg = dbg;
275*4d9fdb46SRobert Mustacchi pubnames_context->pu_pub_offset = pubnames_section_offset;
27607dc1947SRichard Lowe pubnames_ptr_past_end_cu = pubnames_like_ptr + length;
27707dc1947SRichard Lowe
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);
29207dc1947SRichard Lowe _dwarf_error(dbg, error, version_err_num);
293*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
29407dc1947SRichard Lowe }
29507dc1947SRichard Lowe
29607dc1947SRichard Lowe /* 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
30807dc1947SRichard Lowe pubnames_like_ptr += pubnames_context->pu_length_size;
30907dc1947SRichard Lowe
31007dc1947SRichard Lowe FIX_UP_OFFSET_IRIX_BUG(dbg,
311*4d9fdb46SRobert Mustacchi pubnames_context->pu_offset_of_cu_header,
312*4d9fdb46SRobert 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 }
32307dc1947SRichard Lowe pubnames_like_ptr += pubnames_context->pu_length_size;
32407dc1947SRichard Lowe
32507dc1947SRichard Lowe 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);
32807dc1947SRichard Lowe _dwarf_error(dbg, error, length_err_num);
32907dc1947SRichard Lowe return (DW_DLV_ERROR);
33049d3bc91SRichard Lowe }
33107dc1947SRichard Lowe
332*4d9fdb46SRobert Mustacchi /* Read initial offset (of DIE within CU) of a pubname, final
333*4d9fdb46SRobert 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,
336*4d9fdb46SRobert 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 }
34407dc1947SRichard Lowe pubnames_like_ptr += pubnames_context->pu_length_size;
34507dc1947SRichard Lowe FIX_UP_OFFSET_IRIX_BUG(dbg,
346*4d9fdb46SRobert 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 }
35307dc1947SRichard Lowe
35407dc1947SRichard Lowe /* 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() */
36607dc1947SRichard Lowe global =
367*4d9fdb46SRobert Mustacchi (Dwarf_Global) _dwarf_get_alloc(dbg, global_DLA_code, 1);
36807dc1947SRichard Lowe if (global == NULL) {
369*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
370*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
37107dc1947SRichard Lowe _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
37207dc1947SRichard Lowe return (DW_DLV_ERROR);
37307dc1947SRichard Lowe }
37407dc1947SRichard Lowe global_count++;
37507dc1947SRichard Lowe 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 */
379*4d9fdb46SRobert Mustacchi curr_chain =
380*4d9fdb46SRobert Mustacchi (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
381*4d9fdb46SRobert 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;
40607dc1947SRichard Lowe
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);
414*4d9fdb46SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
415*4d9fdb46SRobert Mustacchi return (DW_DLV_ERROR);
416*4d9fdb46SRobert Mustacchi }
417*4d9fdb46SRobert Mustacchi global_count++;
418*4d9fdb46SRobert Mustacchi global->gl_context = pubnames_context;
41907dc1947SRichard Lowe global->gl_named_die_offset_within_cu = die_offset_in_cu;
42007dc1947SRichard Lowe 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 }
42907dc1947SRichard Lowe pubnames_like_ptr = pubnames_like_ptr +
43007dc1947SRichard Lowe strlen((char *) pubnames_like_ptr) + 1;
43107dc1947SRichard Lowe
432*4d9fdb46SRobert Mustacchi /* Finish off current entry chain */
43307dc1947SRichard Lowe curr_chain =
43407dc1947SRichard Lowe (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
43507dc1947SRichard Lowe if (curr_chain == NULL) {
436*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
437*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
43807dc1947SRichard Lowe _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
43907dc1947SRichard Lowe return (DW_DLV_ERROR);
44007dc1947SRichard Lowe }
44107dc1947SRichard Lowe /* Put current global on singly_linked list. */
44207dc1947SRichard Lowe curr_chain->ch_item = (Dwarf_Global) global;
443*4d9fdb46SRobert Mustacchi curr_chain->ch_itemtype = global_DLA_code;
44407dc1947SRichard Lowe if (head_chain == NULL)
44507dc1947SRichard Lowe head_chain = prev_chain = curr_chain;
44607dc1947SRichard Lowe else {
44707dc1947SRichard Lowe prev_chain->ch_next = curr_chain;
44807dc1947SRichard Lowe prev_chain = curr_chain;
44907dc1947SRichard Lowe }
45007dc1947SRichard Lowe
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,
454*4d9fdb46SRobert 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 }
46207dc1947SRichard Lowe pubnames_like_ptr += pubnames_context->pu_length_size;
46307dc1947SRichard Lowe FIX_UP_OFFSET_IRIX_BUG(dbg,
464*4d9fdb46SRobert Mustacchi die_offset_in_cu, "offset of next die in cu");
46507dc1947SRichard Lowe 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);
46807dc1947SRichard Lowe _dwarf_error(dbg, error, length_err_num);
469*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
47007dc1947SRichard Lowe }
47107dc1947SRichard Lowe }
47207dc1947SRichard Lowe /* ASSERT: die_offset_in_cu == 0 */
47307dc1947SRichard Lowe if (pubnames_like_ptr > pubnames_ptr_past_end_cu) {
47407dc1947SRichard Lowe /* This is some kind of error. This simply cannot happen.
47507dc1947SRichard Lowe The encoding is wrong or the length in the header for
47607dc1947SRichard Lowe this cu's contribution is wrong. */
47707dc1947SRichard Lowe _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;
481*4d9fdb46SRobert Mustacchi }
482*4d9fdb46SRobert Mustacchi /* If there is some kind of padding at the end of the section,
483*4d9fdb46SRobert Mustacchi as emitted by some compilers, skip over that padding and
484*4d9fdb46SRobert Mustacchi simply ignore the bytes thus passed-over. With most
485*4d9fdb46SRobert Mustacchi compilers, pubnames_like_ptr == pubnames_ptr_past_end_cu at
486*4d9fdb46SRobert 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;
49307dc1947SRichard Lowe }
49407dc1947SRichard Lowe pubnames_like_ptr = pubnames_ptr_past_end_cu;
495*4d9fdb46SRobert Mustacchi } while (pubnames_like_ptr < section_end_ptr);
49649d3bc91SRichard Lowe
49749d3bc91SRichard Lowe /* Points to contiguous block of Dwarf_Global's. */
49849d3bc91SRichard Lowe ret_globals = (Dwarf_Global *)
49907dc1947SRichard Lowe _dwarf_get_alloc(dbg, DW_DLA_LIST, global_count);
50049d3bc91SRichard Lowe if (ret_globals == NULL) {
501*4d9fdb46SRobert Mustacchi dealloc_globals_chain(dbg,head_chain);
502*4d9fdb46SRobert Mustacchi dwarf_dealloc(dbg,pubnames_context,context_DLA_code);
50307dc1947SRichard Lowe _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
504*4d9fdb46SRobert Mustacchi return DW_DLV_ERROR;
50549d3bc91SRichard Lowe }
50649d3bc91SRichard Lowe
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 */
51049d3bc91SRichard Lowe curr_chain = head_chain;
51149d3bc91SRichard Lowe for (i = 0; i < global_count; i++) {
51207dc1947SRichard Lowe *(ret_globals + i) = curr_chain->ch_item;
51307dc1947SRichard Lowe prev_chain = curr_chain;
51407dc1947SRichard Lowe curr_chain = curr_chain->ch_next;
515*4d9fdb46SRobert Mustacchi prev_chain->ch_item = 0; /* Not actually necessary. */
51607dc1947SRichard Lowe dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
51749d3bc91SRichard Lowe }
51849d3bc91SRichard Lowe *globals = ret_globals;
51907dc1947SRichard Lowe *return_count = (Dwarf_Signed) global_count;
52049d3bc91SRichard Lowe return DW_DLV_OK;
52149d3bc91SRichard Lowe }
52249d3bc91SRichard Lowe
52307dc1947SRichard Lowe
524*4d9fdb46SRobert Mustacchi /* Given a pubnames entry (or other like section entry)
525*4d9fdb46SRobert Mustacchi return thru the ret_name pointer
526*4d9fdb46SRobert Mustacchi a pointer to the string which is the entry name. */
52749d3bc91SRichard Lowe int
dwarf_globname(Dwarf_Global glob,char ** ret_name,Dwarf_Error * error)52849d3bc91SRichard Lowe dwarf_globname(Dwarf_Global glob, char **ret_name, Dwarf_Error * error)
52949d3bc91SRichard Lowe {
53049d3bc91SRichard Lowe if (glob == NULL) {
53107dc1947SRichard Lowe _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
53207dc1947SRichard Lowe return (DW_DLV_ERROR);
53349d3bc91SRichard Lowe }
53449d3bc91SRichard Lowe
53549d3bc91SRichard Lowe *ret_name = (char *) (glob->gl_name);
53649d3bc91SRichard Lowe return DW_DLV_OK;
53749d3bc91SRichard Lowe }
53849d3bc91SRichard Lowe
53949d3bc91SRichard Lowe
540*4d9fdb46SRobert Mustacchi /* Given a pubnames entry (or other like section entry)
541*4d9fdb46SRobert Mustacchi return thru the ret_off pointer the
542*4d9fdb46SRobert Mustacchi global offset of the DIE for this entry.
543*4d9fdb46SRobert Mustacchi The global offset is the offset within the .debug_info
544*4d9fdb46SRobert Mustacchi section as a whole. */
54549d3bc91SRichard Lowe int
dwarf_global_die_offset(Dwarf_Global global,Dwarf_Off * ret_off,Dwarf_Error * error)54649d3bc91SRichard Lowe dwarf_global_die_offset(Dwarf_Global global,
547*4d9fdb46SRobert Mustacchi Dwarf_Off * ret_off, Dwarf_Error * error)
54849d3bc91SRichard Lowe {
54949d3bc91SRichard Lowe if (global == NULL) {
55007dc1947SRichard Lowe _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
55107dc1947SRichard Lowe return (DW_DLV_ERROR);
55249d3bc91SRichard Lowe }
55349d3bc91SRichard Lowe
55449d3bc91SRichard Lowe if (global->gl_context == NULL) {
55507dc1947SRichard Lowe _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
55607dc1947SRichard Lowe return (DW_DLV_ERROR);
55749d3bc91SRichard Lowe }
55849d3bc91SRichard Lowe
55949d3bc91SRichard Lowe *ret_off = (global->gl_named_die_offset_within_cu +
560*4d9fdb46SRobert Mustacchi global->gl_context->pu_offset_of_cu_header);
56149d3bc91SRichard Lowe return DW_DLV_OK;
56249d3bc91SRichard Lowe }
56349d3bc91SRichard Lowe
564*4d9fdb46SRobert Mustacchi /* Given a pubnames entry (or other like section entry)
565*4d9fdb46SRobert Mustacchi return thru the ret_off pointer the
566*4d9fdb46SRobert Mustacchi offset of the compilation unit header of the
567*4d9fdb46SRobert Mustacchi compilation unit the global is part of.
568*4d9fdb46SRobert Mustacchi
569*4d9fdb46SRobert Mustacchi In early versions of this, the value returned was
570*4d9fdb46SRobert Mustacchi the offset of the compilation unit die, and
571*4d9fdb46SRobert Mustacchi other cu-local die offsets were faked so adding this to
572*4d9fdb46SRobert Mustacchi such a cu-local offset got a true section offset.
573*4d9fdb46SRobert Mustacchi Now things do as they say (adding *cu_header_offset to
574*4d9fdb46SRobert Mustacchi a cu-local offset gets the section offset). */
57549d3bc91SRichard Lowe int
dwarf_global_cu_offset(Dwarf_Global global,Dwarf_Off * cu_header_offset,Dwarf_Error * error)57649d3bc91SRichard Lowe dwarf_global_cu_offset(Dwarf_Global global,
577*4d9fdb46SRobert Mustacchi Dwarf_Off * cu_header_offset,
578*4d9fdb46SRobert Mustacchi Dwarf_Error * error)
57949d3bc91SRichard Lowe {
58007dc1947SRichard Lowe Dwarf_Global_Context con = 0;
58149d3bc91SRichard Lowe
58249d3bc91SRichard Lowe if (global == NULL) {
58307dc1947SRichard Lowe _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
58407dc1947SRichard Lowe return (DW_DLV_ERROR);
58549d3bc91SRichard Lowe }
58649d3bc91SRichard Lowe
58749d3bc91SRichard Lowe con = global->gl_context;
58849d3bc91SRichard Lowe
58949d3bc91SRichard Lowe if (con == NULL) {
59007dc1947SRichard Lowe _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
59107dc1947SRichard Lowe return (DW_DLV_ERROR);
59249d3bc91SRichard Lowe }
59349d3bc91SRichard Lowe
594*4d9fdb46SRobert Mustacchi /* In early libdwarf, this incorrectly returned the offset of the
595*4d9fdb46SRobert Mustacchi CU DIE. Now correctly returns the header offset. */
59649d3bc91SRichard Lowe *cu_header_offset = con->pu_offset_of_cu_header;
59749d3bc91SRichard Lowe
59849d3bc91SRichard Lowe return DW_DLV_OK;
59949d3bc91SRichard Lowe }
60049d3bc91SRichard Lowe
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
62249d3bc91SRichard Lowe /*
62349d3bc91SRichard Lowe Give back the pubnames entry (or any other like section)
62449d3bc91SRichard Lowe name, symbol DIE offset, and the cu-DIE offset.
62507dc1947SRichard Lowe
62607dc1947SRichard Lowe Various errors are possible.
62707dc1947SRichard Lowe
62807dc1947SRichard Lowe The string pointer returned thru ret_name is not
629*4d9fdb46SRobert Mustacchi dwarf_get_alloc()ed, so no dwarf_dealloc()
63007dc1947SRichard Lowe DW_DLA_STRING should be applied to it.
63107dc1947SRichard Lowe
63249d3bc91SRichard Lowe */
63349d3bc91SRichard Lowe int
dwarf_global_name_offsets(Dwarf_Global global,char ** ret_name,Dwarf_Off * die_offset,Dwarf_Off * cu_die_offset,Dwarf_Error * error)63449d3bc91SRichard Lowe dwarf_global_name_offsets(Dwarf_Global global,
635*4d9fdb46SRobert Mustacchi char **ret_name,
636*4d9fdb46SRobert Mustacchi Dwarf_Off * die_offset,
637*4d9fdb46SRobert Mustacchi Dwarf_Off * cu_die_offset,
638*4d9fdb46SRobert Mustacchi Dwarf_Error * error)
63949d3bc91SRichard Lowe {
64007dc1947SRichard Lowe Dwarf_Global_Context con = 0;
64107dc1947SRichard Lowe Dwarf_Debug dbg = 0;
642*4d9fdb46SRobert Mustacchi Dwarf_Off cuhdr_off = 0;
64349d3bc91SRichard Lowe
64449d3bc91SRichard Lowe if (global == NULL) {
64507dc1947SRichard Lowe _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
64607dc1947SRichard Lowe return (DW_DLV_ERROR);
64749d3bc91SRichard Lowe }
64849d3bc91SRichard Lowe
64949d3bc91SRichard Lowe con = global->gl_context;
65049d3bc91SRichard Lowe
65149d3bc91SRichard Lowe if (con == NULL) {
65207dc1947SRichard Lowe _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
65307dc1947SRichard Lowe return (DW_DLV_ERROR);
65449d3bc91SRichard Lowe }
65549d3bc91SRichard Lowe
656*4d9fdb46SRobert Mustacchi cuhdr_off = con->pu_offset_of_cu_header;
657*4d9fdb46SRobert Mustacchi /* The offset had better not be too close to the end. If it is,
658*4d9fdb46SRobert Mustacchi _dwarf_length_of_cu_header() will step off the end and therefore
659*4d9fdb46SRobert Mustacchi must not be used. 10 is a meaningless heuristic, but no CU
660*4d9fdb46SRobert Mustacchi header is that small so it is safe. An erroneous offset is due
661*4d9fdb46SRobert Mustacchi to a bug in the tool chain. A bug like this has been seen on
662*4d9fdb46SRobert Mustacchi IRIX with MIPSpro 7.3.1.3 and an executable > 2GB in size and
663*4d9fdb46SRobert Mustacchi with 2 million pubnames entries. */
66407dc1947SRichard Lowe #define MIN_CU_HDR_SIZE 10
66549d3bc91SRichard Lowe dbg = con->pu_dbg;
66649d3bc91SRichard Lowe if (dbg == NULL) {
66707dc1947SRichard Lowe _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
66807dc1947SRichard Lowe return (DW_DLV_ERROR);
66907dc1947SRichard Lowe }
670*4d9fdb46SRobert Mustacchi /* Cannot refer to debug_types */
67107dc1947SRichard Lowe 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);
68007dc1947SRichard Lowe return (DW_DLV_ERROR);
68149d3bc91SRichard Lowe }
68207dc1947SRichard Lowe #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;
693*4d9fdb46SRobert Mustacchi }
69407dc1947SRichard Lowe }
69507dc1947SRichard Lowe *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;
70007dc1947SRichard Lowe int res = _dwarf_load_debug_info(dbg, error);
70107dc1947SRichard Lowe
70207dc1947SRichard Lowe if (res != DW_DLV_OK) {
70307dc1947SRichard Lowe return res;
70407dc1947SRichard Lowe }
705*4d9fdb46SRobert Mustacchi /* The offset had better not be too close to the end.
706*4d9fdb46SRobert Mustacchi If it is,
707*4d9fdb46SRobert Mustacchi _dwarf_length_of_cu_header() will step off the end and
708*4d9fdb46SRobert Mustacchi therefore must not be used. 10 is a meaningless heuristic,
709*4d9fdb46SRobert 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);
72007dc1947SRichard Lowe return (DW_DLV_ERROR);
72107dc1947SRichard Lowe }
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;
726*4d9fdb46SRobert Mustacchi }
727*4d9fdb46SRobert Mustacchi *cu_die_offset = cuhdr_off + headerlen;
72849d3bc91SRichard Lowe }
729*4d9fdb46SRobert Mustacchi return DW_DLV_OK;
730*4d9fdb46SRobert Mustacchi }
73149d3bc91SRichard Lowe
73249d3bc91SRichard Lowe
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 }
78449d3bc91SRichard Lowe return DW_DLV_OK;
78549d3bc91SRichard Lowe }
78649d3bc91SRichard Lowe
787*4d9fdb46SRobert Mustacchi
788*4d9fdb46SRobert Mustacchi /* We have the offset to a CU header.
789*4d9fdb46SRobert Mustacchi Return thru outFileOffset the offset of the CU DIE.
790*4d9fdb46SRobert Mustacchi
791*4d9fdb46SRobert 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 ...)
796*4d9fdb46SRobert Mustacchi
797*4d9fdb46SRobert 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
80249d3bc91SRichard Lowe */
80349d3bc91SRichard Lowe
80449d3bc91SRichard Lowe /* ARGSUSED */
80549d3bc91SRichard Lowe 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)80649d3bc91SRichard Lowe dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg,
80707dc1947SRichard Lowe Dwarf_Off in_cu_header_offset,
80807dc1947SRichard Lowe Dwarf_Off * out_cu_die_offset,
809*4d9fdb46SRobert Mustacchi UNUSEDARG Dwarf_Error * err)
81049d3bc91SRichard Lowe {
811*4d9fdb46SRobert Mustacchi Dwarf_Off headerlen = 0;
812*4d9fdb46SRobert Mustacchi int cres = 0;
81349d3bc91SRichard Lowe
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 }
822*4d9fdb46SRobert 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;
84149d3bc91SRichard Lowe
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;
84849d3bc91SRichard Lowe return DW_DLV_OK;
84949d3bc91SRichard Lowe }
850*4d9fdb46SRobert Mustacchi /* dwarf_CU_dieoffset_given_die returns
851*4d9fdb46SRobert Mustacchi the global debug_info section offset of the CU die
852*4d9fdb46SRobert Mustacchi that is the CU containing the given (passed-in) die.
853*4d9fdb46SRobert Mustacchi This information makes it possible for a consumer to
854*4d9fdb46SRobert Mustacchi find and print context information for any die.
855*4d9fdb46SRobert Mustacchi
856*4d9fdb46SRobert Mustacchi Use dwarf_offdie() passing in the offset this returns
857*4d9fdb46SRobert Mustacchi to get a die pointer to the CU die. */
858*4d9fdb46SRobert Mustacchi int
dwarf_CU_dieoffset_given_die(Dwarf_Die die,Dwarf_Off * return_offset,Dwarf_Error * error)85907dc1947SRichard Lowe dwarf_CU_dieoffset_given_die(Dwarf_Die die,
86007dc1947SRichard Lowe Dwarf_Off* return_offset,
86107dc1947SRichard Lowe Dwarf_Error* error)
862*4d9fdb46SRobert Mustacchi {
86307dc1947SRichard Lowe Dwarf_Off dieoff = 0;
86407dc1947SRichard Lowe Dwarf_CU_Context cucontext = 0;
865*4d9fdb46SRobert Mustacchi
86607dc1947SRichard Lowe CHECK_DIE(die, DW_DLV_ERROR);
86707dc1947SRichard Lowe cucontext = die->di_cu_context;
868*4d9fdb46SRobert Mustacchi dieoff = cucontext->cc_debug_offset;
869*4d9fdb46SRobert 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;
88807dc1947SRichard Lowe return DW_DLV_OK;
88907dc1947SRichard Lowe }
890