1 /*
2   Copyright (C) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
3   Portions Copyright (C) 2007-2012 David Anderson. All Rights Reserved.
4   Portions Copyright 2012 SN Systems Ltd. All rights reserved.
5 
6   This program is free software; you can redistribute it and/or modify it
7   under the terms of version 2.1 of the GNU Lesser General Public License
8   as published by the Free Software Foundation.
9 
10   This program is distributed in the hope that it would be useful, but
11   WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 
14   Further, this software is distributed without any warranty that it is
15   free of the rightful claim of any third person regarding infringement
16   or the like.  Any license provided herein, whether implied or
17   otherwise, applies only to this software file.  Patent licenses, if
18   any, provided herein do not apply to combinations of this program with
19   other software, or any other product whatsoever.
20 
21   You should have received a copy of the GNU Lesser General Public
22   License along with this program; if not, write the Free Software
23   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24   USA.
25 
26 */
27 
28 #include "config.h"
29 #include "dwarf_incl.h"
30 #ifdef HAVE_ELF_H
31 #include <elf.h>
32 #endif
33 #include <stdio.h>
34 #include "dwarf_die_deliv.h"
35 
36 #define FALSE 0
37 #define TRUE 1
38 
39 /*  New October 2011.  Enables client code to know if
40     it is a debug_info or debug_types context. */
41 Dwarf_Bool
dwarf_get_die_infotypes_flag(Dwarf_Die die)42 dwarf_get_die_infotypes_flag(Dwarf_Die die)
43 {
44     return die->di_is_info;
45 }
46 
47 /*
48     For a given Dwarf_Debug dbg, this function checks
49     if a CU that includes the given offset has been read
50     or not.  If yes, it returns the Dwarf_CU_Context
51     for the CU.  Otherwise it returns NULL.  Being an
52     internal routine, it is assumed that a valid dbg
53     is passed.
54 
55     **This is a sequential search.  May be too slow.
56 
57     If debug_info and debug_abbrev not loaded, this will
58     wind up returning NULL. So no need to load before calling
59     this.
60 */
61 static Dwarf_CU_Context
_dwarf_find_CU_Context(Dwarf_Debug dbg,Dwarf_Off offset,Dwarf_Bool is_info)62 _dwarf_find_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset,Dwarf_Bool is_info)
63 {
64     Dwarf_CU_Context cu_context = 0;
65     Dwarf_Debug_InfoTypes dis = is_info? &dbg->de_info_reading:
66         &dbg->de_types_reading;
67 
68     if (offset >= dis->de_last_offset)
69         return (NULL);
70 
71     if (dis->de_cu_context != NULL &&
72         dis->de_cu_context->cc_next != NULL &&
73         dis->de_cu_context->cc_next->cc_debug_offset == offset) {
74 
75         return (dis->de_cu_context->cc_next);
76     }
77 
78     if (dis->de_cu_context != NULL &&
79         dis->de_cu_context->cc_debug_offset <= offset) {
80 
81         for (cu_context = dis->de_cu_context;
82             cu_context != NULL; cu_context = cu_context->cc_next) {
83 
84             if (offset >= cu_context->cc_debug_offset &&
85                 offset < cu_context->cc_debug_offset +
86                 cu_context->cc_length + cu_context->cc_length_size
87                 + cu_context->cc_extension_size) {
88 
89                 return (cu_context);
90             }
91         }
92     }
93 
94     for (cu_context = dis->de_cu_context_list;
95         cu_context != NULL; cu_context = cu_context->cc_next) {
96 
97         if (offset >= cu_context->cc_debug_offset &&
98             offset < cu_context->cc_debug_offset +
99             cu_context->cc_length + cu_context->cc_length_size
100             + cu_context->cc_extension_size) {
101 
102             return (cu_context);
103         }
104     }
105 
106     return (NULL);
107 }
108 
109 
110 /*  This routine checks the dwarf_offdie() list of
111     CU contexts for the right CU context.  */
112 static Dwarf_CU_Context
_dwarf_find_offdie_CU_Context(Dwarf_Debug dbg,Dwarf_Off offset,Dwarf_Bool is_info)113 _dwarf_find_offdie_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset,
114     Dwarf_Bool is_info)
115 {
116     Dwarf_CU_Context cu_context = 0;
117     Dwarf_Debug_InfoTypes dis = is_info? &dbg->de_info_reading:
118         &dbg->de_types_reading;
119 
120     for (cu_context = dis->de_offdie_cu_context;
121         cu_context != NULL; cu_context = cu_context->cc_next)
122 
123         if (offset >= cu_context->cc_debug_offset &&
124             offset < cu_context->cc_debug_offset +
125             cu_context->cc_length + cu_context->cc_length_size
126             + cu_context->cc_extension_size)
127 
128             return (cu_context);
129 
130     return (NULL);
131 }
132 
133 int
dwarf_get_debugfission_for_die(Dwarf_Die die,struct Dwarf_Debug_Fission_Per_CU_s * fission_out,Dwarf_Error * error)134 dwarf_get_debugfission_for_die(Dwarf_Die die,
135     struct Dwarf_Debug_Fission_Per_CU_s *fission_out,
136     Dwarf_Error *error)
137 {
138     Dwarf_CU_Context context = 0;
139     Dwarf_Debug dbg = 0;
140     struct Dwarf_Debug_Fission_Per_CU_s * percu = 0;
141 
142     CHECK_DIE(die, DW_DLV_ERROR);
143     context = die->di_cu_context;
144     dbg = context->cc_dbg;
145     if (!_dwarf_file_has_debug_fission_index(dbg)) {
146         return DW_DLV_NO_ENTRY;
147     }
148 
149     if (context->cc_unit_type == DW_UT_type ) {
150         if (!_dwarf_file_has_debug_fission_tu_index(dbg)) {
151             return DW_DLV_NO_ENTRY;
152         }
153     } else {
154         if (!_dwarf_file_has_debug_fission_cu_index(dbg)) {
155             return DW_DLV_NO_ENTRY;
156         }
157     }
158     percu = &context->cc_dwp_offsets;
159     if (!percu->pcu_type) {
160         return DW_DLV_NO_ENTRY;
161     }
162     *fission_out = *percu;
163     return DW_DLV_OK;
164 }
165 
166 /* ASSERT: whichone is a DW_SECT* macro value. */
167 Dwarf_Unsigned
_dwarf_get_dwp_extra_offset(struct Dwarf_Debug_Fission_Per_CU_s * dwp,unsigned whichone,Dwarf_Unsigned * size)168 _dwarf_get_dwp_extra_offset(struct Dwarf_Debug_Fission_Per_CU_s* dwp,
169     unsigned whichone, Dwarf_Unsigned * size)
170 {
171     Dwarf_Unsigned abbrevoff = 0;
172     if (!dwp->pcu_type) {
173         return 0;
174     }
175     abbrevoff = dwp->pcu_offset[whichone];
176     *size = dwp->pcu_size[whichone];
177     return abbrevoff;
178 }
179 
180 
181 /*  _dwarf_get_fission_addition_die return DW_DLV_OK etc instead.
182 */
183 int
_dwarf_get_fission_addition_die(Dwarf_Die die,int dw_sect_index,Dwarf_Unsigned * offset,Dwarf_Unsigned * size,Dwarf_Error * error)184 _dwarf_get_fission_addition_die(Dwarf_Die die, int dw_sect_index,
185    Dwarf_Unsigned *offset,
186    Dwarf_Unsigned *size,
187    Dwarf_Error *error)
188 {
189     /* We do not yet know the DIE hash, so we cannot use it
190         to identify the offset. */
191     Dwarf_CU_Context context = 0;
192     Dwarf_Unsigned dwpadd = 0;
193     Dwarf_Unsigned dwpsize = 0;
194 
195     CHECK_DIE(die, DW_DLV_ERROR);
196     context = die->di_cu_context;
197     dwpadd =  _dwarf_get_dwp_extra_offset(&context->cc_dwp_offsets,
198         dw_sect_index,&dwpsize);
199     *offset = dwpadd;
200     *size = dwpsize;
201     return DW_DLV_OK;
202 }
203 
204 /*  Not sure if this is the only way to be sure early on in
205     reading a compile unit.  */
206 static int
section_name_ends_with_dwo(const char * name)207 section_name_ends_with_dwo(const char *name)
208 {
209     int lenstr = 0;
210     int dotpos = 0;
211     if (!name) {
212         return FALSE;
213     }
214     lenstr = strlen(name);
215     if (lenstr < 5) {
216         return FALSE;
217     }
218     dotpos = lenstr - 4;
219     if(strcmp(name+dotpos,".dwo")) {
220         return FALSE;
221     }
222     return TRUE;
223 }
224 
225 
226 /*  This function is used to create a CU Context for
227     a compilation-unit that begins at offset in
228     .debug_info.  The CU Context is attached to the
229     list of CU Contexts for this dbg.  It is assumed
230     that the CU at offset has not been read before,
231     and so do not call this routine before making
232     sure of this with _dwarf_find_CU_Context().
233     Returns NULL on error.  As always, being an
234     internal routine, assumes a good dbg.
235 
236     The offset argument is global offset, the offset
237     in the section, irrespective of CUs.
238     The offset has the DWP Package File offset built in
239     as it comes from the actual section.
240 
241     max_cu_local_offset is a local offset in this CU.
242     So zero of this field is immediately following the length
243     field of the CU header. so max_cu_local_offset is
244     identical to the CU length field.
245     max_cu_global_offset is the offset one-past the end
246     of this entire CU.  */
247 static int
_dwarf_make_CU_Context(Dwarf_Debug dbg,Dwarf_Off offset,Dwarf_Bool is_info,Dwarf_CU_Context * context_out,Dwarf_Error * error)248 _dwarf_make_CU_Context(Dwarf_Debug dbg,
249     Dwarf_Off offset,Dwarf_Bool is_info,
250     Dwarf_CU_Context * context_out,Dwarf_Error * error)
251 {
252     Dwarf_CU_Context cu_context = 0;
253     Dwarf_Unsigned length = 0;
254     Dwarf_Signed abbrev_offset = 0;
255     Dwarf_Unsigned typeoffset = 0;
256     Dwarf_Sig8 signaturedata;
257     Dwarf_Unsigned types_extra_len = 0;
258     Dwarf_Unsigned max_cu_local_offset =  0;
259     Dwarf_Unsigned max_cu_global_offset =  0;
260     Dwarf_Byte_Ptr cu_ptr = 0;
261     Dwarf_Byte_Ptr section_end_ptr = 0;
262     int local_extension_size = 0;
263     int local_length_size = 0;
264     const char *secname = is_info?dbg->de_debug_info.dss_name:
265         dbg->de_debug_types.dss_name;
266     Dwarf_Debug_InfoTypes dis = is_info? &dbg->de_info_reading:
267         &dbg->de_types_reading;
268     Dwarf_Unsigned section_size = is_info? dbg->de_debug_info.dss_size:
269         dbg->de_debug_types.dss_size;
270     int unit_type = 0;
271     int version = 0;
272     int is_type_tu = 0;
273     Dwarf_Small *dataptr = 0;
274 
275     cu_context =
276         (Dwarf_CU_Context) _dwarf_get_alloc(dbg, DW_DLA_CU_CONTEXT, 1);
277     if (cu_context == NULL) {
278         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
279         return DW_DLV_ERROR;
280     }
281     cu_context->cc_dbg = dbg;
282     cu_context->cc_is_info = is_info;
283 
284     dataptr = is_info? dbg->de_debug_info.dss_data:
285         dbg->de_debug_types.dss_data;
286     if (!dataptr) {
287         _dwarf_error(dbg, error, DW_DLE_INFO_HEADER_ERROR);
288         return DW_DLV_ERROR;
289     }
290     if (offset >= section_size) {
291         _dwarf_error(dbg, error, DW_DLE_INFO_HEADER_ERROR);
292         return DW_DLV_ERROR;
293     }
294     if ((offset+4) > section_size) {
295         _dwarf_error(dbg, error, DW_DLE_INFO_HEADER_ERROR);
296         return DW_DLV_ERROR;
297     }
298     section_end_ptr = dataptr+section_size;
299     cu_ptr = (Dwarf_Byte_Ptr) (dataptr+offset);
300 
301     if (section_name_ends_with_dwo(secname)) {
302         cu_context->cc_is_dwo = TRUE;
303     }
304     /* READ_AREA_LENGTH updates cu_ptr for consumed bytes */
305     READ_AREA_LENGTH_CK(dbg, length, Dwarf_Unsigned,
306         cu_ptr, local_length_size, local_extension_size,
307         error,section_size,section_end_ptr);
308     cu_context->cc_length_size = local_length_size;
309     cu_context->cc_extension_size = local_extension_size;
310 
311 
312     cu_context->cc_length = length;
313     max_cu_local_offset =  length;
314     max_cu_global_offset =  offset + length +
315         local_extension_size + local_length_size;
316     if(length > section_size) {
317         _dwarf_error(dbg, error, DW_DLE_CU_LENGTH_ERROR);
318         return DW_DLV_ERROR;
319     }
320     if(max_cu_global_offset > section_size) {
321         _dwarf_error(dbg, error, DW_DLE_CU_LENGTH_ERROR);
322         return DW_DLV_ERROR;
323     }
324 
325     READ_UNALIGNED_CK(dbg, cu_context->cc_version_stamp, Dwarf_Half,
326         cu_ptr, sizeof(Dwarf_Half),error,section_end_ptr);
327     version = cu_context->cc_version_stamp;
328     cu_ptr += sizeof(Dwarf_Half);
329     if (version == DW_CU_VERSION5) {
330         unsigned char ub = 0;
331         READ_UNALIGNED_CK(dbg, ub, unsigned char,
332             cu_ptr, sizeof(ub),error,section_end_ptr);
333         cu_ptr += sizeof(ub);
334         unit_type = ub;
335         if (unit_type != DW_UT_compile && unit_type != DW_UT_partial
336             && unit_type != DW_UT_type) {
337             _dwarf_error(dbg, error, DW_DLE_CU_UT_TYPE_ERROR);
338             return DW_DLV_ERROR;
339         }
340     } else {
341         /*  We don't know if it is or DW_UT_partial or not. */
342         unit_type = is_info?DW_UT_compile:DW_UT_type;
343     }
344 
345     READ_UNALIGNED_CK(dbg, abbrev_offset, Dwarf_Unsigned,
346         cu_ptr, local_length_size,error,section_end_ptr);
347 
348     cu_ptr += local_length_size;
349 
350     /*  In a dwp context, this offset is incomplete.
351         We need to add in the base from the .debug_cu_index
352         or .debug_tu_index . Done below */
353     cu_context->cc_abbrev_offset = abbrev_offset;
354 
355     cu_context->cc_address_size = *(Dwarf_Small *) cu_ptr;
356     /*  The CU header has no selector size. See DW_AT_segment
357         and the DWARF5 line table header and the
358         DWARF5 .debug_aranges header. */
359     cu_context->cc_segment_selector_size = 0;
360     ++cu_ptr;
361 
362     if (cu_ptr > section_end_ptr) {
363         _dwarf_error(dbg, error, DW_DLE_INFO_HEADER_ERROR);
364     }
365 
366     if (cu_context->cc_address_size  > sizeof(Dwarf_Addr)) {
367         _dwarf_error(dbg, error, DW_DLE_CU_ADDRESS_SIZE_BAD);
368         return DW_DLV_ERROR;
369     }
370 
371     is_type_tu = FALSE;
372     if (!is_info ||
373         (version == DW_CU_VERSION5 && unit_type == DW_UT_type )) {
374         is_type_tu = TRUE;
375     }
376     if (is_type_tu) {
377         /* types CU headers have extra header bytes. */
378         types_extra_len = sizeof(signaturedata) + local_length_size;
379     }
380     if ((length < (CU_VERSION_STAMP_SIZE + local_length_size +
381         CU_ADDRESS_SIZE_SIZE + types_extra_len)) ||
382         (max_cu_global_offset > section_size)) {
383 
384         dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
385         _dwarf_error(dbg, error, DW_DLE_CU_LENGTH_ERROR);
386         return DW_DLV_ERROR;
387     }
388 
389     if (cu_context->cc_version_stamp != DW_CU_VERSION2
390         && cu_context->cc_version_stamp != DW_CU_VERSION3
391         && cu_context->cc_version_stamp != DW_CU_VERSION4
392         && cu_context->cc_version_stamp != DW_CU_VERSION5) {
393         dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
394         _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
395         return DW_DLV_ERROR;
396     }
397     if (is_type_tu) {
398         if (version != DW_CU_VERSION4 &&
399             version != DW_CU_VERSION5) {
400             dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
401             /* Error name  misleading, version 5 has types too. */
402             _dwarf_error(dbg, error, DW_DLE_DEBUG_TYPES_ONLY_DWARF4);
403             return DW_DLV_ERROR;
404         }
405         /*  Now read the debug_types extra header fields of
406             the signature (8 bytes) and the typeoffset.
407             This can be in executable, ordinary object,
408             or .dwo or .dwp object. */
409         memcpy(&signaturedata,cu_ptr,sizeof(signaturedata));
410         cu_context->cc_signature_present = TRUE;
411         cu_ptr += sizeof(signaturedata);
412         READ_UNALIGNED_CK(dbg, typeoffset, Dwarf_Unsigned,
413             cu_ptr, local_length_size,error,section_end_ptr);
414         cu_context->cc_type_signature = signaturedata;
415         cu_context->cc_type_signature_offset = typeoffset;
416         {
417             if (typeoffset >= max_cu_local_offset) {
418                 dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
419                 _dwarf_error(dbg, error, DW_DLE_DEBUG_TYPEOFFSET_BAD);
420                 return DW_DLV_ERROR;
421             }
422         }
423     }
424     cu_context->cc_unit_type = unit_type;
425     if (is_type_tu) {
426         if (_dwarf_file_has_debug_fission_tu_index(dbg) ){
427             int resdf = 0;
428             resdf = dwarf_get_debugfission_for_key(dbg,
429                 &signaturedata,
430                 "tu",
431                 &cu_context->cc_dwp_offsets,
432                 error);
433             if (resdf != DW_DLV_OK) {
434                 dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
435                 _dwarf_error(dbg, error,
436                     DW_DLE_MISSING_REQUIRED_TU_OFFSET_HASH);
437                 return DW_DLV_ERROR;
438             }
439         }
440     } else {
441         if (_dwarf_file_has_debug_fission_cu_index(dbg) ){
442             int resdf = 0;
443             resdf = _dwarf_get_debugfission_for_offset(dbg,
444                 offset,
445                 &cu_context->cc_dwp_offsets,
446                 error);
447             if (resdf != DW_DLV_OK) {
448                 dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
449                 _dwarf_error(dbg, error,
450                     DW_DLE_MISSING_REQUIRED_CU_OFFSET_HASH);
451                 return DW_DLV_ERROR;
452             }
453             /*  Eventually we will see the DW_AT_dwo_id
454                 or DW_AT_GNU_dwo_id
455                 and we should check against  this signature
456                 at that time.  */
457             cu_context->cc_type_signature =
458                 cu_context->cc_dwp_offsets.pcu_hash;
459         }
460     }
461     if (cu_context->cc_dwp_offsets.pcu_type) {
462         /*  We need to update certain offsets as this is a package file.
463             This is to reflect how DWP files are organized. */
464         Dwarf_Unsigned absize = 0;
465         Dwarf_Unsigned aboff = 0;
466         aboff =  _dwarf_get_dwp_extra_offset(&cu_context->cc_dwp_offsets,
467             DW_SECT_ABBREV, &absize);
468         cu_context->cc_abbrev_offset +=  aboff;
469         abbrev_offset = cu_context->cc_abbrev_offset;
470     }
471 
472     if ((Dwarf_Unsigned)abbrev_offset >= dbg->de_debug_abbrev.dss_size) {
473         dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
474         _dwarf_error(dbg, error, DW_DLE_ABBREV_OFFSET_ERROR);
475         return DW_DLV_ERROR;
476     }
477 
478     cu_context->cc_abbrev_hash_table =
479         (Dwarf_Hash_Table) _dwarf_get_alloc(dbg, DW_DLA_HASH_TABLE, 1);
480     if (cu_context->cc_abbrev_hash_table == NULL) {
481         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
482         return DW_DLV_ERROR;
483     }
484 
485     cu_context->cc_debug_offset = offset;
486 
487     dis->de_last_offset = max_cu_global_offset;
488 
489     if (dis->de_cu_context_list == NULL) {
490         dis->de_cu_context_list = cu_context;
491         dis->de_cu_context_list_end = cu_context;
492     } else {
493         dis->de_cu_context_list_end->cc_next = cu_context;
494         dis->de_cu_context_list_end = cu_context;
495     }
496     *context_out  = cu_context;
497     return DW_DLV_OK;
498 }
499 
500 static int
reloc_incomplete(int res,Dwarf_Error err)501 reloc_incomplete(int res,Dwarf_Error err)
502 {
503     int e = 0;
504 
505     if (res == DW_DLV_OK) {
506         return FALSE;
507     }
508     if (res == DW_DLV_NO_ENTRY) {
509         return FALSE;
510     }
511     e = dwarf_errno(err);
512     if (e == DW_DLE_RELOC_MISMATCH_INDEX       ||
513         e == DW_DLE_RELOC_MISMATCH_RELOC_INDEX  ||
514         e == DW_DLE_RELOC_MISMATCH_STRTAB_INDEX ||
515         e == DW_DLE_RELOC_SECTION_MISMATCH      ||
516         e == DW_DLE_RELOC_SECTION_MISSING_INDEX  ||
517         e == DW_DLE_RELOC_SECTION_LENGTH_ODD     ||
518         e == DW_DLE_RELOC_SECTION_PTR_NULL        ||
519         e == DW_DLE_RELOC_SECTION_MALLOC_FAIL      ||
520         e == DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD  ) {
521         return TRUE;
522     }
523     return FALSE;
524 }
525 
526 
527 
528 /*  Returns offset of next compilation-unit thru next_cu_offset
529     pointer.
530     It sequentially moves from one
531     cu to the next.  The current cu is recorded
532     internally by libdwarf.
533 
534     The _b form is new for DWARF4 adding new returned fields.  */
535 int
dwarf_next_cu_header(Dwarf_Debug dbg,Dwarf_Unsigned * cu_header_length,Dwarf_Half * version_stamp,Dwarf_Unsigned * abbrev_offset,Dwarf_Half * address_size,Dwarf_Unsigned * next_cu_offset,Dwarf_Error * error)536 dwarf_next_cu_header(Dwarf_Debug dbg,
537     Dwarf_Unsigned * cu_header_length,
538     Dwarf_Half * version_stamp,
539     Dwarf_Unsigned * abbrev_offset,
540     Dwarf_Half * address_size,
541     Dwarf_Unsigned * next_cu_offset,
542     Dwarf_Error * error)
543 {
544     Dwarf_Bool is_info = true;
545     Dwarf_Half header_type = 0;
546     return _dwarf_next_cu_header_internal(dbg,
547         is_info,
548         cu_header_length,
549         version_stamp,
550         abbrev_offset,
551         address_size,
552         0,0,0,0,0,
553         next_cu_offset,
554         &header_type,
555         error);
556 }
557 int
dwarf_next_cu_header_b(Dwarf_Debug dbg,Dwarf_Unsigned * cu_header_length,Dwarf_Half * version_stamp,Dwarf_Unsigned * abbrev_offset,Dwarf_Half * address_size,Dwarf_Half * offset_size,Dwarf_Half * extension_size,Dwarf_Unsigned * next_cu_offset,Dwarf_Error * error)558 dwarf_next_cu_header_b(Dwarf_Debug dbg,
559     Dwarf_Unsigned * cu_header_length,
560     Dwarf_Half * version_stamp,
561     Dwarf_Unsigned * abbrev_offset,
562     Dwarf_Half * address_size,
563     Dwarf_Half * offset_size,
564     Dwarf_Half * extension_size,
565     Dwarf_Unsigned * next_cu_offset,
566     Dwarf_Error * error)
567 {
568     Dwarf_Bool is_info = true;
569     Dwarf_Half header_type = 0;
570     return _dwarf_next_cu_header_internal(dbg,
571         is_info,
572         cu_header_length,
573         version_stamp,
574         abbrev_offset,
575         address_size,
576         offset_size,extension_size,
577         0,0,0,
578         next_cu_offset,
579         &header_type,
580         error);
581 }
582 
583 int
dwarf_next_cu_header_c(Dwarf_Debug dbg,Dwarf_Bool is_info,Dwarf_Unsigned * cu_header_length,Dwarf_Half * version_stamp,Dwarf_Unsigned * abbrev_offset,Dwarf_Half * address_size,Dwarf_Half * offset_size,Dwarf_Half * extension_size,Dwarf_Sig8 * signature,Dwarf_Unsigned * typeoffset,Dwarf_Unsigned * next_cu_offset,Dwarf_Error * error)584 dwarf_next_cu_header_c(Dwarf_Debug dbg,
585     Dwarf_Bool is_info,
586     Dwarf_Unsigned * cu_header_length,
587     Dwarf_Half * version_stamp,
588     Dwarf_Unsigned * abbrev_offset,
589     Dwarf_Half * address_size,
590     Dwarf_Half * offset_size,
591     Dwarf_Half * extension_size,
592     Dwarf_Sig8 * signature,
593     Dwarf_Unsigned * typeoffset,
594     Dwarf_Unsigned * next_cu_offset,
595     Dwarf_Error * error)
596 {
597     Dwarf_Half header_type = 0;
598     int res =_dwarf_next_cu_header_internal(dbg,
599         is_info,
600         cu_header_length,
601         version_stamp,
602         abbrev_offset,
603         address_size,
604         offset_size,
605         extension_size,
606         signature,
607         0,
608         typeoffset,
609         next_cu_offset,
610         &header_type,
611         error);
612     return res;
613 }
614 int
dwarf_next_cu_header_d(Dwarf_Debug dbg,Dwarf_Bool is_info,Dwarf_Unsigned * cu_header_length,Dwarf_Half * version_stamp,Dwarf_Unsigned * abbrev_offset,Dwarf_Half * address_size,Dwarf_Half * offset_size,Dwarf_Half * extension_size,Dwarf_Sig8 * signature,Dwarf_Unsigned * typeoffset,Dwarf_Unsigned * next_cu_offset,Dwarf_Half * header_cu_type,Dwarf_Error * error)615 dwarf_next_cu_header_d(Dwarf_Debug dbg,
616     Dwarf_Bool is_info,
617     Dwarf_Unsigned * cu_header_length,
618     Dwarf_Half * version_stamp,
619     Dwarf_Unsigned * abbrev_offset,
620     Dwarf_Half * address_size,
621     Dwarf_Half * offset_size,
622     Dwarf_Half * extension_size,
623     Dwarf_Sig8 * signature,
624     Dwarf_Unsigned * typeoffset,
625     Dwarf_Unsigned * next_cu_offset,
626     Dwarf_Half * header_cu_type,
627     Dwarf_Error * error)
628 {
629     int res = _dwarf_next_cu_header_internal(dbg,
630         is_info,
631         cu_header_length,
632         version_stamp,
633         abbrev_offset,
634         address_size,
635         offset_size,
636         extension_size,
637         signature,
638         0,
639         typeoffset,
640         next_cu_offset,
641         header_cu_type,
642         error);
643     return res;
644 }
645 
646 
647 
648 /* If sig_present_return not set TRUE here
649     then something must be wrong. ??
650     Compiler bug?
651     A DWO/DWP CU has different base fields than
652     a normal object/executable, but this finds
653     the base fields for both types.
654 */
655 static int
find_context_base_fields(Dwarf_Debug dbg,Dwarf_Die cudie,Dwarf_Sig8 * sig_return,Dwarf_Bool * sig_present_return,Dwarf_Unsigned * str_offsets_base_return,Dwarf_Bool * str_offsets_base_present_return,Dwarf_Unsigned * addr_base_return,Dwarf_Bool * addr_base_present_return,Dwarf_Unsigned * ranges_base_return,Dwarf_Bool * ranges_base_present_return,Dwarf_Error * error)656 find_context_base_fields(Dwarf_Debug dbg,
657     Dwarf_Die cudie,
658     Dwarf_Sig8 *sig_return,
659     Dwarf_Bool *sig_present_return,
660     Dwarf_Unsigned *str_offsets_base_return,
661     Dwarf_Bool *str_offsets_base_present_return,
662     Dwarf_Unsigned *addr_base_return,
663     Dwarf_Bool *addr_base_present_return,
664     Dwarf_Unsigned *ranges_base_return,
665     Dwarf_Bool *ranges_base_present_return,
666     Dwarf_Error* error)
667 {
668     Dwarf_Sig8 signature;
669     Dwarf_Bool sig_present = FALSE;
670     Dwarf_Off str_offsets_base = 0;
671     Dwarf_Off ranges_base = 0;
672     Dwarf_Off addr_base = 0;
673     Dwarf_Bool str_offsets_base_present = FALSE;
674     Dwarf_Bool addr_base_present = FALSE;
675     Dwarf_Bool ranges_base_present = FALSE;
676 
677     Dwarf_Attribute * alist = 0;
678     Dwarf_Signed      atcount = 0;
679     int alres = 0;
680 
681     alres = dwarf_attrlist(cudie, &alist,
682         &atcount,error);
683     if(alres == DW_DLV_OK) {
684         Dwarf_Signed i = 0;
685         for(i = 0;  i < atcount; ++i) {
686             Dwarf_Half attrnum;
687             int ares = 0;
688             Dwarf_Attribute attr = alist[i];
689             ares = dwarf_whatattr(attr,&attrnum,error);
690             if (ares == DW_DLV_OK) {
691                 if (attrnum == DW_AT_dwo_id ||
692                     attrnum == DW_AT_GNU_dwo_id ) {
693                     int sres = 0;
694                     sres = dwarf_formsig8_const(attr,
695                         &signature,error);
696                     if(sres == DW_DLV_OK) {
697                         sig_present = TRUE;
698                     } else {
699                         /* Something is badly wrong. */
700                         dwarf_dealloc(dbg,attr,DW_DLA_ATTR);
701                         dwarf_dealloc(dbg,alist,DW_DLA_LIST);
702                         return sres;
703                     }
704                 } else if (attrnum == DW_AT_str_offsets_base){
705                     int udres = 0;
706                     udres = dwarf_global_formref(attr,&str_offsets_base,
707                         error);
708                     if(udres == DW_DLV_OK) {
709                         str_offsets_base_present = TRUE;
710                     } else {
711                         dwarf_dealloc(dbg,attr,DW_DLA_ATTR);
712                         dwarf_dealloc(dbg,alist,DW_DLA_LIST);
713                         /* Something is badly wrong. */
714                         return udres;
715                     }
716                 } else if (attrnum == DW_AT_addr_base
717                     || attrnum == DW_AT_GNU_addr_base){
718                     int udres = 0;
719                     udres = dwarf_global_formref(attr,&addr_base,
720                         error);
721                     if(udres == DW_DLV_OK) {
722                         addr_base_present = TRUE;
723                     } else {
724                         dwarf_dealloc(dbg,attr,DW_DLA_ATTR);
725                         dwarf_dealloc(dbg,alist,DW_DLA_LIST);
726                         /* Something is badly wrong. */
727                         return udres;
728                     }
729                 } else if (attrnum == DW_AT_ranges_base
730                     || attrnum == DW_AT_GNU_ranges_base){
731                     int udres = 0;
732                     udres = dwarf_global_formref(attr,&ranges_base,
733                         error);
734                     if(udres == DW_DLV_OK) {
735                         ranges_base_present = TRUE;
736                     } else {
737                         dwarf_dealloc(dbg,attr,DW_DLA_ATTR);
738                         dwarf_dealloc(dbg,alist,DW_DLA_LIST);
739                         /* Something is badly wrong. */
740                         return udres;
741                     }
742                 }  /* else nothing to do here. */
743             }
744             dwarf_dealloc(dbg,attr,DW_DLA_ATTR);
745         }
746         dwarf_dealloc(dbg,alist,DW_DLA_LIST);
747     } else {
748         /* Something is badly wrong. No attrlist. FIXME */
749         _dwarf_error(dbg,error, DW_DLE_DWP_MISSING_DWO_ID);
750         return DW_DLV_ERROR;
751     }
752     *sig_present_return = sig_present;
753     if (sig_present) {
754         *sig_return = signature;
755     }
756     *str_offsets_base_present_return = str_offsets_base_present;
757     if (str_offsets_base_present) {
758         *str_offsets_base_return = str_offsets_base;
759     }
760     *addr_base_present_return = addr_base_present;
761     if (addr_base_present) {
762         *addr_base_return = addr_base;
763     }
764     *ranges_base_present_return = ranges_base_present;
765     if (ranges_base_present) {
766         *ranges_base_return = ranges_base;
767     }
768     return DW_DLV_OK;
769 }
770 
771 
772 int
_dwarf_next_cu_header_internal(Dwarf_Debug dbg,Dwarf_Bool is_info,Dwarf_Unsigned * cu_header_length,Dwarf_Half * version_stamp,Dwarf_Unsigned * abbrev_offset,Dwarf_Half * address_size,Dwarf_Half * offset_size,Dwarf_Half * extension_size,Dwarf_Sig8 * signature_out,Dwarf_Bool * has_signature,Dwarf_Unsigned * typeoffset,Dwarf_Unsigned * next_cu_offset,Dwarf_Half * header_type,Dwarf_Error * error)773 _dwarf_next_cu_header_internal(Dwarf_Debug dbg,
774     Dwarf_Bool is_info,
775     Dwarf_Unsigned * cu_header_length,
776     Dwarf_Half * version_stamp,
777     Dwarf_Unsigned * abbrev_offset,
778     Dwarf_Half * address_size,
779     Dwarf_Half * offset_size,
780     Dwarf_Half * extension_size,
781     Dwarf_Sig8 * signature_out,
782     Dwarf_Bool * has_signature,
783     Dwarf_Unsigned *typeoffset,
784     Dwarf_Unsigned * next_cu_offset,
785 
786     /*  header_type: DW_UT_compile, DW_UT_partial, DW_UT_type
787         returned through the pointer.
788         A new item in DWARF5, synthesized for earlier DWARF
789         CUs (& TUs). */
790     Dwarf_Half * header_type,
791     Dwarf_Error * error)
792 {
793     /* Offset for current and new CU. */
794     Dwarf_Unsigned new_offset = 0;
795 
796     /* CU Context for current CU. */
797     Dwarf_CU_Context cu_context = 0;
798     Dwarf_Debug_InfoTypes dis = 0;
799     Dwarf_Unsigned section_size =  0;
800     int res = 0;
801 
802 
803 
804     /* ***** BEGIN CODE ***** */
805 
806     if (dbg == NULL) {
807         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
808         return (DW_DLV_ERROR);
809     }
810     dis = is_info? &dbg->de_info_reading: &dbg->de_types_reading;
811     /*  Get offset into .debug_info of next CU. If dbg has no context,
812         this has to be the first one. */
813     if (dis->de_cu_context == NULL) {
814         Dwarf_Small *dataptr = is_info? dbg->de_debug_info.dss_data:
815             dbg->de_debug_types.dss_data;
816         new_offset = 0;
817         if (!dataptr) {
818             Dwarf_Error err2= 0;
819             int resd = is_info?_dwarf_load_debug_info(dbg, &err2):
820                 _dwarf_load_debug_types(dbg,&err2);
821 
822             if (resd != DW_DLV_OK) {
823                 if (reloc_incomplete(resd,err2)) {
824                     /*  We will assume all is ok, though it is not.
825                         Relocation errors need not be fatal.  */
826                     char msg_buf[200];
827                     snprintf(msg_buf,sizeof(msg_buf),
828                         "Relocations did not complete successfully, but we are "
829                         " ignoring error: %s",dwarf_errmsg(err2));
830                     dwarf_insert_harmless_error(dbg,msg_buf);
831                     resd = DW_DLV_OK;
832                     /*  Fall thru to use the newly loaded section.
833                         even though it might not be adequately
834                         relocated. */
835                 } else {
836                     if (error) {
837                         *error = err2;
838                         err2 = 0;
839                     }
840                     /*  There is nothing here, or
841                         what is here is damaged. */
842                     return resd;
843                 }
844 
845             }
846         }
847         /*  We are leaving new_offset zero. We are at the
848             start of a section. */
849     } else {
850         new_offset = dis->de_cu_context->cc_debug_offset +
851             dis->de_cu_context->cc_length +
852             dis->de_cu_context->cc_length_size +
853             dis->de_cu_context->cc_extension_size;
854     }
855 
856     /*  Check that there is room in .debug_info beyond
857         the new offset for at least a new cu header.
858         If not, return -1 (DW_DLV_NO_ENTRY) to indicate end
859         of debug_info section, and reset
860         de_cu_debug_info_offset to
861         enable looping back through the cu's. */
862     section_size = is_info? dbg->de_debug_info.dss_size:
863         dbg->de_debug_types.dss_size;
864     if ((new_offset + _dwarf_length_of_cu_header_simple(dbg,is_info)) >=
865         section_size) {
866         dis->de_cu_context = NULL;
867         return (DW_DLV_NO_ENTRY);
868     }
869 
870     /* Check if this CU has been read before. */
871     cu_context = _dwarf_find_CU_Context(dbg, new_offset,is_info);
872 
873     /* If not, make CU Context for it. */
874     if (cu_context == NULL) {
875         res = _dwarf_make_CU_Context(dbg, new_offset,is_info,
876             &cu_context,error);
877         if (res != DW_DLV_OK) {
878             return res;
879         }
880     }
881 
882     dis->de_cu_context = cu_context;
883 
884     if (cu_header_length != NULL) {
885         *cu_header_length = cu_context->cc_length;
886     }
887 
888     if (version_stamp != NULL) {
889         *version_stamp = cu_context->cc_version_stamp;
890     }
891     if (abbrev_offset != NULL) {
892         *abbrev_offset = cu_context->cc_abbrev_offset;
893     }
894 
895     if (address_size != NULL) {
896         *address_size = cu_context->cc_address_size;
897     }
898     if (offset_size != NULL) {
899         *offset_size = cu_context->cc_length_size;
900     }
901     if (extension_size != NULL) {
902         *extension_size = cu_context->cc_extension_size;
903     }
904     if (header_type) {
905         *header_type = cu_context->cc_unit_type;
906     }
907 
908     if ( (dbg->de_tied_data.td_is_tied_object ||
909         _dwarf_file_has_debug_fission_cu_index(dbg)) &&
910         (cu_context->cc_unit_type == DW_UT_compile ||
911             cu_context->cc_unit_type == DW_UT_partial)) {
912         /*  ASSERT: !cu_context->cc_type_signature_present */
913         /*  Look for DW_AT_dwo_id and
914             if there is one pick up the hash
915             and the base array.
916             Also pick up cc_str_offset_base. */
917         Dwarf_Die cudie = 0;
918 
919         int resdwo = dwarf_siblingof_b(dbg,NULL,is_info,
920             &cudie, error);
921         if (resdwo == DW_DLV_OK) {
922             int dwo_idres = 0;
923             Dwarf_Sig8 dwosignature;
924             Dwarf_Bool sig_present = FALSE;
925             Dwarf_Unsigned str_offsets_base = 0;
926             Dwarf_Unsigned addr_base = 0;
927             Dwarf_Unsigned ranges_base = 0;
928             Dwarf_Bool str_offsets_base_present = FALSE;
929             Dwarf_Bool addr_base_present = FALSE;
930             Dwarf_Bool ranges_base_present = FALSE;
931             dwo_idres = find_context_base_fields(dbg,
932                 cudie,&dwosignature,&sig_present,
933                 &str_offsets_base,&str_offsets_base_present,
934                 &addr_base,&addr_base_present,
935                 &ranges_base,&ranges_base_present,
936                 error);
937 
938             if (dwo_idres == DW_DLV_OK) {
939                 if(sig_present) {
940                     /*  This can be in executable or ordinary .o
941                         or .dwo or .dwp */
942                     cu_context->cc_type_signature = dwosignature;
943                     cu_context->cc_signature_present = TRUE;
944                 }
945                 if (addr_base_present) {
946                     /* This can be in executable or ordinary .o */
947                     cu_context->cc_addr_base = addr_base;
948                     cu_context->cc_addr_base_present = TRUE;
949                 }
950 
951                 if(str_offsets_base_present) {
952                     /*  This can be in executable or ordinary .o
953                         or .dwo or .dwp */
954                     cu_context->cc_str_offsets_base = str_offsets_base;
955                     cu_context->cc_str_offsets_base_present = TRUE;
956                 }
957                 if(ranges_base_present) {
958                     /*  This can be in executable or ordinary .o */
959                     cu_context->cc_ranges_base = ranges_base;
960                     cu_context->cc_ranges_base_present = TRUE;
961                 }
962             }
963             dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
964         } else if (resdwo == DW_DLV_NO_ENTRY) {
965             /* Impossible */
966             _dwarf_error(NULL, error, DW_DLE_DWP_SIBLING_ERROR);
967             return DW_DLV_ERROR;
968         } else {
969             /* Something is badly wrong. */
970             return resdwo;
971         }
972     }
973     if (typeoffset) {
974         *typeoffset = cu_context->cc_type_signature_offset;
975     }
976     if (signature_out) {
977         *signature_out = cu_context->cc_type_signature;
978     }
979     if (has_signature) {
980         *has_signature = cu_context->cc_signature_present;
981     }
982     new_offset = new_offset + cu_context->cc_length +
983         cu_context->cc_length_size + cu_context->cc_extension_size;
984     *next_cu_offset = new_offset;
985     return (DW_DLV_OK);
986 }
987 
988 /*  Given hash signature, return the CU_die of the applicable CU.
989     The hash is assumed to be from 'somewhere',
990     such as from a skeleton DIE DW_AT_dwo_id  ("cu" case) or
991     from a DW_FORM_ref_sig8 ("tu" case).
992 
993     If "tu" request,  the CU_die
994     of of the type unit.
995     Works on either a dwp package file or a dwo object.
996 
997     If "cu" request,  the CU_die
998     of the compilation unit.
999     Works on either a dwp package file or a dwo object.
1000 
1001     If the hash passed is not present, returns DW_DLV_NO_ENTRY
1002     (but read the next two paragraphs for more detail).
1003 
1004     If a dwp package file with the hash signature
1005     is present in the applicable index but no matching
1006     compilation unit can be found, it returns DW_DLV_ERROR.
1007 
1008     If a .dwo object there is no index and we look at the
1009     compilation units (possibly all of them). If not present
1010     then we return DW_DLV_NO_ENTRY.
1011 
1012     The returned_die is a CU DIE if the sig_type is "cu".
1013     The returned_die is a type DIE if the sig_type is "tu".
1014     Perhaps both should return CU die. FIXME
1015 
1016     New 27 April, 2015
1017 */
1018 int
dwarf_die_from_hash_signature(Dwarf_Debug dbg,Dwarf_Sig8 * hash_sig,const char * sig_type,Dwarf_Die * returned_die,Dwarf_Error * error)1019 dwarf_die_from_hash_signature(Dwarf_Debug dbg,
1020     Dwarf_Sig8 *     hash_sig,
1021     const char *     sig_type  /* "tu" or "cu"*/,
1022     Dwarf_Die  *     returned_die,
1023     Dwarf_Error*     error)
1024 {
1025     Dwarf_Bool is_type_unit = FALSE;
1026     int sres = 0;
1027 
1028     sres = _dwarf_load_debug_info(dbg,error);
1029     if (sres == DW_DLV_ERROR) {
1030         return sres;
1031     }
1032     sres = _dwarf_load_debug_types(dbg,error);
1033     if (sres == DW_DLV_ERROR) {
1034         return sres;
1035     }
1036 
1037     if (!strcmp(sig_type,"tu")) {
1038         is_type_unit = TRUE;
1039     } else if (!strcmp(sig_type,"cu")) {
1040         is_type_unit = FALSE;
1041     } else {
1042         _dwarf_error(dbg,error,DW_DLE_SIG_TYPE_WRONG_STRING);
1043         return DW_DLV_ERROR;
1044     }
1045 
1046     if (_dwarf_file_has_debug_fission_index(dbg)) {
1047         /* This is a dwp package file. */
1048         int fisres = 0;
1049         Dwarf_Bool is_info2 = 0;
1050         Dwarf_Off cu_header_off = 0;
1051         Dwarf_Off cu_size = 0;
1052         Dwarf_Off cu_die_off = 0;
1053         Dwarf_Off typeoffset = 0;
1054         Dwarf_Die cudie = 0;
1055         Dwarf_Die typedie = 0;
1056         Dwarf_CU_Context context = 0;
1057         Dwarf_Debug_Fission_Per_CU fiss;
1058 
1059         memset(&fiss,0,sizeof(fiss));
1060         fisres = dwarf_get_debugfission_for_key(dbg,hash_sig,
1061             sig_type,&fiss,error);
1062         if (fisres != DW_DLV_OK) {
1063             return fisres;
1064         }
1065         /* Found it */
1066         if(is_type_unit) {
1067             /*  DW4 has debug_types, so look in .debug_types.
1068                 Else look in .debug_info.  */
1069             is_info2 = dbg->de_debug_types.dss_size?FALSE:TRUE;
1070         } else {
1071             is_info2 = TRUE;
1072         }
1073 
1074         cu_header_off = _dwarf_get_dwp_extra_offset(&fiss,
1075             is_info2?DW_SECT_INFO:DW_SECT_TYPES,
1076             &cu_size);
1077 
1078         fisres = dwarf_get_cu_die_offset_given_cu_header_offset_b(
1079             dbg,cu_header_off,
1080             is_info2,
1081             &cu_die_off,error);
1082         if (fisres != DW_DLV_OK) {
1083             return fisres;
1084         }
1085         fisres = dwarf_offdie_b(dbg,cu_die_off,is_info2,
1086             &cudie,error);
1087         if (fisres != DW_DLV_OK) {
1088             return fisres;
1089         }
1090         if (!is_type_unit) {
1091             *returned_die = cudie;
1092             return DW_DLV_OK;
1093         }
1094         context = cudie->di_cu_context;
1095         typeoffset = context->cc_type_signature_offset;
1096         typeoffset += cu_header_off;
1097         fisres = dwarf_offdie_b(dbg,typeoffset,is_info2,
1098             &typedie,error);
1099         if (fisres != DW_DLV_OK) {
1100             dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1101             return fisres;
1102         }
1103         *returned_die = typedie;
1104         dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1105         return DW_DLV_OK;
1106     }
1107     /*  Look thru all the CUs, there is no DWP tu/cu index.
1108         There will be COMDAT sections for  the type TUs
1109             (DW_UT_type).
1110         A single non-comdat for the DW_UT_compile. */
1111     /*  FIXME: DW_DLE_DEBUG_FISSION_INCOMPLETE  */
1112     _dwarf_error(dbg,error,DW_DLE_DEBUG_FISSION_INCOMPLETE);
1113     return DW_DLV_ERROR;
1114 }
1115 
1116 static int
dwarf_ptr_CU_offset(Dwarf_CU_Context cu_context,Dwarf_Byte_Ptr di_ptr,Dwarf_Bool is_info,Dwarf_Off * cu_off)1117 dwarf_ptr_CU_offset(Dwarf_CU_Context cu_context,
1118     Dwarf_Byte_Ptr di_ptr,
1119     Dwarf_Bool is_info,
1120     Dwarf_Off * cu_off)
1121 {
1122     Dwarf_Debug dbg = cu_context->cc_dbg;
1123     Dwarf_Small *dataptr = is_info? dbg->de_debug_info.dss_data:
1124         dbg->de_debug_types.dss_data;
1125     *cu_off = (di_ptr - dataptr);
1126     return DW_DLV_OK;
1127 }
1128 #if 0 /* FOR DEBUGGING */
1129 /* Just for debug purposes */
1130 void print_sib_offset(Dwarf_Die sibling)
1131 {
1132     Dwarf_Off sib_off;
1133     Dwarf_Error error;
1134     dwarf_dieoffset(sibling,&sib_off,&error);
1135     fprintf(stderr," SIB OFF = 0x%" DW_PR_XZEROS DW_PR_DUx,sib_off);
1136 }
1137 void print_ptr_offset(Dwarf_CU_Context cu_context,Dwarf_Byte_Ptr di_ptr)
1138 {
1139     Dwarf_Off ptr_off;
1140     dwarf_ptr_CU_offset(cu_context,di_ptr,&ptr_off);
1141     fprintf(stderr," PTR OFF = 0x%" DW_PR_XZEROS DW_PR_DUx,ptr_off);
1142 }
1143 #endif
1144 
1145 
1146 /*  Validate the sibling DIE. This only makes sense to call
1147     if the sibling's DIEs have been travsersed and
1148     dwarf_child() called on each,
1149     so that the last DIE dwarf_child saw was the last.
1150     Essentially ensuring that (after such traversal) that we
1151     are in the same place a sibling attribute would identify.
1152     In case we return DW_DLV_ERROR, the global offset of the last
1153     DIE traversed by dwarf_child is returned through *offset
1154 
1155     It is essentially guaranteed that  dbg->de_last_die
1156     is a stale DIE pointer of a deallocated DIE when we get here.
1157     It must not be used as a DIE pointer here,
1158     just as a sort of anonymous pointer that we just check against
1159     NULL.
1160 
1161     There is a (subtle?) dependence on the fact that when we call this
1162     the last dwarf_child() call would have been for this sibling.
1163     Meaning that this works in a depth-first traversal even though there
1164     is no stack of 'de_last_die' values.
1165 
1166     The check for dbg->de_last_die just ensures sanity.
1167 
1168     If one is switching between normal debug_frame and eh_frame
1169     (traversing them in tandem, let us say) in a single
1170     Dwarf_Debug this validator makes no sense.
1171     It works if one processes a .debug_frame (entirely) and
1172     then an eh_frame (or vice versa) though.
1173     Use caution.
1174 */
1175 int
dwarf_validate_die_sibling(Dwarf_Die sibling,Dwarf_Off * offset)1176 dwarf_validate_die_sibling(Dwarf_Die sibling,Dwarf_Off *offset)
1177 {
1178     Dwarf_Debug dbg = 0;
1179     Dwarf_Error *error = 0;
1180     Dwarf_Debug_InfoTypes dis = 0;
1181     CHECK_DIE(sibling, DW_DLV_ERROR);
1182     dbg = sibling->di_cu_context->cc_dbg;
1183 
1184     dis = sibling->di_is_info? &dbg->de_info_reading: &dbg->de_types_reading;
1185 
1186     *offset = 0;
1187     if (dis->de_last_die && dis->de_last_di_ptr) {
1188         if (sibling->di_debug_ptr == dis->de_last_di_ptr) {
1189             return (DW_DLV_OK);
1190         }
1191     }
1192     /* Calculate global offset used for error reporting */
1193     dwarf_ptr_CU_offset(sibling->di_cu_context,
1194         dis->de_last_di_ptr,sibling->di_is_info,offset);
1195     return (DW_DLV_ERROR);
1196 }
1197 
1198 /*  This function does two slightly different things
1199     depending on the input flag want_AT_sibling.  If
1200     this flag is true, it checks if the input die has
1201     a DW_AT_sibling attribute.  If it does it returns
1202     a pointer to the start of the sibling die in the
1203     .debug_info section.  Otherwise it behaves the
1204     same as the want_AT_sibling false case.
1205 
1206     If the want_AT_sibling flag is false, it returns
1207     a pointer to the immediately adjacent die in the
1208     .debug_info section.
1209 
1210     Die_info_end points to the end of the .debug_info
1211     portion for the cu the die belongs to.  It is used
1212     to check that the search for the next die does not
1213     cross the end of the current cu.  Cu_info_start points
1214     to the start of the .debug_info portion for the
1215     current cu, and is used to add to the offset for
1216     DW_AT_sibling attributes.  Finally, has_die_child
1217     is a pointer to a Dwarf_Bool that is set true if
1218     the present die has children, false otherwise.
1219     However, in case want_AT_child is true and the die
1220     has a DW_AT_sibling attribute *has_die_child is set
1221     false to indicate that the children are being skipped.
1222 
1223     die_info_end  points to the last byte+1 of the cu.  */
1224 static int
_dwarf_next_die_info_ptr(Dwarf_Byte_Ptr die_info_ptr,Dwarf_CU_Context cu_context,Dwarf_Byte_Ptr die_info_end,Dwarf_Byte_Ptr cu_info_start,Dwarf_Bool want_AT_sibling,Dwarf_Bool * has_die_child,Dwarf_Byte_Ptr * next_die_ptr_out,Dwarf_Error * error)1225 _dwarf_next_die_info_ptr(Dwarf_Byte_Ptr die_info_ptr,
1226     Dwarf_CU_Context cu_context,
1227     Dwarf_Byte_Ptr die_info_end,
1228     Dwarf_Byte_Ptr cu_info_start,
1229     Dwarf_Bool want_AT_sibling,
1230     Dwarf_Bool * has_die_child,
1231     Dwarf_Byte_Ptr *next_die_ptr_out,
1232     Dwarf_Error *error)
1233 {
1234     Dwarf_Byte_Ptr info_ptr = 0;
1235     Dwarf_Byte_Ptr abbrev_ptr = 0;
1236     Dwarf_Word abbrev_code = 0;
1237     Dwarf_Abbrev_List abbrev_list = 0;
1238     Dwarf_Half attr = 0;
1239     Dwarf_Half attr_form = 0;
1240     Dwarf_Unsigned offset = 0;
1241     Dwarf_Unsigned utmp = 0;
1242     Dwarf_Debug dbg = 0;
1243     Dwarf_Byte_Ptr abbrev_end = 0;
1244     int lres = 0;
1245 
1246     info_ptr = die_info_ptr;
1247     DECODE_LEB128_UWORD_CK(info_ptr, utmp,dbg,error,die_info_end);
1248     abbrev_code = (Dwarf_Word) utmp;
1249     if (abbrev_code == 0) {
1250         /*  Should never happen. Tested before we got here. */
1251         _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PTR_NULL);
1252         return DW_DLV_ERROR;
1253     }
1254 
1255 
1256     lres = _dwarf_get_abbrev_for_code(cu_context, abbrev_code,
1257         &abbrev_list,error);
1258     if (lres == DW_DLV_ERROR) {
1259         return lres;
1260     }
1261     if (lres == DW_DLV_NO_ENTRY) {
1262         _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_NO_ABBREV_LIST);
1263         return DW_DLV_ERROR;
1264     }
1265     dbg = cu_context->cc_dbg;
1266 
1267     *has_die_child = abbrev_list->abl_has_child;
1268 
1269     abbrev_ptr = abbrev_list->abl_abbrev_ptr;
1270     abbrev_end = _dwarf_calculate_abbrev_section_end_ptr(cu_context);
1271 
1272     do {
1273         Dwarf_Unsigned utmp2;
1274 
1275         DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp2,dbg,error,abbrev_end);
1276         attr = (Dwarf_Half) utmp2;
1277         DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp2,dbg,error,abbrev_end);
1278         attr_form = (Dwarf_Half) utmp2;
1279         if (attr_form == DW_FORM_indirect) {
1280             Dwarf_Unsigned utmp6;
1281 
1282             /* DECODE_LEB128_UWORD updates info_ptr */
1283             DECODE_LEB128_UWORD_CK(info_ptr, utmp6,dbg,error,die_info_end);
1284             attr_form = (Dwarf_Half) utmp6;
1285 
1286         }
1287 
1288         if (want_AT_sibling && attr == DW_AT_sibling) {
1289             switch (attr_form) {
1290             case DW_FORM_ref1:
1291                 offset = *(Dwarf_Small *) info_ptr;
1292                 break;
1293             case DW_FORM_ref2:
1294                 /* READ_UNALIGNED does not update info_ptr */
1295                 READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,
1296                     info_ptr, sizeof(Dwarf_Half),
1297                     error,die_info_end);
1298                 break;
1299             case DW_FORM_ref4:
1300                 READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,
1301                     info_ptr, sizeof(Dwarf_ufixed),
1302                     error,die_info_end);
1303                 break;
1304             case DW_FORM_ref8:
1305                 READ_UNALIGNED_CK(dbg, offset, Dwarf_Unsigned,
1306                     info_ptr, sizeof(Dwarf_Unsigned),
1307                     error,die_info_end);
1308                 break;
1309             case DW_FORM_ref_udata:
1310                 DECODE_LEB128_UWORD_CK(info_ptr, offset,
1311                     dbg,error,die_info_end);
1312                 break;
1313             case DW_FORM_ref_addr:
1314                 /*  Very unusual.  The FORM is intended to refer to
1315                     a different CU, but a different CU cannot
1316                     be a sibling, can it?
1317                     We could ignore this and treat as if no DW_AT_sibling
1318                     present.   Or derive the offset from it and if
1319                     it is in the same CU use it directly.
1320                     The offset here is *supposed* to be a global offset,
1321                     so adding cu_info_start is wrong  to any offset
1322                     we find here unless cu_info_start
1323                     is zero! Lets pretend there is no DW_AT_sibling
1324                     attribute.  */
1325                 goto no_sibling_attr;
1326             default:
1327                 _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_WRONG_FORM);
1328                 return DW_DLV_ERROR;
1329             }
1330 
1331             /*  Reset *has_die_child to indicate children skipped.  */
1332             *has_die_child = false;
1333 
1334             /*  A value beyond die_info_end indicates an error. Exactly
1335                 at die_info_end means 1-past-cu-end and simply means we
1336                 are at the end, do not return error. Higher level
1337                 will detect that we are at the end. */
1338             if (cu_info_start + offset > die_info_end) {
1339                 /* Error case, bad DWARF. */
1340                 _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PAST_END);
1341                 return DW_DLV_ERROR;
1342             }
1343             /* At or before end-of-cu */
1344             *next_die_ptr_out = cu_info_start + offset;
1345             return DW_DLV_OK;
1346         }
1347 
1348         no_sibling_attr:
1349         if (attr_form != 0) {
1350             int res = 0;
1351             Dwarf_Unsigned sizeofval = 0;
1352             ptrdiff_t  sizeb = 0;
1353             res = _dwarf_get_size_of_val(cu_context->cc_dbg,
1354                 attr_form,
1355                 cu_context->cc_version_stamp,
1356                 cu_context->cc_address_size,
1357                 info_ptr,
1358                 cu_context->cc_length_size,
1359                 &sizeofval,
1360                 die_info_end,
1361                 error);
1362             if(res != DW_DLV_OK) {
1363                 return res;
1364             }
1365             /*  It is ok for info_ptr == die_info_end, as we will test
1366                 later before using a too-large info_ptr */
1367             sizeb = (ptrdiff_t)sizeofval;
1368             if (sizeb > (die_info_end - info_ptr) ||
1369                 sizeb < 0) {
1370                 _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PAST_END);
1371                 return DW_DLV_ERROR;
1372             }
1373             info_ptr += sizeofval;
1374             if (info_ptr > die_info_end) {
1375                 /*  More than one-past-end indicates a bug somewhere,
1376                     likely bad dwarf generation. */
1377                 _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PAST_END);
1378                 return DW_DLV_ERROR;
1379             }
1380         }
1381     } while (attr != 0 || attr_form != 0);
1382     *next_die_ptr_out = info_ptr;
1383     return DW_DLV_OK;
1384 }
1385 
1386 /*  Multiple TAGs are in fact compile units.
1387     Allow them all.
1388     Return non-zero if a CU tag.
1389     Else return 0.
1390 */
1391 static int
is_cu_tag(int t)1392 is_cu_tag(int t)
1393 {
1394     if (t == DW_TAG_compile_unit ||
1395         t == DW_TAG_partial_unit ||
1396         t == DW_TAG_imported_unit ||
1397         t == DW_TAG_type_unit) {
1398         return 1;
1399     }
1400     return 0;
1401 }
1402 
1403 /*  Given a Dwarf_Debug dbg, and a Dwarf_Die die, it returns
1404     a Dwarf_Die for the sibling of die.  In case die is NULL,
1405     it returns (thru ptr) a Dwarf_Die for the first die in the current
1406     cu in dbg.  Returns DW_DLV_ERROR on error.
1407 
1408     It is assumed that every sibling chain including those with
1409     only one element is terminated with a NULL die, except a
1410     chain with only a NULL die.
1411 
1412     The algorithm moves from one die to the adjacent one.  It
1413     returns when the depth of children it sees equals the number
1414     of sibling chain terminations.  A single count, child_depth
1415     is used to track the depth of children and sibling terminations
1416     encountered.  Child_depth is incremented when a die has the
1417     Has-Child flag set unless the child happens to be a NULL die.
1418     Child_depth is decremented when a die has Has-Child false,
1419     and the adjacent die is NULL.  Algorithm returns when
1420     child_depth is 0.
1421 
1422     **NOTE: Do not modify input die, since it is used at the end.  */
1423 int
dwarf_siblingof(Dwarf_Debug dbg,Dwarf_Die die,Dwarf_Die * caller_ret_die,Dwarf_Error * error)1424 dwarf_siblingof(Dwarf_Debug dbg,
1425     Dwarf_Die die,
1426     Dwarf_Die * caller_ret_die, Dwarf_Error * error)
1427 {
1428     Dwarf_Bool is_info = true;
1429     return dwarf_siblingof_b(dbg,die,is_info,caller_ret_die,error);
1430 }
1431 /*  This is the new form, October 2011.  On calling with 'die' NULL,
1432     we cannot tell if this is debug_info or debug_types, so
1433     we must be informed!. */
1434 int
dwarf_siblingof_b(Dwarf_Debug dbg,Dwarf_Die die,Dwarf_Bool is_info,Dwarf_Die * caller_ret_die,Dwarf_Error * error)1435 dwarf_siblingof_b(Dwarf_Debug dbg,
1436     Dwarf_Die die,
1437     Dwarf_Bool is_info,
1438     Dwarf_Die * caller_ret_die, Dwarf_Error * error)
1439 {
1440     Dwarf_Die ret_die = 0;
1441     Dwarf_Byte_Ptr die_info_ptr = 0;
1442     Dwarf_Byte_Ptr cu_info_start = 0;
1443 
1444     /* die_info_end points 1-past end of die (once set) */
1445     Dwarf_Byte_Ptr die_info_end = 0;
1446     Dwarf_Word abbrev_code = 0;
1447     Dwarf_Unsigned utmp = 0;
1448     int lres = 0;
1449     /* Since die may be NULL, we rely on the input argument. */
1450     Dwarf_Debug_InfoTypes dis = is_info? &dbg->de_info_reading:
1451         &dbg->de_types_reading;
1452     Dwarf_Small *dataptr = is_info? dbg->de_debug_info.dss_data:
1453         dbg->de_debug_types.dss_data;
1454 
1455 
1456 
1457     if (dbg == NULL) {
1458         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
1459         return (DW_DLV_ERROR);
1460     }
1461 
1462     if (die == NULL) {
1463         /*  Find root die of cu */
1464         /*  die_info_end is untouched here, need not be set in this
1465             branch. */
1466         Dwarf_Off off2;
1467         Dwarf_CU_Context context=0;
1468         Dwarf_Unsigned headerlen = 0;
1469         int cres = 0;
1470 
1471         /*  If we've not loaded debug_info
1472             de_cu_context will be NULL. */
1473 
1474         context = dis->de_cu_context;
1475         if (context == NULL) {
1476             _dwarf_error(dbg, error, DW_DLE_DBG_NO_CU_CONTEXT);
1477             return (DW_DLV_ERROR);
1478         }
1479 
1480         off2 = context->cc_debug_offset;
1481         cu_info_start = dataptr + off2;
1482         cres = _dwarf_length_of_cu_header(dbg, off2,is_info,
1483             &headerlen,error);
1484         if (cres != DW_DLV_OK) {
1485             return cres;
1486         }
1487         die_info_ptr = cu_info_start + headerlen;
1488         die_info_end = _dwarf_calculate_info_section_end_ptr(context);
1489         /*  Recording the CU die pointer so we can later access
1490             for special FORMs relating to .debug_str_offsets
1491             and .debug_addr  */
1492         context->cc_cu_die_offset_present = TRUE;
1493         context->cc_cu_die_global_sec_offset = off2 + headerlen;
1494     } else {
1495         /* Find sibling die. */
1496         Dwarf_Bool has_child = false;
1497         Dwarf_Sword child_depth = 0;
1498         Dwarf_CU_Context context=0;
1499 
1500         /*  We cannot have a legal die unless debug_info was loaded, so
1501             no need to load debug_info here. */
1502         CHECK_DIE(die, DW_DLV_ERROR);
1503 
1504         die_info_ptr = die->di_debug_ptr;
1505         if (*die_info_ptr == 0) {
1506             return (DW_DLV_NO_ENTRY);
1507         }
1508         context = die->di_cu_context;
1509         cu_info_start = dataptr+ context->cc_debug_offset;
1510         die_info_end = _dwarf_calculate_info_section_end_ptr(context);
1511 
1512         if ((*die_info_ptr) == 0) {
1513             return (DW_DLV_NO_ENTRY);
1514         }
1515         child_depth = 0;
1516         do {
1517             int res2 = 0;
1518             Dwarf_Byte_Ptr die_info_ptr2 = 0;
1519             res2 = _dwarf_next_die_info_ptr(die_info_ptr,
1520                 die->di_cu_context, die_info_end,
1521                 cu_info_start, true, &has_child,
1522                 &die_info_ptr2,
1523                 error);
1524             if(res2 != DW_DLV_OK) {
1525                 return res2;
1526             }
1527             if (die_info_ptr2 < die_info_ptr) {
1528                 /*  There is something very wrong, our die value
1529                     decreased.  Bad DWARF. */
1530                 _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_LOW_ERROR);
1531                 return (DW_DLV_ERROR);
1532             }
1533             if (die_info_ptr2 > die_info_end) {
1534                 _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PAST_END);
1535                 return (DW_DLV_ERROR);
1536             }
1537             die_info_ptr = die_info_ptr2;
1538 
1539             /*  die_info_end is one past end. Do not read it!
1540                 A test for ``!= die_info_end''  would work as well,
1541                 but perhaps < reads more like the meaning. */
1542             if (die_info_ptr < die_info_end) {
1543                 if ((*die_info_ptr) == 0 && has_child) {
1544                     die_info_ptr++;
1545                     has_child = false;
1546                 }
1547             }
1548 
1549             /*  die_info_ptr can be one-past-end.  */
1550             if ((die_info_ptr == die_info_end) ||
1551                 ((*die_info_ptr) == 0)) {
1552                 /* We are at the end of a sibling list.
1553                     get back to the next containing
1554                     sibling list (looking for a libling
1555                     list with more on it).
1556                     */
1557                 for (;;) {
1558                     if (child_depth == 0) {
1559                         /*  Meaning there is no outer list,
1560                             so stop. */
1561                         break;
1562                     }
1563                     if (die_info_ptr == die_info_end) {
1564                         /*  September 2016: do not deref
1565                             if we are past end.
1566                             If we are at end at this point
1567                             it means the sibling list
1568                             inside this CU is not properly
1569                             terminated. We run off the end.
1570                             An error.*/
1571                         _dwarf_error(dbg, error,DW_DLE_SIBLING_LIST_IMPROPER);
1572                         return (DW_DLV_ERROR);
1573                     }
1574                     if (*die_info_ptr) {
1575                         /* We have a real sibling. */
1576                         break;
1577                     }
1578                     /*  Move out one DIE level.
1579                         Move past NUL byte marking end of
1580                         this sibling list. */
1581                     child_depth--;
1582                     die_info_ptr++;
1583                 }
1584             } else {
1585                 child_depth = has_child ? child_depth + 1 : child_depth;
1586             }
1587 
1588         } while (child_depth != 0);
1589     }
1590 
1591     /*  die_info_ptr > die_info_end is really a bug (possibly in dwarf
1592         generation)(but we are past end, no more DIEs here), whereas
1593         die_info_ptr == die_info_end means 'one past end, no more DIEs
1594         here'. */
1595     if (die_info_ptr >= die_info_end) {
1596         return (DW_DLV_NO_ENTRY);
1597     }
1598     if ((*die_info_ptr) == 0) {
1599         return (DW_DLV_NO_ENTRY);
1600     }
1601 
1602     ret_die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1);
1603     if (ret_die == NULL) {
1604         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1605         return (DW_DLV_ERROR);
1606     }
1607 
1608     ret_die->di_is_info = is_info;
1609     ret_die->di_debug_ptr = die_info_ptr;
1610     ret_die->di_cu_context =
1611         die == NULL ? dis->de_cu_context : die->di_cu_context;
1612 
1613     DECODE_LEB128_UWORD_CK(die_info_ptr, utmp,dbg,error,die_info_end);
1614     if (die_info_ptr > die_info_end) {
1615         /*  We managed to go past the end of the CU!.
1616             Something is badly wrong. */
1617         dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
1618         _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
1619         return (DW_DLV_ERROR);
1620     }
1621     abbrev_code = (Dwarf_Word) utmp;
1622     if (abbrev_code == 0) {
1623         /* Zero means a null DIE */
1624         dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
1625         return (DW_DLV_NO_ENTRY);
1626     }
1627     ret_die->di_abbrev_code = abbrev_code;
1628     lres = _dwarf_get_abbrev_for_code(ret_die->di_cu_context, abbrev_code,
1629         &ret_die->di_abbrev_list,error);
1630     if (lres == DW_DLV_ERROR) {
1631         dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
1632         return lres;
1633     }
1634     if (lres == DW_DLV_NO_ENTRY) {
1635         dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
1636         _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_LIST_NULL);
1637         return DW_DLV_ERROR;
1638     }
1639     if (die == NULL && !is_cu_tag(ret_die->di_abbrev_list->abl_tag)) {
1640         dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
1641         _dwarf_error(dbg, error, DW_DLE_FIRST_DIE_NOT_CU);
1642         return DW_DLV_ERROR;
1643     }
1644 
1645     *caller_ret_die = ret_die;
1646     return (DW_DLV_OK);
1647 }
1648 
1649 
1650 int
dwarf_child(Dwarf_Die die,Dwarf_Die * caller_ret_die,Dwarf_Error * error)1651 dwarf_child(Dwarf_Die die,
1652     Dwarf_Die * caller_ret_die,
1653     Dwarf_Error * error)
1654 {
1655     Dwarf_Byte_Ptr die_info_ptr = 0;
1656     Dwarf_Byte_Ptr die_info_ptr2 = 0;
1657 
1658     /* die_info_end points one-past-end of die area. */
1659     Dwarf_Byte_Ptr die_info_end = 0;
1660     Dwarf_Die ret_die = 0;
1661     Dwarf_Bool has_die_child = 0;
1662     Dwarf_Debug dbg;
1663     Dwarf_Word abbrev_code = 0;
1664     Dwarf_Unsigned utmp = 0;
1665     Dwarf_Debug_InfoTypes dis = 0;
1666     int res = 0;
1667     Dwarf_CU_Context context = 0;
1668     int lres = 0;
1669 
1670     CHECK_DIE(die, DW_DLV_ERROR);
1671     dbg = die->di_cu_context->cc_dbg;
1672     dis = die->di_is_info? &dbg->de_info_reading:
1673         &dbg->de_types_reading;
1674     die_info_ptr = die->di_debug_ptr;
1675 
1676     /*  We are saving a DIE pointer here, but the pointer
1677         will not be presumed live later, when it is tested. */
1678     dis->de_last_die = die;
1679     dis->de_last_di_ptr = die_info_ptr;
1680 
1681     /* NULL die has no child. */
1682     if ((*die_info_ptr) == 0) {
1683         return DW_DLV_NO_ENTRY;
1684     }
1685     context = die->di_cu_context;
1686     die_info_end = _dwarf_calculate_info_section_end_ptr(context);
1687 
1688     res = _dwarf_next_die_info_ptr(die_info_ptr, die->di_cu_context,
1689         die_info_end,
1690         NULL, false,
1691         &has_die_child,
1692         &die_info_ptr2,
1693         error);
1694     if(res != DW_DLV_OK) {
1695         return res;
1696     }
1697     if (die_info_ptr == die_info_end) {
1698         return DW_DLV_NO_ENTRY;
1699     }
1700     die_info_ptr = die_info_ptr2;
1701 
1702     dis->de_last_di_ptr = die_info_ptr;
1703 
1704     if (!has_die_child) {
1705         /* Look for end of sibling chain. */
1706         while (dis->de_last_di_ptr < die_info_end) {
1707             if (*dis->de_last_di_ptr) {
1708                 break;
1709             }
1710             ++dis->de_last_di_ptr;
1711         }
1712         return DW_DLV_NO_ENTRY;
1713     }
1714 
1715     ret_die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1);
1716     if (ret_die == NULL) {
1717         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1718         return DW_DLV_ERROR;
1719     }
1720     ret_die->di_debug_ptr = die_info_ptr;
1721     ret_die->di_cu_context = die->di_cu_context;
1722     ret_die->di_is_info = die->di_is_info;
1723 
1724     DECODE_LEB128_UWORD_CK(die_info_ptr, utmp,
1725         dbg,error,die_info_end);
1726     abbrev_code = (Dwarf_Word) utmp;
1727 
1728     dis->de_last_di_ptr = die_info_ptr;
1729 
1730     if (abbrev_code == 0) {
1731         /* Look for end of sibling chain */
1732         while (dis->de_last_di_ptr < die_info_end) {
1733             if (*dis->de_last_di_ptr) {
1734                 break;
1735             }
1736             ++dis->de_last_di_ptr;
1737         }
1738 
1739         /*  We have arrived at a null DIE, at the end of a CU or the end
1740             of a list of siblings. */
1741         *caller_ret_die = 0;
1742         dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
1743         return DW_DLV_NO_ENTRY;
1744     }
1745     ret_die->di_abbrev_code = abbrev_code;
1746     lres = _dwarf_get_abbrev_for_code(die->di_cu_context, abbrev_code,
1747         &ret_die->di_abbrev_list,error);
1748     if (lres == DW_DLV_ERROR) {
1749         dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
1750         return lres;
1751     }
1752     if (lres == DW_DLV_NO_ENTRY) {
1753         dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
1754         _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
1755         return DW_DLV_ERROR;
1756     }
1757 
1758     *caller_ret_die = ret_die;
1759     return (DW_DLV_OK);
1760 }
1761 
1762 /*  Given a (global, not cu_relative) die offset, this returns
1763     a pointer to a DIE thru *new_die.
1764     It is up to the caller to do a
1765     dwarf_dealloc(dbg,*new_die,DW_DLE_DIE);
1766     The old form only works with debug_info.
1767     The new _b form works with debug_info or debug_types.
1768     */
1769 int
dwarf_offdie(Dwarf_Debug dbg,Dwarf_Off offset,Dwarf_Die * new_die,Dwarf_Error * error)1770 dwarf_offdie(Dwarf_Debug dbg,
1771     Dwarf_Off offset, Dwarf_Die * new_die, Dwarf_Error * error)
1772 {
1773     Dwarf_Bool is_info = true;
1774     return dwarf_offdie_b(dbg,offset,is_info,new_die,error);
1775 }
1776 
1777 int
dwarf_offdie_b(Dwarf_Debug dbg,Dwarf_Off offset,Dwarf_Bool is_info,Dwarf_Die * new_die,Dwarf_Error * error)1778 dwarf_offdie_b(Dwarf_Debug dbg,
1779     Dwarf_Off offset, Dwarf_Bool is_info,
1780     Dwarf_Die * new_die, Dwarf_Error * error)
1781 {
1782     Dwarf_CU_Context cu_context = 0;
1783     Dwarf_Off new_cu_offset = 0;
1784     Dwarf_Die die = 0;
1785     Dwarf_Byte_Ptr info_ptr = 0;
1786     Dwarf_Unsigned abbrev_code = 0;
1787     Dwarf_Unsigned utmp = 0;
1788     int lres = 0;
1789     Dwarf_Debug_InfoTypes dis = 0;
1790     Dwarf_Byte_Ptr die_info_end = 0;
1791 
1792     if (dbg == NULL) {
1793         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
1794         return (DW_DLV_ERROR);
1795     }
1796     dis = is_info? &dbg->de_info_reading:
1797         &dbg->de_types_reading;
1798 
1799     cu_context = _dwarf_find_CU_Context(dbg, offset,is_info);
1800     if (cu_context == NULL) {
1801         cu_context = _dwarf_find_offdie_CU_Context(dbg, offset,is_info);
1802     }
1803 
1804     if (cu_context == NULL) {
1805         Dwarf_Unsigned section_size = is_info? dbg->de_debug_info.dss_size:
1806             dbg->de_debug_types.dss_size;
1807         int res = is_info?_dwarf_load_debug_info(dbg, error):
1808             _dwarf_load_debug_types(dbg,error);
1809 
1810         if (res != DW_DLV_OK) {
1811             return res;
1812         }
1813 
1814         if (dis->de_offdie_cu_context_end != NULL) {
1815             Dwarf_CU_Context lcu_context =
1816                 dis->de_offdie_cu_context_end;
1817             new_cu_offset =
1818                 lcu_context->cc_debug_offset +
1819                 lcu_context->cc_length +
1820                 lcu_context->cc_length_size +
1821                 lcu_context->cc_extension_size;
1822         }
1823 
1824 
1825         do {
1826             if ((new_cu_offset +
1827                 _dwarf_length_of_cu_header_simple(dbg,is_info)) >=
1828                 section_size) {
1829                 _dwarf_error(dbg, error, DW_DLE_OFFSET_BAD);
1830                 return (DW_DLV_ERROR);
1831             }
1832             res = _dwarf_make_CU_Context(dbg, new_cu_offset,is_info,
1833                 &cu_context,error);
1834             if (res != DW_DLV_OK) {
1835                 return res;
1836             }
1837             if (dis->de_offdie_cu_context == NULL) {
1838                 dis->de_offdie_cu_context = cu_context;
1839                 dis->de_offdie_cu_context_end = cu_context;
1840             } else {
1841                 dis->de_offdie_cu_context_end->cc_next = cu_context;
1842                 dis->de_offdie_cu_context_end = cu_context;
1843             }
1844 
1845             new_cu_offset = new_cu_offset + cu_context->cc_length +
1846                 cu_context->cc_length_size +
1847                 cu_context->cc_extension_size;
1848 
1849         } while (offset >= new_cu_offset);
1850     }
1851 
1852     die_info_end = _dwarf_calculate_info_section_end_ptr(cu_context);
1853     die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1);
1854     if (die == NULL) {
1855         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1856         return (DW_DLV_ERROR);
1857     }
1858     die->di_cu_context = cu_context;
1859     die->di_is_info = is_info;
1860 
1861     {
1862         Dwarf_Small *dataptr = is_info? dbg->de_debug_info.dss_data:
1863             dbg->de_debug_types.dss_data;
1864         info_ptr = dataptr + offset;
1865     }
1866     die->di_debug_ptr = info_ptr;
1867     DECODE_LEB128_UWORD_CK(info_ptr, utmp,dbg,error,die_info_end);
1868     abbrev_code = utmp;
1869     if (abbrev_code == 0) {
1870         /* we are at a null DIE (or there is a bug). */
1871         *new_die = 0;
1872         dwarf_dealloc(dbg, die, DW_DLA_DIE);
1873         return DW_DLV_NO_ENTRY;
1874     }
1875     die->di_abbrev_code = abbrev_code;
1876     lres = _dwarf_get_abbrev_for_code(cu_context, abbrev_code,
1877         &die->di_abbrev_list,error);
1878     if (lres == DW_DLV_ERROR) {
1879         dwarf_dealloc(dbg, die, DW_DLA_DIE);
1880         return lres;
1881     }
1882     if (lres == DW_DLV_NO_ENTRY) {
1883         dwarf_dealloc(dbg, die, DW_DLA_DIE);
1884         _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_LIST_NULL);
1885         return DW_DLV_ERROR;
1886     }
1887     *new_die = die;
1888     return DW_DLV_OK;
1889 }
1890 
1891 /*  New March 2016.
1892     Lets one cross check the abbreviations section and
1893     the DIE information presented  by dwarfdump -i -G -v. */
1894 int
dwarf_die_abbrev_global_offset(Dwarf_Die die,Dwarf_Off * abbrev_goffset,Dwarf_Unsigned * abbrev_count,Dwarf_Error * error)1895 dwarf_die_abbrev_global_offset(Dwarf_Die die,
1896     Dwarf_Off       * abbrev_goffset,
1897     Dwarf_Unsigned  * abbrev_count,
1898     Dwarf_Error*      error)
1899 {
1900     Dwarf_Abbrev_List dal = 0;
1901     Dwarf_Debug dbg = 0;
1902 
1903     CHECK_DIE(die, DW_DLV_ERROR);
1904     dbg = die->di_cu_context->cc_dbg;
1905     dal = die->di_abbrev_list;
1906     if(!dal) {
1907         _dwarf_error(dbg,error,DW_DLE_DWARF_ABBREV_NULL);
1908         return DW_DLV_ERROR;
1909     }
1910     *abbrev_goffset = dal->abl_goffset;
1911     *abbrev_count = dal->abl_count;
1912     return DW_DLV_OK;
1913 }
1914 
1915 
1916 /*  This is useful when printing DIE data.
1917     The string pointer returned must not be freed.
1918     With non-elf objects it is possible the
1919     string returned might be empty or NULL,
1920     so callers should be prepared for that kind
1921     of return. */
1922 int
dwarf_get_die_section_name(Dwarf_Debug dbg,Dwarf_Bool is_info,const char ** sec_name,Dwarf_Error * error)1923 dwarf_get_die_section_name(Dwarf_Debug dbg,
1924     Dwarf_Bool    is_info,
1925     const char ** sec_name,
1926     Dwarf_Error * error)
1927 {
1928     struct Dwarf_Section_s *sec = 0;
1929 
1930     if (dbg == NULL) {
1931         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
1932         return (DW_DLV_ERROR);
1933     }
1934     if (is_info) {
1935         sec = &dbg->de_debug_info;
1936     } else {
1937         sec = &dbg->de_debug_types;
1938     }
1939     if (sec->dss_size == 0) {
1940         /* We don't have such a  section at all. */
1941         return DW_DLV_NO_ENTRY;
1942     }
1943     *sec_name = sec->dss_name;
1944     return DW_DLV_OK;
1945 }
1946 
1947 /* This one assumes is_info not known to caller but a DIE is known. */
1948 int
dwarf_get_die_section_name_b(Dwarf_Die die,const char ** sec_name,Dwarf_Error * error)1949 dwarf_get_die_section_name_b(Dwarf_Die die,
1950     const char ** sec_name,
1951     Dwarf_Error * error)
1952 {
1953     Dwarf_CU_Context context = 0;
1954     Dwarf_Bool is_info = 0;
1955     Dwarf_Debug dbg = 0;
1956 
1957     CHECK_DIE(die, DW_DLV_ERROR);
1958     context = die->di_cu_context;
1959     dbg = context->cc_dbg;
1960     is_info = context->cc_is_info;
1961     return dwarf_get_die_section_name(dbg,is_info,sec_name,error);
1962 }
1963 
1964 
1965 
1966