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

Generated by: LCOV version 1.13