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

Generated by: LCOV version 1.12