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