libdwP.h revision 675229bb5dcf38df3c09f7f74e41b861e32dd0f2
15a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/* Internal definitions for libdwarf.
25a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt   Copyright (C) 2002-2010 Red Hat, Inc.
35a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt   This file is part of Red Hat elfutils.
45a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
55a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
65a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt   Red Hat elfutils is free software; you can redistribute it and/or modify
75a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt   it under the terms of the GNU General Public License as published by the
85a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt   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 CIE format.  */
65#define CIE_VERSION 1
66
67
68/* Known location expressions already decoded.  */
69struct loc_s
70{
71  void *addr;
72  Dwarf_Op *loc;
73  size_t nloc;
74};
75
76/* Known DW_OP_implicit_value blocks already decoded.
77   This overlaps struct loc_s exactly, but only the
78   first member really has to match.  */
79struct loc_block_s
80{
81  void *addr;
82  unsigned char *data;
83  size_t length;
84};
85
86/* Valid indeces for the section data.  */
87enum
88  {
89    IDX_debug_info = 0,
90    IDX_debug_abbrev,
91    IDX_debug_aranges,
92    IDX_debug_line,
93    IDX_debug_frame,
94    IDX_debug_loc,
95    IDX_debug_pubnames,
96    IDX_debug_str,
97    IDX_debug_funcnames,
98    IDX_debug_typenames,
99    IDX_debug_varnames,
100    IDX_debug_weaknames,
101    IDX_debug_macinfo,
102    IDX_debug_ranges,
103    IDX_last
104  };
105
106
107/* Error values.  */
108enum
109{
110  DWARF_E_NOERROR = 0,
111  DWARF_E_UNKNOWN_ERROR,
112  DWARF_E_INVALID_ACCESS,
113  DWARF_E_NO_REGFILE,
114  DWARF_E_IO_ERROR,
115  DWARF_E_INVALID_ELF,
116  DWARF_E_NO_DWARF,
117  DWARF_E_NOELF,
118  DWARF_E_GETEHDR_ERROR,
119  DWARF_E_NOMEM,
120  DWARF_E_UNIMPL,
121  DWARF_E_INVALID_CMD,
122  DWARF_E_INVALID_VERSION,
123  DWARF_E_INVALID_FILE,
124  DWARF_E_NO_ENTRY,
125  DWARF_E_INVALID_DWARF,
126  DWARF_E_NO_STRING,
127  DWARF_E_NO_ADDR,
128  DWARF_E_NO_CONSTANT,
129  DWARF_E_NO_REFERENCE,
130  DWARF_E_INVALID_REFERENCE,
131  DWARF_E_NO_DEBUG_LINE,
132  DWARF_E_INVALID_DEBUG_LINE,
133  DWARF_E_TOO_BIG,
134  DWARF_E_VERSION,
135  DWARF_E_INVALID_DIR_IDX,
136  DWARF_E_ADDR_OUTOFRANGE,
137  DWARF_E_NO_LOCLIST,
138  DWARF_E_NO_BLOCK,
139  DWARF_E_INVALID_LINE_IDX,
140  DWARF_E_INVALID_ARANGE_IDX,
141  DWARF_E_NO_MATCH,
142  DWARF_E_NO_FLAG,
143  DWARF_E_INVALID_OFFSET,
144  DWARF_E_NO_DEBUG_RANGES,
145  DWARF_E_INVALID_CFI,
146};
147
148
149/* This is the structure representing the debugging state.  */
150struct Dwarf
151{
152  /* The underlying ELF file.  */
153  Elf *elf;
154
155  /* The section data.  */
156  Elf_Data *sectiondata[IDX_last];
157
158  /* True if the file has a byte order different from the host.  */
159  bool other_byte_order;
160
161  /* If true, we allocated the ELF descriptor ourselves.  */
162  bool free_elf;
163
164  /* Information for traversing the .debug_pubnames section.  This is
165     an array and separately allocated with malloc.  */
166  struct pubnames_s
167  {
168    Dwarf_Off cu_offset;
169    Dwarf_Off set_start;
170    unsigned int cu_header_size;
171    int address_len;
172  } *pubnames_sets;
173  size_t pubnames_nsets;
174
175  /* Search tree for the CUs.  */
176  void *cu_tree;
177  Dwarf_Off next_cu_offset;
178
179  /* Address ranges.  */
180  Dwarf_Aranges *aranges;
181
182  /* Cached info from the CFI section.  */
183  struct Dwarf_CFI_s *cfi;
184
185  /* Internal memory handling.  This is basically a simplified
186     reimplementation of obstacks.  Unfortunately the standard obstack
187     implementation is not usable in libraries.  */
188  struct libdw_memblock
189  {
190    size_t size;
191    size_t remaining;
192    struct libdw_memblock *prev;
193    char mem[0];
194  } *mem_tail;
195
196  /* Default size of allocated memory blocks.  */
197  size_t mem_default_size;
198
199  /* Registered OOM handler.  */
200  Dwarf_OOM oom_handler;
201};
202
203
204/* Abbreviation representation.  */
205struct Dwarf_Abbrev
206{
207  Dwarf_Off offset;
208  unsigned char *attrp;
209  unsigned int attrcnt;
210  unsigned int code;
211  unsigned int tag;
212  bool has_children;
213};
214
215#include "dwarf_abbrev_hash.h"
216
217
218/* Files in line information records.  */
219struct Dwarf_Files_s
220  {
221    struct Dwarf_CU *cu;
222    unsigned int ndirs;
223    unsigned int nfiles;
224    struct Dwarf_Fileinfo_s
225    {
226      char *name;
227      Dwarf_Word mtime;
228      Dwarf_Word length;
229    } info[0];
230    /* nfiles of those, followed by char *[ndirs].  */
231  };
232typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo;
233
234
235/* Representation of a row in the line table.  */
236
237struct Dwarf_Line_s
238{
239  Dwarf_Files *files;
240
241  Dwarf_Addr addr;
242  unsigned int file;
243  int line;
244  unsigned short int column;
245  unsigned int is_stmt:1;
246  unsigned int basic_block:1;
247  unsigned int end_sequence:1;
248  unsigned int prologue_end:1;
249  unsigned int epilogue_begin:1;
250};
251
252struct Dwarf_Lines_s
253{
254  size_t nlines;
255  struct Dwarf_Line_s info[0];
256};
257
258/* Representation of address ranges.  */
259struct Dwarf_Aranges_s
260{
261  Dwarf *dbg;
262  size_t naranges;
263
264  struct Dwarf_Arange_s
265  {
266    Dwarf_Addr addr;
267    Dwarf_Word length;
268    Dwarf_Off offset;
269  } info[0];
270};
271
272
273/* CU representation.  */
274struct Dwarf_CU
275{
276  Dwarf *dbg;
277  Dwarf_Off start;
278  Dwarf_Off end;
279  uint8_t address_size;
280  uint8_t offset_size;
281  uint16_t version;
282
283  /* Hash table for the abbreviations.  */
284  Dwarf_Abbrev_Hash abbrev_hash;
285  /* Offset of the first abbreviation.  */
286  size_t orig_abbrev_offset;
287  /* Offset past last read abbreviation.  */
288  size_t last_abbrev_offset;
289
290  /* The srcline information.  */
291  Dwarf_Lines *lines;
292
293  /* The source file information.  */
294  Dwarf_Files *files;
295
296  /* Known location lists.  */
297  void *locs;
298};
299
300/* Compute the offset of a CU's first DIE from its offset.  This
301   is either:
302        LEN       VER     OFFSET    ADDR
303      4-bytes + 2-bytes + 4-bytes + 1-byte  for 32-bit dwarf
304     12-bytes + 2-bytes + 8-bytes + 1-byte  for 64-bit dwarf
305
306   Note the trick in the computation.  If the offset_size is 4
307   the '- 4' term changes the '3 *' into a '2 *'.  If the
308   offset_size is 8 it accounts for the 4-byte escape value
309   used at the start of the length.  */
310#define DIE_OFFSET_FROM_CU_OFFSET(cu_offset, offset_size) \
311  ((cu_offset) + 3 * (offset_size) - 4 + 3)
312
313#define CUDIE(fromcu) \
314  ((Dwarf_Die)								      \
315   {									      \
316     .cu = (fromcu),							      \
317     .addr = ((char *) (fromcu)->dbg->sectiondata[IDX_debug_info]->d_buf      \
318	      + (fromcu)->start + 3 * (fromcu)->offset_size - 4 + 3),	      \
319   })
320
321
322/* Macro information.  */
323struct Dwarf_Macro_s
324{
325  unsigned int opcode;
326  Dwarf_Word param1;
327  union
328  {
329    Dwarf_Word u;
330    const char *s;
331  } param2;
332};
333
334
335/* We have to include the file at this point because the inline
336   functions access internals of the Dwarf structure.  */
337#include "memory-access.h"
338
339
340/* Set error value.  */
341extern void __libdw_seterrno (int value) internal_function;
342
343
344/* Memory handling, the easy parts.  This macro does not do any locking.  */
345#define libdw_alloc(dbg, type, tsize, cnt) \
346  ({ struct libdw_memblock *_tail = (dbg)->mem_tail;			      \
347     size_t _required = (tsize) * (cnt);				      \
348     type *_result = (type *) (_tail->mem + (_tail->size - _tail->remaining));\
349     size_t _padding = ((__alignof (type)				      \
350			 - ((uintptr_t) _result & (__alignof (type) - 1)))    \
351			& (__alignof (type) - 1));			      \
352     if (unlikely (_tail->remaining < _required + _padding))		      \
353       _result = (type *) __libdw_allocate (dbg, _required, __alignof (type));\
354     else								      \
355       {								      \
356	 _required += _padding;						      \
357	 _result = (type *) ((char *) _result + _padding);		      \
358	 _tail->remaining -= _required;					      \
359       }								      \
360     _result; })
361
362#define libdw_typed_alloc(dbg, type) \
363  libdw_alloc (dbg, type, sizeof (type), 1)
364
365/* Callback to allocate more.  */
366extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align)
367     __attribute__ ((__malloc__)) __nonnull_attribute__ (1);
368
369/* Default OOM handler.  */
370extern void __libdw_oom (void) __attribute ((noreturn, visibility ("hidden")));
371
372/* Find CU for given offset.  */
373extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset)
374     __nonnull_attribute__ (1) internal_function;
375
376/* Return tag of given DIE.  */
377extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu,
378					 unsigned int code)
379     __nonnull_attribute__ (1) internal_function;
380
381/* Get abbreviation at given offset.  */
382extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu,
383					Dwarf_Off offset, size_t *lengthp,
384					Dwarf_Abbrev *result)
385     __nonnull_attribute__ (1) internal_function;
386
387/* Helper functions for form handling.  */
388extern size_t __libdw_form_val_len (Dwarf *dbg, struct Dwarf_CU *cu,
389				    unsigned int form,
390				    const unsigned char *valp)
391     __nonnull_attribute__ (1, 2, 4) internal_function;
392
393/* Helper function for DW_FORM_ref* handling.  */
394extern int __libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset)
395     __nonnull_attribute__ (1, 2) internal_function;
396
397
398/* Helper function to locate attribute.  */
399extern unsigned char *__libdw_find_attr (Dwarf_Die *die,
400					 unsigned int search_name,
401					 unsigned int *codep,
402					 unsigned int *formp)
403     __nonnull_attribute__ (1) internal_function;
404
405/* Helper function to access integer attribute.  */
406extern int __libdw_attr_intval (Dwarf_Die *die, int *valp, int attval)
407     __nonnull_attribute__ (1, 2) internal_function;
408
409/* Helper function to walk scopes.  */
410struct Dwarf_Die_Chain
411{
412  Dwarf_Die die;
413  struct Dwarf_Die_Chain *parent;
414  bool prune;			/* The PREVISIT function can set this.  */
415};
416extern int __libdw_visit_scopes (unsigned int depth,
417				 struct Dwarf_Die_Chain *root,
418				 int (*previsit) (unsigned int depth,
419						  struct Dwarf_Die_Chain *,
420						  void *arg),
421				 int (*postvisit) (unsigned int depth,
422						   struct Dwarf_Die_Chain *,
423						   void *arg),
424				 void *arg)
425  __nonnull_attribute__ (2, 3) internal_function;
426
427/* Parse a DWARF Dwarf_Block into an array of Dwarf_Op's,
428   and cache the result (via tsearch).  */
429extern int __libdw_intern_expression (Dwarf *dbg,
430				      bool other_byte_order,
431				      unsigned int address_size,
432				      unsigned int ref_size,
433				      void **cache, const Dwarf_Block *block,
434				      bool cfap, bool valuep,
435				      Dwarf_Op **llbuf, size_t *listlen,
436				      int sec_index)
437  __nonnull_attribute__ (5, 6, 9, 10) internal_function;
438
439
440/* Return error code of last failing function call.  This value is kept
441   separately for each thread.  */
442extern int __dwarf_errno_internal (void);
443
444
445/* Reader hooks.  */
446
447/* Relocation hooks return -1 on error (in that case the error code
448   must already have been set), 0 if there is no relocation and 1 if a
449   relocation was present.*/
450
451static inline int
452__libdw_relocate_address (Dwarf *dbg __attribute__ ((unused)),
453			  int sec_index __attribute__ ((unused)),
454			  const void *addr __attribute__ ((unused)),
455			  int width __attribute__ ((unused)),
456			  Dwarf_Addr *val __attribute__ ((unused)))
457{
458  return 0;
459}
460
461static inline int
462__libdw_relocate_offset (Dwarf *dbg __attribute__ ((unused)),
463			 int sec_index __attribute__ ((unused)),
464			 const void *addr __attribute__ ((unused)),
465			 int width __attribute__ ((unused)),
466			 Dwarf_Off *val __attribute__ ((unused)))
467{
468  return 0;
469}
470
471static inline Elf_Data *
472__libdw_checked_get_data (Dwarf *dbg, int sec_index)
473{
474  Elf_Data *data = dbg->sectiondata[sec_index];
475  if (unlikely (data == NULL)
476      || unlikely (data->d_buf == NULL))
477    {
478      __libdw_seterrno (DWARF_E_INVALID_DWARF);
479      return NULL;
480    }
481  return data;
482}
483
484static inline int
485__libdw_offset_in_section (Dwarf *dbg, int sec_index,
486			   Dwarf_Off offset, size_t size)
487{
488  Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
489  if (data == NULL)
490    return -1;
491  if (unlikely (offset > data->d_size)
492      || unlikely (data->d_size - offset < size))
493    {
494      __libdw_seterrno (DWARF_E_INVALID_OFFSET);
495      return -1;
496    }
497
498  return 0;
499}
500
501static inline bool
502__libdw_in_section (Dwarf *dbg, int sec_index,
503		    const void *addr, size_t size)
504{
505  Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
506  if (data == NULL)
507    return false;
508  if (unlikely (addr < data->d_buf)
509      || unlikely (data->d_size - (addr - data->d_buf) < size))
510    {
511      __libdw_seterrno (DWARF_E_INVALID_OFFSET);
512      return false;
513    }
514
515  return true;
516}
517
518#define READ_AND_RELOCATE(RELOC_HOOK, VAL)				\
519  ({									\
520    if (!__libdw_in_section (dbg, sec_index, addr, width))		\
521      return -1;							\
522									\
523    const unsigned char *orig_addr = addr;				\
524    if (width == 4)							\
525      VAL = read_4ubyte_unaligned_inc (dbg, addr);			\
526    else								\
527      VAL = read_8ubyte_unaligned_inc (dbg, addr);			\
528									\
529    int status = RELOC_HOOK (dbg, sec_index, orig_addr, width, &VAL);	\
530    if (status < 0)							\
531      return status;							\
532    status > 0;								\
533   })
534
535static inline int
536__libdw_read_address_inc (Dwarf *dbg,
537			  int sec_index, const unsigned char **addrp,
538			  int width, Dwarf_Addr *ret)
539{
540  const unsigned char *addr = *addrp;
541  READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
542  *addrp = addr;
543  return 0;
544}
545
546static inline int
547__libdw_read_address (Dwarf *dbg,
548		      int sec_index, const unsigned char *addr,
549		      int width, Dwarf_Addr *ret)
550{
551  READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
552  return 0;
553}
554
555static inline int
556__libdw_read_offset_inc (Dwarf *dbg,
557			 int sec_index, const unsigned char **addrp,
558			 int width, Dwarf_Off *ret, int sec_ret,
559			 size_t size)
560{
561  const unsigned char *addr = *addrp;
562  READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
563  *addrp = addr;
564  return __libdw_offset_in_section (dbg, sec_ret, *ret, size);
565}
566
567static inline int
568__libdw_read_offset (Dwarf *dbg,
569		     int sec_index, const unsigned char *addr,
570		     int width, Dwarf_Off *ret, int sec_ret,
571		     size_t size)
572{
573  READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
574  return __libdw_offset_in_section (dbg, sec_ret, *ret, size);
575}
576
577/* Read up begin/end pair and increment read pointer.
578    - If it's normal range record, set up *BEGINP and *ENDP and return 0.
579    - If it's base address selection record, set up *BASEP and return 1.
580    - If it's end of rangelist, don't set anything and return 2
581    - If an error occurs, don't set anything and return <0.  */
582int __libdw_read_begin_end_pair_inc (Dwarf *dbg, int sec_index,
583				     unsigned char **addr, int width,
584				     Dwarf_Addr *beginp, Dwarf_Addr *endp,
585				     Dwarf_Addr *basep)
586  internal_function;
587
588unsigned char * __libdw_formptr (Dwarf_Attribute *attr, int sec_index,
589				 int err_nodata, unsigned char **endpp,
590				 Dwarf_Off *offsetp)
591  internal_function;
592
593
594
595/* Aliases to avoid PLTs.  */
596INTDECL (dwarf_aggregate_size)
597INTDECL (dwarf_attr)
598INTDECL (dwarf_attr_integrate)
599INTDECL (dwarf_begin_elf)
600INTDECL (dwarf_child)
601INTDECL (dwarf_dieoffset)
602INTDECL (dwarf_diename)
603INTDECL (dwarf_end)
604INTDECL (dwarf_entrypc)
605INTDECL (dwarf_errmsg)
606INTDECL (dwarf_formaddr)
607INTDECL (dwarf_formblock)
608INTDECL (dwarf_formref_die)
609INTDECL (dwarf_formsdata)
610INTDECL (dwarf_formstring)
611INTDECL (dwarf_formudata)
612INTDECL (dwarf_getarange_addr)
613INTDECL (dwarf_getarangeinfo)
614INTDECL (dwarf_getaranges)
615INTDECL (dwarf_getsrcfiles)
616INTDECL (dwarf_getsrclines)
617INTDECL (dwarf_hasattr)
618INTDECL (dwarf_haschildren)
619INTDECL (dwarf_haspc)
620INTDECL (dwarf_highpc)
621INTDECL (dwarf_lowpc)
622INTDECL (dwarf_nextcu)
623INTDECL (dwarf_offdie)
624INTDECL (dwarf_ranges)
625INTDECL (dwarf_siblingof)
626INTDECL (dwarf_srclang)
627INTDECL (dwarf_tag)
628
629#endif	/* libdwP.h */
630