Home | History | Annotate | Download | only in libdw
      1 /* Internal definitions for libdwarf.
      2    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc.
      3    This file is part of Red Hat elfutils.
      4    Written by Ulrich Drepper <drepper (at) redhat.com>, 2002.
      5 
      6    Red Hat elfutils is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by the
      8    Free Software Foundation; version 2 of the License.
      9 
     10    Red Hat elfutils is distributed in the hope that it will be useful, but
     11    WITHOUT ANY WARRANTY; without even the implied warranty of
     12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13    General Public License for more details.
     14 
     15    You should have received a copy of the GNU General Public License along
     16    with Red Hat elfutils; if not, write to the Free Software Foundation,
     17    Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
     18 
     19    In addition, as a special exception, Red Hat, Inc. gives You the
     20    additional right to link the code of Red Hat elfutils with code licensed
     21    under any Open Source Initiative certified open source license
     22    (http://www.opensource.org/licenses/index.php) which requires the
     23    distribution of source code with any binary distribution and to
     24    distribute linked combinations of the two.  Non-GPL Code permitted under
     25    this exception must only link to the code of Red Hat elfutils through
     26    those well defined interfaces identified in the file named EXCEPTION
     27    found in the source code files (the "Approved Interfaces").  The files
     28    of Non-GPL Code may instantiate templates or use macros or inline
     29    functions from the Approved Interfaces without causing the resulting
     30    work to be covered by the GNU General Public License.  Only Red Hat,
     31    Inc. may make changes or additions to the list of Approved Interfaces.
     32    Red Hat's grant of this exception is conditioned upon your not adding
     33    any new exceptions.  If you wish to add a new Approved Interface or
     34    exception, please contact Red Hat.  You must obey the GNU General Public
     35    License in all respects for all of the Red Hat elfutils code and other
     36    code used in conjunction with Red Hat elfutils except the Non-GPL Code
     37    covered by this exception.  If you modify this file, you may extend this
     38    exception to your version of the file, but you are not obligated to do
     39    so.  If you do not wish to provide this exception without modification,
     40    you must delete this exception statement from your version and license
     41    this file solely under the GPL without exception.
     42 
     43    Red Hat elfutils is an included package of the Open Invention Network.
     44    An included package of the Open Invention Network is a package for which
     45    Open Invention Network licensees cross-license their patents.  No patent
     46    license is granted, either expressly or impliedly, by designation as an
     47    included package.  Should you wish to participate in the Open Invention
     48    Network licensing program, please visit www.openinventionnetwork.com
     49    <http://www.openinventionnetwork.com>.  */
     50 
     51 #ifndef _LIBDWP_H
     52 #define _LIBDWP_H 1
     53 
     54 #include <libintl.h>
     55 #include <stdbool.h>
     56 
     57 #include <libdw.h>
     58 
     59 
     60 /* gettext helper macros.  */
     61 #define _(Str) dgettext ("elfutils", Str)
     62 
     63 
     64 /* Version of the DWARF specification we support.  */
     65 #define DWARF_VERSION 3
     66 
     67 /* Version of the CIE format.  */
     68 #define CIE_VERSION 1
     69 
     70 
     71 /* Known location expressions already decoded.  */
     72 struct loc_s
     73 {
     74   void *addr;
     75   Dwarf_Op *loc;
     76   size_t nloc;
     77 };
     78 
     79 /* Valid indeces for the section data.  */
     80 enum
     81   {
     82     IDX_debug_info = 0,
     83     IDX_debug_abbrev,
     84     IDX_debug_aranges,
     85     IDX_debug_line,
     86     IDX_debug_frame,
     87     IDX_eh_frame,
     88     IDX_debug_loc,
     89     IDX_debug_pubnames,
     90     IDX_debug_str,
     91     IDX_debug_funcnames,
     92     IDX_debug_typenames,
     93     IDX_debug_varnames,
     94     IDX_debug_weaknames,
     95     IDX_debug_macinfo,
     96     IDX_debug_ranges,
     97     IDX_last
     98   };
     99 
    100 
    101 /* Error values.  */
    102 enum
    103 {
    104   DWARF_E_NOERROR = 0,
    105   DWARF_E_UNKNOWN_ERROR,
    106   DWARF_E_INVALID_ACCESS,
    107   DWARF_E_NO_REGFILE,
    108   DWARF_E_IO_ERROR,
    109   DWARF_E_INVALID_ELF,
    110   DWARF_E_NO_DWARF,
    111   DWARF_E_NOELF,
    112   DWARF_E_GETEHDR_ERROR,
    113   DWARF_E_NOMEM,
    114   DWARF_E_UNIMPL,
    115   DWARF_E_INVALID_CMD,
    116   DWARF_E_INVALID_VERSION,
    117   DWARF_E_INVALID_FILE,
    118   DWARF_E_NO_ENTRY,
    119   DWARF_E_INVALID_DWARF,
    120   DWARF_E_NO_STRING,
    121   DWARF_E_NO_ADDR,
    122   DWARF_E_NO_CONSTANT,
    123   DWARF_E_NO_REFERENCE,
    124   DWARF_E_INVALID_REFERENCE,
    125   DWARF_E_NO_DEBUG_LINE,
    126   DWARF_E_INVALID_DEBUG_LINE,
    127   DWARF_E_TOO_BIG,
    128   DWARF_E_VERSION,
    129   DWARF_E_INVALID_DIR_IDX,
    130   DWARF_E_ADDR_OUTOFRANGE,
    131   DWARF_E_NO_LOCLIST,
    132   DWARF_E_NO_BLOCK,
    133   DWARF_E_INVALID_LINE_IDX,
    134   DWARF_E_INVALID_ARANGE_IDX,
    135   DWARF_E_NO_MATCH,
    136   DWARF_E_NO_FLAG,
    137   DWARF_E_INVALID_OFFSET,
    138   DWARF_E_NO_DEBUG_RANGES,
    139 };
    140 
    141 
    142 /* This is the structure representing the debugging state.  */
    143 struct Dwarf
    144 {
    145   /* The underlying ELF file.  */
    146   Elf *elf;
    147 
    148   /* The section data.  */
    149   Elf_Data *sectiondata[IDX_last];
    150 
    151   /* True if the file has a byte order different from the host.  */
    152   bool other_byte_order;
    153 
    154   /* If true, we allocated the ELF descriptor ourselves.  */
    155   bool free_elf;
    156 
    157   /* Information for traversing the .debug_pubnames section.  This is
    158      an array and separately allocated with malloc.  */
    159   struct pubnames_s
    160   {
    161     Dwarf_Off cu_offset;
    162     Dwarf_Off set_start;
    163     unsigned int cu_header_size;
    164     int address_len;
    165   } *pubnames_sets;
    166   size_t pubnames_nsets;
    167 
    168   /* Search tree for the CUs.  */
    169   void *cu_tree;
    170   Dwarf_Off next_cu_offset;
    171 
    172   /* Address ranges.  */
    173   Dwarf_Aranges *aranges;
    174 
    175   /* Internal memory handling.  This is basically a simplified
    176      reimplementation of obstacks.  Unfortunately the standard obstack
    177      implementation is not usable in libraries.  */
    178   struct libdw_memblock
    179   {
    180     size_t size;
    181     size_t remaining;
    182     struct libdw_memblock *prev;
    183     char mem[0];
    184   } *mem_tail;
    185 
    186   /* Default size of allocated memory blocks.  */
    187   size_t mem_default_size;
    188 
    189   /* Registered OOM handler.  */
    190   Dwarf_OOM oom_handler;
    191 };
    192 
    193 
    194 /* Abbreviation representation.  */
    195 struct Dwarf_Abbrev
    196 {
    197   unsigned int code;
    198   unsigned int tag;
    199   int has_children;
    200   unsigned int attrcnt;
    201   unsigned char *attrp;
    202   Dwarf_Off offset;
    203 };
    204 
    205 #include "dwarf_abbrev_hash.h"
    206 
    207 
    208 /* Files in line information records.  */
    209 struct Dwarf_Files_s
    210   {
    211     Dwarf *dbg;
    212     unsigned int ndirs;
    213     unsigned int nfiles;
    214     struct Dwarf_Fileinfo_s
    215     {
    216       char *name;
    217       Dwarf_Word mtime;
    218       Dwarf_Word length;
    219     } info[0];
    220     /* nfiles of those, followed by char *[ndirs].  */
    221   };
    222 typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo;
    223 
    224 
    225 /* Representation of a row in the line table.  */
    226 struct Dwarf_Lines_s
    227   {
    228     size_t nlines;
    229 
    230     struct Dwarf_Line_s
    231     {
    232       Dwarf_Addr addr;
    233       unsigned int file;
    234       int line;
    235       unsigned short int column;
    236       unsigned int is_stmt:1;
    237       unsigned int basic_block:1;
    238       unsigned int end_sequence:1;
    239       unsigned int prologue_end:1;
    240       unsigned int epilogue_begin:1;
    241 
    242       Dwarf_Files *files;
    243     } info[0];
    244   };
    245 
    246 
    247 /* Representation of address ranges.  */
    248 struct Dwarf_Aranges_s
    249 {
    250   Dwarf *dbg;
    251   size_t naranges;
    252 
    253   struct Dwarf_Arange_s
    254   {
    255     Dwarf_Addr addr;
    256     Dwarf_Word length;
    257     Dwarf_Off offset;
    258   } info[0];
    259 };
    260 
    261 
    262 /* CU representation.  */
    263 struct Dwarf_CU
    264 {
    265   Dwarf *dbg;
    266   Dwarf_Off start;
    267   Dwarf_Off end;
    268   uint8_t address_size;
    269   uint8_t offset_size;
    270   uint16_t version;
    271 
    272   /* Hash table for the abbreviations.  */
    273   Dwarf_Abbrev_Hash abbrev_hash;
    274   /* Offset of the first abbreviation.  */
    275   size_t orig_abbrev_offset;
    276   /* Offset past last read abbreviation.  */
    277   size_t last_abbrev_offset;
    278 
    279   /* The srcline information.  */
    280   Dwarf_Lines *lines;
    281 
    282   /* The source file information.  */
    283   Dwarf_Files *files;
    284 
    285   /* Known location lists.  */
    286   void *locs;
    287 };
    288 
    289 /* Compute the offset of a CU's first DIE from its offset.  This
    290    is either:
    291         LEN       VER     OFFSET    ADDR
    292       4-bytes + 2-bytes + 4-bytes + 1-byte  for 32-bit dwarf
    293      12-bytes + 2-bytes + 8-bytes + 1-byte  for 64-bit dwarf
    294 
    295    Note the trick in the computation.  If the offset_size is 4
    296    the '- 4' term changes the '3 *' into a '2 *'.  If the
    297    offset_size is 8 it accounts for the 4-byte escape value
    298    used at the start of the length.  */
    299 #define DIE_OFFSET_FROM_CU_OFFSET(cu_offset, offset_size) \
    300   ((cu_offset) + 3 * (offset_size) - 4 + 3)
    301 
    302 #define CUDIE(fromcu) \
    303   ((Dwarf_Die)								      \
    304    {									      \
    305      .cu = (fromcu),							      \
    306      .addr = ((char *) (fromcu)->dbg->sectiondata[IDX_debug_info]->d_buf      \
    307 	      + (fromcu)->start + 3 * (fromcu)->offset_size - 4 + 3),	      \
    308    })
    309 
    310 
    311 /* Macro information.  */
    312 struct Dwarf_Macro_s
    313 {
    314   unsigned int opcode;
    315   Dwarf_Word param1;
    316   union
    317   {
    318     Dwarf_Word u;
    319     const char *s;
    320   } param2;
    321 };
    322 
    323 
    324 /* We have to include the file at this point because the inline
    325    functions access internals of the Dwarf structure.  */
    326 #include "memory-access.h"
    327 
    328 
    329 /* Set error value.  */
    330 extern void __libdw_seterrno (int value) internal_function;
    331 
    332 
    333 /* Memory handling, the easy parts.  This macro does not do any locking.  */
    334 #define libdw_alloc(dbg, type, tsize, cnt) \
    335   ({ struct libdw_memblock *_tail = (dbg)->mem_tail;			      \
    336      size_t _required = (tsize) * (cnt);				      \
    337      type *_result = (type *) (_tail->mem + (_tail->size - _tail->remaining));\
    338      size_t _padding = ((__alignof (type)				      \
    339 			 - ((uintptr_t) _result & (__alignof (type) - 1)))    \
    340 			& (__alignof (type) - 1));			      \
    341      if (unlikely (_tail->remaining < _required + _padding))		      \
    342        _result = (type *) __libdw_allocate (dbg, _required, __alignof (type));\
    343      else								      \
    344        {								      \
    345 	 _required += _padding;						      \
    346 	 _result = (type *) ((char *) _result + _padding);		      \
    347 	 _tail->remaining -= _required;					      \
    348        }								      \
    349      _result; })
    350 
    351 #define libdw_typed_alloc(dbg, type) \
    352   libdw_alloc (dbg, type, sizeof (type), 1)
    353 
    354 /* Callback to allocate more.  */
    355 extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align)
    356      __attribute__ ((__malloc__)) __nonnull_attribute__ (1);
    357 
    358 /* Default OOM handler.  */
    359 extern void __libdw_oom (void) __attribute ((noreturn, visibility ("hidden")));
    360 
    361 /* Find CU for given offset.  */
    362 extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset)
    363      __nonnull_attribute__ (1) internal_function;
    364 
    365 /* Return tag of given DIE.  */
    366 extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu,
    367 					 unsigned int code)
    368      __nonnull_attribute__ (1) internal_function;
    369 
    370 /* Get abbreviation at given offset.  */
    371 extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu,
    372 					Dwarf_Off offset, size_t *lengthp,
    373 					Dwarf_Abbrev *result)
    374      __nonnull_attribute__ (1) internal_function;
    375 
    376 /* Helper functions for form handling.  */
    377 extern size_t __libdw_form_val_len (Dwarf *dbg, struct Dwarf_CU *cu,
    378 				    unsigned int form,
    379 				    const unsigned char *valp)
    380      __nonnull_attribute__ (1, 2, 4) internal_function;
    381 
    382 /* Helper function for DW_FORM_ref* handling.  */
    383 extern int __libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset)
    384      __nonnull_attribute__ (1, 2) internal_function;
    385 
    386 
    387 /* Helper function to locate attribute.  */
    388 extern unsigned char *__libdw_find_attr (Dwarf_Die *die,
    389 					 unsigned int search_name,
    390 					 unsigned int *codep,
    391 					 unsigned int *formp)
    392      __nonnull_attribute__ (1) internal_function;
    393 
    394 /* Helper function to access integer attribute.  */
    395 extern int __libdw_attr_intval (Dwarf_Die *die, int *valp, int attval)
    396      __nonnull_attribute__ (1, 2) internal_function;
    397 
    398 /* Helper function to walk scopes.  */
    399 struct Dwarf_Die_Chain
    400 {
    401   Dwarf_Die die;
    402   struct Dwarf_Die_Chain *parent;
    403   bool prune;			/* The PREVISIT function can set this.  */
    404 };
    405 extern int __libdw_visit_scopes (unsigned int depth,
    406 				 struct Dwarf_Die_Chain *root,
    407 				 int (*previsit) (unsigned int depth,
    408 						  struct Dwarf_Die_Chain *,
    409 						  void *arg),
    410 				 int (*postvisit) (unsigned int depth,
    411 						   struct Dwarf_Die_Chain *,
    412 						   void *arg),
    413 				 void *arg)
    414   __nonnull_attribute__ (2, 3) internal_function;
    415 
    416 /* Return error code of last failing function call.  This value is kept
    417    separately for each thread.  */
    418 extern int __dwarf_errno_internal (void);
    419 
    420 
    421 /* Aliases to avoid PLTs.  */
    422 INTDECL (dwarf_attr)
    423 INTDECL (dwarf_attr_integrate)
    424 INTDECL (dwarf_begin_elf)
    425 INTDECL (dwarf_child)
    426 INTDECL (dwarf_dieoffset)
    427 INTDECL (dwarf_diename)
    428 INTDECL (dwarf_end)
    429 INTDECL (dwarf_entrypc)
    430 INTDECL (dwarf_errmsg)
    431 INTDECL (dwarf_formaddr)
    432 INTDECL (dwarf_formblock)
    433 INTDECL (dwarf_formref_die)
    434 INTDECL (dwarf_formsdata)
    435 INTDECL (dwarf_formstring)
    436 INTDECL (dwarf_formudata)
    437 INTDECL (dwarf_getarange_addr)
    438 INTDECL (dwarf_getarangeinfo)
    439 INTDECL (dwarf_getaranges)
    440 INTDECL (dwarf_getsrcfiles)
    441 INTDECL (dwarf_getsrclines)
    442 INTDECL (dwarf_hasattr)
    443 INTDECL (dwarf_haschildren)
    444 INTDECL (dwarf_haspc)
    445 INTDECL (dwarf_highpc)
    446 INTDECL (dwarf_lowpc)
    447 INTDECL (dwarf_nextcu)
    448 INTDECL (dwarf_offdie)
    449 INTDECL (dwarf_ranges)
    450 INTDECL (dwarf_siblingof)
    451 INTDECL (dwarf_tag)
    452 
    453 #endif	/* libdwP.h */
    454