• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Internal definitions for libdw.
2    Copyright (C) 2002-2011, 2013-2018 Red Hat, Inc.
3    This file is part of elfutils.
4 
5    This file is free software; you can redistribute it and/or modify
6    it under the terms of either
7 
8      * the GNU Lesser General Public License as published by the Free
9        Software Foundation; either version 3 of the License, or (at
10        your option) any later version
11 
12    or
13 
14      * the GNU General Public License as published by the Free
15        Software Foundation; either version 2 of the License, or (at
16        your option) any later version
17 
18    or both in parallel, as here.
19 
20    elfutils is distributed in the hope that it will be useful, but
21    WITHOUT ANY WARRANTY; without even the implied warranty of
22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23    General Public License for more details.
24 
25    You should have received copies of the GNU General Public License and
26    the GNU Lesser General Public License along with this program.  If
27    not, see <http://www.gnu.org/licenses/>.  */
28 
29 #ifndef _LIBDWP_H
30 #define _LIBDWP_H 1
31 
32 #include <libintl.h>
33 #include <stdbool.h>
34 
35 #include <libdw.h>
36 #include <dwarf.h>
37 
38 
39 /* gettext helper macros.  */
40 #define _(Str) dgettext ("elfutils", Str)
41 
42 
43 /* Known location expressions already decoded.  */
44 struct loc_s
45 {
46   void *addr;
47   Dwarf_Op *loc;
48   size_t nloc;
49 };
50 
51 /* Known DW_OP_implicit_value blocks already decoded.
52    This overlaps struct loc_s exactly, but only the
53    first member really has to match.  */
54 struct loc_block_s
55 {
56   void *addr;
57   unsigned char *data;
58   size_t length;
59 };
60 
61 /* Already decoded .debug_line units.  */
62 struct files_lines_s
63 {
64   Dwarf_Off debug_line_offset;
65   Dwarf_Files *files;
66   Dwarf_Lines *lines;
67 };
68 
69 /* Valid indeces for the section data.  */
70 enum
71   {
72     IDX_debug_info = 0,
73     IDX_debug_types,
74     IDX_debug_abbrev,
75     IDX_debug_aranges,
76     IDX_debug_addr,
77     IDX_debug_line,
78     IDX_debug_line_str,
79     IDX_debug_frame,
80     IDX_debug_loc,
81     IDX_debug_loclists,
82     IDX_debug_pubnames,
83     IDX_debug_str,
84     IDX_debug_str_offsets,
85     IDX_debug_macinfo,
86     IDX_debug_macro,
87     IDX_debug_ranges,
88     IDX_debug_rnglists,
89     IDX_gnu_debugaltlink,
90     IDX_last
91   };
92 
93 
94 /* Error values.  */
95 enum
96 {
97   DWARF_E_NOERROR = 0,
98   DWARF_E_UNKNOWN_ERROR,
99   DWARF_E_INVALID_ACCESS,
100   DWARF_E_NO_REGFILE,
101   DWARF_E_IO_ERROR,
102   DWARF_E_INVALID_ELF,
103   DWARF_E_NO_DWARF,
104   DWARF_E_COMPRESSED_ERROR,
105   DWARF_E_NOELF,
106   DWARF_E_GETEHDR_ERROR,
107   DWARF_E_NOMEM,
108   DWARF_E_UNIMPL,
109   DWARF_E_INVALID_CMD,
110   DWARF_E_INVALID_VERSION,
111   DWARF_E_INVALID_FILE,
112   DWARF_E_NO_ENTRY,
113   DWARF_E_INVALID_DWARF,
114   DWARF_E_NO_STRING,
115   DWARF_E_NO_DEBUG_STR,
116   DWARF_E_NO_DEBUG_LINE_STR,
117   DWARF_E_NO_STR_OFFSETS,
118   DWARF_E_NO_ADDR,
119   DWARF_E_NO_CONSTANT,
120   DWARF_E_NO_REFERENCE,
121   DWARF_E_INVALID_REFERENCE,
122   DWARF_E_NO_DEBUG_LINE,
123   DWARF_E_INVALID_DEBUG_LINE,
124   DWARF_E_TOO_BIG,
125   DWARF_E_VERSION,
126   DWARF_E_INVALID_DIR_IDX,
127   DWARF_E_ADDR_OUTOFRANGE,
128   DWARF_E_NO_DEBUG_LOC,
129   DWARF_E_NO_DEBUG_LOCLISTS,
130   DWARF_E_NO_LOC_VALUE,
131   DWARF_E_NO_BLOCK,
132   DWARF_E_INVALID_LINE_IDX,
133   DWARF_E_INVALID_ARANGE_IDX,
134   DWARF_E_NO_MATCH,
135   DWARF_E_NO_FLAG,
136   DWARF_E_INVALID_OFFSET,
137   DWARF_E_NO_DEBUG_RANGES,
138   DWARF_E_NO_DEBUG_RNGLISTS,
139   DWARF_E_INVALID_CFI,
140   DWARF_E_NO_ALT_DEBUGLINK,
141   DWARF_E_INVALID_OPCODE,
142   DWARF_E_NOT_CUDIE,
143   DWARF_E_UNKNOWN_LANGUAGE,
144   DWARF_E_NO_DEBUG_ADDR,
145 };
146 
147 
148 #include "dwarf_sig8_hash.h"
149 
150 /* This is the structure representing the debugging state.  */
151 struct Dwarf
152 {
153   /* The underlying ELF file.  */
154   Elf *elf;
155 
156   /* The (absolute) path to the ELF dir, if known.  To help locating
157      alt and dwo files.  */
158   char *debugdir;
159 
160   /* dwz alternate DWARF file.  */
161   Dwarf *alt_dwarf;
162 
163   /* The section data.  */
164   Elf_Data *sectiondata[IDX_last];
165 
166   /* True if the file has a byte order different from the host.  */
167   bool other_byte_order;
168 
169   /* If true, we allocated the ELF descriptor ourselves.  */
170   bool free_elf;
171 
172   /* If >= 0, we allocated the alt_dwarf ourselves and must end it and
173      close this file descriptor.  */
174   int alt_fd;
175 
176   /* Information for traversing the .debug_pubnames section.  This is
177      an array and separately allocated with malloc.  */
178   struct pubnames_s
179   {
180     Dwarf_Off cu_offset;
181     Dwarf_Off set_start;
182     unsigned int cu_header_size;
183     int address_len;
184   } *pubnames_sets;
185   size_t pubnames_nsets;
186 
187   /* Search tree for the CUs.  */
188   void *cu_tree;
189   Dwarf_Off next_cu_offset;
190 
191   /* Search tree and sig8 hash table for .debug_types type units.  */
192   void *tu_tree;
193   Dwarf_Off next_tu_offset;
194   Dwarf_Sig8_Hash sig8_hash;
195 
196   /* Search tree for split Dwarf associated with CUs in this debug.  */
197   void *split_tree;
198 
199   /* Search tree for .debug_macro operator tables.  */
200   void *macro_ops;
201 
202   /* Search tree for decoded .debug_line units.  */
203   void *files_lines;
204 
205   /* Address ranges.  */
206   Dwarf_Aranges *aranges;
207 
208   /* Cached info from the CFI section.  */
209   struct Dwarf_CFI_s *cfi;
210 
211   /* Fake loc CU.  Used when synthesizing attributes for Dwarf_Ops that
212      came from a location list entry in dwarf_getlocation_attr.
213      Depending on version this is the .debug_loc or .debug_loclists
214      section (could be both if mixing CUs with different DWARF versions).  */
215   struct Dwarf_CU *fake_loc_cu;
216   struct Dwarf_CU *fake_loclists_cu;
217 
218   /* Similar for addrx/constx, which will come from .debug_addr section.  */
219   struct Dwarf_CU *fake_addr_cu;
220 
221   /* Internal memory handling.  This is basically a simplified
222      reimplementation of obstacks.  Unfortunately the standard obstack
223      implementation is not usable in libraries.  */
224   struct libdw_memblock
225   {
226     size_t size;
227     size_t remaining;
228     struct libdw_memblock *prev;
229     char mem[0];
230   } *mem_tail;
231 
232   /* Default size of allocated memory blocks.  */
233   size_t mem_default_size;
234 
235   /* Registered OOM handler.  */
236   Dwarf_OOM oom_handler;
237 };
238 
239 
240 /* Abbreviation representation.  */
241 struct Dwarf_Abbrev
242 {
243   Dwarf_Off offset;	  /* Offset to start of abbrev into .debug_abbrev.  */
244   unsigned char *attrp;   /* Pointer to start of attribute name/form pairs. */
245   bool has_children : 1;  /* Whether or not the DIE has children. */
246   unsigned int code : 31; /* The (unique) abbrev code.  */
247   unsigned int tag;	  /* The tag of the DIE. */
248 } attribute_packed;
249 
250 #include "dwarf_abbrev_hash.h"
251 
252 
253 /* Files in line information records.  */
254 struct Dwarf_Files_s
255   {
256     unsigned int ndirs;
257     unsigned int nfiles;
258     struct Dwarf_Fileinfo_s
259     {
260       char *name;
261       Dwarf_Word mtime;
262       Dwarf_Word length;
263     } info[0];
264     /* nfiles of those, followed by char *[ndirs].  */
265   };
266 typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo;
267 
268 
269 /* Representation of a row in the line table.  */
270 
271 struct Dwarf_Line_s
272 {
273   Dwarf_Files *files;
274 
275   Dwarf_Addr addr;
276   unsigned int file;
277   int line;
278   unsigned short int column;
279   unsigned int is_stmt:1;
280   unsigned int basic_block:1;
281   unsigned int end_sequence:1;
282   unsigned int prologue_end:1;
283   unsigned int epilogue_begin:1;
284   /* The remaining bit fields are not flags, but hold values presumed to be
285      small.  All the flags and other bit fields should add up to 48 bits
286      to give the whole struct a nice round size.  */
287   unsigned int op_index:8;
288   unsigned int isa:8;
289   unsigned int discriminator:24;
290 };
291 
292 struct Dwarf_Lines_s
293 {
294   size_t nlines;
295   struct Dwarf_Line_s info[0];
296 };
297 
298 /* Representation of address ranges.  */
299 struct Dwarf_Aranges_s
300 {
301   Dwarf *dbg;
302   size_t naranges;
303 
304   struct Dwarf_Arange_s
305   {
306     Dwarf_Addr addr;
307     Dwarf_Word length;
308     Dwarf_Off offset;
309   } info[0];
310 };
311 
312 
313 /* CU representation.  */
314 struct Dwarf_CU
315 {
316   Dwarf *dbg;
317   Dwarf_Off start;
318   Dwarf_Off end;
319   uint8_t address_size;
320   uint8_t offset_size;
321   uint16_t version;
322 
323   size_t sec_idx; /* Normally .debug_info, could be .debug_type or "fake". */
324 
325   /* The unit type if version >= 5.  Otherwise 0 for normal CUs (from
326      .debug_info) or 1 for v4 type units (from .debug_types).  */
327   uint8_t unit_type;
328 
329   /* Zero if the unit type doesn't support a die/type offset and/or id/sig.
330      Nonzero if it is a v4 type unit or for DWARFv5 units depending on
331      unit_type.  */
332   size_t subdie_offset;
333   uint64_t unit_id8;
334 
335   /* If this is a skeleton unit this points to the split compile unit.
336      Or the other way around if this is a split compile unit.  Set to -1
337      if not yet searched.  Always use __libdw_find_split_unit to access
338      this field.  */
339   struct Dwarf_CU *split;
340 
341   /* Hash table for the abbreviations.  */
342   Dwarf_Abbrev_Hash abbrev_hash;
343   /* Offset of the first abbreviation.  */
344   size_t orig_abbrev_offset;
345   /* Offset past last read abbreviation.  */
346   size_t last_abbrev_offset;
347 
348   /* The srcline information.  */
349   Dwarf_Lines *lines;
350 
351   /* The source file information.  */
352   Dwarf_Files *files;
353 
354   /* Known location lists.  */
355   void *locs;
356 
357   /* Base address for use with ranges and locs.
358      Don't access directly, call __libdw_cu_base_address.  */
359   Dwarf_Addr base_address;
360 
361   /* The offset into the .debug_addr section where index zero begins.
362      Don't access directly, call __libdw_cu_addr_base.  */
363   Dwarf_Off addr_base;
364 
365   /* The offset into the .debug_str_offsets section where index zero begins.
366      Don't access directly, call __libdw_cu_str_off_base.  */
367   Dwarf_Off str_off_base;
368 
369   /* The offset into the .debug_ranges section to use for GNU
370      DebugFission split units.  Don't access directly, call
371      __libdw_cu_ranges_base.  */
372   Dwarf_Off ranges_base;
373 
374   /* The start of the offset table in .debug_loclists.
375      Don't access directly, call __libdw_cu_locs_base.  */
376   Dwarf_Off locs_base;
377 
378   /* Memory boundaries of this CU.  */
379   void *startp;
380   void *endp;
381 };
382 
383 #define ISV4TU(cu) ((cu)->version == 4 && (cu)->sec_idx == IDX_debug_types)
384 
385 /* Compute the offset of a CU's first DIE from the CU offset.
386    CU must be a valid/known version/unit_type.  */
387 static inline Dwarf_Off
__libdw_first_die_from_cu_start(Dwarf_Off cu_start,uint8_t offset_size,uint16_t version,uint8_t unit_type)388 __libdw_first_die_from_cu_start (Dwarf_Off cu_start,
389 				 uint8_t offset_size,
390 				 uint16_t version,
391 				 uint8_t unit_type)
392 {
393 /*
394   assert (offset_size == 4 || offset_size == 8);
395   assert (version >= 2 && version <= 5);
396   assert (unit_type == DW_UT_compile
397 	  || unit_type == DW_UT_partial
398 	  || unit_type == DW_UT_skeleton
399 	  || unit_type == DW_UT_split_compile
400 	  || unit_type == DW_UT_type
401 	  || unit_type == DW_UT_split_type);
402 */
403 
404   Dwarf_Off off = cu_start;
405   if (version < 5)
406     {
407    /*
408         LEN       VER     OFFSET    ADDR
409       4-bytes + 2-bytes + 4-bytes + 1-byte  for 32-bit dwarf
410      12-bytes + 2-bytes + 8-bytes + 1-byte  for 64-bit dwarf
411    or in .debug_types, 			     SIGNATURE TYPE-OFFSET
412       4-bytes + 2-bytes + 4-bytes + 1-byte + 8-bytes + 4-bytes  for 32-bit
413      12-bytes + 2-bytes + 8-bytes + 1-byte + 8-bytes + 8-bytes  for 64-bit
414 
415    Note the trick in the computation.  If the offset_size is 4
416    the '- 4' term changes the '3 *' (or '4 *') into a '2 *' (or '3 *).
417    If the offset_size is 8 it accounts for the 4-byte escape value
418    used at the start of the length.  */
419       if (unit_type != DW_UT_type)
420 	off += 3 * offset_size - 4 + 3;
421       else
422 	off += 4 * offset_size - 4 + 3 + 8;
423     }
424   else
425     {
426      /*
427         LEN       VER      TYPE     ADDR     OFFSET   SIGNATURE  TYPE-OFFSET
428       4-bytes + 2-bytes + 1-byte + 1-byte + 4-bytes + 8-bytes + 4-bytes 32-bit
429      12-bytes + 2-bytes + 1-byte + 1-byte + 8-bytes + 8-bytes + 8-bytes 64-bit
430         Both signature and type offset are optional.
431 
432         Note same 4/8 offset size trick as above.
433         We explicitly ignore unknow unit types (see asserts above).  */
434       off += 3 * offset_size - 4 + 4;
435       if (unit_type == DW_UT_skeleton || unit_type == DW_UT_split_compile
436 	  || unit_type == DW_UT_type || unit_type == DW_UT_split_type)
437 	{
438 	  off += 8;
439 	  if (unit_type == DW_UT_type || unit_type == DW_UT_split_type)
440 	    off += offset_size;
441 	}
442     }
443 
444   return off;
445 }
446 
447 static inline Dwarf_Off
__libdw_first_die_off_from_cu(struct Dwarf_CU * cu)448 __libdw_first_die_off_from_cu (struct Dwarf_CU *cu)
449 {
450   return __libdw_first_die_from_cu_start (cu->start,
451 					  cu->offset_size,
452 					  cu->version,
453 					  cu->unit_type);
454 }
455 
456 #define CUDIE(fromcu)							      \
457   ((Dwarf_Die)								      \
458    {									      \
459      .cu = (fromcu),							      \
460      .addr = ((char *) (fromcu)->dbg->sectiondata[cu_sec_idx (fromcu)]->d_buf \
461 	      + __libdw_first_die_off_from_cu (fromcu))			      \
462    })
463 
464 #define SUBDIE(fromcu)							      \
465   ((Dwarf_Die)								      \
466    {									      \
467      .cu = (fromcu),							      \
468      .addr = ((char *) (fromcu)->dbg->sectiondata[cu_sec_idx (fromcu)]->d_buf \
469 	      + (fromcu)->start + (fromcu)->subdie_offset)		      \
470    })
471 
472 
473 /* Prototype of a single .debug_macro operator.  */
474 typedef struct
475 {
476   Dwarf_Word nforms;
477   unsigned char const *forms;
478 } Dwarf_Macro_Op_Proto;
479 
480 /* Prototype table.  */
481 typedef struct
482 {
483   /* Offset of .debug_macro section.  */
484   Dwarf_Off offset;
485 
486   /* Offset of associated .debug_line section.  */
487   Dwarf_Off line_offset;
488 
489   /* The source file information.  */
490   Dwarf_Files *files;
491 
492   /* If this macro unit was opened through dwarf_getmacros or
493      dwarf_getmacros_die, this caches value of DW_AT_comp_dir, if
494      present.  */
495   const char *comp_dir;
496 
497   /* Header length.  */
498   Dwarf_Half header_len;
499 
500   uint16_t version;
501   bool is_64bit;
502   uint8_t sec_index;	/* IDX_debug_macro or IDX_debug_macinfo.  */
503 
504   /* Shows where in TABLE each opcode is defined.  Since opcode 0 is
505      never used, it stores index of opcode X in X-1'th element.  The
506      value of 0xff means not stored at all.  */
507   unsigned char opcodes[255];
508 
509   /* Individual opcode prototypes.  */
510   Dwarf_Macro_Op_Proto table[];
511 } Dwarf_Macro_Op_Table;
512 
513 struct Dwarf_Macro_s
514 {
515   Dwarf_Macro_Op_Table *table;
516   Dwarf_Attribute *attributes;
517   uint8_t opcode;
518 };
519 
520 static inline Dwarf_Word
libdw_macro_nforms(Dwarf_Macro * macro)521 libdw_macro_nforms (Dwarf_Macro *macro)
522 {
523   return macro->table->table[macro->table->opcodes[macro->opcode - 1]].nforms;
524 }
525 
526 /* Returns true for any allowed FORM in the opcode_operands_table as
527    mentioned in the DWARF5 spec (6.3.1 Macro Information Header).
528    Or those mentioned in DWARF5 spec (6.2.4.2 Vendor-defined Content
529    Descriptions) for the directory/file table (plus DW_FORM_strp_sup).  */
530 static inline bool
libdw_valid_user_form(int form)531 libdw_valid_user_form (int form)
532 {
533   switch (form)
534     {
535       case DW_FORM_block:
536       case DW_FORM_block1:
537       case DW_FORM_block2:
538       case DW_FORM_block4:
539       case DW_FORM_data1:
540       case DW_FORM_data2:
541       case DW_FORM_data4:
542       case DW_FORM_data8:
543       case DW_FORM_data16:
544       case DW_FORM_flag:
545       case DW_FORM_line_strp:
546       case DW_FORM_sdata:
547       case DW_FORM_sec_offset:
548       case DW_FORM_string:
549       case DW_FORM_strp:
550       case DW_FORM_strp_sup:
551       case DW_FORM_strx:
552       case DW_FORM_strx1:
553       case DW_FORM_strx2:
554       case DW_FORM_strx3:
555       case DW_FORM_strx4:
556       case DW_FORM_udata:
557 	return true;
558       default:
559 	return false;
560     }
561 }
562 
563 
564 /* We have to include the file at this point because the inline
565    functions access internals of the Dwarf structure.  */
566 #include "memory-access.h"
567 
568 
569 /* Set error value.  */
570 extern void __libdw_seterrno (int value) internal_function;
571 
572 
573 /* Memory handling, the easy parts.  This macro does not do any locking.  */
574 #define libdw_alloc(dbg, type, tsize, cnt) \
575   ({ struct libdw_memblock *_tail = (dbg)->mem_tail;			      \
576      size_t _required = (tsize) * (cnt);				      \
577      type *_result = (type *) (_tail->mem + (_tail->size - _tail->remaining));\
578      size_t _padding = ((__alignof (type)				      \
579 			 - ((uintptr_t) _result & (__alignof (type) - 1)))    \
580 			& (__alignof (type) - 1));			      \
581      if (unlikely (_tail->remaining < _required + _padding))		      \
582        _result = (type *) __libdw_allocate (dbg, _required, __alignof (type));\
583      else								      \
584        {								      \
585 	 _required += _padding;						      \
586 	 _result = (type *) ((char *) _result + _padding);		      \
587 	 _tail->remaining -= _required;					      \
588        }								      \
589      _result; })
590 
591 #define libdw_typed_alloc(dbg, type) \
592   libdw_alloc (dbg, type, sizeof (type), 1)
593 
594 /* Callback to allocate more.  */
595 extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align)
596      __attribute__ ((__malloc__)) __nonnull_attribute__ (1);
597 
598 /* Default OOM handler.  */
599 extern void __libdw_oom (void) __attribute ((noreturn)) attribute_hidden;
600 
601 /* Read next unit (or v4 debug type) and return next offset.  Doesn't
602    create an actual Dwarf_CU just provides necessary header fields.  */
603 extern int
604 internal_function
605 __libdw_next_unit (Dwarf *dbg, bool v4_debug_types, Dwarf_Off off,
606 		   Dwarf_Off *next_off, size_t *header_sizep,
607 		   Dwarf_Half *versionp, uint8_t *unit_typep,
608 		   Dwarf_Off *abbrev_offsetp, uint8_t *address_sizep,
609 		   uint8_t *offset_sizep, uint64_t *unit_id8p,
610 		   Dwarf_Off *subdie_offsetp)
611      __nonnull_attribute__ (4) internal_function;
612 
613 /* Allocate the internal data for a unit not seen before.  */
614 extern struct Dwarf_CU *__libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
615      __nonnull_attribute__ (1) internal_function;
616 
617 /* Find CU for given offset.  */
618 extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset, bool tu)
619      __nonnull_attribute__ (1) internal_function;
620 
621 /* Find CU for given DIE address.  */
622 extern struct Dwarf_CU *__libdw_findcu_addr (Dwarf *dbg, void *addr)
623      __nonnull_attribute__ (1) internal_function;
624 
625 /* Find split Dwarf for given DIE address.  */
626 extern struct Dwarf *__libdw_find_split_dbg_addr (Dwarf *dbg, void *addr)
627      __nonnull_attribute__ (1) internal_function;
628 
629 /* Find the split (or skeleton) unit.  */
630 extern struct Dwarf_CU *__libdw_find_split_unit (Dwarf_CU *cu)
631      internal_function;
632 
633 /* Get abbreviation with given code.  */
634 extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu,
635 					 unsigned int code)
636      __nonnull_attribute__ (1) internal_function;
637 
638 /* Get abbreviation at given offset.  */
639 extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu,
640 					Dwarf_Off offset, size_t *lengthp,
641 					Dwarf_Abbrev *result)
642      __nonnull_attribute__ (1) internal_function;
643 
644 /* Get abbreviation of given DIE, and optionally set *READP to the DIE memory
645    just past the abbreviation code.  */
646 static inline Dwarf_Abbrev *
647 __nonnull_attribute__ (1)
__libdw_dieabbrev(Dwarf_Die * die,const unsigned char ** readp)648 __libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp)
649 {
650   /* Do we need to get the abbreviation, or need to read after the code?  */
651   if (die->abbrev == NULL || readp != NULL)
652     {
653       /* Get the abbreviation code.  */
654       unsigned int code;
655       const unsigned char *addr = die->addr;
656       if (unlikely (die->cu == NULL
657 		    || addr >= (const unsigned char *) die->cu->endp))
658 	return die->abbrev = DWARF_END_ABBREV;
659       get_uleb128 (code, addr, die->cu->endp);
660       if (readp != NULL)
661 	*readp = addr;
662 
663       /* Find the abbreviation.  */
664       if (die->abbrev == NULL)
665 	die->abbrev = __libdw_findabbrev (die->cu, code);
666     }
667   return die->abbrev;
668 }
669 
670 /* Helper functions for form handling.  */
671 extern size_t __libdw_form_val_compute_len (struct Dwarf_CU *cu,
672 					    unsigned int form,
673 					    const unsigned char *valp)
674      __nonnull_attribute__ (1, 3) internal_function;
675 
676 /* Find the length of a form attribute in DIE/info data.  */
677 static inline size_t
678 __nonnull_attribute__ (1, 3)
__libdw_form_val_len(struct Dwarf_CU * cu,unsigned int form,const unsigned char * valp)679 __libdw_form_val_len (struct Dwarf_CU *cu, unsigned int form,
680 		      const unsigned char *valp)
681 {
682   /* Small lookup table of forms with fixed lengths.  Absent indexes are
683      initialized 0, so any truly desired 0 is set to 0x80 and masked.  */
684   static const uint8_t form_lengths[] =
685     {
686       [DW_FORM_flag_present] = 0x80,
687       [DW_FORM_implicit_const] = 0x80, /* Value is in abbrev, not in info.  */
688 
689       [DW_FORM_flag] = 1,
690       [DW_FORM_data1] = 1, [DW_FORM_ref1] = 1,
691       [DW_FORM_addrx1] = 1, [DW_FORM_strx1] = 1,
692 
693       [DW_FORM_data2] = 2, [DW_FORM_ref2] = 2,
694       [DW_FORM_addrx2] = 2, [DW_FORM_strx2] = 2,
695 
696       [DW_FORM_addrx3] = 3, [DW_FORM_strx3] = 3,
697 
698       [DW_FORM_data4] = 4, [DW_FORM_ref4] = 4, [DW_FORM_ref_sup4] = 4,
699       [DW_FORM_addrx4] = 4, [DW_FORM_strx4] = 4,
700 
701       [DW_FORM_ref_sig8] = 8,
702       [DW_FORM_data8] = 8, [DW_FORM_ref8] = 8, [DW_FORM_ref_sup8] = 8,
703 
704       [DW_FORM_data16] = 16,
705     };
706 
707   /* Return immediately for forms with fixed lengths.  */
708   if (form < sizeof form_lengths / sizeof form_lengths[0])
709     {
710       uint8_t len = form_lengths[form];
711       if (len != 0)
712 	{
713 	  const unsigned char *endp = cu->endp;
714 	  len &= 0x7f; /* Mask to allow 0x80 -> 0.  */
715 	  if (unlikely (len > (size_t) (endp - valp)))
716 	    {
717 	      __libdw_seterrno (DWARF_E_INVALID_DWARF);
718 	      return -1;
719 	    }
720 	  return len;
721 	}
722     }
723 
724   /* Other forms require some computation.  */
725   return __libdw_form_val_compute_len (cu, form, valp);
726 }
727 
728 /* Helper function for DW_FORM_ref* handling.  */
729 extern int __libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset)
730      __nonnull_attribute__ (1, 2) internal_function;
731 
732 
733 /* Helper function to locate attribute.  */
734 extern unsigned char *__libdw_find_attr (Dwarf_Die *die,
735 					 unsigned int search_name,
736 					 unsigned int *codep,
737 					 unsigned int *formp)
738      __nonnull_attribute__ (1) internal_function;
739 
740 /* Helper function to access integer attribute.  */
741 extern int __libdw_attr_intval (Dwarf_Die *die, int *valp, int attval)
742      __nonnull_attribute__ (1, 2) internal_function;
743 
744 /* Helper function to walk scopes.  */
745 struct Dwarf_Die_Chain
746 {
747   Dwarf_Die die;
748   struct Dwarf_Die_Chain *parent;
749   bool prune;			/* The PREVISIT function can set this.  */
750 };
751 extern int __libdw_visit_scopes (unsigned int depth,
752 				 struct Dwarf_Die_Chain *root,
753 				 struct Dwarf_Die_Chain *imports,
754 				 int (*previsit) (unsigned int depth,
755 						  struct Dwarf_Die_Chain *,
756 						  void *arg),
757 				 int (*postvisit) (unsigned int depth,
758 						   struct Dwarf_Die_Chain *,
759 						   void *arg),
760 				 void *arg)
761   __nonnull_attribute__ (2, 4) internal_function;
762 
763 /* Parse a DWARF Dwarf_Block into an array of Dwarf_Op's,
764    and cache the result (via tsearch).  */
765 extern int __libdw_intern_expression (Dwarf *dbg,
766 				      bool other_byte_order,
767 				      unsigned int address_size,
768 				      unsigned int ref_size,
769 				      void **cache, const Dwarf_Block *block,
770 				      bool cfap, bool valuep,
771 				      Dwarf_Op **llbuf, size_t *listlen,
772 				      int sec_index)
773   __nonnull_attribute__ (5, 6, 9, 10) internal_function;
774 
775 extern Dwarf_Die *__libdw_offdie (Dwarf *dbg, Dwarf_Off offset,
776 				  Dwarf_Die *result, bool debug_types)
777   internal_function;
778 
779 
780 /* Return error code of last failing function call.  This value is kept
781    separately for each thread.  */
782 extern int __dwarf_errno_internal (void);
783 
784 
785 /* Reader hooks.  */
786 
787 /* Relocation hooks return -1 on error (in that case the error code
788    must already have been set), 0 if there is no relocation and 1 if a
789    relocation was present.*/
790 
791 static inline int
__libdw_relocate_address(Dwarf * dbg,int sec_index,const void * addr,int width,Dwarf_Addr * val)792 __libdw_relocate_address (Dwarf *dbg __attribute__ ((unused)),
793 			  int sec_index __attribute__ ((unused)),
794 			  const void *addr __attribute__ ((unused)),
795 			  int width __attribute__ ((unused)),
796 			  Dwarf_Addr *val __attribute__ ((unused)))
797 {
798   return 0;
799 }
800 
801 static inline int
__libdw_relocate_offset(Dwarf * dbg,int sec_index,const void * addr,int width,Dwarf_Off * val)802 __libdw_relocate_offset (Dwarf *dbg __attribute__ ((unused)),
803 			 int sec_index __attribute__ ((unused)),
804 			 const void *addr __attribute__ ((unused)),
805 			 int width __attribute__ ((unused)),
806 			 Dwarf_Off *val __attribute__ ((unused)))
807 {
808   return 0;
809 }
810 
811 static inline Elf_Data *
__libdw_checked_get_data(Dwarf * dbg,int sec_index)812 __libdw_checked_get_data (Dwarf *dbg, int sec_index)
813 {
814   Elf_Data *data = dbg->sectiondata[sec_index];
815   if (unlikely (data == NULL)
816       || unlikely (data->d_buf == NULL))
817     {
818       __libdw_seterrno (DWARF_E_INVALID_DWARF);
819       return NULL;
820     }
821   return data;
822 }
823 
824 static inline int
__libdw_offset_in_section(Dwarf * dbg,int sec_index,Dwarf_Off offset,size_t size)825 __libdw_offset_in_section (Dwarf *dbg, int sec_index,
826 			   Dwarf_Off offset, size_t size)
827 {
828   Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
829   if (data == NULL)
830     return -1;
831   if (unlikely (offset > data->d_size)
832       || unlikely (data->d_size < size)
833       || unlikely (offset > data->d_size - size))
834     {
835       __libdw_seterrno (DWARF_E_INVALID_OFFSET);
836       return -1;
837     }
838 
839   return 0;
840 }
841 
842 static inline bool
__libdw_in_section(Dwarf * dbg,int sec_index,const void * addr,size_t size)843 __libdw_in_section (Dwarf *dbg, int sec_index,
844 		    const void *addr, size_t size)
845 {
846   Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
847   if (data == NULL)
848     return false;
849   if (unlikely (addr < data->d_buf)
850       || unlikely (data->d_size < size)
851       || unlikely ((size_t)(addr - data->d_buf) > data->d_size - size))
852     {
853       __libdw_seterrno (DWARF_E_INVALID_OFFSET);
854       return false;
855     }
856 
857   return true;
858 }
859 
860 #define READ_AND_RELOCATE(RELOC_HOOK, VAL)				\
861   ({									\
862     if (!__libdw_in_section (dbg, sec_index, addr, width))		\
863       return -1;							\
864 									\
865     const unsigned char *orig_addr = addr;				\
866     if (width == 4)							\
867       VAL = read_4ubyte_unaligned_inc (dbg, addr);			\
868     else								\
869       VAL = read_8ubyte_unaligned_inc (dbg, addr);			\
870 									\
871     int status = RELOC_HOOK (dbg, sec_index, orig_addr, width, &VAL);	\
872     if (status < 0)							\
873       return status;							\
874     status > 0;								\
875    })
876 
877 static inline int
__libdw_read_address_inc(Dwarf * dbg,int sec_index,const unsigned char ** addrp,int width,Dwarf_Addr * ret)878 __libdw_read_address_inc (Dwarf *dbg,
879 			  int sec_index, const unsigned char **addrp,
880 			  int width, Dwarf_Addr *ret)
881 {
882   const unsigned char *addr = *addrp;
883   READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
884   *addrp = addr;
885   return 0;
886 }
887 
888 static inline int
__libdw_read_address(Dwarf * dbg,int sec_index,const unsigned char * addr,int width,Dwarf_Addr * ret)889 __libdw_read_address (Dwarf *dbg,
890 		      int sec_index, const unsigned char *addr,
891 		      int width, Dwarf_Addr *ret)
892 {
893   READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
894   return 0;
895 }
896 
897 static inline int
__libdw_read_offset_inc(Dwarf * dbg,int sec_index,const unsigned char ** addrp,int width,Dwarf_Off * ret,int sec_ret,size_t size)898 __libdw_read_offset_inc (Dwarf *dbg,
899 			 int sec_index, const unsigned char **addrp,
900 			 int width, Dwarf_Off *ret, int sec_ret,
901 			 size_t size)
902 {
903   const unsigned char *addr = *addrp;
904   READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
905   *addrp = addr;
906   return __libdw_offset_in_section (dbg, sec_ret, *ret, size);
907 }
908 
909 static inline int
__libdw_read_offset(Dwarf * dbg,Dwarf * dbg_ret,int sec_index,const unsigned char * addr,int width,Dwarf_Off * ret,int sec_ret,size_t size)910 __libdw_read_offset (Dwarf *dbg, Dwarf *dbg_ret,
911 		     int sec_index, const unsigned char *addr,
912 		     int width, Dwarf_Off *ret, int sec_ret,
913 		     size_t size)
914 {
915   READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
916   return __libdw_offset_in_section (dbg_ret, sec_ret, *ret, size);
917 }
918 
919 static inline size_t
cu_sec_idx(struct Dwarf_CU * cu)920 cu_sec_idx (struct Dwarf_CU *cu)
921 {
922   return cu->sec_idx;
923 }
924 
925 static inline bool
is_cudie(Dwarf_Die * cudie)926 is_cudie (Dwarf_Die *cudie)
927 {
928   return cudie->cu != NULL && CUDIE (cudie->cu).addr == cudie->addr;
929 }
930 
931 /* Read up begin/end pair and increment read pointer.
932     - If it's normal range record, set up *BEGINP and *ENDP and return 0.
933     - If it's base address selection record, set up *BASEP and return 1.
934     - If it's end of rangelist, don't set anything and return 2
935     - If an error occurs, don't set anything and return <0.  */
936 int __libdw_read_begin_end_pair_inc (Dwarf_CU *cu, int sec_index,
937 				     const unsigned char **readp,
938 				     const unsigned char *readend,
939 				     int width,
940 				     Dwarf_Addr *beginp, Dwarf_Addr *endp,
941 				     Dwarf_Addr *basep)
942   internal_function;
943 
944 const unsigned char * __libdw_formptr (Dwarf_Attribute *attr, int sec_index,
945 				       int err_nodata,
946 				       const unsigned char **endpp,
947 				       Dwarf_Off *offsetp)
948   internal_function;
949 
950 /* Fills in the given attribute to point at an empty location expression.  */
951 void __libdw_empty_loc_attr (Dwarf_Attribute *attr)
952   internal_function;
953 
954 /* Load .debug_line unit at DEBUG_LINE_OFFSET.  COMP_DIR is a value of
955    DW_AT_comp_dir or NULL if that attribute is not available.  Caches
956    the loaded unit and optionally set *LINESP and/or *FILESP (if not
957    NULL) with loaded information.  Returns 0 for success or a negative
958    value for failure.  */
959 int __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
960 			 const char *comp_dir, unsigned address_size,
961 			 Dwarf_Lines **linesp, Dwarf_Files **filesp)
962   internal_function
963   __nonnull_attribute__ (1);
964 
965 /* Load and return value of DW_AT_comp_dir from CUDIE.  */
966 const char *__libdw_getcompdir (Dwarf_Die *cudie);
967 
968 /* Get the base address for the CU, fetches it when not yet set.
969    This is used as initial base address for ranges and loclists.  */
970 Dwarf_Addr __libdw_cu_base_address (Dwarf_CU *cu);
971 
972 /* Get the address base for the CU, fetches it when not yet set.  */
973 static inline Dwarf_Off
__libdw_cu_addr_base(Dwarf_CU * cu)974 __libdw_cu_addr_base (Dwarf_CU *cu)
975 {
976   if (cu->addr_base == (Dwarf_Off) -1)
977     {
978       Dwarf_Die cu_die = CUDIE(cu);
979       Dwarf_Attribute attr;
980       Dwarf_Off offset = 0;
981       if (dwarf_attr (&cu_die, DW_AT_GNU_addr_base, &attr) != NULL
982 	  || dwarf_attr (&cu_die, DW_AT_addr_base, &attr) != NULL)
983 	{
984 	  Dwarf_Word off;
985 	  if (dwarf_formudata (&attr, &off) == 0)
986 	    offset = off;
987 	}
988       cu->addr_base = offset;
989     }
990 
991   return cu->addr_base;
992 }
993 
994 /* Gets the .debug_str_offsets base offset to use.  static inline to
995    be shared between libdw and eu-readelf.  */
996 static inline Dwarf_Off
str_offsets_base_off(Dwarf * dbg,Dwarf_CU * cu)997 str_offsets_base_off (Dwarf *dbg, Dwarf_CU *cu)
998 {
999   /* If we don't have a CU, then find and use the first one in the
1000      debug file (when we support .dwp files, we must actually find the
1001      one matching our "caller" - aka macro or line).  If we (now) have
1002      a cu and str_offsets_base attribute, just use that.  Otherwise
1003      use the first offset.  But we might have to parse the header
1004      first, but only if this is version 5.  Assume if all else fails,
1005      this is version 4, without header.  */
1006 
1007   if (cu == NULL && dbg != NULL)
1008     {
1009       Dwarf_CU *first_cu;
1010       if (dwarf_get_units (dbg, NULL, &first_cu,
1011 			   NULL, NULL, NULL, NULL) == 0)
1012 	cu = first_cu;
1013     }
1014 
1015   if (cu != NULL)
1016     {
1017       if (cu->str_off_base == (Dwarf_Off) -1)
1018 	{
1019 	  Dwarf_Die cu_die = CUDIE(cu);
1020 	  Dwarf_Attribute attr;
1021 	  if (dwarf_attr (&cu_die, DW_AT_str_offsets_base, &attr) != NULL)
1022 	    {
1023 	      Dwarf_Word off;
1024 	      if (dwarf_formudata (&attr, &off) == 0)
1025 		{
1026 		  cu->str_off_base = off;
1027 		  return cu->str_off_base;
1028 		}
1029 	    }
1030 	  /* For older DWARF simply assume zero (no header).  */
1031 	  if (cu->version < 5)
1032 	    {
1033 	      cu->str_off_base = 0;
1034 	      return cu->str_off_base;
1035 	    }
1036 
1037 	  if (dbg == NULL)
1038 	    dbg = cu->dbg;
1039 	}
1040       else
1041 	return cu->str_off_base;
1042     }
1043 
1044   /* No str_offsets_base attribute, we have to assume "zero".
1045      But there could be a header first.  */
1046   Dwarf_Off off = 0;
1047   if (dbg == NULL)
1048     goto no_header;
1049 
1050   Elf_Data *data =  dbg->sectiondata[IDX_debug_str_offsets];
1051   if (data == NULL)
1052     goto no_header;
1053 
1054   const unsigned char *start;
1055   const unsigned char *readp;
1056   const unsigned char *readendp;
1057   start = readp = (const unsigned char *) data->d_buf;
1058   readendp = (const unsigned char *) data->d_buf + data->d_size;
1059 
1060   uint64_t unit_length;
1061   uint16_t version;
1062 
1063   unit_length = read_4ubyte_unaligned_inc (dbg, readp);
1064   if (unlikely (unit_length == 0xffffffff))
1065     {
1066       if (unlikely (readendp - readp < 8))
1067 	goto no_header;
1068       unit_length = read_8ubyte_unaligned_inc (dbg, readp);
1069       /* In theory the offset size could be different
1070 	 between CU and str_offsets unit.  But we just
1071 	 ignore that here. */
1072     }
1073 
1074   /* We need at least 2-bytes (version) + 2-bytes (padding) =
1075      4 bytes to complete the header.  And this unit cannot go
1076      beyond the section data.  */
1077   if (readendp - readp < 4
1078       || unit_length < 4
1079       || (uint64_t) (readendp - readp) < unit_length)
1080     goto no_header;
1081 
1082   version = read_2ubyte_unaligned_inc (dbg, readp);
1083   if (version != 5)
1084     goto no_header;
1085   /* padding */
1086   read_2ubyte_unaligned_inc (dbg, readp);
1087 
1088   off = (Dwarf_Off) (readp - start);
1089 
1090  no_header:
1091   if (cu != NULL)
1092     cu->str_off_base = off;
1093 
1094   return off;
1095 }
1096 
1097 
1098 /* Get the string offsets base for the CU, fetches it when not yet set.  */
__libdw_cu_str_off_base(Dwarf_CU * cu)1099 static inline Dwarf_Off __libdw_cu_str_off_base (Dwarf_CU *cu)
1100 {
1101   return str_offsets_base_off (NULL, cu);
1102 }
1103 
1104 
1105 /* Either a direct offset into .debug_ranges for version < 5, or the
1106    start of the offset table in .debug_rnglists for version > 5.  */
1107 static inline Dwarf_Off
__libdw_cu_ranges_base(Dwarf_CU * cu)1108 __libdw_cu_ranges_base (Dwarf_CU *cu)
1109 {
1110   if (cu->ranges_base == (Dwarf_Off) -1)
1111     {
1112       Dwarf_Off offset = 0;
1113       Dwarf_Die cu_die = CUDIE(cu);
1114       Dwarf_Attribute attr;
1115       if (cu->version < 5)
1116 	{
1117 	  if (dwarf_attr (&cu_die, DW_AT_GNU_ranges_base, &attr) != NULL)
1118 	    {
1119 	      Dwarf_Word off;
1120 	      if (dwarf_formudata (&attr, &off) == 0)
1121 		offset = off;
1122 	    }
1123 	}
1124       else
1125 	{
1126 	  if (dwarf_attr (&cu_die, DW_AT_rnglists_base, &attr) != NULL)
1127 	    {
1128 	      Dwarf_Word off;
1129 	      if (dwarf_formudata (&attr, &off) == 0)
1130 		offset = off;
1131 	    }
1132 
1133 	  /* There wasn't an rnglists_base, if the Dwarf does have a
1134 	     .debug_rnglists section, then it might be we need the
1135 	     base after the first header. */
1136 	  Elf_Data *data = cu->dbg->sectiondata[IDX_debug_rnglists];
1137 	  if (offset == 0 && data != NULL)
1138 	    {
1139 	      Dwarf *dbg = cu->dbg;
1140 	      const unsigned char *readp = data->d_buf;
1141 	      const unsigned char *const dataend
1142 		= (unsigned char *) data->d_buf + data->d_size;
1143 
1144 	      uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
1145 	      unsigned int offset_size = 4;
1146 	      if (unlikely (unit_length == 0xffffffff))
1147 		{
1148 		  if (unlikely (readp > dataend - 8))
1149 		    goto no_header;
1150 
1151 		  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
1152 		  offset_size = 8;
1153 		}
1154 
1155 	      if (readp > dataend - 8
1156 		  || unit_length < 8
1157 		  || unit_length > (uint64_t) (dataend - readp))
1158 		goto no_header;
1159 
1160 	      uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
1161 	      if (version != 5)
1162 		goto no_header;
1163 
1164 	      uint8_t address_size = *readp++;
1165 	      if (address_size != 4 && address_size != 8)
1166 		goto no_header;
1167 
1168 	      uint8_t segment_size = *readp++;
1169 	      if (segment_size != 0)
1170 		goto no_header;
1171 
1172 	      uint32_t offset_entry_count;
1173 	      offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
1174 
1175 	      const unsigned char *offset_array_start = readp;
1176 	      if (offset_entry_count <= 0)
1177 		goto no_header;
1178 
1179 	      uint64_t needed = offset_entry_count * offset_size;
1180 	      if (unit_length - 8 < needed)
1181 		goto no_header;
1182 
1183 	      offset = (Dwarf_Off) (offset_array_start
1184 				    - (unsigned char *) data->d_buf);
1185 	    }
1186 	}
1187     no_header:
1188       cu->ranges_base = offset;
1189     }
1190 
1191   return cu->ranges_base;
1192 }
1193 
1194 
1195 /* The start of the offset table in .debug_loclists for DWARF5.  */
1196 static inline Dwarf_Off
__libdw_cu_locs_base(Dwarf_CU * cu)1197 __libdw_cu_locs_base (Dwarf_CU *cu)
1198 {
1199   if (cu->locs_base == (Dwarf_Off) -1)
1200     {
1201       Dwarf_Off offset = 0;
1202       Dwarf_Die cu_die = CUDIE(cu);
1203       Dwarf_Attribute attr;
1204       if (dwarf_attr (&cu_die, DW_AT_loclists_base, &attr) != NULL)
1205 	{
1206 	  Dwarf_Word off;
1207 	  if (dwarf_formudata (&attr, &off) == 0)
1208 	    offset = off;
1209 	}
1210 
1211       /* There wasn't an loclists_base, if the Dwarf does have a
1212 	 .debug_loclists section, then it might be we need the
1213 	 base after the first header. */
1214       Elf_Data *data = cu->dbg->sectiondata[IDX_debug_loclists];
1215       if (offset == 0 && data != NULL)
1216 	{
1217 	  Dwarf *dbg = cu->dbg;
1218 	  const unsigned char *readp = data->d_buf;
1219 	  const unsigned char *const dataend
1220 	    = (unsigned char *) data->d_buf + data->d_size;
1221 
1222 	  uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
1223 	  unsigned int offset_size = 4;
1224 	  if (unlikely (unit_length == 0xffffffff))
1225 	    {
1226 	      if (unlikely (readp > dataend - 8))
1227 		goto no_header;
1228 
1229 	      unit_length = read_8ubyte_unaligned_inc (dbg, readp);
1230 	      offset_size = 8;
1231 	    }
1232 
1233 	  if (readp > dataend - 8
1234 	      || unit_length < 8
1235 	      || unit_length > (uint64_t) (dataend - readp))
1236 	    goto no_header;
1237 
1238 	  uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
1239 	  if (version != 5)
1240 	    goto no_header;
1241 
1242 	  uint8_t address_size = *readp++;
1243 	  if (address_size != 4 && address_size != 8)
1244 	    goto no_header;
1245 
1246 	  uint8_t segment_size = *readp++;
1247 	  if (segment_size != 0)
1248 	    goto no_header;
1249 
1250 	  uint32_t offset_entry_count;
1251 	  offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
1252 
1253 	  const unsigned char *offset_array_start = readp;
1254 	  if (offset_entry_count <= 0)
1255 	    goto no_header;
1256 
1257 	  uint64_t needed = offset_entry_count * offset_size;
1258 	  if (unit_length - 8 < needed)
1259 	    goto no_header;
1260 
1261 	  offset = (Dwarf_Off) (offset_array_start
1262 				- (unsigned char *) data->d_buf);
1263 	}
1264 
1265     no_header:
1266       cu->locs_base = offset;
1267     }
1268 
1269   return cu->locs_base;
1270 }
1271 
1272 /* Helper function for tsearch/tfind split_tree Dwarf.  */
1273 int __libdw_finddbg_cb (const void *arg1, const void *arg2);
1274 
1275 /* Link skeleton and split compile units.  */
1276 static inline void
__libdw_link_skel_split(Dwarf_CU * skel,Dwarf_CU * split)1277 __libdw_link_skel_split (Dwarf_CU *skel, Dwarf_CU *split)
1278 {
1279   skel->split = split;
1280   split->split = skel;
1281 
1282   /* Get .debug_addr and addr_base greedy.
1283      We also need it for the fake addr cu.
1284      There is only one per split debug.  */
1285   Dwarf *dbg = skel->dbg;
1286   Dwarf *sdbg = split->dbg;
1287   if (sdbg->sectiondata[IDX_debug_addr] == NULL
1288       && dbg->sectiondata[IDX_debug_addr] != NULL)
1289     {
1290       sdbg->sectiondata[IDX_debug_addr]
1291 	= dbg->sectiondata[IDX_debug_addr];
1292       split->addr_base = __libdw_cu_addr_base (skel);
1293       sdbg->fake_addr_cu = dbg->fake_addr_cu;
1294     }
1295 }
1296 
1297 
1298 /* Given an address index for a CU return the address.
1299    Returns -1 and sets libdw_errno if an error occurs.  */
1300 int __libdw_addrx (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr);
1301 
1302 
1303 /* Helper function to set debugdir field in Dwarf, used from dwarf_begin_elf
1304    and libdwfl process_file.  */
1305 char * __libdw_debugdir (int fd);
1306 
1307 
1308 /* Given the directory of a debug file, an absolute or relative dir
1309    to look in, and file returns a full path.
1310 
1311    If the file is absolute (starts with a /) a copy of file is returned.
1312    the file isn't absolute, but dir is absolute, then a path that is
1313    the concatenation of dir and file is returned.  If neither file,
1314    nor dir is absolute, the path will be constructed using dir (if not
1315    NULL) and file relative to the debugdir (if valid).
1316 
1317    The debugdir and the dir may be NULL (in which case they aren't used).
1318    If file is NULL, or no full path can be constructed NULL is returned.
1319 
1320    The caller is responsible for freeing the result if not NULL.  */
1321 char * __libdw_filepath (const char *debugdir, const char *dir,
1322 			 const char *file)
1323   internal_function;
1324 
1325 
1326 /* Aliases to avoid PLTs.  */
1327 INTDECL (dwarf_aggregate_size)
1328 INTDECL (dwarf_attr)
1329 INTDECL (dwarf_attr_integrate)
1330 INTDECL (dwarf_begin)
1331 INTDECL (dwarf_begin_elf)
1332 INTDECL (dwarf_child)
1333 INTDECL (dwarf_default_lower_bound)
1334 INTDECL (dwarf_dieoffset)
1335 INTDECL (dwarf_diename)
1336 INTDECL (dwarf_end)
1337 INTDECL (dwarf_entrypc)
1338 INTDECL (dwarf_errmsg)
1339 INTDECL (dwarf_formaddr)
1340 INTDECL (dwarf_formblock)
1341 INTDECL (dwarf_formref_die)
1342 INTDECL (dwarf_formsdata)
1343 INTDECL (dwarf_formstring)
1344 INTDECL (dwarf_formudata)
1345 INTDECL (dwarf_getabbrevattr_data)
1346 INTDECL (dwarf_getalt)
1347 INTDECL (dwarf_getarange_addr)
1348 INTDECL (dwarf_getarangeinfo)
1349 INTDECL (dwarf_getaranges)
1350 INTDECL (dwarf_getlocation_die)
1351 INTDECL (dwarf_getsrcfiles)
1352 INTDECL (dwarf_getsrclines)
1353 INTDECL (dwarf_hasattr)
1354 INTDECL (dwarf_haschildren)
1355 INTDECL (dwarf_haspc)
1356 INTDECL (dwarf_highpc)
1357 INTDECL (dwarf_lowpc)
1358 INTDECL (dwarf_nextcu)
1359 INTDECL (dwarf_next_unit)
1360 INTDECL (dwarf_offdie)
1361 INTDECL (dwarf_peel_type)
1362 INTDECL (dwarf_ranges)
1363 INTDECL (dwarf_setalt)
1364 INTDECL (dwarf_siblingof)
1365 INTDECL (dwarf_srclang)
1366 INTDECL (dwarf_tag)
1367 
1368 #endif	/* libdwP.h */
1369