libdwP.h revision de2ed97f33139af5c7a0811e4ec66fc896a13cf2
1/* Internal definitions for libdwarf.
2   Copyright (C) 2002-2011 Red Hat, Inc.
3   This file is part of elfutils.
4   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
5
6   This file is free software; you can redistribute it and/or modify
7   it under the terms of either
8
9     * the GNU Lesser General Public License as published by the Free
10       Software Foundation; either version 3 of the License, or (at
11       your option) any later version
12
13   or
14
15     * the GNU General Public License as published by the Free
16       Software Foundation; either version 2 of the License, or (at
17       your option) any later version
18
19   or both in parallel, as here.
20
21   elfutils is distributed in the hope that it will be useful, but
22   WITHOUT ANY WARRANTY; without even the implied warranty of
23   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24   General Public License for more details.
25
26   You should have received copies of the GNU General Public License and
27   the GNU Lesser General Public License along with this program.  If
28   not, see <http://www.gnu.org/licenses/>.  */
29
30#ifndef _LIBDWP_H
31#define _LIBDWP_H 1
32
33#include <libintl.h>
34#include <stdbool.h>
35
36#include <libdw.h>
37
38
39/* gettext helper macros.  */
40#define _(Str) dgettext ("elfutils", Str)
41
42
43/* Known location expressions already decoded.  */
44struct loc_s
45{
46  void *addr;
47  Dwarf_Op *loc;
48  size_t nloc;
49};
50
51/* Known DW_OP_implicit_value blocks already decoded.
52   This overlaps struct loc_s exactly, but only the
53   first member really has to match.  */
54struct loc_block_s
55{
56  void *addr;
57  unsigned char *data;
58  size_t length;
59};
60
61/* Valid indeces for the section data.  */
62enum
63  {
64    IDX_debug_info = 0,
65    IDX_debug_types,
66    IDX_debug_abbrev,
67    IDX_debug_aranges,
68    IDX_debug_line,
69    IDX_debug_frame,
70    IDX_debug_loc,
71    IDX_debug_pubnames,
72    IDX_debug_str,
73    IDX_debug_macinfo,
74    IDX_debug_ranges,
75    IDX_last
76  };
77
78
79/* Error values.  */
80enum
81{
82  DWARF_E_NOERROR = 0,
83  DWARF_E_UNKNOWN_ERROR,
84  DWARF_E_INVALID_ACCESS,
85  DWARF_E_NO_REGFILE,
86  DWARF_E_IO_ERROR,
87  DWARF_E_INVALID_ELF,
88  DWARF_E_NO_DWARF,
89  DWARF_E_NOELF,
90  DWARF_E_GETEHDR_ERROR,
91  DWARF_E_NOMEM,
92  DWARF_E_UNIMPL,
93  DWARF_E_INVALID_CMD,
94  DWARF_E_INVALID_VERSION,
95  DWARF_E_INVALID_FILE,
96  DWARF_E_NO_ENTRY,
97  DWARF_E_INVALID_DWARF,
98  DWARF_E_NO_STRING,
99  DWARF_E_NO_ADDR,
100  DWARF_E_NO_CONSTANT,
101  DWARF_E_NO_REFERENCE,
102  DWARF_E_INVALID_REFERENCE,
103  DWARF_E_NO_DEBUG_LINE,
104  DWARF_E_INVALID_DEBUG_LINE,
105  DWARF_E_TOO_BIG,
106  DWARF_E_VERSION,
107  DWARF_E_INVALID_DIR_IDX,
108  DWARF_E_ADDR_OUTOFRANGE,
109  DWARF_E_NO_LOCLIST,
110  DWARF_E_NO_BLOCK,
111  DWARF_E_INVALID_LINE_IDX,
112  DWARF_E_INVALID_ARANGE_IDX,
113  DWARF_E_NO_MATCH,
114  DWARF_E_NO_FLAG,
115  DWARF_E_INVALID_OFFSET,
116  DWARF_E_NO_DEBUG_RANGES,
117  DWARF_E_INVALID_CFI,
118};
119
120
121#include "dwarf_sig8_hash.h"
122
123/* This is the structure representing the debugging state.  */
124struct Dwarf
125{
126  /* The underlying ELF file.  */
127  Elf *elf;
128
129  /* The section data.  */
130  Elf_Data *sectiondata[IDX_last];
131
132#if USE_ZLIB
133  /* The 1 << N bit is set if sectiondata[N] is malloc'd decompressed data.  */
134  unsigned int sectiondata_gzip_mask:IDX_last;
135#endif
136
137  /* True if the file has a byte order different from the host.  */
138  bool other_byte_order;
139
140  /* If true, we allocated the ELF descriptor ourselves.  */
141  bool free_elf;
142
143  /* Information for traversing the .debug_pubnames section.  This is
144     an array and separately allocated with malloc.  */
145  struct pubnames_s
146  {
147    Dwarf_Off cu_offset;
148    Dwarf_Off set_start;
149    unsigned int cu_header_size;
150    int address_len;
151  } *pubnames_sets;
152  size_t pubnames_nsets;
153
154  /* Search tree for the CUs.  */
155  void *cu_tree;
156  Dwarf_Off next_cu_offset;
157
158  /* Search tree and sig8 hash table for .debug_types type units.  */
159  void *tu_tree;
160  Dwarf_Off next_tu_offset;
161  Dwarf_Sig8_Hash sig8_hash;
162
163  /* Address ranges.  */
164  Dwarf_Aranges *aranges;
165
166  /* Cached info from the CFI section.  */
167  struct Dwarf_CFI_s *cfi;
168
169  /* Internal memory handling.  This is basically a simplified
170     reimplementation of obstacks.  Unfortunately the standard obstack
171     implementation is not usable in libraries.  */
172  struct libdw_memblock
173  {
174    size_t size;
175    size_t remaining;
176    struct libdw_memblock *prev;
177    char mem[0];
178  } *mem_tail;
179
180  /* Default size of allocated memory blocks.  */
181  size_t mem_default_size;
182
183  /* Registered OOM handler.  */
184  Dwarf_OOM oom_handler;
185};
186
187
188/* Abbreviation representation.  */
189struct Dwarf_Abbrev
190{
191  Dwarf_Off offset;
192  unsigned char *attrp;
193  unsigned int attrcnt;
194  unsigned int code;
195  unsigned int tag;
196  bool has_children;
197};
198
199#include "dwarf_abbrev_hash.h"
200
201
202/* Files in line information records.  */
203struct Dwarf_Files_s
204  {
205    struct Dwarf_CU *cu;
206    unsigned int ndirs;
207    unsigned int nfiles;
208    struct Dwarf_Fileinfo_s
209    {
210      char *name;
211      Dwarf_Word mtime;
212      Dwarf_Word length;
213    } info[0];
214    /* nfiles of those, followed by char *[ndirs].  */
215  };
216typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo;
217
218
219/* Representation of a row in the line table.  */
220
221struct Dwarf_Line_s
222{
223  Dwarf_Files *files;
224
225  Dwarf_Addr addr;
226  unsigned int file;
227  int line;
228  unsigned short int column;
229  unsigned int is_stmt:1;
230  unsigned int basic_block:1;
231  unsigned int end_sequence:1;
232  unsigned int prologue_end:1;
233  unsigned int epilogue_begin:1;
234  /* The remaining bit fields are not flags, but hold values presumed to be
235     small.  All the flags and other bit fields should add up to 48 bits
236     to give the whole struct a nice round size.  */
237  unsigned int op_index:8;
238  unsigned int isa:8;
239  unsigned int discriminator:24;
240};
241
242struct Dwarf_Lines_s
243{
244  size_t nlines;
245  struct Dwarf_Line_s info[0];
246};
247
248/* Representation of address ranges.  */
249struct Dwarf_Aranges_s
250{
251  Dwarf *dbg;
252  size_t naranges;
253
254  struct Dwarf_Arange_s
255  {
256    Dwarf_Addr addr;
257    Dwarf_Word length;
258    Dwarf_Off offset;
259  } info[0];
260};
261
262
263/* CU representation.  */
264struct Dwarf_CU
265{
266  Dwarf *dbg;
267  Dwarf_Off start;
268  Dwarf_Off end;
269  uint8_t address_size;
270  uint8_t offset_size;
271  uint16_t version;
272
273  /* Zero if this is a normal CU.  Nonzero if it is a type unit.  */
274  size_t type_offset;
275  uint64_t type_sig8;
276
277  /* Hash table for the abbreviations.  */
278  Dwarf_Abbrev_Hash abbrev_hash;
279  /* Offset of the first abbreviation.  */
280  size_t orig_abbrev_offset;
281  /* Offset past last read abbreviation.  */
282  size_t last_abbrev_offset;
283
284  /* The srcline information.  */
285  Dwarf_Lines *lines;
286
287  /* The source file information.  */
288  Dwarf_Files *files;
289
290  /* Known location lists.  */
291  void *locs;
292};
293
294/* Compute the offset of a CU's first DIE from its offset.  This
295   is either:
296        LEN       VER     OFFSET    ADDR
297      4-bytes + 2-bytes + 4-bytes + 1-byte  for 32-bit dwarf
298     12-bytes + 2-bytes + 8-bytes + 1-byte  for 64-bit dwarf
299   or in .debug_types, 			     SIGNATURE TYPE-OFFSET
300      4-bytes + 2-bytes + 4-bytes + 1-byte + 8-bytes + 4-bytes  for 32-bit
301     12-bytes + 2-bytes + 8-bytes + 1-byte + 8-bytes + 8-bytes  for 64-bit
302
303   Note the trick in the computation.  If the offset_size is 4
304   the '- 4' term changes the '3 *' into a '2 *'.  If the
305   offset_size is 8 it accounts for the 4-byte escape value
306   used at the start of the length.  */
307#define DIE_OFFSET_FROM_CU_OFFSET(cu_offset, offset_size, type_unit)	\
308  ((type_unit) ? ((cu_offset) + 4 * (offset_size) - 4 + 3 + 8)		\
309   : ((cu_offset) + 3 * (offset_size) - 4 + 3))
310
311#define CUDIE(fromcu)							      \
312  ((Dwarf_Die)								      \
313   {									      \
314     .cu = (fromcu),							      \
315     .addr = ((char *) cu_data (fromcu)->d_buf				      \
316	      + DIE_OFFSET_FROM_CU_OFFSET ((fromcu)->start,		      \
317					   (fromcu)->offset_size,	      \
318					   (fromcu)->type_offset != 0))	      \
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#if USE_ZLIB
373extern void __libdw_free_zdata (Dwarf *dwarf) internal_function;
374#else
375# define __libdw_free_zdata(dwarf)	((void) (dwarf))
376#endif
377
378/* Allocate the internal data for a unit not seen before.  */
379extern struct Dwarf_CU *__libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
380     __nonnull_attribute__ (1) internal_function;
381
382/* Find CU for given offset.  */
383extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset, bool tu)
384     __nonnull_attribute__ (1) internal_function;
385
386/* Return tag of given DIE.  */
387extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu,
388					 unsigned int code)
389     __nonnull_attribute__ (1) internal_function;
390
391/* Get abbreviation at given offset.  */
392extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu,
393					Dwarf_Off offset, size_t *lengthp,
394					Dwarf_Abbrev *result)
395     __nonnull_attribute__ (1) internal_function;
396
397/* Helper functions for form handling.  */
398extern size_t __libdw_form_val_len (Dwarf *dbg, struct Dwarf_CU *cu,
399				    unsigned int form,
400				    const unsigned char *valp)
401     __nonnull_attribute__ (1, 2, 4) internal_function;
402
403/* Helper function for DW_FORM_ref* handling.  */
404extern int __libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset)
405     __nonnull_attribute__ (1, 2) internal_function;
406
407
408/* Helper function to locate attribute.  */
409extern unsigned char *__libdw_find_attr (Dwarf_Die *die,
410					 unsigned int search_name,
411					 unsigned int *codep,
412					 unsigned int *formp)
413     __nonnull_attribute__ (1) internal_function;
414
415/* Helper function to access integer attribute.  */
416extern int __libdw_attr_intval (Dwarf_Die *die, int *valp, int attval)
417     __nonnull_attribute__ (1, 2) internal_function;
418
419/* Helper function to walk scopes.  */
420struct Dwarf_Die_Chain
421{
422  Dwarf_Die die;
423  struct Dwarf_Die_Chain *parent;
424  bool prune;			/* The PREVISIT function can set this.  */
425};
426extern int __libdw_visit_scopes (unsigned int depth,
427				 struct Dwarf_Die_Chain *root,
428				 int (*previsit) (unsigned int depth,
429						  struct Dwarf_Die_Chain *,
430						  void *arg),
431				 int (*postvisit) (unsigned int depth,
432						   struct Dwarf_Die_Chain *,
433						   void *arg),
434				 void *arg)
435  __nonnull_attribute__ (2, 3) internal_function;
436
437/* Parse a DWARF Dwarf_Block into an array of Dwarf_Op's,
438   and cache the result (via tsearch).  */
439extern int __libdw_intern_expression (Dwarf *dbg,
440				      bool other_byte_order,
441				      unsigned int address_size,
442				      unsigned int ref_size,
443				      void **cache, const Dwarf_Block *block,
444				      bool cfap, bool valuep,
445				      Dwarf_Op **llbuf, size_t *listlen,
446				      int sec_index)
447  __nonnull_attribute__ (5, 6, 9, 10) internal_function;
448
449extern Dwarf_Die *__libdw_offdie (Dwarf *dbg, Dwarf_Off offset,
450				  Dwarf_Die *result, bool debug_types)
451  internal_function;
452
453
454/* Return error code of last failing function call.  This value is kept
455   separately for each thread.  */
456extern int __dwarf_errno_internal (void);
457
458
459/* Reader hooks.  */
460
461/* Relocation hooks return -1 on error (in that case the error code
462   must already have been set), 0 if there is no relocation and 1 if a
463   relocation was present.*/
464
465static inline int
466__libdw_relocate_address (Dwarf *dbg __attribute__ ((unused)),
467			  int sec_index __attribute__ ((unused)),
468			  const void *addr __attribute__ ((unused)),
469			  int width __attribute__ ((unused)),
470			  Dwarf_Addr *val __attribute__ ((unused)))
471{
472  return 0;
473}
474
475static inline int
476__libdw_relocate_offset (Dwarf *dbg __attribute__ ((unused)),
477			 int sec_index __attribute__ ((unused)),
478			 const void *addr __attribute__ ((unused)),
479			 int width __attribute__ ((unused)),
480			 Dwarf_Off *val __attribute__ ((unused)))
481{
482  return 0;
483}
484
485static inline Elf_Data *
486__libdw_checked_get_data (Dwarf *dbg, int sec_index)
487{
488  Elf_Data *data = dbg->sectiondata[sec_index];
489  if (unlikely (data == NULL)
490      || unlikely (data->d_buf == NULL))
491    {
492      __libdw_seterrno (DWARF_E_INVALID_DWARF);
493      return NULL;
494    }
495  return data;
496}
497
498static inline int
499__libdw_offset_in_section (Dwarf *dbg, int sec_index,
500			   Dwarf_Off offset, size_t size)
501{
502  Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
503  if (data == NULL)
504    return -1;
505  if (unlikely (offset > data->d_size)
506      || unlikely (data->d_size - offset < size))
507    {
508      __libdw_seterrno (DWARF_E_INVALID_OFFSET);
509      return -1;
510    }
511
512  return 0;
513}
514
515static inline bool
516__libdw_in_section (Dwarf *dbg, int sec_index,
517		    const void *addr, size_t size)
518{
519  Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
520  if (data == NULL)
521    return false;
522  if (unlikely (addr < data->d_buf)
523      || unlikely (data->d_size - (addr - data->d_buf) < size))
524    {
525      __libdw_seterrno (DWARF_E_INVALID_OFFSET);
526      return false;
527    }
528
529  return true;
530}
531
532#define READ_AND_RELOCATE(RELOC_HOOK, VAL)				\
533  ({									\
534    if (!__libdw_in_section (dbg, sec_index, addr, width))		\
535      return -1;							\
536									\
537    const unsigned char *orig_addr = addr;				\
538    if (width == 4)							\
539      VAL = read_4ubyte_unaligned_inc (dbg, addr);			\
540    else								\
541      VAL = read_8ubyte_unaligned_inc (dbg, addr);			\
542									\
543    int status = RELOC_HOOK (dbg, sec_index, orig_addr, width, &VAL);	\
544    if (status < 0)							\
545      return status;							\
546    status > 0;								\
547   })
548
549static inline int
550__libdw_read_address_inc (Dwarf *dbg,
551			  int sec_index, const unsigned char **addrp,
552			  int width, Dwarf_Addr *ret)
553{
554  const unsigned char *addr = *addrp;
555  READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
556  *addrp = addr;
557  return 0;
558}
559
560static inline int
561__libdw_read_address (Dwarf *dbg,
562		      int sec_index, const unsigned char *addr,
563		      int width, Dwarf_Addr *ret)
564{
565  READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
566  return 0;
567}
568
569static inline int
570__libdw_read_offset_inc (Dwarf *dbg,
571			 int sec_index, const unsigned char **addrp,
572			 int width, Dwarf_Off *ret, int sec_ret,
573			 size_t size)
574{
575  const unsigned char *addr = *addrp;
576  READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
577  *addrp = addr;
578  return __libdw_offset_in_section (dbg, sec_ret, *ret, size);
579}
580
581static inline int
582__libdw_read_offset (Dwarf *dbg,
583		     int sec_index, const unsigned char *addr,
584		     int width, Dwarf_Off *ret, int sec_ret,
585		     size_t size)
586{
587  READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
588  return __libdw_offset_in_section (dbg, sec_ret, *ret, size);
589}
590
591static inline size_t
592cu_sec_idx (struct Dwarf_CU *cu)
593{
594  return cu->type_offset == 0 ? IDX_debug_info : IDX_debug_types;
595}
596
597static inline Elf_Data *
598cu_data (struct Dwarf_CU *cu)
599{
600  return cu->dbg->sectiondata[cu_sec_idx (cu)];
601}
602
603/* Read up begin/end pair and increment read pointer.
604    - If it's normal range record, set up *BEGINP and *ENDP and return 0.
605    - If it's base address selection record, set up *BASEP and return 1.
606    - If it's end of rangelist, don't set anything and return 2
607    - If an error occurs, don't set anything and return <0.  */
608int __libdw_read_begin_end_pair_inc (Dwarf *dbg, int sec_index,
609				     unsigned char **addr, int width,
610				     Dwarf_Addr *beginp, Dwarf_Addr *endp,
611				     Dwarf_Addr *basep)
612  internal_function;
613
614unsigned char * __libdw_formptr (Dwarf_Attribute *attr, int sec_index,
615				 int err_nodata, unsigned char **endpp,
616				 Dwarf_Off *offsetp)
617  internal_function;
618
619
620
621/* Aliases to avoid PLTs.  */
622INTDECL (dwarf_aggregate_size)
623INTDECL (dwarf_attr)
624INTDECL (dwarf_attr_integrate)
625INTDECL (dwarf_begin_elf)
626INTDECL (dwarf_child)
627INTDECL (dwarf_dieoffset)
628INTDECL (dwarf_diename)
629INTDECL (dwarf_end)
630INTDECL (dwarf_entrypc)
631INTDECL (dwarf_errmsg)
632INTDECL (dwarf_formaddr)
633INTDECL (dwarf_formblock)
634INTDECL (dwarf_formref_die)
635INTDECL (dwarf_formsdata)
636INTDECL (dwarf_formstring)
637INTDECL (dwarf_formudata)
638INTDECL (dwarf_getarange_addr)
639INTDECL (dwarf_getarangeinfo)
640INTDECL (dwarf_getaranges)
641INTDECL (dwarf_getsrcfiles)
642INTDECL (dwarf_getsrclines)
643INTDECL (dwarf_hasattr)
644INTDECL (dwarf_haschildren)
645INTDECL (dwarf_haspc)
646INTDECL (dwarf_highpc)
647INTDECL (dwarf_lowpc)
648INTDECL (dwarf_nextcu)
649INTDECL (dwarf_next_unit)
650INTDECL (dwarf_offdie)
651INTDECL (dwarf_ranges)
652INTDECL (dwarf_siblingof)
653INTDECL (dwarf_srclang)
654INTDECL (dwarf_tag)
655
656#endif	/* libdwP.h */
657