Home | History | Annotate | Download | only in libdw
      1 /* Internal definitions for libdwarf.
      2    Copyright (C) 2002-2011, 2013-2015 Red Hat, Inc.
      3    This file is part of elfutils.
      4    Written by Ulrich Drepper <drepper (at) redhat.com>, 2002.
      5 
      6    This file is free software; you can redistribute it and/or modify
      7    it under the terms of either
      8 
      9      * the GNU Lesser General Public License as published by the Free
     10        Software Foundation; either version 3 of the License, or (at
     11        your option) any later version
     12 
     13    or
     14 
     15      * the GNU General Public License as published by the Free
     16        Software Foundation; either version 2 of the License, or (at
     17        your option) any later version
     18 
     19    or both in parallel, as here.
     20 
     21    elfutils is distributed in the hope that it will be useful, but
     22    WITHOUT ANY WARRANTY; without even the implied warranty of
     23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     24    General Public License for more details.
     25 
     26    You should have received copies of the GNU General Public License and
     27    the GNU Lesser General Public License along with this program.  If
     28    not, see <http://www.gnu.org/licenses/>.  */
     29 
     30 #ifndef _LIBDWP_H
     31 #define _LIBDWP_H 1
     32 
     33 #include <libintl.h>
     34 #include <stdbool.h>
     35 
     36 #include <libdw.h>
     37 #include <dwarf.h>
     38 
     39 
     40 /* gettext helper macros.  */
     41 #define _(Str) dgettext ("elfutils", Str)
     42 
     43 
     44 /* Known location expressions already decoded.  */
     45 struct loc_s
     46 {
     47   void *addr;
     48   Dwarf_Op *loc;
     49   size_t nloc;
     50 };
     51 
     52 /* Known DW_OP_implicit_value blocks already decoded.
     53    This overlaps struct loc_s exactly, but only the
     54    first member really has to match.  */
     55 struct loc_block_s
     56 {
     57   void *addr;
     58   unsigned char *data;
     59   size_t length;
     60 };
     61 
     62 /* Already decoded .debug_line units.  */
     63 struct files_lines_s
     64 {
     65   Dwarf_Off debug_line_offset;
     66   Dwarf_Files *files;
     67   Dwarf_Lines *lines;
     68 };
     69 
     70 /* Valid indeces for the section data.  */
     71 enum
     72   {
     73     IDX_debug_info = 0,
     74     IDX_debug_types,
     75     IDX_debug_abbrev,
     76     IDX_debug_aranges,
     77     IDX_debug_line,
     78     IDX_debug_frame,
     79     IDX_debug_loc,
     80     IDX_debug_pubnames,
     81     IDX_debug_str,
     82     IDX_debug_macinfo,
     83     IDX_debug_macro,
     84     IDX_debug_ranges,
     85     IDX_gnu_debugaltlink,
     86     IDX_last
     87   };
     88 
     89 
     90 /* Error values.  */
     91 enum
     92 {
     93   DWARF_E_NOERROR = 0,
     94   DWARF_E_UNKNOWN_ERROR,
     95   DWARF_E_INVALID_ACCESS,
     96   DWARF_E_NO_REGFILE,
     97   DWARF_E_IO_ERROR,
     98   DWARF_E_INVALID_ELF,
     99   DWARF_E_NO_DWARF,
    100   DWARF_E_COMPRESSED_ERROR,
    101   DWARF_E_NOELF,
    102   DWARF_E_GETEHDR_ERROR,
    103   DWARF_E_NOMEM,
    104   DWARF_E_UNIMPL,
    105   DWARF_E_INVALID_CMD,
    106   DWARF_E_INVALID_VERSION,
    107   DWARF_E_INVALID_FILE,
    108   DWARF_E_NO_ENTRY,
    109   DWARF_E_INVALID_DWARF,
    110   DWARF_E_NO_STRING,
    111   DWARF_E_NO_ADDR,
    112   DWARF_E_NO_CONSTANT,
    113   DWARF_E_NO_REFERENCE,
    114   DWARF_E_INVALID_REFERENCE,
    115   DWARF_E_NO_DEBUG_LINE,
    116   DWARF_E_INVALID_DEBUG_LINE,
    117   DWARF_E_TOO_BIG,
    118   DWARF_E_VERSION,
    119   DWARF_E_INVALID_DIR_IDX,
    120   DWARF_E_ADDR_OUTOFRANGE,
    121   DWARF_E_NO_LOCLIST,
    122   DWARF_E_NO_BLOCK,
    123   DWARF_E_INVALID_LINE_IDX,
    124   DWARF_E_INVALID_ARANGE_IDX,
    125   DWARF_E_NO_MATCH,
    126   DWARF_E_NO_FLAG,
    127   DWARF_E_INVALID_OFFSET,
    128   DWARF_E_NO_DEBUG_RANGES,
    129   DWARF_E_INVALID_CFI,
    130   DWARF_E_NO_ALT_DEBUGLINK,
    131   DWARF_E_INVALID_OPCODE,
    132   DWARF_E_NOT_CUDIE,
    133 };
    134 
    135 
    136 #include "dwarf_sig8_hash.h"
    137 
    138 /* This is the structure representing the debugging state.  */
    139 struct Dwarf
    140 {
    141   /* The underlying ELF file.  */
    142   Elf *elf;
    143 
    144   /* dwz alternate DWARF file.  */
    145   Dwarf *alt_dwarf;
    146 
    147   /* The section data.  */
    148   Elf_Data *sectiondata[IDX_last];
    149 
    150   /* True if the file has a byte order different from the host.  */
    151   bool other_byte_order;
    152 
    153   /* If true, we allocated the ELF descriptor ourselves.  */
    154   bool free_elf;
    155 
    156   /* Information for traversing the .debug_pubnames section.  This is
    157      an array and separately allocated with malloc.  */
    158   struct pubnames_s
    159   {
    160     Dwarf_Off cu_offset;
    161     Dwarf_Off set_start;
    162     unsigned int cu_header_size;
    163     int address_len;
    164   } *pubnames_sets;
    165   size_t pubnames_nsets;
    166 
    167   /* Search tree for the CUs.  */
    168   void *cu_tree;
    169   Dwarf_Off next_cu_offset;
    170 
    171   /* Search tree and sig8 hash table for .debug_types type units.  */
    172   void *tu_tree;
    173   Dwarf_Off next_tu_offset;
    174   Dwarf_Sig8_Hash sig8_hash;
    175 
    176   /* Search tree for .debug_macro operator tables.  */
    177   void *macro_ops;
    178 
    179   /* Search tree for decoded .debug_line units.  */
    180   void *files_lines;
    181 
    182   /* Address ranges.  */
    183   Dwarf_Aranges *aranges;
    184 
    185   /* Cached info from the CFI section.  */
    186   struct Dwarf_CFI_s *cfi;
    187 
    188   /* Fake loc CU.  Used when synthesizing attributes for Dwarf_Ops that
    189      came from a location list entry in dwarf_getlocation_attr.  */
    190   struct Dwarf_CU *fake_loc_cu;
    191 
    192   /* Internal memory handling.  This is basically a simplified
    193      reimplementation of obstacks.  Unfortunately the standard obstack
    194      implementation is not usable in libraries.  */
    195   struct libdw_memblock
    196   {
    197     size_t size;
    198     size_t remaining;
    199     struct libdw_memblock *prev;
    200     char mem[0];
    201   } *mem_tail;
    202 
    203   /* Default size of allocated memory blocks.  */
    204   size_t mem_default_size;
    205 
    206   /* Registered OOM handler.  */
    207   Dwarf_OOM oom_handler;
    208 };
    209 
    210 
    211 /* Abbreviation representation.  */
    212 struct Dwarf_Abbrev
    213 {
    214   Dwarf_Off offset;
    215   unsigned char *attrp;
    216   unsigned int attrcnt;
    217   unsigned int code;
    218   unsigned int tag;
    219   bool has_children;
    220 };
    221 
    222 #include "dwarf_abbrev_hash.h"
    223 
    224 
    225 /* Files in line information records.  */
    226 struct Dwarf_Files_s
    227   {
    228     unsigned int ndirs;
    229     unsigned int nfiles;
    230     struct Dwarf_Fileinfo_s
    231     {
    232       char *name;
    233       Dwarf_Word mtime;
    234       Dwarf_Word length;
    235     } info[0];
    236     /* nfiles of those, followed by char *[ndirs].  */
    237   };
    238 typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo;
    239 
    240 
    241 /* Representation of a row in the line table.  */
    242 
    243 struct Dwarf_Line_s
    244 {
    245   Dwarf_Files *files;
    246 
    247   Dwarf_Addr addr;
    248   unsigned int file;
    249   int line;
    250   unsigned short int column;
    251   unsigned int is_stmt:1;
    252   unsigned int basic_block:1;
    253   unsigned int end_sequence:1;
    254   unsigned int prologue_end:1;
    255   unsigned int epilogue_begin:1;
    256   /* The remaining bit fields are not flags, but hold values presumed to be
    257      small.  All the flags and other bit fields should add up to 48 bits
    258      to give the whole struct a nice round size.  */
    259   unsigned int op_index:8;
    260   unsigned int isa:8;
    261   unsigned int discriminator:24;
    262 };
    263 
    264 struct Dwarf_Lines_s
    265 {
    266   size_t nlines;
    267   struct Dwarf_Line_s info[0];
    268 };
    269 
    270 /* Representation of address ranges.  */
    271 struct Dwarf_Aranges_s
    272 {
    273   Dwarf *dbg;
    274   size_t naranges;
    275 
    276   struct Dwarf_Arange_s
    277   {
    278     Dwarf_Addr addr;
    279     Dwarf_Word length;
    280     Dwarf_Off offset;
    281   } info[0];
    282 };
    283 
    284 
    285 /* CU representation.  */
    286 struct Dwarf_CU
    287 {
    288   Dwarf *dbg;
    289   Dwarf_Off start;
    290   Dwarf_Off end;
    291   uint8_t address_size;
    292   uint8_t offset_size;
    293   uint16_t version;
    294 
    295   /* Zero if this is a normal CU.  Nonzero if it is a type unit.  */
    296   size_t type_offset;
    297   uint64_t type_sig8;
    298 
    299   /* Hash table for the abbreviations.  */
    300   Dwarf_Abbrev_Hash abbrev_hash;
    301   /* Offset of the first abbreviation.  */
    302   size_t orig_abbrev_offset;
    303   /* Offset past last read abbreviation.  */
    304   size_t last_abbrev_offset;
    305 
    306   /* The srcline information.  */
    307   Dwarf_Lines *lines;
    308 
    309   /* The source file information.  */
    310   Dwarf_Files *files;
    311 
    312   /* Known location lists.  */
    313   void *locs;
    314 
    315   /* Memory boundaries of this CU.  */
    316   void *startp;
    317   void *endp;
    318 };
    319 
    320 /* Compute the offset of a CU's first DIE from its offset.  This
    321    is either:
    322         LEN       VER     OFFSET    ADDR
    323       4-bytes + 2-bytes + 4-bytes + 1-byte  for 32-bit dwarf
    324      12-bytes + 2-bytes + 8-bytes + 1-byte  for 64-bit dwarf
    325    or in .debug_types, 			     SIGNATURE TYPE-OFFSET
    326       4-bytes + 2-bytes + 4-bytes + 1-byte + 8-bytes + 4-bytes  for 32-bit
    327      12-bytes + 2-bytes + 8-bytes + 1-byte + 8-bytes + 8-bytes  for 64-bit
    328 
    329    Note the trick in the computation.  If the offset_size is 4
    330    the '- 4' term changes the '3 *' into a '2 *'.  If the
    331    offset_size is 8 it accounts for the 4-byte escape value
    332    used at the start of the length.  */
    333 #define DIE_OFFSET_FROM_CU_OFFSET(cu_offset, offset_size, type_unit)	\
    334   ((type_unit) ? ((cu_offset) + 4 * (offset_size) - 4 + 3 + 8)		\
    335    : ((cu_offset) + 3 * (offset_size) - 4 + 3))
    336 
    337 #define CUDIE(fromcu)							      \
    338   ((Dwarf_Die)								      \
    339    {									      \
    340      .cu = (fromcu),							      \
    341      .addr = ((char *) fromcu->dbg->sectiondata[cu_sec_idx (fromcu)]->d_buf   \
    342 	      + DIE_OFFSET_FROM_CU_OFFSET ((fromcu)->start,		      \
    343 					   (fromcu)->offset_size,	      \
    344 					   (fromcu)->type_offset != 0))	      \
    345    })									      \
    346 
    347 
    348 /* Prototype of a single .debug_macro operator.  */
    349 typedef struct
    350 {
    351   Dwarf_Word nforms;
    352   unsigned char const *forms;
    353 } Dwarf_Macro_Op_Proto;
    354 
    355 /* Prototype table.  */
    356 typedef struct
    357 {
    358   /* Offset of .debug_macro section.  */
    359   Dwarf_Off offset;
    360 
    361   /* Offset of associated .debug_line section.  */
    362   Dwarf_Off line_offset;
    363 
    364   /* The source file information.  */
    365   Dwarf_Files *files;
    366 
    367   /* If this macro unit was opened through dwarf_getmacros or
    368      dwarf_getmacros_die, this caches value of DW_AT_comp_dir, if
    369      present.  */
    370   const char *comp_dir;
    371 
    372   /* Header length.  */
    373   Dwarf_Half header_len;
    374 
    375   uint16_t version;
    376   bool is_64bit;
    377   uint8_t sec_index;	/* IDX_debug_macro or IDX_debug_macinfo.  */
    378 
    379   /* Shows where in TABLE each opcode is defined.  Since opcode 0 is
    380      never used, it stores index of opcode X in X-1'th element.  The
    381      value of 0xff means not stored at all.  */
    382   unsigned char opcodes[255];
    383 
    384   /* Individual opcode prototypes.  */
    385   Dwarf_Macro_Op_Proto table[];
    386 } Dwarf_Macro_Op_Table;
    387 
    388 struct Dwarf_Macro_s
    389 {
    390   Dwarf_Macro_Op_Table *table;
    391   Dwarf_Attribute *attributes;
    392   uint8_t opcode;
    393 };
    394 
    395 static inline Dwarf_Word
    396 libdw_macro_nforms (Dwarf_Macro *macro)
    397 {
    398   return macro->table->table[macro->table->opcodes[macro->opcode - 1]].nforms;
    399 }
    400 
    401 /* We have to include the file at this point because the inline
    402    functions access internals of the Dwarf structure.  */
    403 #include "memory-access.h"
    404 
    405 
    406 /* Set error value.  */
    407 extern void __libdw_seterrno (int value) internal_function;
    408 
    409 
    410 /* Memory handling, the easy parts.  This macro does not do any locking.  */
    411 #define libdw_alloc(dbg, type, tsize, cnt) \
    412   ({ struct libdw_memblock *_tail = (dbg)->mem_tail;			      \
    413      size_t _required = (tsize) * (cnt);				      \
    414      type *_result = (type *) (_tail->mem + (_tail->size - _tail->remaining));\
    415      size_t _padding = ((__alignof (type)				      \
    416 			 - ((uintptr_t) _result & (__alignof (type) - 1)))    \
    417 			& (__alignof (type) - 1));			      \
    418      if (unlikely (_tail->remaining < _required + _padding))		      \
    419        _result = (type *) __libdw_allocate (dbg, _required, __alignof (type));\
    420      else								      \
    421        {								      \
    422 	 _required += _padding;						      \
    423 	 _result = (type *) ((char *) _result + _padding);		      \
    424 	 _tail->remaining -= _required;					      \
    425        }								      \
    426      _result; })
    427 
    428 #define libdw_typed_alloc(dbg, type) \
    429   libdw_alloc (dbg, type, sizeof (type), 1)
    430 
    431 /* Callback to allocate more.  */
    432 extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align)
    433      __attribute__ ((__malloc__)) __nonnull_attribute__ (1);
    434 
    435 /* Default OOM handler.  */
    436 extern void __libdw_oom (void) __attribute ((noreturn, visibility ("hidden")));
    437 
    438 /* Allocate the internal data for a unit not seen before.  */
    439 extern struct Dwarf_CU *__libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
    440      __nonnull_attribute__ (1) internal_function;
    441 
    442 /* Find CU for given offset.  */
    443 extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset, bool tu)
    444      __nonnull_attribute__ (1) internal_function;
    445 
    446 /* Get abbreviation with given code.  */
    447 extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu,
    448 					 unsigned int code)
    449      __nonnull_attribute__ (1) internal_function;
    450 
    451 /* Get abbreviation at given offset.  */
    452 extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu,
    453 					Dwarf_Off offset, size_t *lengthp,
    454 					Dwarf_Abbrev *result)
    455      __nonnull_attribute__ (1) internal_function;
    456 
    457 /* Get abbreviation of given DIE, and optionally set *READP to the DIE memory
    458    just past the abbreviation code.  */
    459 static inline Dwarf_Abbrev *
    460 __nonnull_attribute__ (1)
    461 __libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp)
    462 {
    463   /* Do we need to get the abbreviation, or need to read after the code?  */
    464   if (die->abbrev == NULL || readp != NULL)
    465     {
    466       /* Get the abbreviation code.  */
    467       unsigned int code;
    468       const unsigned char *addr = die->addr;
    469       get_uleb128 (code, addr, die->cu->endp);
    470       if (readp != NULL)
    471 	*readp = addr;
    472 
    473       /* Find the abbreviation.  */
    474       if (die->abbrev == NULL)
    475 	die->abbrev = __libdw_findabbrev (die->cu, code);
    476     }
    477   return die->abbrev;
    478 }
    479 
    480 /* Helper functions for form handling.  */
    481 extern size_t __libdw_form_val_compute_len (struct Dwarf_CU *cu,
    482 					    unsigned int form,
    483 					    const unsigned char *valp)
    484      __nonnull_attribute__ (1, 3) internal_function;
    485 
    486 /* Find the length of a form attribute.  */
    487 static inline size_t
    488 __nonnull_attribute__ (1, 3)
    489 __libdw_form_val_len (struct Dwarf_CU *cu, unsigned int form,
    490 		      const unsigned char *valp)
    491 {
    492   /* Small lookup table of forms with fixed lengths.  Absent indexes are
    493      initialized 0, so any truly desired 0 is set to 0x80 and masked.  */
    494   static const uint8_t form_lengths[] =
    495     {
    496       [DW_FORM_flag_present] = 0x80,
    497       [DW_FORM_data1] = 1, [DW_FORM_ref1] = 1, [DW_FORM_flag] = 1,
    498       [DW_FORM_data2] = 2, [DW_FORM_ref2] = 2,
    499       [DW_FORM_data4] = 4, [DW_FORM_ref4] = 4,
    500       [DW_FORM_data8] = 8, [DW_FORM_ref8] = 8, [DW_FORM_ref_sig8] = 8,
    501     };
    502 
    503   /* Return immediately for forms with fixed lengths.  */
    504   if (form < sizeof form_lengths / sizeof form_lengths[0])
    505     {
    506       uint8_t len = form_lengths[form];
    507       if (len != 0)
    508 	{
    509 	  const unsigned char *endp = cu->endp;
    510 	  len &= 0x7f; /* Mask to allow 0x80 -> 0.  */
    511 	  if (unlikely (len > (size_t) (endp - valp)))
    512 	    {
    513 	      __libdw_seterrno (DWARF_E_INVALID_DWARF);
    514 	      return -1;
    515 	    }
    516 	  return len;
    517 	}
    518     }
    519 
    520   /* Other forms require some computation.  */
    521   return __libdw_form_val_compute_len (cu, form, valp);
    522 }
    523 
    524 /* Helper function for DW_FORM_ref* handling.  */
    525 extern int __libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset)
    526      __nonnull_attribute__ (1, 2) internal_function;
    527 
    528 
    529 /* Helper function to locate attribute.  */
    530 extern unsigned char *__libdw_find_attr (Dwarf_Die *die,
    531 					 unsigned int search_name,
    532 					 unsigned int *codep,
    533 					 unsigned int *formp)
    534      __nonnull_attribute__ (1) internal_function;
    535 
    536 /* Helper function to access integer attribute.  */
    537 extern int __libdw_attr_intval (Dwarf_Die *die, int *valp, int attval)
    538      __nonnull_attribute__ (1, 2) internal_function;
    539 
    540 /* Helper function to walk scopes.  */
    541 struct Dwarf_Die_Chain
    542 {
    543   Dwarf_Die die;
    544   struct Dwarf_Die_Chain *parent;
    545   bool prune;			/* The PREVISIT function can set this.  */
    546 };
    547 extern int __libdw_visit_scopes (unsigned int depth,
    548 				 struct Dwarf_Die_Chain *root,
    549 				 struct Dwarf_Die_Chain *imports,
    550 				 int (*previsit) (unsigned int depth,
    551 						  struct Dwarf_Die_Chain *,
    552 						  void *arg),
    553 				 int (*postvisit) (unsigned int depth,
    554 						   struct Dwarf_Die_Chain *,
    555 						   void *arg),
    556 				 void *arg)
    557   __nonnull_attribute__ (2, 4) internal_function;
    558 
    559 /* Parse a DWARF Dwarf_Block into an array of Dwarf_Op's,
    560    and cache the result (via tsearch).  */
    561 extern int __libdw_intern_expression (Dwarf *dbg,
    562 				      bool other_byte_order,
    563 				      unsigned int address_size,
    564 				      unsigned int ref_size,
    565 				      void **cache, const Dwarf_Block *block,
    566 				      bool cfap, bool valuep,
    567 				      Dwarf_Op **llbuf, size_t *listlen,
    568 				      int sec_index)
    569   __nonnull_attribute__ (5, 6, 9, 10) internal_function;
    570 
    571 extern Dwarf_Die *__libdw_offdie (Dwarf *dbg, Dwarf_Off offset,
    572 				  Dwarf_Die *result, bool debug_types)
    573   internal_function;
    574 
    575 
    576 /* Return error code of last failing function call.  This value is kept
    577    separately for each thread.  */
    578 extern int __dwarf_errno_internal (void);
    579 
    580 
    581 /* Reader hooks.  */
    582 
    583 /* Relocation hooks return -1 on error (in that case the error code
    584    must already have been set), 0 if there is no relocation and 1 if a
    585    relocation was present.*/
    586 
    587 static inline int
    588 __libdw_relocate_address (Dwarf *dbg __attribute__ ((unused)),
    589 			  int sec_index __attribute__ ((unused)),
    590 			  const void *addr __attribute__ ((unused)),
    591 			  int width __attribute__ ((unused)),
    592 			  Dwarf_Addr *val __attribute__ ((unused)))
    593 {
    594   return 0;
    595 }
    596 
    597 static inline int
    598 __libdw_relocate_offset (Dwarf *dbg __attribute__ ((unused)),
    599 			 int sec_index __attribute__ ((unused)),
    600 			 const void *addr __attribute__ ((unused)),
    601 			 int width __attribute__ ((unused)),
    602 			 Dwarf_Off *val __attribute__ ((unused)))
    603 {
    604   return 0;
    605 }
    606 
    607 static inline Elf_Data *
    608 __libdw_checked_get_data (Dwarf *dbg, int sec_index)
    609 {
    610   Elf_Data *data = dbg->sectiondata[sec_index];
    611   if (unlikely (data == NULL)
    612       || unlikely (data->d_buf == NULL))
    613     {
    614       __libdw_seterrno (DWARF_E_INVALID_DWARF);
    615       return NULL;
    616     }
    617   return data;
    618 }
    619 
    620 static inline int
    621 __libdw_offset_in_section (Dwarf *dbg, int sec_index,
    622 			   Dwarf_Off offset, size_t size)
    623 {
    624   Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
    625   if (data == NULL)
    626     return -1;
    627   if (unlikely (offset > data->d_size)
    628       || unlikely (data->d_size - offset < size))
    629     {
    630       __libdw_seterrno (DWARF_E_INVALID_OFFSET);
    631       return -1;
    632     }
    633 
    634   return 0;
    635 }
    636 
    637 static inline bool
    638 __libdw_in_section (Dwarf *dbg, int sec_index,
    639 		    const void *addr, size_t size)
    640 {
    641   Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
    642   if (data == NULL)
    643     return false;
    644   if (unlikely (addr < data->d_buf)
    645       || unlikely (data->d_size - (addr - data->d_buf) < size))
    646     {
    647       __libdw_seterrno (DWARF_E_INVALID_OFFSET);
    648       return false;
    649     }
    650 
    651   return true;
    652 }
    653 
    654 #define READ_AND_RELOCATE(RELOC_HOOK, VAL)				\
    655   ({									\
    656     if (!__libdw_in_section (dbg, sec_index, addr, width))		\
    657       return -1;							\
    658 									\
    659     const unsigned char *orig_addr = addr;				\
    660     if (width == 4)							\
    661       VAL = read_4ubyte_unaligned_inc (dbg, addr);			\
    662     else								\
    663       VAL = read_8ubyte_unaligned_inc (dbg, addr);			\
    664 									\
    665     int status = RELOC_HOOK (dbg, sec_index, orig_addr, width, &VAL);	\
    666     if (status < 0)							\
    667       return status;							\
    668     status > 0;								\
    669    })
    670 
    671 static inline int
    672 __libdw_read_address_inc (Dwarf *dbg,
    673 			  int sec_index, const unsigned char **addrp,
    674 			  int width, Dwarf_Addr *ret)
    675 {
    676   const unsigned char *addr = *addrp;
    677   READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
    678   *addrp = addr;
    679   return 0;
    680 }
    681 
    682 static inline int
    683 __libdw_read_address (Dwarf *dbg,
    684 		      int sec_index, const unsigned char *addr,
    685 		      int width, Dwarf_Addr *ret)
    686 {
    687   READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
    688   return 0;
    689 }
    690 
    691 static inline int
    692 __libdw_read_offset_inc (Dwarf *dbg,
    693 			 int sec_index, const unsigned char **addrp,
    694 			 int width, Dwarf_Off *ret, int sec_ret,
    695 			 size_t size)
    696 {
    697   const unsigned char *addr = *addrp;
    698   READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
    699   *addrp = addr;
    700   return __libdw_offset_in_section (dbg, sec_ret, *ret, size);
    701 }
    702 
    703 static inline int
    704 __libdw_read_offset (Dwarf *dbg, Dwarf *dbg_ret,
    705 		     int sec_index, const unsigned char *addr,
    706 		     int width, Dwarf_Off *ret, int sec_ret,
    707 		     size_t size)
    708 {
    709   READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
    710   return __libdw_offset_in_section (dbg_ret, sec_ret, *ret, size);
    711 }
    712 
    713 static inline size_t
    714 cu_sec_idx (struct Dwarf_CU *cu)
    715 {
    716   return cu->type_offset == 0 ? IDX_debug_info : IDX_debug_types;
    717 }
    718 
    719 static inline bool
    720 is_cudie (Dwarf_Die *cudie)
    721 {
    722   return CUDIE (cudie->cu).addr == cudie->addr;
    723 }
    724 
    725 /* Read up begin/end pair and increment read pointer.
    726     - If it's normal range record, set up *BEGINP and *ENDP and return 0.
    727     - If it's base address selection record, set up *BASEP and return 1.
    728     - If it's end of rangelist, don't set anything and return 2
    729     - If an error occurs, don't set anything and return <0.  */
    730 int __libdw_read_begin_end_pair_inc (Dwarf *dbg, int sec_index,
    731 				     unsigned char **addr, int width,
    732 				     Dwarf_Addr *beginp, Dwarf_Addr *endp,
    733 				     Dwarf_Addr *basep)
    734   internal_function;
    735 
    736 unsigned char * __libdw_formptr (Dwarf_Attribute *attr, int sec_index,
    737 				 int err_nodata, unsigned char **endpp,
    738 				 Dwarf_Off *offsetp)
    739   internal_function;
    740 
    741 /* Fills in the given attribute to point at an empty location expression.  */
    742 void __libdw_empty_loc_attr (Dwarf_Attribute *attr)
    743   internal_function;
    744 
    745 /* Load .debug_line unit at DEBUG_LINE_OFFSET.  COMP_DIR is a value of
    746    DW_AT_comp_dir or NULL if that attribute is not available.  Caches
    747    the loaded unit and optionally set *LINESP and/or *FILESP (if not
    748    NULL) with loaded information.  Returns 0 for success or a negative
    749    value for failure.  */
    750 int __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
    751 			 const char *comp_dir, unsigned address_size,
    752 			 Dwarf_Lines **linesp, Dwarf_Files **filesp)
    753   internal_function
    754   __nonnull_attribute__ (1);
    755 
    756 /* Load and return value of DW_AT_comp_dir from CUDIE.  */
    757 const char *__libdw_getcompdir (Dwarf_Die *cudie);
    758 
    759 
    760 /* Aliases to avoid PLTs.  */
    761 INTDECL (dwarf_aggregate_size)
    762 INTDECL (dwarf_attr)
    763 INTDECL (dwarf_attr_integrate)
    764 INTDECL (dwarf_begin)
    765 INTDECL (dwarf_begin_elf)
    766 INTDECL (dwarf_child)
    767 INTDECL (dwarf_dieoffset)
    768 INTDECL (dwarf_diename)
    769 INTDECL (dwarf_end)
    770 INTDECL (dwarf_entrypc)
    771 INTDECL (dwarf_errmsg)
    772 INTDECL (dwarf_formaddr)
    773 INTDECL (dwarf_formblock)
    774 INTDECL (dwarf_formref_die)
    775 INTDECL (dwarf_formsdata)
    776 INTDECL (dwarf_formstring)
    777 INTDECL (dwarf_formudata)
    778 INTDECL (dwarf_getalt)
    779 INTDECL (dwarf_getarange_addr)
    780 INTDECL (dwarf_getarangeinfo)
    781 INTDECL (dwarf_getaranges)
    782 INTDECL (dwarf_getlocation_die)
    783 INTDECL (dwarf_getsrcfiles)
    784 INTDECL (dwarf_getsrclines)
    785 INTDECL (dwarf_hasattr)
    786 INTDECL (dwarf_haschildren)
    787 INTDECL (dwarf_haspc)
    788 INTDECL (dwarf_highpc)
    789 INTDECL (dwarf_lowpc)
    790 INTDECL (dwarf_nextcu)
    791 INTDECL (dwarf_next_unit)
    792 INTDECL (dwarf_offdie)
    793 INTDECL (dwarf_peel_type)
    794 INTDECL (dwarf_ranges)
    795 INTDECL (dwarf_setalt)
    796 INTDECL (dwarf_siblingof)
    797 INTDECL (dwarf_srclang)
    798 INTDECL (dwarf_tag)
    799 
    800 #endif	/* libdwP.h */
    801