1/* Internal definitions for libdwarf.
2   Copyright (C) 2002, 2003, 2004 Red Hat, Inc.
3   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
4
5   This program is Open Source software; you can redistribute it and/or
6   modify it under the terms of the Open Software License version 1.0 as
7   published by the Open Source Initiative.
8
9   You should have received a copy of the Open Software License along
10   with this program; if not, you may obtain a copy of the Open Software
11   License version 1.0 from http://www.opensource.org/licenses/osl.php or
12   by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
13   3001 King Ranch Road, Ukiah, CA 95482.   */
14
15#ifndef _LIBDWP_H
16#define _LIBDWP_H 1
17
18#include <libintl.h>
19#include <stdbool.h>
20
21#include <libdw.h>
22
23
24/* gettext helper macros.  */
25#define _(Str) dgettext ("elfutils", Str)
26
27
28/* Version of the DWARF specification we support.  */
29#define DWARF_VERSION 2
30
31/* Version of the CIE format.  */
32#define CIE_VERSION 1
33
34
35/* Known location lists.  */
36struct loc_s
37{
38  void *addr;
39  Dwarf_Loc *loc;
40  size_t nloc;
41};
42
43/* Valid indeces for the section data.  */
44enum
45  {
46    IDX_debug_info = 0,
47    IDX_debug_abbrev,
48    IDX_debug_aranges,
49    IDX_debug_line,
50    IDX_debug_frame,
51    IDX_eh_frame,
52    IDX_debug_loc,
53    IDX_debug_pubnames,
54    IDX_debug_str,
55    IDX_debug_funcnames,
56    IDX_debug_typenames,
57    IDX_debug_varnames,
58    IDX_debug_weaknames,
59    IDX_debug_macinfo,
60    IDX_last
61  };
62
63
64/* Error values.  */
65enum
66{
67  DWARF_E_NOERROR = 0,
68  DWARF_E_UNKNOWN_ERROR,
69  DWARF_E_INVALID_ACCESS,
70  DWARF_E_NO_REGFILE,
71  DWARF_E_IO_ERROR,
72  DWARF_E_INVALID_ELF,
73  DWARF_E_NO_DWARF,
74  DWARF_E_NOELF,
75  DWARF_E_GETEHDR_ERROR,
76  DWARF_E_NOMEM,
77  DWARF_E_UNIMPL,
78  DWARF_E_INVALID_CMD,
79  DWARF_E_INVALID_VERSION,
80  DWARF_E_INVALID_FILE,
81  DWARF_E_NO_ENTRY,
82  DWARF_E_INVALID_DWARF,
83  DWARF_E_NO_STRING,
84  DWARF_E_NO_ADDR,
85  DWARF_E_NO_CONSTANT,
86  DWARF_E_NO_REFERENCE,
87  DWARF_E_INVALID_REFERENCE,
88  DWARF_E_NO_DEBUG_LINE,
89  DWARF_E_INVALID_DEBUG_LINE,
90  DWARF_E_TOO_BIG,
91  DWARF_E_VERSION,
92  DWARF_E_INVALID_DIR_IDX,
93  DWARF_E_ADDR_OUTOFRANGE,
94  DWARF_E_NO_LOCLIST,
95  DWARF_E_NO_BLOCK,
96  DWARF_E_INVALID_LINE_IDX,
97  DWARF_E_INVALID_ARANGE_IDX,
98  DWARF_E_NO_MATCH,
99  DWARF_E_NO_FLAG,
100};
101
102
103/* This is the structure representing the debugging state.  */
104struct Dwarf
105{
106  /* The underlying ELF file.  */
107  Elf *elf;
108
109  /* The section data.  */
110  Elf_Data *sectiondata[IDX_last];
111
112  /* True if the file has a byte order different from the host.  */
113  bool other_byte_order;
114
115  /* If true, we allocated the ELF descriptor ourselves.  */
116  bool free_elf;
117
118  /* Information for traversing the .debug_pubnames section.  This is
119     an array and separately allocated with malloc.  */
120  struct pubnames_s
121  {
122    Dwarf_Off cu_offset;
123    Dwarf_Off set_start;
124    unsigned int cu_header_size;
125    int address_len;
126  } *pubnames_sets;
127  size_t pubnames_nsets;
128
129  /* Search tree for the CUs.  */
130  void *cu_tree;
131  Dwarf_Off next_cu_offset;
132
133  /* Address ranges.  */
134  Dwarf_Aranges *aranges;
135
136  /* Internal memory handling.  This is basically a simplified
137     reimplementation of obstacks.  Unfortunately the standard obstack
138     implementation is not usable in libraries.  */
139  struct libdw_memblock
140  {
141    size_t size;
142    size_t remaining;
143    struct libdw_memblock *prev;
144    char mem[0];
145  } *mem_tail;
146
147  /* Default size of allocated memory blocks.  */
148  size_t mem_default_size;
149
150  /* Registered OOM handler.  */
151  Dwarf_OOM oom_handler;
152};
153
154
155/* Abbreviation representation.  */
156struct Dwarf_Abbrev
157{
158  unsigned int code;
159  unsigned int tag;
160  int has_children;
161  unsigned int attrcnt;
162  unsigned char *attrp;
163  Dwarf_Off offset;
164};
165
166#include "dwarf_abbrev_hash.h"
167
168
169/* Files in line information records.  */
170struct Dwarf_Files_s
171  {
172    Dwarf *dbg;
173    unsigned int nfiles;
174    struct Dwarf_Fileinfo_s
175    {
176      char *name;
177      Dwarf_Word mtime;
178      Dwarf_Word length;
179    } info[0];
180  };
181typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo;
182
183
184/* Representation of a row in the line table.  */
185struct Dwarf_Lines_s
186  {
187    size_t nlines;
188
189    struct Dwarf_Line_s
190    {
191      Dwarf_Addr addr;
192      unsigned int file;
193      int line;
194      unsigned short int column;
195      unsigned int is_stmt:1;
196      unsigned int basic_block:1;
197      unsigned int end_sequence:1;
198      unsigned int prologue_end:1;
199      unsigned int epilogue_begin:1;
200
201      Dwarf_Files *files;
202    } info[0];
203  };
204
205
206/* Representation of address ranges.  */
207struct Dwarf_Aranges_s
208{
209  Dwarf *dbg;
210  size_t naranges;
211
212  struct Dwarf_Arange_s
213  {
214    Dwarf_Addr addr;
215    Dwarf_Word length;
216    Dwarf_Off offset;
217  } info[0];
218};
219
220
221/* CU representation.  */
222struct Dwarf_CU
223{
224  Dwarf *dbg;
225  Dwarf_Off start;
226  Dwarf_Off end;
227  uint8_t address_size;
228  uint8_t offset_size;
229
230  /* Hash table for the abbreviations.  */
231  Dwarf_Abbrev_Hash abbrev_hash;
232  /* Offset of the first abbreviation.  */
233  size_t orig_abbrev_offset;
234  /* Offset past last read abbreviation.  */
235  size_t last_abbrev_offset;
236
237  /* The srcline information.  */
238  Dwarf_Lines *lines;
239
240  /* The source file information.  */
241  Dwarf_Files *files;
242
243  /* Known location lists.  */
244  void *locs;
245};
246
247
248/* We have to include the file at this point because the inline
249   functions access internals of the Dwarf structure.  */
250#include "memory-access.h"
251
252
253/* Set error value.  */
254extern void __libdw_seterrno (int value) internal_function;
255
256
257/* Memory handling, the easy parts.  This macro does not do any locking.  */
258#define libdw_alloc(dbg, type, tsize, cnt) \
259  ({ struct libdw_memblock *_tail = (dbg)->mem_tail;			      \
260     size_t _required = (tsize) * (cnt);				      \
261     type *_result = (type *) (_tail->mem + (_tail->size - _tail->remaining));\
262     size_t _padding = ((__alignof (type)				      \
263			 - ((uintptr_t) _result & (__alignof (type) - 1)))    \
264			& (__alignof (type) - 1));			      \
265     if (unlikely (_tail->remaining < _required + _padding))		      \
266       {								      \
267	 _result = (type *) __libdw_allocate (dbg, _required);		      \
268	 _tail = (dbg)->mem_tail;					      \
269       }								      \
270     else								      \
271       {								      \
272	 _required += _padding;						      \
273	 _result = (type *) ((char *) _result + _padding);		      \
274       }								      \
275     _tail->remaining -= _required;					      \
276     _result; })
277
278#define libdw_typed_alloc(dbg, type) \
279  libdw_alloc (dbg, type, sizeof (type), 1)
280
281/* Callback to allocate more.  */
282extern void *__libdw_allocate (Dwarf *dbg, size_t minsize)
283     __attribute__ ((__malloc__)) __nonnull_attribute__ (1);
284
285/* Default OOM handler.  */
286extern void __libdw_oom (void) __attribute ((noreturn, visibility ("hidden")));
287
288/* Find CU for given offset.  */
289extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset)
290     __nonnull_attribute__ (1) internal_function;
291
292/* Return tag of given DIE.  */
293extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu,
294					 unsigned int code)
295     __nonnull_attribute__ (1) internal_function;
296
297/* Get abbreviation at given offset.  */
298extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu,
299					Dwarf_Off offset, size_t *lengthp,
300					Dwarf_Abbrev *result)
301     __nonnull_attribute__ (1) internal_function;
302
303/* Helper functions for form handling.  */
304extern size_t __libdw_form_val_len (Dwarf *dbg, struct Dwarf_CU *cu,
305				    unsigned int form, unsigned char *valp)
306     __nonnull_attribute__ (1, 2, 4) internal_function;
307
308/* Helper function to locate attribute.  */
309extern unsigned char *__libdw_find_attr (Dwarf_Die *die,
310					 unsigned int search_name,
311					 unsigned int *codep,
312					 unsigned int *formp)
313     __nonnull_attribute__ (1) internal_function;
314
315#endif	/* libdwP.h */
316