LCOV - code coverage report
Current view: top level - libdw - libdwP.h (source / functions) Hit Total Coverage
Test: elfutils-0.175 Lines: 165 209 78.9 %
Date: 2018-11-16 13:02:39 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     2448639 : __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     2448639 :   Dwarf_Off off = cu_start;
     405     2448639 :   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     2447917 :       if (unit_type != DW_UT_type)
     420     2447866 :         off += 3 * offset_size - 4 + 3;
     421             :       else
     422          51 :         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         722 :       off += 3 * offset_size - 4 + 4;
     435        1444 :       if (unit_type == DW_UT_skeleton || unit_type == DW_UT_split_compile
     436         843 :           || 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     2448639 :   return off;
     445             : }
     446             : 
     447             : static inline Dwarf_Off
     448             : __libdw_first_die_off_from_cu (struct Dwarf_CU *cu)
     449             : {
     450     2420773 :   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   115456892 : __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   115456892 :   if (die->abbrev == NULL || readp != NULL)
     652             :     {
     653             :       /* Get the abbreviation code.  */
     654             :       unsigned int code;
     655    67193006 :       const unsigned char *addr = die->addr;
     656    67193006 :       if (unlikely (die->cu == NULL
     657             :                     || addr >= (const unsigned char *) die->cu->endp))
     658        8838 :         return die->abbrev = DWARF_END_ABBREV;
     659    67184168 :       get_uleb128 (code, addr, die->cu->endp);
     660    67184168 :       if (readp != NULL)
     661    43701680 :         *readp = addr;
     662             : 
     663             :       /* Find the abbreviation.  */
     664    67184168 :       if (die->abbrev == NULL)
     665    34452745 :         die->abbrev = __libdw_findabbrev (die->cu, code);
     666             :     }
     667   115448054 :   return die->abbrev;
     668             : }
     669             : 
     670             : /* Helper functions for form handling.  */
     671             : extern size_t __libdw_form_val_compute_len (struct Dwarf_CU *cu,
     672             :                                             unsigned int form,
     673             :                                             const unsigned char *valp)
     674             :      __nonnull_attribute__ (1, 3) internal_function;
     675             : 
     676             : /* Find the length of a form attribute in DIE/info data.  */
     677             : static inline size_t
     678             : __nonnull_attribute__ (1, 3)
     679   132775714 : __libdw_form_val_len (struct Dwarf_CU *cu, unsigned int form,
     680             :                       const unsigned char *valp)
     681             : {
     682             :   /* Small lookup table of forms with fixed lengths.  Absent indexes are
     683             :      initialized 0, so any truly desired 0 is set to 0x80 and masked.  */
     684             :   static const uint8_t form_lengths[] =
     685             :     {
     686             :       [DW_FORM_flag_present] = 0x80,
     687             :       [DW_FORM_implicit_const] = 0x80, /* Value is in abbrev, not in info.  */
     688             : 
     689             :       [DW_FORM_flag] = 1,
     690             :       [DW_FORM_data1] = 1, [DW_FORM_ref1] = 1,
     691             :       [DW_FORM_addrx1] = 1, [DW_FORM_strx1] = 1,
     692             : 
     693             :       [DW_FORM_data2] = 2, [DW_FORM_ref2] = 2,
     694             :       [DW_FORM_addrx2] = 2, [DW_FORM_strx2] = 2,
     695             : 
     696             :       [DW_FORM_addrx3] = 3, [DW_FORM_strx3] = 3,
     697             : 
     698             :       [DW_FORM_data4] = 4, [DW_FORM_ref4] = 4, [DW_FORM_ref_sup4] = 4,
     699             :       [DW_FORM_addrx4] = 4, [DW_FORM_strx4] = 4,
     700             : 
     701             :       [DW_FORM_ref_sig8] = 8,
     702             :       [DW_FORM_data8] = 8, [DW_FORM_ref8] = 8, [DW_FORM_ref_sup8] = 8,
     703             : 
     704             :       [DW_FORM_data16] = 16,
     705             :     };
     706             : 
     707             :   /* Return immediately for forms with fixed lengths.  */
     708   132775714 :   if (form < sizeof form_lengths / sizeof form_lengths[0])
     709             :     {
     710   132773238 :       uint8_t len = form_lengths[form];
     711   132773238 :       if (len != 0)
     712             :         {
     713    88529935 :           const unsigned char *endp = cu->endp;
     714    88529935 :           len &= 0x7f; /* Mask to allow 0x80 -> 0.  */
     715    88529935 :           if (unlikely (len > (size_t) (endp - valp)))
     716             :             {
     717           0 :               __libdw_seterrno (DWARF_E_INVALID_DWARF);
     718           0 :               return -1;
     719             :             }
     720             :           return len;
     721             :         }
     722             :     }
     723             : 
     724             :   /* Other forms require some computation.  */
     725    44245779 :   return __libdw_form_val_compute_len (cu, form, valp);
     726             : }
     727             : 
     728             : /* Helper function for DW_FORM_ref* handling.  */
     729             : extern int __libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset)
     730             :      __nonnull_attribute__ (1, 2) internal_function;
     731             : 
     732             : 
     733             : /* Helper function to locate attribute.  */
     734             : extern unsigned char *__libdw_find_attr (Dwarf_Die *die,
     735             :                                          unsigned int search_name,
     736             :                                          unsigned int *codep,
     737             :                                          unsigned int *formp)
     738             :      __nonnull_attribute__ (1) internal_function;
     739             : 
     740             : /* Helper function to access integer attribute.  */
     741             : extern int __libdw_attr_intval (Dwarf_Die *die, int *valp, int attval)
     742             :      __nonnull_attribute__ (1, 2) internal_function;
     743             : 
     744             : /* Helper function to walk scopes.  */
     745             : struct Dwarf_Die_Chain
     746             : {
     747             :   Dwarf_Die die;
     748             :   struct Dwarf_Die_Chain *parent;
     749             :   bool prune;                   /* The PREVISIT function can set this.  */
     750             : };
     751             : extern int __libdw_visit_scopes (unsigned int depth,
     752             :                                  struct Dwarf_Die_Chain *root,
     753             :                                  struct Dwarf_Die_Chain *imports,
     754             :                                  int (*previsit) (unsigned int depth,
     755             :                                                   struct Dwarf_Die_Chain *,
     756             :                                                   void *arg),
     757             :                                  int (*postvisit) (unsigned int depth,
     758             :                                                    struct Dwarf_Die_Chain *,
     759             :                                                    void *arg),
     760             :                                  void *arg)
     761             :   __nonnull_attribute__ (2, 4) internal_function;
     762             : 
     763             : /* Parse a DWARF Dwarf_Block into an array of Dwarf_Op's,
     764             :    and cache the result (via tsearch).  */
     765             : extern int __libdw_intern_expression (Dwarf *dbg,
     766             :                                       bool other_byte_order,
     767             :                                       unsigned int address_size,
     768             :                                       unsigned int ref_size,
     769             :                                       void **cache, const Dwarf_Block *block,
     770             :                                       bool cfap, bool valuep,
     771             :                                       Dwarf_Op **llbuf, size_t *listlen,
     772             :                                       int sec_index)
     773             :   __nonnull_attribute__ (5, 6, 9, 10) internal_function;
     774             : 
     775             : extern Dwarf_Die *__libdw_offdie (Dwarf *dbg, Dwarf_Off offset,
     776             :                                   Dwarf_Die *result, bool debug_types)
     777             :   internal_function;
     778             : 
     779             : 
     780             : /* Return error code of last failing function call.  This value is kept
     781             :    separately for each thread.  */
     782             : extern int __dwarf_errno_internal (void);
     783             : 
     784             : 
     785             : /* Reader hooks.  */
     786             : 
     787             : /* Relocation hooks return -1 on error (in that case the error code
     788             :    must already have been set), 0 if there is no relocation and 1 if a
     789             :    relocation was present.*/
     790             : 
     791             : static inline int
     792             : __libdw_relocate_address (Dwarf *dbg __attribute__ ((unused)),
     793             :                           int sec_index __attribute__ ((unused)),
     794             :                           const void *addr __attribute__ ((unused)),
     795             :                           int width __attribute__ ((unused)),
     796             :                           Dwarf_Addr *val __attribute__ ((unused)))
     797             : {
     798             :   return 0;
     799             : }
     800             : 
     801             : static inline int
     802             : __libdw_relocate_offset (Dwarf *dbg __attribute__ ((unused)),
     803             :                          int sec_index __attribute__ ((unused)),
     804             :                          const void *addr __attribute__ ((unused)),
     805             :                          int width __attribute__ ((unused)),
     806             :                          Dwarf_Off *val __attribute__ ((unused)))
     807             : {
     808             :   return 0;
     809             : }
     810             : 
     811             : static inline Elf_Data *
     812             : __libdw_checked_get_data (Dwarf *dbg, int sec_index)
     813             : {
     814     6928236 :   Elf_Data *data = dbg->sectiondata[sec_index];
     815     6928236 :   if (unlikely (data == NULL)
     816     6928236 :       || unlikely (data->d_buf == NULL))
     817             :     {
     818           0 :       __libdw_seterrno (DWARF_E_INVALID_DWARF);
     819             :       return NULL;
     820             :     }
     821             :   return data;
     822             : }
     823             : 
     824             : static inline int
     825     1321064 : __libdw_offset_in_section (Dwarf *dbg, int sec_index,
     826             :                            Dwarf_Off offset, size_t size)
     827             : {
     828           0 :   Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
     829             :   if (data == NULL)
     830             :     return -1;
     831     1321064 :   if (unlikely (offset > data->d_size)
     832     1321064 :       || unlikely (data->d_size < size)
     833     1321064 :       || unlikely (offset > data->d_size - size))
     834             :     {
     835           0 :       __libdw_seterrno (DWARF_E_INVALID_OFFSET);
     836           0 :       return -1;
     837             :     }
     838             : 
     839             :   return 0;
     840             : }
     841             : 
     842             : static inline bool
     843     5601781 : __libdw_in_section (Dwarf *dbg, int sec_index,
     844             :                     const void *addr, size_t size)
     845             : {
     846           0 :   Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
     847             :   if (data == NULL)
     848             :     return false;
     849     5601781 :   if (unlikely (addr < data->d_buf)
     850     5601781 :       || unlikely (data->d_size < size)
     851     5601781 :       || unlikely ((size_t)(addr - data->d_buf) > data->d_size - size))
     852             :     {
     853           0 :       __libdw_seterrno (DWARF_E_INVALID_OFFSET);
     854           0 :       return false;
     855             :     }
     856             : 
     857             :   return true;
     858             : }
     859             : 
     860             : #define READ_AND_RELOCATE(RELOC_HOOK, VAL)                              \
     861             :   ({                                                                    \
     862             :     if (!__libdw_in_section (dbg, sec_index, addr, width))              \
     863             :       return -1;                                                        \
     864             :                                                                         \
     865             :     const unsigned char *orig_addr = addr;                              \
     866             :     if (width == 4)                                                     \
     867             :       VAL = read_4ubyte_unaligned_inc (dbg, addr);                      \
     868             :     else                                                                \
     869             :       VAL = read_8ubyte_unaligned_inc (dbg, addr);                      \
     870             :                                                                         \
     871             :     int status = RELOC_HOOK (dbg, sec_index, orig_addr, width, &VAL);       \
     872             :     if (status < 0)                                                  \
     873             :       return status;                                                    \
     874             :     status > 0;                                                              \
     875             :    })
     876             : 
     877             : static inline int
     878       14262 : __libdw_read_address_inc (Dwarf *dbg,
     879             :                           int sec_index, const unsigned char **addrp,
     880             :                           int width, Dwarf_Addr *ret)
     881             : {
     882       14262 :   const unsigned char *addr = *addrp;
     883       14435 :   READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
     884       14262 :   *addrp = addr;
     885       14262 :   return 0;
     886             : }
     887             : 
     888             : static inline int
     889      230943 : __libdw_read_address (Dwarf *dbg,
     890             :                       int sec_index, const unsigned char *addr,
     891             :                       int width, Dwarf_Addr *ret)
     892             : {
     893      231139 :   READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
     894             :   return 0;
     895             : }
     896             : 
     897             : static inline int
     898       34644 : __libdw_read_offset_inc (Dwarf *dbg,
     899             :                          int sec_index, const unsigned char **addrp,
     900             :                          int width, Dwarf_Off *ret, int sec_ret,
     901             :                          size_t size)
     902             : {
     903       34644 :   const unsigned char *addr = *addrp;
     904       34747 :   READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
     905       34644 :   *addrp = addr;
     906       34644 :   return __libdw_offset_in_section (dbg, sec_ret, *ret, size);
     907             : }
     908             : 
     909             : static inline int
     910     1280834 : __libdw_read_offset (Dwarf *dbg, Dwarf *dbg_ret,
     911             :                      int sec_index, const unsigned char *addr,
     912             :                      int width, Dwarf_Off *ret, int sec_ret,
     913             :                      size_t size)
     914             : {
     915     1305442 :   READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
     916     1280834 :   return __libdw_offset_in_section (dbg_ret, sec_ret, *ret, size);
     917             : }
     918             : 
     919             : static inline size_t
     920             : cu_sec_idx (struct Dwarf_CU *cu)
     921             : {
     922             :   return cu->sec_idx;
     923             : }
     924             : 
     925             : static inline bool
     926     1795387 : is_cudie (Dwarf_Die *cudie)
     927             : {
     928     3589008 :   return cudie->cu != NULL && CUDIE (cudie->cu).addr == cudie->addr;
     929             : }
     930             : 
     931             : /* Read up begin/end pair and increment read pointer.
     932             :     - If it's normal range record, set up *BEGINP and *ENDP and return 0.
     933             :     - If it's base address selection record, set up *BASEP and return 1.
     934             :     - If it's end of rangelist, don't set anything and return 2
     935             :     - If an error occurs, don't set anything and return <0.  */
     936             : int __libdw_read_begin_end_pair_inc (Dwarf_CU *cu, int sec_index,
     937             :                                      const unsigned char **readp,
     938             :                                      const unsigned char *readend,
     939             :                                      int width,
     940             :                                      Dwarf_Addr *beginp, Dwarf_Addr *endp,
     941             :                                      Dwarf_Addr *basep)
     942             :   internal_function;
     943             : 
     944             : const unsigned char * __libdw_formptr (Dwarf_Attribute *attr, int sec_index,
     945             :                                        int err_nodata,
     946             :                                        const unsigned char **endpp,
     947             :                                        Dwarf_Off *offsetp)
     948             :   internal_function;
     949             : 
     950             : /* Fills in the given attribute to point at an empty location expression.  */
     951             : void __libdw_empty_loc_attr (Dwarf_Attribute *attr)
     952             :   internal_function;
     953             : 
     954             : /* Load .debug_line unit at DEBUG_LINE_OFFSET.  COMP_DIR is a value of
     955             :    DW_AT_comp_dir or NULL if that attribute is not available.  Caches
     956             :    the loaded unit and optionally set *LINESP and/or *FILESP (if not
     957             :    NULL) with loaded information.  Returns 0 for success or a negative
     958             :    value for failure.  */
     959             : int __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
     960             :                          const char *comp_dir, unsigned address_size,
     961             :                          Dwarf_Lines **linesp, Dwarf_Files **filesp)
     962             :   internal_function
     963             :   __nonnull_attribute__ (1);
     964             : 
     965             : /* Load and return value of DW_AT_comp_dir from CUDIE.  */
     966             : const char *__libdw_getcompdir (Dwarf_Die *cudie);
     967             : 
     968             : /* Get the base address for the CU, fetches it when not yet set.
     969             :    This is used as initial base address for ranges and loclists.  */
     970             : Dwarf_Addr __libdw_cu_base_address (Dwarf_CU *cu);
     971             : 
     972             : /* Get the address base for the CU, fetches it when not yet set.  */
     973             : static inline Dwarf_Off
     974         631 : __libdw_cu_addr_base (Dwarf_CU *cu)
     975             : {
     976         631 :   if (cu->addr_base == (Dwarf_Off) -1)
     977             :     {
     978          96 :       Dwarf_Die cu_die = CUDIE(cu);
     979             :       Dwarf_Attribute attr;
     980          48 :       Dwarf_Off offset = 0;
     981          48 :       if (dwarf_attr (&cu_die, DW_AT_GNU_addr_base, &attr) != NULL
     982          22 :           || dwarf_attr (&cu_die, DW_AT_addr_base, &attr) != NULL)
     983             :         {
     984             :           Dwarf_Word off;
     985          48 :           if (dwarf_formudata (&attr, &off) == 0)
     986          48 :             offset = off;
     987             :         }
     988          48 :       cu->addr_base = offset;
     989             :     }
     990             : 
     991         631 :   return cu->addr_base;
     992             : }
     993             : 
     994             : /* Gets the .debug_str_offsets base offset to use.  static inline to
     995             :    be shared between libdw and eu-readelf.  */
     996             : static inline Dwarf_Off
     997        1944 : str_offsets_base_off (Dwarf *dbg, Dwarf_CU *cu)
     998             : {
     999             :   /* If we don't have a CU, then find and use the first one in the
    1000             :      debug file (when we support .dwp files, we must actually find the
    1001             :      one matching our "caller" - aka macro or line).  If we (now) have
    1002             :      a cu and str_offsets_base attribute, just use that.  Otherwise
    1003             :      use the first offset.  But we might have to parse the header
    1004             :      first, but only if this is version 5.  Assume if all else fails,
    1005             :      this is version 4, without header.  */
    1006             : 
    1007        1944 :   if (cu == NULL && dbg != NULL)
    1008             :     {
    1009             :       Dwarf_CU *first_cu;
    1010        1268 :       if (dwarf_get_units (dbg, NULL, &first_cu,
    1011             :                            NULL, NULL, NULL, NULL) == 0)
    1012        1268 :         cu = first_cu;
    1013             :     }
    1014             : 
    1015        1944 :   if (cu != NULL)
    1016             :     {
    1017        1944 :       if (cu->str_off_base == (Dwarf_Off) -1)
    1018             :         {
    1019         170 :           Dwarf_Die cu_die = CUDIE(cu);
    1020             :           Dwarf_Attribute attr;
    1021          85 :           if (dwarf_attr (&cu_die, DW_AT_str_offsets_base, &attr) != NULL)
    1022             :             {
    1023             :               Dwarf_Word off;
    1024           0 :               if (dwarf_formudata (&attr, &off) == 0)
    1025             :                 {
    1026           0 :                   cu->str_off_base = off;
    1027           0 :                   return cu->str_off_base;
    1028             :                 }
    1029             :             }
    1030             :           /* For older DWARF simply assume zero (no header).  */
    1031          85 :           if (cu->version < 5)
    1032             :             {
    1033          70 :               cu->str_off_base = 0;
    1034          70 :               return cu->str_off_base;
    1035             :             }
    1036             : 
    1037          15 :           if (dbg == NULL)
    1038          14 :             dbg = cu->dbg;
    1039             :         }
    1040             :       else
    1041             :         return cu->str_off_base;
    1042             :     }
    1043             : 
    1044             :   /* No str_offsets_base attribute, we have to assume "zero".
    1045             :      But there could be a header first.  */
    1046          15 :   Dwarf_Off off = 0;
    1047          15 :   if (dbg == NULL)
    1048             :     goto no_header;
    1049             : 
    1050          15 :   Elf_Data *data =  dbg->sectiondata[IDX_debug_str_offsets];
    1051          15 :   if (data == NULL)
    1052             :     goto no_header;
    1053             : 
    1054             :   const unsigned char *start;
    1055             :   const unsigned char *readp;
    1056             :   const unsigned char *readendp;
    1057          14 :   start = readp = (const unsigned char *) data->d_buf;
    1058          14 :   readendp = (const unsigned char *) data->d_buf + data->d_size;
    1059             : 
    1060             :   uint64_t unit_length;
    1061             :   uint16_t version;
    1062             : 
    1063          14 :   unit_length = read_4ubyte_unaligned_inc (dbg, readp);
    1064          14 :   if (unlikely (unit_length == 0xffffffff))
    1065             :     {
    1066           0 :       if (unlikely (readendp - readp < 8))
    1067             :         goto no_header;
    1068           0 :       unit_length = read_8ubyte_unaligned_inc (dbg, readp);
    1069             :       /* In theory the offset size could be different
    1070             :          between CU and str_offsets unit.  But we just
    1071             :          ignore that here. */
    1072             :     }
    1073             : 
    1074             :   /* We need at least 2-bytes (version) + 2-bytes (padding) =
    1075             :      4 bytes to complete the header.  And this unit cannot go
    1076             :      beyond the section data.  */
    1077          14 :   if (readendp - readp < 4
    1078          14 :       || unit_length < 4
    1079          14 :       || (uint64_t) (readendp - readp) < unit_length)
    1080             :     goto no_header;
    1081             : 
    1082          14 :   version = read_2ubyte_unaligned_inc (dbg, readp);
    1083          14 :   if (version != 5)
    1084             :     goto no_header;
    1085             :   /* padding */
    1086          14 :   read_2ubyte_unaligned_inc (dbg, readp);
    1087             : 
    1088          14 :   off = (Dwarf_Off) (readp - start);
    1089             : 
    1090          16 :  no_header:
    1091          15 :   if (cu != NULL)
    1092          15 :     cu->str_off_base = off;
    1093             : 
    1094             :   return off;
    1095             : }
    1096             : 
    1097             : 
    1098             : /* Get the string offsets base for the CU, fetches it when not yet set.  */
    1099             : static inline Dwarf_Off __libdw_cu_str_off_base (Dwarf_CU *cu)
    1100             : {
    1101         142 :   return str_offsets_base_off (NULL, cu);
    1102             : }
    1103             : 
    1104             : 
    1105             : /* Either a direct offset into .debug_ranges for version < 5, or the
    1106             :    start of the offset table in .debug_rnglists for version > 5.  */
    1107             : static inline Dwarf_Off
    1108          14 : __libdw_cu_ranges_base (Dwarf_CU *cu)
    1109             : {
    1110          14 :   if (cu->ranges_base == (Dwarf_Off) -1)
    1111             :     {
    1112           5 :       Dwarf_Off offset = 0;
    1113          10 :       Dwarf_Die cu_die = CUDIE(cu);
    1114             :       Dwarf_Attribute attr;
    1115           5 :       if (cu->version < 5)
    1116             :         {
    1117           4 :           if (dwarf_attr (&cu_die, DW_AT_GNU_ranges_base, &attr) != NULL)
    1118             :             {
    1119             :               Dwarf_Word off;
    1120           4 :               if (dwarf_formudata (&attr, &off) == 0)
    1121           4 :                 offset = off;
    1122             :             }
    1123             :         }
    1124             :       else
    1125             :         {
    1126           1 :           if (dwarf_attr (&cu_die, DW_AT_rnglists_base, &attr) != NULL)
    1127             :             {
    1128             :               Dwarf_Word off;
    1129           1 :               if (dwarf_formudata (&attr, &off) == 0)
    1130           1 :                 offset = off;
    1131             :             }
    1132             : 
    1133             :           /* There wasn't an rnglists_base, if the Dwarf does have a
    1134             :              .debug_rnglists section, then it might be we need the
    1135             :              base after the first header. */
    1136           1 :           Elf_Data *data = cu->dbg->sectiondata[IDX_debug_rnglists];
    1137           1 :           if (offset == 0 && data != NULL)
    1138             :             {
    1139           0 :               Dwarf *dbg = cu->dbg;
    1140           0 :               const unsigned char *readp = data->d_buf;
    1141           0 :               const unsigned char *const dataend
    1142           0 :                 = (unsigned char *) data->d_buf + data->d_size;
    1143             : 
    1144           0 :               uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
    1145           0 :               unsigned int offset_size = 4;
    1146           0 :               if (unlikely (unit_length == 0xffffffff))
    1147             :                 {
    1148           0 :                   if (unlikely (readp > dataend - 8))
    1149             :                     goto no_header;
    1150             : 
    1151           0 :                   unit_length = read_8ubyte_unaligned_inc (dbg, readp);
    1152           0 :                   offset_size = 8;
    1153             :                 }
    1154             : 
    1155           0 :               if (readp > dataend - 8
    1156           0 :                   || unit_length < 8
    1157           0 :                   || unit_length > (uint64_t) (dataend - readp))
    1158             :                 goto no_header;
    1159             : 
    1160           0 :               uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
    1161           0 :               if (version != 5)
    1162             :                 goto no_header;
    1163             : 
    1164           0 :               uint8_t address_size = *readp++;
    1165           0 :               if (address_size != 4 && address_size != 8)
    1166             :                 goto no_header;
    1167             : 
    1168           0 :               uint8_t segment_size = *readp++;
    1169           0 :               if (segment_size != 0)
    1170             :                 goto no_header;
    1171             : 
    1172             :               uint32_t offset_entry_count;
    1173           0 :               offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
    1174             : 
    1175           0 :               const unsigned char *offset_array_start = readp;
    1176           0 :               if (offset_entry_count <= 0)
    1177             :                 goto no_header;
    1178             : 
    1179           0 :               uint64_t needed = offset_entry_count * offset_size;
    1180           0 :               if (unit_length - 8 < needed)
    1181             :                 goto no_header;
    1182             : 
    1183           0 :               offset = (Dwarf_Off) (offset_array_start
    1184           0 :                                     - (unsigned char *) data->d_buf);
    1185             :             }
    1186             :         }
    1187           6 :     no_header:
    1188           5 :       cu->ranges_base = offset;
    1189             :     }
    1190             : 
    1191          14 :   return cu->ranges_base;
    1192             : }
    1193             : 
    1194             : 
    1195             : /* The start of the offset table in .debug_loclists for DWARF5.  */
    1196             : static inline Dwarf_Off
    1197          67 : __libdw_cu_locs_base (Dwarf_CU *cu)
    1198             : {
    1199          67 :   if (cu->locs_base == (Dwarf_Off) -1)
    1200             :     {
    1201           2 :       Dwarf_Off offset = 0;
    1202           4 :       Dwarf_Die cu_die = CUDIE(cu);
    1203             :       Dwarf_Attribute attr;
    1204           2 :       if (dwarf_attr (&cu_die, DW_AT_loclists_base, &attr) != NULL)
    1205             :         {
    1206             :           Dwarf_Word off;
    1207           2 :           if (dwarf_formudata (&attr, &off) == 0)
    1208           2 :             offset = off;
    1209             :         }
    1210             : 
    1211             :       /* There wasn't an loclists_base, if the Dwarf does have a
    1212             :          .debug_loclists section, then it might be we need the
    1213             :          base after the first header. */
    1214           2 :       Elf_Data *data = cu->dbg->sectiondata[IDX_debug_loclists];
    1215           2 :       if (offset == 0 && data != NULL)
    1216             :         {
    1217           2 :           Dwarf *dbg = cu->dbg;
    1218           2 :           const unsigned char *readp = data->d_buf;
    1219           2 :           const unsigned char *const dataend
    1220           2 :             = (unsigned char *) data->d_buf + data->d_size;
    1221             : 
    1222           2 :           uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
    1223           2 :           unsigned int offset_size = 4;
    1224           2 :           if (unlikely (unit_length == 0xffffffff))
    1225             :             {
    1226           0 :               if (unlikely (readp > dataend - 8))
    1227             :                 goto no_header;
    1228             : 
    1229           0 :               unit_length = read_8ubyte_unaligned_inc (dbg, readp);
    1230           0 :               offset_size = 8;
    1231             :             }
    1232             : 
    1233           2 :           if (readp > dataend - 8
    1234           2 :               || unit_length < 8
    1235           2 :               || unit_length > (uint64_t) (dataend - readp))
    1236             :             goto no_header;
    1237             : 
    1238           2 :           uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
    1239           2 :           if (version != 5)
    1240             :             goto no_header;
    1241             : 
    1242           2 :           uint8_t address_size = *readp++;
    1243           2 :           if (address_size != 4 && address_size != 8)
    1244             :             goto no_header;
    1245             : 
    1246           2 :           uint8_t segment_size = *readp++;
    1247           2 :           if (segment_size != 0)
    1248             :             goto no_header;
    1249             : 
    1250             :           uint32_t offset_entry_count;
    1251           2 :           offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
    1252             : 
    1253           2 :           const unsigned char *offset_array_start = readp;
    1254           2 :           if (offset_entry_count <= 0)
    1255             :             goto no_header;
    1256             : 
    1257           2 :           uint64_t needed = offset_entry_count * offset_size;
    1258           2 :           if (unit_length - 8 < needed)
    1259             :             goto no_header;
    1260             : 
    1261           2 :           offset = (Dwarf_Off) (offset_array_start
    1262           2 :                                 - (unsigned char *) data->d_buf);
    1263             :         }
    1264             : 
    1265           2 :     no_header:
    1266           2 :       cu->locs_base = offset;
    1267             :     }
    1268             : 
    1269          67 :   return cu->locs_base;
    1270             : }
    1271             : 
    1272             : /* Helper function for tsearch/tfind split_tree Dwarf.  */
    1273             : int __libdw_finddbg_cb (const void *arg1, const void *arg2);
    1274             : 
    1275             : /* Link skeleton and split compile units.  */
    1276             : static inline void
    1277          48 : __libdw_link_skel_split (Dwarf_CU *skel, Dwarf_CU *split)
    1278             : {
    1279          48 :   skel->split = split;
    1280          48 :   split->split = skel;
    1281             : 
    1282             :   /* Get .debug_addr and addr_base greedy.
    1283             :      We also need it for the fake addr cu.
    1284             :      There is only one per split debug.  */
    1285          48 :   Dwarf *dbg = skel->dbg;
    1286          48 :   Dwarf *sdbg = split->dbg;
    1287          48 :   if (sdbg->sectiondata[IDX_debug_addr] == NULL
    1288          48 :       && dbg->sectiondata[IDX_debug_addr] != NULL)
    1289             :     {
    1290             :       sdbg->sectiondata[IDX_debug_addr]
    1291          48 :         = dbg->sectiondata[IDX_debug_addr];
    1292          48 :       split->addr_base = __libdw_cu_addr_base (skel);
    1293          48 :       sdbg->fake_addr_cu = dbg->fake_addr_cu;
    1294             :     }
    1295          48 : }
    1296             : 
    1297             : 
    1298             : /* Given an address index for a CU return the address.
    1299             :    Returns -1 and sets libdw_errno if an error occurs.  */
    1300             : int __libdw_addrx (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr);
    1301             : 
    1302             : 
    1303             : /* Helper function to set debugdir field in Dwarf, used from dwarf_begin_elf
    1304             :    and libdwfl process_file.  */
    1305             : char * __libdw_debugdir (int fd);
    1306             : 
    1307             : 
    1308             : /* Given the directory of a debug file, an absolute or relative dir
    1309             :    to look in, and file returns a full path.
    1310             : 
    1311             :    If the file is absolute (starts with a /) a copy of file is returned.
    1312             :    the file isn't absolute, but dir is absolute, then a path that is
    1313             :    the concatenation of dir and file is returned.  If neither file,
    1314             :    nor dir is absolute, the path will be constructed using dir (if not
    1315             :    NULL) and file relative to the debugdir (if valid).
    1316             : 
    1317             :    The debugdir and the dir may be NULL (in which case they aren't used).
    1318             :    If file is NULL, or no full path can be constructed NULL is returned.
    1319             : 
    1320             :    The caller is responsible for freeing the result if not NULL.  */
    1321             : char * __libdw_filepath (const char *debugdir, const char *dir,
    1322             :                          const char *file)
    1323             :   internal_function;
    1324             : 
    1325             : 
    1326             : /* Aliases to avoid PLTs.  */
    1327             : INTDECL (dwarf_aggregate_size)
    1328             : INTDECL (dwarf_attr)
    1329             : INTDECL (dwarf_attr_integrate)
    1330             : INTDECL (dwarf_begin)
    1331             : INTDECL (dwarf_begin_elf)
    1332             : INTDECL (dwarf_child)
    1333             : INTDECL (dwarf_default_lower_bound)
    1334             : INTDECL (dwarf_dieoffset)
    1335             : INTDECL (dwarf_diename)
    1336             : INTDECL (dwarf_end)
    1337             : INTDECL (dwarf_entrypc)
    1338             : INTDECL (dwarf_errmsg)
    1339             : INTDECL (dwarf_formaddr)
    1340             : INTDECL (dwarf_formblock)
    1341             : INTDECL (dwarf_formref_die)
    1342             : INTDECL (dwarf_formsdata)
    1343             : INTDECL (dwarf_formstring)
    1344             : INTDECL (dwarf_formudata)
    1345             : INTDECL (dwarf_getabbrevattr_data)
    1346             : INTDECL (dwarf_getalt)
    1347             : INTDECL (dwarf_getarange_addr)
    1348             : INTDECL (dwarf_getarangeinfo)
    1349             : INTDECL (dwarf_getaranges)
    1350             : INTDECL (dwarf_getlocation_die)
    1351             : INTDECL (dwarf_getsrcfiles)
    1352             : INTDECL (dwarf_getsrclines)
    1353             : INTDECL (dwarf_hasattr)
    1354             : INTDECL (dwarf_haschildren)
    1355             : INTDECL (dwarf_haspc)
    1356             : INTDECL (dwarf_highpc)
    1357             : INTDECL (dwarf_lowpc)
    1358             : INTDECL (dwarf_nextcu)
    1359             : INTDECL (dwarf_next_unit)
    1360             : INTDECL (dwarf_offdie)
    1361             : INTDECL (dwarf_peel_type)
    1362             : INTDECL (dwarf_ranges)
    1363             : INTDECL (dwarf_setalt)
    1364             : INTDECL (dwarf_siblingof)
    1365             : INTDECL (dwarf_srclang)
    1366             : INTDECL (dwarf_tag)
    1367             : 
    1368             : #endif  /* libdwP.h */

Generated by: LCOV version 1.13