• Home
  • History
  • Annotate
  • 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