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