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