LCOV - code coverage report
Current view: top level - libdw - libdwP.h (source / functions) Hit Total Coverage
Test: elfutils-0.171 Lines: 165 209 78.9 %
Date: 2018-06-04 08:50:22 Functions: 16 16 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13