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