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@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.  */
72struct loc_s
73{
74  void *addr;
75  Dwarf_Op *loc;
76  size_t nloc;
77};
78
79/* Valid indeces for the section data.  */
80enum
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.  */
102enum
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.  */
143struct 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.  */
195struct 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.  */
209struct 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  };
222typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo;
223
224
225/* Representation of a row in the line table.  */
226struct 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.  */
248struct 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.  */
263struct 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.  */
312struct 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.  */
330extern 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.  */
355extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align)
356     __attribute__ ((__malloc__)) __nonnull_attribute__ (1);
357
358/* Default OOM handler.  */
359extern void __libdw_oom (void) __attribute ((noreturn, visibility ("hidden")));
360
361/* Find CU for given offset.  */
362extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset)
363     __nonnull_attribute__ (1) internal_function;
364
365/* Return tag of given DIE.  */
366extern 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.  */
371extern 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.  */
377extern 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.  */
383extern 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.  */
388extern 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.  */
395extern 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.  */
399struct Dwarf_Die_Chain
400{
401  Dwarf_Die die;
402  struct Dwarf_Die_Chain *parent;
403  bool prune;			/* The PREVISIT function can set this.  */
404};
405extern 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.  */
418extern int __dwarf_errno_internal (void);
419
420
421/* Aliases to avoid PLTs.  */
422INTDECL (dwarf_attr)
423INTDECL (dwarf_attr_integrate)
424INTDECL (dwarf_begin_elf)
425INTDECL (dwarf_child)
426INTDECL (dwarf_dieoffset)
427INTDECL (dwarf_diename)
428INTDECL (dwarf_end)
429INTDECL (dwarf_entrypc)
430INTDECL (dwarf_errmsg)
431INTDECL (dwarf_formaddr)
432INTDECL (dwarf_formblock)
433INTDECL (dwarf_formref_die)
434INTDECL (dwarf_formsdata)
435INTDECL (dwarf_formstring)
436INTDECL (dwarf_formudata)
437INTDECL (dwarf_getarange_addr)
438INTDECL (dwarf_getarangeinfo)
439INTDECL (dwarf_getaranges)
440INTDECL (dwarf_getsrcfiles)
441INTDECL (dwarf_getsrclines)
442INTDECL (dwarf_hasattr)
443INTDECL (dwarf_haschildren)
444INTDECL (dwarf_haspc)
445INTDECL (dwarf_highpc)
446INTDECL (dwarf_lowpc)
447INTDECL (dwarf_nextcu)
448INTDECL (dwarf_offdie)
449INTDECL (dwarf_ranges)
450INTDECL (dwarf_siblingof)
451INTDECL (dwarf_tag)
452
453#endif	/* libdwP.h */
454