LCOV - code coverage report
Current view: top level - libdw - libdwP.h (source / functions) Hit Total Coverage
Test: lcov.out Lines: 48 55 87.3 %
Date: 2017-01-05 09:15:16 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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@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         648 :   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    20830183 : __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    20830183 :   if (die->abbrev == NULL || readp != NULL)
     465             :     {
     466             :       /* Get the abbreviation code.  */
     467             :       unsigned int code;
     468     7062474 :       const unsigned char *addr = die->addr;
     469     7062474 :       get_uleb128 (code, addr, die->cu->endp);
     470     7062474 :       if (readp != NULL)
     471     4501840 :         *readp = addr;
     472             : 
     473             :       /* Find the abbreviation.  */
     474     7062474 :       if (die->abbrev == NULL)
     475     3137040 :         die->abbrev = __libdw_findabbrev (die->cu, code);
     476             :     }
     477    20830183 :   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    14620863 : __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    14620863 :   if (form < sizeof form_lengths / sizeof form_lengths[0])
     505             :     {
     506    14606962 :       uint8_t len = form_lengths[form];
     507    14606962 :       if (len != 0)
     508             :         {
     509    10467302 :           const unsigned char *endp = cu->endp;
     510    10467302 :           len &= 0x7f; /* Mask to allow 0x80 -> 0.  */
     511    10467302 :           if (unlikely (len > (size_t) (endp - valp)))
     512             :             {
     513           0 :               __libdw_seterrno (DWARF_E_INVALID_DWARF);
     514           0 :               return -1;
     515             :             }
     516             :           return len;
     517             :         }
     518             :     }
     519             : 
     520             :   /* Other forms require some computation.  */
     521     4153561 :   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     1902547 :   Elf_Data *data = dbg->sectiondata[sec_index];
     611     1902547 :   if (unlikely (data == NULL)
     612     1902547 :       || unlikely (data->d_buf == NULL))
     613             :     {
     614           0 :       __libdw_seterrno (DWARF_E_INVALID_DWARF);
     615             :       return NULL;
     616             :     }
     617             :   return data;
     618             : }
     619             : 
     620             : static inline int
     621      868341 : __libdw_offset_in_section (Dwarf *dbg, int sec_index,
     622             :                            Dwarf_Off offset, size_t size)
     623             : {
     624      868341 :   Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
     625      868341 :   if (data == NULL)
     626             :     return -1;
     627      868341 :   if (unlikely (offset > data->d_size)
     628      868341 :       || unlikely (data->d_size - offset < size))
     629             :     {
     630           0 :       __libdw_seterrno (DWARF_E_INVALID_OFFSET);
     631           0 :       return -1;
     632             :     }
     633             : 
     634             :   return 0;
     635             : }
     636             : 
     637             : static inline bool
     638     1029868 : __libdw_in_section (Dwarf *dbg, int sec_index,
     639             :                     const void *addr, size_t size)
     640             : {
     641     1029868 :   Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
     642     1029868 :   if (data == NULL)
     643             :     return false;
     644     1029868 :   if (unlikely (addr < data->d_buf)
     645     1029868 :       || unlikely (data->d_size - (addr - data->d_buf) < size))
     646             :     {
     647           0 :       __libdw_seterrno (DWARF_E_INVALID_OFFSET);
     648           0 :       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        5551 : __libdw_read_address_inc (Dwarf *dbg,
     673             :                           int sec_index, const unsigned char **addrp,
     674             :                           int width, Dwarf_Addr *ret)
     675             : {
     676        5551 :   const unsigned char *addr = *addrp;
     677        5650 :   READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
     678        5551 :   *addrp = addr;
     679        5551 :   return 0;
     680             : }
     681             : 
     682             : static inline int
     683      160076 : __libdw_read_address (Dwarf *dbg,
     684             :                       int sec_index, const unsigned char *addr,
     685             :                       int width, Dwarf_Addr *ret)
     686             : {
     687      160176 :   READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
     688             :   return 0;
     689             : }
     690             : 
     691             : static inline int
     692      113986 : __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      113986 :   const unsigned char *addr = *addrp;
     698      114111 :   READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
     699      113986 :   *addrp = addr;
     700      113986 :   return __libdw_offset_in_section (dbg, sec_ret, *ret, size);
     701             : }
     702             : 
     703             : static inline int
     704      750009 : __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      774486 :   READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
     710      750009 :   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      963764 :   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       15236 :   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 */

Generated by: LCOV version 1.12