xref: /titanic_52/usr/src/lib/libdwarf/common/dwarf_global.c (revision 7fd791373689a6af05e27efec3b1ab556e02aa23)
1*7fd79137SRobert Mustacchi /*
2*7fd79137SRobert Mustacchi 
3*7fd79137SRobert Mustacchi   Copyright (C) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
4*7fd79137SRobert Mustacchi   Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
5*7fd79137SRobert Mustacchi 
6*7fd79137SRobert Mustacchi   This program is free software; you can redistribute it and/or modify it
7*7fd79137SRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
8*7fd79137SRobert Mustacchi   as published by the Free Software Foundation.
9*7fd79137SRobert Mustacchi 
10*7fd79137SRobert Mustacchi   This program is distributed in the hope that it would be useful, but
11*7fd79137SRobert Mustacchi   WITHOUT ANY WARRANTY; without even the implied warranty of
12*7fd79137SRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13*7fd79137SRobert Mustacchi 
14*7fd79137SRobert Mustacchi   Further, this software is distributed without any warranty that it is
15*7fd79137SRobert Mustacchi   free of the rightful claim of any third person regarding infringement
16*7fd79137SRobert Mustacchi   or the like.  Any license provided herein, whether implied or
17*7fd79137SRobert Mustacchi   otherwise, applies only to this software file.  Patent licenses, if
18*7fd79137SRobert Mustacchi   any, provided herein do not apply to combinations of this program with
19*7fd79137SRobert Mustacchi   other software, or any other product whatsoever.
20*7fd79137SRobert Mustacchi 
21*7fd79137SRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
22*7fd79137SRobert Mustacchi   License along with this program; if not, write the Free Software
23*7fd79137SRobert Mustacchi   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24*7fd79137SRobert Mustacchi   USA.
25*7fd79137SRobert Mustacchi 
26*7fd79137SRobert Mustacchi   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
27*7fd79137SRobert Mustacchi   Mountain View, CA 94043, or:
28*7fd79137SRobert Mustacchi 
29*7fd79137SRobert Mustacchi   http://www.sgi.com
30*7fd79137SRobert Mustacchi 
31*7fd79137SRobert Mustacchi   For further information regarding this notice, see:
32*7fd79137SRobert Mustacchi 
33*7fd79137SRobert Mustacchi   http://oss.sgi.com/projects/GenInfo/NoticeExplan
34*7fd79137SRobert Mustacchi 
35*7fd79137SRobert Mustacchi */
36*7fd79137SRobert Mustacchi /* The address of the Free Software Foundation is
37*7fd79137SRobert Mustacchi    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
38*7fd79137SRobert Mustacchi    Boston, MA 02110-1301, USA.
39*7fd79137SRobert Mustacchi    SGI has moved from the Crittenden Lane address.
40*7fd79137SRobert Mustacchi */
41*7fd79137SRobert Mustacchi 
42*7fd79137SRobert Mustacchi 
43*7fd79137SRobert Mustacchi 
44*7fd79137SRobert Mustacchi 
45*7fd79137SRobert Mustacchi #include "config.h"
46*7fd79137SRobert Mustacchi #include "dwarf_incl.h"
47*7fd79137SRobert Mustacchi #include <stdio.h>
48*7fd79137SRobert Mustacchi #include "dwarf_global.h"
49*7fd79137SRobert Mustacchi 
50*7fd79137SRobert Mustacchi 
51*7fd79137SRobert Mustacchi #ifdef __sgi  /* __sgi should only be defined for IRIX/MIPS. */
52*7fd79137SRobert Mustacchi /* The 'fixup' here intended for IRIX targets only.
53*7fd79137SRobert Mustacchi    With a  2+GB Elf64 IRIX executable (under 4GB in size),
54*7fd79137SRobert Mustacchi    some DIE offsets wrongly
55*7fd79137SRobert Mustacchi    got the 32bit upper bit sign extended.  For the cu-header
56*7fd79137SRobert Mustacchi    offset in the .debug_pubnames section  and in the
57*7fd79137SRobert Mustacchi    .debug_aranges section.
58*7fd79137SRobert Mustacchi    the 'varp' here is a pointer to an offset into .debug_info.
59*7fd79137SRobert Mustacchi    We fix up the offset here if it seems advisable..
60*7fd79137SRobert Mustacchi 
61*7fd79137SRobert Mustacchi    As of June 2005 we have identified a series of mistakes
62*7fd79137SRobert Mustacchi    in ldx64 that can cause this (64 bit values getting passed
63*7fd79137SRobert Mustacchi    thru 32-bit signed knothole).
64*7fd79137SRobert Mustacchi */
65*7fd79137SRobert Mustacchi void
66*7fd79137SRobert Mustacchi _dwarf_fix_up_offset_irix(Dwarf_Debug dbg,
67*7fd79137SRobert Mustacchi     Dwarf_Unsigned * varp, char *caller_site_name)
68*7fd79137SRobert Mustacchi {
69*7fd79137SRobert Mustacchi 
70*7fd79137SRobert Mustacchi     Dwarf_Unsigned var = *varp;
71*7fd79137SRobert Mustacchi 
72*7fd79137SRobert Mustacchi #define UPPER33 0xffffffff80000000LL
73*7fd79137SRobert Mustacchi #define LOWER32         0xffffffffLL
74*7fd79137SRobert Mustacchi     /* Restrict the hack to the known case. Upper 32 bits erroneously
75*7fd79137SRobert Mustacchi        sign extended from lower 32 upper bit. */
76*7fd79137SRobert Mustacchi     if ((var & UPPER33) == UPPER33) {
77*7fd79137SRobert Mustacchi         var &= LOWER32;
78*7fd79137SRobert Mustacchi         /* Apply the fix. Dreadful hack. */
79*7fd79137SRobert Mustacchi         *varp = var;
80*7fd79137SRobert Mustacchi     }
81*7fd79137SRobert Mustacchi #undef UPPER33
82*7fd79137SRobert Mustacchi #undef LOWER32
83*7fd79137SRobert Mustacchi     return;
84*7fd79137SRobert Mustacchi }
85*7fd79137SRobert Mustacchi #endif
86*7fd79137SRobert Mustacchi 
87*7fd79137SRobert Mustacchi 
88*7fd79137SRobert Mustacchi int
89*7fd79137SRobert Mustacchi dwarf_get_globals(Dwarf_Debug dbg,
90*7fd79137SRobert Mustacchi     Dwarf_Global ** globals,
91*7fd79137SRobert Mustacchi     Dwarf_Signed * return_count, Dwarf_Error * error)
92*7fd79137SRobert Mustacchi {
93*7fd79137SRobert Mustacchi     int res = _dwarf_load_section(dbg, &dbg->de_debug_pubnames,error);
94*7fd79137SRobert Mustacchi     if (res != DW_DLV_OK) {
95*7fd79137SRobert Mustacchi         return res;
96*7fd79137SRobert Mustacchi     }
97*7fd79137SRobert Mustacchi 
98*7fd79137SRobert Mustacchi     return _dwarf_internal_get_pubnames_like_data(dbg,
99*7fd79137SRobert Mustacchi         dbg->de_debug_pubnames.dss_data,
100*7fd79137SRobert Mustacchi         dbg->de_debug_pubnames.dss_size,
101*7fd79137SRobert Mustacchi         globals,
102*7fd79137SRobert Mustacchi         return_count,
103*7fd79137SRobert Mustacchi         error,
104*7fd79137SRobert Mustacchi         DW_DLA_GLOBAL_CONTEXT,
105*7fd79137SRobert Mustacchi         DW_DLA_GLOBAL,
106*7fd79137SRobert Mustacchi         DW_DLE_PUBNAMES_LENGTH_BAD,
107*7fd79137SRobert Mustacchi         DW_DLE_PUBNAMES_VERSION_ERROR);
108*7fd79137SRobert Mustacchi 
109*7fd79137SRobert Mustacchi }
110*7fd79137SRobert Mustacchi 
111*7fd79137SRobert Mustacchi /* Deallocating fully requires deallocating the list
112*7fd79137SRobert Mustacchi    and all entries.  But some internal data is
113*7fd79137SRobert Mustacchi    not exposed, so we need a function with internal knowledge.
114*7fd79137SRobert Mustacchi */
115*7fd79137SRobert Mustacchi 
116*7fd79137SRobert Mustacchi void
117*7fd79137SRobert Mustacchi dwarf_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl,
118*7fd79137SRobert Mustacchi     Dwarf_Signed count)
119*7fd79137SRobert Mustacchi {
120*7fd79137SRobert Mustacchi     _dwarf_internal_globals_dealloc(dbg, dwgl,
121*7fd79137SRobert Mustacchi         count,
122*7fd79137SRobert Mustacchi         DW_DLA_GLOBAL_CONTEXT,
123*7fd79137SRobert Mustacchi         DW_DLA_GLOBAL, DW_DLA_LIST);
124*7fd79137SRobert Mustacchi     return;
125*7fd79137SRobert Mustacchi }
126*7fd79137SRobert Mustacchi 
127*7fd79137SRobert Mustacchi void
128*7fd79137SRobert Mustacchi _dwarf_internal_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl,
129*7fd79137SRobert Mustacchi     Dwarf_Signed count,
130*7fd79137SRobert Mustacchi     int context_code,
131*7fd79137SRobert Mustacchi     int global_code, int list_code)
132*7fd79137SRobert Mustacchi {
133*7fd79137SRobert Mustacchi     Dwarf_Signed i;
134*7fd79137SRobert Mustacchi     struct Dwarf_Global_Context_s *gcp = 0;
135*7fd79137SRobert Mustacchi     struct Dwarf_Global_Context_s *lastgcp = 0;
136*7fd79137SRobert Mustacchi 
137*7fd79137SRobert Mustacchi     for (i = 0; i < count; i++) {
138*7fd79137SRobert Mustacchi         Dwarf_Global dgb = dwgl[i];
139*7fd79137SRobert Mustacchi 
140*7fd79137SRobert Mustacchi         gcp = dgb->gl_context;
141*7fd79137SRobert Mustacchi 
142*7fd79137SRobert Mustacchi         if (lastgcp != gcp) {
143*7fd79137SRobert Mustacchi             lastgcp = gcp;
144*7fd79137SRobert Mustacchi             dwarf_dealloc(dbg, gcp, context_code);
145*7fd79137SRobert Mustacchi         }
146*7fd79137SRobert Mustacchi         dwarf_dealloc(dbg, dgb, global_code);
147*7fd79137SRobert Mustacchi     }
148*7fd79137SRobert Mustacchi     dwarf_dealloc(dbg, dwgl, list_code);
149*7fd79137SRobert Mustacchi     return;
150*7fd79137SRobert Mustacchi }
151*7fd79137SRobert Mustacchi 
152*7fd79137SRobert Mustacchi 
153*7fd79137SRobert Mustacchi /* Sweeps the complete  section.
154*7fd79137SRobert Mustacchi */
155*7fd79137SRobert Mustacchi int
156*7fd79137SRobert Mustacchi _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg,
157*7fd79137SRobert Mustacchi     Dwarf_Small * section_data_ptr,
158*7fd79137SRobert Mustacchi     Dwarf_Unsigned section_length,
159*7fd79137SRobert Mustacchi     Dwarf_Global ** globals,
160*7fd79137SRobert Mustacchi     Dwarf_Signed * return_count,
161*7fd79137SRobert Mustacchi     Dwarf_Error * error,
162*7fd79137SRobert Mustacchi     int context_code,
163*7fd79137SRobert Mustacchi     int global_code,
164*7fd79137SRobert Mustacchi     int length_err_num,
165*7fd79137SRobert Mustacchi     int version_err_num)
166*7fd79137SRobert Mustacchi {
167*7fd79137SRobert Mustacchi 
168*7fd79137SRobert Mustacchi 
169*7fd79137SRobert Mustacchi     Dwarf_Small *pubnames_like_ptr = 0;
170*7fd79137SRobert Mustacchi 
171*7fd79137SRobert Mustacchi 
172*7fd79137SRobert Mustacchi 
173*7fd79137SRobert Mustacchi     /* Points to the context for the current set of global names, and
174*7fd79137SRobert Mustacchi        contains information to identify the compilation-unit that the
175*7fd79137SRobert Mustacchi        set refers to. */
176*7fd79137SRobert Mustacchi     Dwarf_Global_Context pubnames_context = 0;
177*7fd79137SRobert Mustacchi 
178*7fd79137SRobert Mustacchi     Dwarf_Half version = 0;
179*7fd79137SRobert Mustacchi 
180*7fd79137SRobert Mustacchi     /*
181*7fd79137SRobert Mustacchi        Offset from the start of compilation-unit for the current
182*7fd79137SRobert Mustacchi        global. */
183*7fd79137SRobert Mustacchi     Dwarf_Off die_offset_in_cu = 0;
184*7fd79137SRobert Mustacchi 
185*7fd79137SRobert Mustacchi     Dwarf_Unsigned global_count = 0;
186*7fd79137SRobert Mustacchi 
187*7fd79137SRobert Mustacchi     /* Points to the current global read. */
188*7fd79137SRobert Mustacchi     Dwarf_Global global = 0;
189*7fd79137SRobert Mustacchi 
190*7fd79137SRobert Mustacchi     /* Used to chain the Dwarf_Global_s structs for creating contiguous
191*7fd79137SRobert Mustacchi        list of pointers to the structs. */
192*7fd79137SRobert Mustacchi     Dwarf_Chain curr_chain = 0;
193*7fd79137SRobert Mustacchi     Dwarf_Chain prev_chain = 0;
194*7fd79137SRobert Mustacchi     Dwarf_Chain head_chain = 0;
195*7fd79137SRobert Mustacchi 
196*7fd79137SRobert Mustacchi     /* Points to contiguous block of Dwarf_Global's to be returned. */
197*7fd79137SRobert Mustacchi     Dwarf_Global *ret_globals = 0;
198*7fd79137SRobert Mustacchi 
199*7fd79137SRobert Mustacchi     /* Temporary counter. */
200*7fd79137SRobert Mustacchi     Dwarf_Unsigned i = 0;
201*7fd79137SRobert Mustacchi 
202*7fd79137SRobert Mustacchi 
203*7fd79137SRobert Mustacchi 
204*7fd79137SRobert Mustacchi 
205*7fd79137SRobert Mustacchi     if (dbg == NULL) {
206*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
207*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
208*7fd79137SRobert Mustacchi     }
209*7fd79137SRobert Mustacchi     /* We will eventually need the .debug_info data. Load it now. */
210*7fd79137SRobert Mustacchi     if (!dbg->de_debug_info.dss_data) {
211*7fd79137SRobert Mustacchi         int res = _dwarf_load_debug_info(dbg, error);
212*7fd79137SRobert Mustacchi 
213*7fd79137SRobert Mustacchi         if (res != DW_DLV_OK) {
214*7fd79137SRobert Mustacchi             return res;
215*7fd79137SRobert Mustacchi         }
216*7fd79137SRobert Mustacchi     }
217*7fd79137SRobert Mustacchi 
218*7fd79137SRobert Mustacchi     if (section_data_ptr == NULL) {
219*7fd79137SRobert Mustacchi         return (DW_DLV_NO_ENTRY);
220*7fd79137SRobert Mustacchi     }
221*7fd79137SRobert Mustacchi 
222*7fd79137SRobert Mustacchi     pubnames_like_ptr = section_data_ptr;
223*7fd79137SRobert Mustacchi     do {
224*7fd79137SRobert Mustacchi         Dwarf_Unsigned length = 0;
225*7fd79137SRobert Mustacchi         int local_extension_size = 0;
226*7fd79137SRobert Mustacchi         int local_length_size = 0;
227*7fd79137SRobert Mustacchi 
228*7fd79137SRobert Mustacchi         /* Some compilers emit padding at the end of each cu's area.
229*7fd79137SRobert Mustacchi            pubnames_ptr_past_end_cu records the true area end for this
230*7fd79137SRobert Mustacchi            cu's data.  Essentially the length in the header and the 0
231*7fd79137SRobert Mustacchi            terminator of the data are redundant information. The
232*7fd79137SRobert Mustacchi            dwarf2/3 spec does not mention what to do if the length is
233*7fd79137SRobert Mustacchi            past the 0 terminator. So we take any bytes left after the 0
234*7fd79137SRobert Mustacchi            as padding and ignore them. */
235*7fd79137SRobert Mustacchi         Dwarf_Small *pubnames_ptr_past_end_cu = 0;
236*7fd79137SRobert Mustacchi 
237*7fd79137SRobert Mustacchi 
238*7fd79137SRobert Mustacchi         pubnames_context = (Dwarf_Global_Context)
239*7fd79137SRobert Mustacchi             _dwarf_get_alloc(dbg, context_code, 1);
240*7fd79137SRobert Mustacchi         if (pubnames_context == NULL) {
241*7fd79137SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
242*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
243*7fd79137SRobert Mustacchi         }
244*7fd79137SRobert Mustacchi         /* READ_AREA_LENGTH updates pubnames_like_ptr for consumed
245*7fd79137SRobert Mustacchi            bytes. */
246*7fd79137SRobert Mustacchi         READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
247*7fd79137SRobert Mustacchi             pubnames_like_ptr, local_length_size,
248*7fd79137SRobert Mustacchi             local_extension_size);
249*7fd79137SRobert Mustacchi         pubnames_context->pu_length_size = local_length_size;
250*7fd79137SRobert Mustacchi         pubnames_context->pu_extension_size = local_extension_size;
251*7fd79137SRobert Mustacchi         pubnames_context->pu_dbg = dbg;
252*7fd79137SRobert Mustacchi 
253*7fd79137SRobert Mustacchi         pubnames_ptr_past_end_cu = pubnames_like_ptr + length;
254*7fd79137SRobert Mustacchi 
255*7fd79137SRobert Mustacchi         READ_UNALIGNED(dbg, version, Dwarf_Half,
256*7fd79137SRobert Mustacchi                        pubnames_like_ptr, sizeof(Dwarf_Half));
257*7fd79137SRobert Mustacchi         pubnames_like_ptr += sizeof(Dwarf_Half);
258*7fd79137SRobert Mustacchi         if (version != CURRENT_VERSION_STAMP) {
259*7fd79137SRobert Mustacchi             _dwarf_error(dbg, error, version_err_num);
260*7fd79137SRobert Mustacchi             return (DW_DLV_ERROR);
261*7fd79137SRobert Mustacchi         }
262*7fd79137SRobert Mustacchi 
263*7fd79137SRobert Mustacchi         /* Offset of CU header in debug section. */
264*7fd79137SRobert Mustacchi         READ_UNALIGNED(dbg, pubnames_context->pu_offset_of_cu_header,
265*7fd79137SRobert Mustacchi                        Dwarf_Off, pubnames_like_ptr,
266*7fd79137SRobert Mustacchi                        pubnames_context->pu_length_size);
267*7fd79137SRobert Mustacchi         pubnames_like_ptr += pubnames_context->pu_length_size;
268*7fd79137SRobert Mustacchi 
269*7fd79137SRobert Mustacchi         FIX_UP_OFFSET_IRIX_BUG(dbg,
270*7fd79137SRobert Mustacchi                                pubnames_context->pu_offset_of_cu_header,
271*7fd79137SRobert Mustacchi                                "pubnames cu header offset");
272*7fd79137SRobert Mustacchi 
273*7fd79137SRobert Mustacchi 
274*7fd79137SRobert Mustacchi         READ_UNALIGNED(dbg, pubnames_context->pu_info_length,
275*7fd79137SRobert Mustacchi                        Dwarf_Unsigned, pubnames_like_ptr,
276*7fd79137SRobert Mustacchi                        pubnames_context->pu_length_size);
277*7fd79137SRobert Mustacchi         pubnames_like_ptr += pubnames_context->pu_length_size;
278*7fd79137SRobert Mustacchi 
279*7fd79137SRobert Mustacchi         if (pubnames_like_ptr > (section_data_ptr + section_length)) {
280*7fd79137SRobert Mustacchi             _dwarf_error(dbg, error, length_err_num);
281*7fd79137SRobert Mustacchi             return (DW_DLV_ERROR);
282*7fd79137SRobert Mustacchi         }
283*7fd79137SRobert Mustacchi 
284*7fd79137SRobert Mustacchi         /* Read initial offset (of DIE within CU) of a pubname, final
285*7fd79137SRobert Mustacchi            entry is not a pair, just a zero offset. */
286*7fd79137SRobert Mustacchi         READ_UNALIGNED(dbg, die_offset_in_cu, Dwarf_Off,
287*7fd79137SRobert Mustacchi                        pubnames_like_ptr,
288*7fd79137SRobert Mustacchi                        pubnames_context->pu_length_size);
289*7fd79137SRobert Mustacchi         pubnames_like_ptr += pubnames_context->pu_length_size;
290*7fd79137SRobert Mustacchi         FIX_UP_OFFSET_IRIX_BUG(dbg,
291*7fd79137SRobert Mustacchi                                die_offset_in_cu, "offset of die in cu");
292*7fd79137SRobert Mustacchi 
293*7fd79137SRobert Mustacchi         /* Loop thru pairs. DIE off with CU followed by string. */
294*7fd79137SRobert Mustacchi         while (die_offset_in_cu != 0) {
295*7fd79137SRobert Mustacchi 
296*7fd79137SRobert Mustacchi             /* Already read offset, pubnames_like_ptr now points to the
297*7fd79137SRobert Mustacchi                string. */
298*7fd79137SRobert Mustacchi             global =
299*7fd79137SRobert Mustacchi                 (Dwarf_Global) _dwarf_get_alloc(dbg, global_code, 1);
300*7fd79137SRobert Mustacchi             if (global == NULL) {
301*7fd79137SRobert Mustacchi                 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
302*7fd79137SRobert Mustacchi                 return (DW_DLV_ERROR);
303*7fd79137SRobert Mustacchi             }
304*7fd79137SRobert Mustacchi             global_count++;
305*7fd79137SRobert Mustacchi 
306*7fd79137SRobert Mustacchi             global->gl_context = pubnames_context;
307*7fd79137SRobert Mustacchi 
308*7fd79137SRobert Mustacchi             global->gl_named_die_offset_within_cu = die_offset_in_cu;
309*7fd79137SRobert Mustacchi 
310*7fd79137SRobert Mustacchi             global->gl_name = pubnames_like_ptr;
311*7fd79137SRobert Mustacchi 
312*7fd79137SRobert Mustacchi             pubnames_like_ptr = pubnames_like_ptr +
313*7fd79137SRobert Mustacchi                 strlen((char *) pubnames_like_ptr) + 1;
314*7fd79137SRobert Mustacchi 
315*7fd79137SRobert Mustacchi 
316*7fd79137SRobert Mustacchi             /* finish off current entry chain */
317*7fd79137SRobert Mustacchi             curr_chain =
318*7fd79137SRobert Mustacchi                 (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
319*7fd79137SRobert Mustacchi             if (curr_chain == NULL) {
320*7fd79137SRobert Mustacchi                 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
321*7fd79137SRobert Mustacchi                 return (DW_DLV_ERROR);
322*7fd79137SRobert Mustacchi             }
323*7fd79137SRobert Mustacchi 
324*7fd79137SRobert Mustacchi             /* Put current global on singly_linked list. */
325*7fd79137SRobert Mustacchi             curr_chain->ch_item = (Dwarf_Global) global;
326*7fd79137SRobert Mustacchi 
327*7fd79137SRobert Mustacchi             if (head_chain == NULL)
328*7fd79137SRobert Mustacchi                 head_chain = prev_chain = curr_chain;
329*7fd79137SRobert Mustacchi             else {
330*7fd79137SRobert Mustacchi                 prev_chain->ch_next = curr_chain;
331*7fd79137SRobert Mustacchi                 prev_chain = curr_chain;
332*7fd79137SRobert Mustacchi             }
333*7fd79137SRobert Mustacchi 
334*7fd79137SRobert Mustacchi             /* read offset for the *next* entry */
335*7fd79137SRobert Mustacchi             READ_UNALIGNED(dbg, die_offset_in_cu, Dwarf_Off,
336*7fd79137SRobert Mustacchi                            pubnames_like_ptr,
337*7fd79137SRobert Mustacchi                            pubnames_context->pu_length_size);
338*7fd79137SRobert Mustacchi 
339*7fd79137SRobert Mustacchi             pubnames_like_ptr += pubnames_context->pu_length_size;
340*7fd79137SRobert Mustacchi             FIX_UP_OFFSET_IRIX_BUG(dbg,
341*7fd79137SRobert Mustacchi                                    die_offset_in_cu,
342*7fd79137SRobert Mustacchi                                    "offset of next die in cu");
343*7fd79137SRobert Mustacchi 
344*7fd79137SRobert Mustacchi             if (pubnames_like_ptr > (section_data_ptr + section_length)) {
345*7fd79137SRobert Mustacchi                 _dwarf_error(dbg, error, length_err_num);
346*7fd79137SRobert Mustacchi                 return (DW_DLV_ERROR);
347*7fd79137SRobert Mustacchi             }
348*7fd79137SRobert Mustacchi         }
349*7fd79137SRobert Mustacchi         /* ASSERT: die_offset_in_cu == 0 */
350*7fd79137SRobert Mustacchi         if (pubnames_like_ptr > pubnames_ptr_past_end_cu) {
351*7fd79137SRobert Mustacchi             /* This is some kind of error. This simply cannot happen.
352*7fd79137SRobert Mustacchi             The encoding is wrong or the length in the header for
353*7fd79137SRobert Mustacchi             this cu's contribution is wrong. */
354*7fd79137SRobert Mustacchi             _dwarf_error(dbg, error, length_err_num);
355*7fd79137SRobert Mustacchi             return (DW_DLV_ERROR);
356*7fd79137SRobert Mustacchi         }
357*7fd79137SRobert Mustacchi         /* If there is some kind of padding at the end of the section,
358*7fd79137SRobert Mustacchi            as emitted by some compilers, skip over that padding and
359*7fd79137SRobert Mustacchi            simply ignore the bytes thus passed-over.  With most
360*7fd79137SRobert Mustacchi            compilers, pubnames_like_ptr == pubnames_ptr_past_end_cu at
361*7fd79137SRobert Mustacchi            this point */
362*7fd79137SRobert Mustacchi         pubnames_like_ptr = pubnames_ptr_past_end_cu;
363*7fd79137SRobert Mustacchi 
364*7fd79137SRobert Mustacchi     } while (pubnames_like_ptr < (section_data_ptr + section_length));
365*7fd79137SRobert Mustacchi 
366*7fd79137SRobert Mustacchi     /* Points to contiguous block of Dwarf_Global's. */
367*7fd79137SRobert Mustacchi     ret_globals = (Dwarf_Global *)
368*7fd79137SRobert Mustacchi         _dwarf_get_alloc(dbg, DW_DLA_LIST, global_count);
369*7fd79137SRobert Mustacchi     if (ret_globals == NULL) {
370*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
371*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
372*7fd79137SRobert Mustacchi     }
373*7fd79137SRobert Mustacchi 
374*7fd79137SRobert Mustacchi     /*
375*7fd79137SRobert Mustacchi        Store pointers to Dwarf_Global_s structs in contiguous block,
376*7fd79137SRobert Mustacchi        and deallocate the chain. */
377*7fd79137SRobert Mustacchi     curr_chain = head_chain;
378*7fd79137SRobert Mustacchi     for (i = 0; i < global_count; i++) {
379*7fd79137SRobert Mustacchi         *(ret_globals + i) = curr_chain->ch_item;
380*7fd79137SRobert Mustacchi         prev_chain = curr_chain;
381*7fd79137SRobert Mustacchi         curr_chain = curr_chain->ch_next;
382*7fd79137SRobert Mustacchi         dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
383*7fd79137SRobert Mustacchi     }
384*7fd79137SRobert Mustacchi 
385*7fd79137SRobert Mustacchi     *globals = ret_globals;
386*7fd79137SRobert Mustacchi     *return_count = (Dwarf_Signed) global_count;
387*7fd79137SRobert Mustacchi     return DW_DLV_OK;
388*7fd79137SRobert Mustacchi }
389*7fd79137SRobert Mustacchi 
390*7fd79137SRobert Mustacchi 
391*7fd79137SRobert Mustacchi /*
392*7fd79137SRobert Mustacchi         Given a pubnames entry (or other like section entry)
393*7fd79137SRobert Mustacchi         return thru the ret_name pointer
394*7fd79137SRobert Mustacchi         a pointer to the string which is the entry name.
395*7fd79137SRobert Mustacchi 
396*7fd79137SRobert Mustacchi */
397*7fd79137SRobert Mustacchi int
398*7fd79137SRobert Mustacchi dwarf_globname(Dwarf_Global glob, char **ret_name, Dwarf_Error * error)
399*7fd79137SRobert Mustacchi {
400*7fd79137SRobert Mustacchi     if (glob == NULL) {
401*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
402*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
403*7fd79137SRobert Mustacchi     }
404*7fd79137SRobert Mustacchi 
405*7fd79137SRobert Mustacchi     *ret_name = (char *) (glob->gl_name);
406*7fd79137SRobert Mustacchi     return DW_DLV_OK;
407*7fd79137SRobert Mustacchi }
408*7fd79137SRobert Mustacchi 
409*7fd79137SRobert Mustacchi 
410*7fd79137SRobert Mustacchi /*
411*7fd79137SRobert Mustacchi         Given a pubnames entry (or other like section entry)
412*7fd79137SRobert Mustacchi         return thru the ret_off pointer the
413*7fd79137SRobert Mustacchi         global offset of the DIE for this entry.
414*7fd79137SRobert Mustacchi         The global offset is the offset within the .debug_info
415*7fd79137SRobert Mustacchi         section as a whole.
416*7fd79137SRobert Mustacchi */
417*7fd79137SRobert Mustacchi int
418*7fd79137SRobert Mustacchi dwarf_global_die_offset(Dwarf_Global global,
419*7fd79137SRobert Mustacchi                         Dwarf_Off * ret_off, Dwarf_Error * error)
420*7fd79137SRobert Mustacchi {
421*7fd79137SRobert Mustacchi     if (global == NULL) {
422*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
423*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
424*7fd79137SRobert Mustacchi     }
425*7fd79137SRobert Mustacchi 
426*7fd79137SRobert Mustacchi     if (global->gl_context == NULL) {
427*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
428*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
429*7fd79137SRobert Mustacchi     }
430*7fd79137SRobert Mustacchi 
431*7fd79137SRobert Mustacchi     *ret_off = (global->gl_named_die_offset_within_cu +
432*7fd79137SRobert Mustacchi                 global->gl_context->pu_offset_of_cu_header);
433*7fd79137SRobert Mustacchi     return DW_DLV_OK;
434*7fd79137SRobert Mustacchi }
435*7fd79137SRobert Mustacchi 
436*7fd79137SRobert Mustacchi /*
437*7fd79137SRobert Mustacchi         Given a pubnames entry (or other like section entry)
438*7fd79137SRobert Mustacchi         return thru the ret_off pointer the
439*7fd79137SRobert Mustacchi         offset of the compilation unit header of the
440*7fd79137SRobert Mustacchi         compilation unit the global is part of.
441*7fd79137SRobert Mustacchi 
442*7fd79137SRobert Mustacchi         In early versions of this, the value returned was
443*7fd79137SRobert Mustacchi         the offset of the compilation unit die, and
444*7fd79137SRobert Mustacchi         other cu-local die offsets were faked so adding this to
445*7fd79137SRobert Mustacchi         such a cu-local offset got a true section offset.
446*7fd79137SRobert Mustacchi         Now things do as they say (adding *cu_header_offset to
447*7fd79137SRobert Mustacchi         a cu-local offset gets the section offset).
448*7fd79137SRobert Mustacchi 
449*7fd79137SRobert Mustacchi */
450*7fd79137SRobert Mustacchi int
451*7fd79137SRobert Mustacchi dwarf_global_cu_offset(Dwarf_Global global,
452*7fd79137SRobert Mustacchi                        Dwarf_Off * cu_header_offset,
453*7fd79137SRobert Mustacchi                        Dwarf_Error * error)
454*7fd79137SRobert Mustacchi {
455*7fd79137SRobert Mustacchi     Dwarf_Global_Context con = 0;
456*7fd79137SRobert Mustacchi 
457*7fd79137SRobert Mustacchi     if (global == NULL) {
458*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
459*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
460*7fd79137SRobert Mustacchi     }
461*7fd79137SRobert Mustacchi 
462*7fd79137SRobert Mustacchi     con = global->gl_context;
463*7fd79137SRobert Mustacchi 
464*7fd79137SRobert Mustacchi     if (con == NULL) {
465*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
466*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
467*7fd79137SRobert Mustacchi     }
468*7fd79137SRobert Mustacchi 
469*7fd79137SRobert Mustacchi     /* In early libdwarf, this incorrectly returned the offset of the
470*7fd79137SRobert Mustacchi        CU DIE. Now correctly returns the header offset. */
471*7fd79137SRobert Mustacchi     *cu_header_offset = con->pu_offset_of_cu_header;
472*7fd79137SRobert Mustacchi 
473*7fd79137SRobert Mustacchi     return DW_DLV_OK;
474*7fd79137SRobert Mustacchi }
475*7fd79137SRobert Mustacchi 
476*7fd79137SRobert Mustacchi /*
477*7fd79137SRobert Mustacchi   Give back the pubnames entry (or any other like section)
478*7fd79137SRobert Mustacchi   name, symbol DIE offset, and the cu-DIE offset.
479*7fd79137SRobert Mustacchi 
480*7fd79137SRobert Mustacchi   Various errors are possible.
481*7fd79137SRobert Mustacchi 
482*7fd79137SRobert Mustacchi   The string pointer returned thru ret_name is not
483*7fd79137SRobert Mustacchi   dwarf_get_alloc()ed, so no dwarf_dealloc()
484*7fd79137SRobert Mustacchi   DW_DLA_STRING should be applied to it.
485*7fd79137SRobert Mustacchi 
486*7fd79137SRobert Mustacchi */
487*7fd79137SRobert Mustacchi int
488*7fd79137SRobert Mustacchi dwarf_global_name_offsets(Dwarf_Global global,
489*7fd79137SRobert Mustacchi                           char **ret_name,
490*7fd79137SRobert Mustacchi                           Dwarf_Off * die_offset,
491*7fd79137SRobert Mustacchi                           Dwarf_Off * cu_die_offset,
492*7fd79137SRobert Mustacchi                           Dwarf_Error * error)
493*7fd79137SRobert Mustacchi {
494*7fd79137SRobert Mustacchi     Dwarf_Global_Context con = 0;
495*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = 0;
496*7fd79137SRobert Mustacchi     Dwarf_Off off = 0;
497*7fd79137SRobert Mustacchi 
498*7fd79137SRobert Mustacchi     if (global == NULL) {
499*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
500*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
501*7fd79137SRobert Mustacchi     }
502*7fd79137SRobert Mustacchi 
503*7fd79137SRobert Mustacchi     con = global->gl_context;
504*7fd79137SRobert Mustacchi 
505*7fd79137SRobert Mustacchi     if (con == NULL) {
506*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
507*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
508*7fd79137SRobert Mustacchi     }
509*7fd79137SRobert Mustacchi 
510*7fd79137SRobert Mustacchi     off = con->pu_offset_of_cu_header;
511*7fd79137SRobert Mustacchi     /* The offset had better not be too close to the end. If it is,
512*7fd79137SRobert Mustacchi        _dwarf_length_of_cu_header() will step off the end and therefore
513*7fd79137SRobert Mustacchi        must not be used. 10 is a meaningless heuristic, but no CU
514*7fd79137SRobert Mustacchi        header is that small so it is safe. An erroneous offset is due
515*7fd79137SRobert Mustacchi        to a bug in the tool chain. A bug like this has been seen on
516*7fd79137SRobert Mustacchi        IRIX with MIPSpro 7.3.1.3 and an executable > 2GB in size and
517*7fd79137SRobert Mustacchi        with 2 million pubnames entries. */
518*7fd79137SRobert Mustacchi #define MIN_CU_HDR_SIZE 10
519*7fd79137SRobert Mustacchi     dbg = con->pu_dbg;
520*7fd79137SRobert Mustacchi     if (dbg == NULL) {
521*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
522*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
523*7fd79137SRobert Mustacchi     }
524*7fd79137SRobert Mustacchi     if (dbg->de_debug_info.dss_size &&
525*7fd79137SRobert Mustacchi         ((off + MIN_CU_HDR_SIZE) >= dbg->de_debug_info.dss_size)) {
526*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_OFFSET_BAD);
527*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
528*7fd79137SRobert Mustacchi     }
529*7fd79137SRobert Mustacchi #undef MIN_CU_HDR_SIZE
530*7fd79137SRobert Mustacchi     if (die_offset != NULL) {
531*7fd79137SRobert Mustacchi         *die_offset = global->gl_named_die_offset_within_cu + off;
532*7fd79137SRobert Mustacchi     }
533*7fd79137SRobert Mustacchi 
534*7fd79137SRobert Mustacchi     *ret_name = (char *) global->gl_name;
535*7fd79137SRobert Mustacchi 
536*7fd79137SRobert Mustacchi     if (cu_die_offset != NULL) {
537*7fd79137SRobert Mustacchi         int res = _dwarf_load_debug_info(dbg, error);
538*7fd79137SRobert Mustacchi 
539*7fd79137SRobert Mustacchi         if (res != DW_DLV_OK) {
540*7fd79137SRobert Mustacchi             return res;
541*7fd79137SRobert Mustacchi         }
542*7fd79137SRobert Mustacchi         /* The offset had better not be too close to the end. If it is,
543*7fd79137SRobert Mustacchi            _dwarf_length_of_cu_header() will step off the end and
544*7fd79137SRobert Mustacchi            therefore must not be used. 10 is a meaningless heuristic,
545*7fd79137SRobert Mustacchi            but no CU header is that small so it is safe. */
546*7fd79137SRobert Mustacchi         if ((off + 10) >= dbg->de_debug_info.dss_size) {
547*7fd79137SRobert Mustacchi             _dwarf_error(NULL, error, DW_DLE_OFFSET_BAD);
548*7fd79137SRobert Mustacchi             return (DW_DLV_ERROR);
549*7fd79137SRobert Mustacchi         }
550*7fd79137SRobert Mustacchi         *cu_die_offset = off + _dwarf_length_of_cu_header(dbg, off);
551*7fd79137SRobert Mustacchi     }
552*7fd79137SRobert Mustacchi 
553*7fd79137SRobert Mustacchi 
554*7fd79137SRobert Mustacchi     return DW_DLV_OK;
555*7fd79137SRobert Mustacchi }
556*7fd79137SRobert Mustacchi 
557*7fd79137SRobert Mustacchi /*
558*7fd79137SRobert Mustacchi         We have the offset to a CU header.
559*7fd79137SRobert Mustacchi         Return thru outFileOffset the offset of the CU DIE.
560*7fd79137SRobert Mustacchi 
561*7fd79137SRobert Mustacchi         New June, 2001.
562*7fd79137SRobert Mustacchi         Used by SGI debuggers.
563*7fd79137SRobert Mustacchi         No error is possible.
564*7fd79137SRobert Mustacchi 
565*7fd79137SRobert Mustacchi         See also dwarf_CU_dieoffset_given_die().
566*7fd79137SRobert Mustacchi */
567*7fd79137SRobert Mustacchi 
568*7fd79137SRobert Mustacchi /* ARGSUSED */
569*7fd79137SRobert Mustacchi int
570*7fd79137SRobert Mustacchi dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg,
571*7fd79137SRobert Mustacchi     Dwarf_Off in_cu_header_offset,
572*7fd79137SRobert Mustacchi     Dwarf_Off * out_cu_die_offset,
573*7fd79137SRobert Mustacchi     Dwarf_Error * err)
574*7fd79137SRobert Mustacchi {
575*7fd79137SRobert Mustacchi     Dwarf_Off len =
576*7fd79137SRobert Mustacchi         _dwarf_length_of_cu_header(dbg, in_cu_header_offset);
577*7fd79137SRobert Mustacchi 
578*7fd79137SRobert Mustacchi     Dwarf_Off newoff = in_cu_header_offset + len;
579*7fd79137SRobert Mustacchi 
580*7fd79137SRobert Mustacchi     *out_cu_die_offset = newoff;
581*7fd79137SRobert Mustacchi     return DW_DLV_OK;
582*7fd79137SRobert Mustacchi }
583*7fd79137SRobert Mustacchi /* dwarf_CU_dieoffset_given_die returns
584*7fd79137SRobert Mustacchi    the global debug_info section offset of the CU die
585*7fd79137SRobert Mustacchi    that is the CU containing the given (passed-in) die.
586*7fd79137SRobert Mustacchi    This information makes it possible for a consumer to
587*7fd79137SRobert Mustacchi    find and print context information for any die.
588*7fd79137SRobert Mustacchi 
589*7fd79137SRobert Mustacchi    Use dwarf_offdie() passing in the offset this returns
590*7fd79137SRobert Mustacchi    to get a die pointer to the CU die.
591*7fd79137SRobert Mustacchi  */
592*7fd79137SRobert Mustacchi int
593*7fd79137SRobert Mustacchi dwarf_CU_dieoffset_given_die(Dwarf_Die die,
594*7fd79137SRobert Mustacchi     Dwarf_Off*       return_offset,
595*7fd79137SRobert Mustacchi     Dwarf_Error*     error)
596*7fd79137SRobert Mustacchi {
597*7fd79137SRobert Mustacchi     Dwarf_Off  dieoff = 0;
598*7fd79137SRobert Mustacchi     Dwarf_CU_Context cucontext = 0;
599*7fd79137SRobert Mustacchi 
600*7fd79137SRobert Mustacchi     CHECK_DIE(die, DW_DLV_ERROR);
601*7fd79137SRobert Mustacchi     cucontext = die->di_cu_context;
602*7fd79137SRobert Mustacchi     dieoff =  cucontext->cc_debug_info_offset;
603*7fd79137SRobert Mustacchi     /* The following call cannot fail, so no error check. */
604*7fd79137SRobert Mustacchi     dwarf_get_cu_die_offset_given_cu_header_offset(
605*7fd79137SRobert Mustacchi        cucontext->cc_dbg, dieoff, return_offset,error);
606*7fd79137SRobert Mustacchi     return DW_DLV_OK;
607*7fd79137SRobert Mustacchi }
608