1/* Internal definitions for libdwarf.
2   Copyright (C) 2002-2011, 2013-2015 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#include <dwarf.h>
38
39
40/* gettext helper macros.  */
41#define _(Str) dgettext ("elfutils", Str)
42
43
44/* Known location expressions already decoded.  */
45struct loc_s
46{
47  void *addr;
48  Dwarf_Op *loc;
49  size_t nloc;
50};
51
52/* Known DW_OP_implicit_value blocks already decoded.
53   This overlaps struct loc_s exactly, but only the
54   first member really has to match.  */
55struct loc_block_s
56{
57  void *addr;
58  unsigned char *data;
59  size_t length;
60};
61
62/* Already decoded .debug_line units.  */
63struct files_lines_s
64{
65  Dwarf_Off debug_line_offset;
66  Dwarf_Files *files;
67  Dwarf_Lines *lines;
68};
69
70/* Valid indeces for the section data.  */
71enum
72  {
73    IDX_debug_info = 0,
74    IDX_debug_types,
75    IDX_debug_abbrev,
76    IDX_debug_aranges,
77    IDX_debug_line,
78    IDX_debug_frame,
79    IDX_debug_loc,
80    IDX_debug_pubnames,
81    IDX_debug_str,
82    IDX_debug_macinfo,
83    IDX_debug_macro,
84    IDX_debug_ranges,
85    IDX_gnu_debugaltlink,
86    IDX_last
87  };
88
89
90/* Error values.  */
91enum
92{
93  DWARF_E_NOERROR = 0,
94  DWARF_E_UNKNOWN_ERROR,
95  DWARF_E_INVALID_ACCESS,
96  DWARF_E_NO_REGFILE,
97  DWARF_E_IO_ERROR,
98  DWARF_E_INVALID_ELF,
99  DWARF_E_NO_DWARF,
100  DWARF_E_COMPRESSED_ERROR,
101  DWARF_E_NOELF,
102  DWARF_E_GETEHDR_ERROR,
103  DWARF_E_NOMEM,
104  DWARF_E_UNIMPL,
105  DWARF_E_INVALID_CMD,
106  DWARF_E_INVALID_VERSION,
107  DWARF_E_INVALID_FILE,
108  DWARF_E_NO_ENTRY,
109  DWARF_E_INVALID_DWARF,
110  DWARF_E_NO_STRING,
111  DWARF_E_NO_ADDR,
112  DWARF_E_NO_CONSTANT,
113  DWARF_E_NO_REFERENCE,
114  DWARF_E_INVALID_REFERENCE,
115  DWARF_E_NO_DEBUG_LINE,
116  DWARF_E_INVALID_DEBUG_LINE,
117  DWARF_E_TOO_BIG,
118  DWARF_E_VERSION,
119  DWARF_E_INVALID_DIR_IDX,
120  DWARF_E_ADDR_OUTOFRANGE,
121  DWARF_E_NO_LOCLIST,
122  DWARF_E_NO_BLOCK,
123  DWARF_E_INVALID_LINE_IDX,
124  DWARF_E_INVALID_ARANGE_IDX,
125  DWARF_E_NO_MATCH,
126  DWARF_E_NO_FLAG,
127  DWARF_E_INVALID_OFFSET,
128  DWARF_E_NO_DEBUG_RANGES,
129  DWARF_E_INVALID_CFI,
130  DWARF_E_NO_ALT_DEBUGLINK,
131  DWARF_E_INVALID_OPCODE,
132  DWARF_E_NOT_CUDIE,
133};
134
135
136#include "dwarf_sig8_hash.h"
137
138/* This is the structure representing the debugging state.  */
139struct Dwarf
140{
141  /* The underlying ELF file.  */
142  Elf *elf;
143
144  /* dwz alternate DWARF file.  */
145  Dwarf *alt_dwarf;
146
147  /* The section data.  */
148  Elf_Data *sectiondata[IDX_last];
149
150  /* True if the file has a byte order different from the host.  */
151  bool other_byte_order;
152
153  /* If true, we allocated the ELF descriptor ourselves.  */
154  bool free_elf;
155
156  /* Information for traversing the .debug_pubnames section.  This is
157     an array and separately allocated with malloc.  */
158  struct pubnames_s
159  {
160    Dwarf_Off cu_offset;
161    Dwarf_Off set_start;
162    unsigned int cu_header_size;
163    int address_len;
164  } *pubnames_sets;
165  size_t pubnames_nsets;
166
167  /* Search tree for the CUs.  */
168  void *cu_tree;
169  Dwarf_Off next_cu_offset;
170
171  /* Search tree and sig8 hash table for .debug_types type units.  */
172  void *tu_tree;
173  Dwarf_Off next_tu_offset;
174  Dwarf_Sig8_Hash sig8_hash;
175
176  /* Search tree for .debug_macro operator tables.  */
177  void *macro_ops;
178
179  /* Search tree for decoded .debug_line units.  */
180  void *files_lines;
181
182  /* Address ranges.  */
183  Dwarf_Aranges *aranges;
184
185  /* Cached info from the CFI section.  */
186  struct Dwarf_CFI_s *cfi;
187
188  /* Fake loc CU.  Used when synthesizing attributes for Dwarf_Ops that
189     came from a location list entry in dwarf_getlocation_attr.  */
190  struct Dwarf_CU *fake_loc_cu;
191
192  /* Internal memory handling.  This is basically a simplified
193     reimplementation of obstacks.  Unfortunately the standard obstack
194     implementation is not usable in libraries.  */
195  struct libdw_memblock
196  {
197    size_t size;
198    size_t remaining;
199    struct libdw_memblock *prev;
200    char mem[0];
201  } *mem_tail;
202
203  /* Default size of allocated memory blocks.  */
204  size_t mem_default_size;
205
206  /* Registered OOM handler.  */
207  Dwarf_OOM oom_handler;
208};
209
210
211/* Abbreviation representation.  */
212struct Dwarf_Abbrev
213{
214  Dwarf_Off offset;
215  unsigned char *attrp;
216  unsigned int attrcnt;
217  unsigned int code;
218  unsigned int tag;
219  bool has_children;
220};
221
222#include "dwarf_abbrev_hash.h"
223
224
225/* Files in line information records.  */
226struct Dwarf_Files_s
227  {
228    unsigned int ndirs;
229    unsigned int nfiles;
230    struct Dwarf_Fileinfo_s
231    {
232      char *name;
233      Dwarf_Word mtime;
234      Dwarf_Word length;
235    } info[0];
236    /* nfiles of those, followed by char *[ndirs].  */
237  };
238typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo;
239
240
241/* Representation of a row in the line table.  */
242
243struct Dwarf_Line_s
244{
245  Dwarf_Files *files;
246
247  Dwarf_Addr addr;
248  unsigned int file;
249  int line;
250  unsigned short int column;
251  unsigned int is_stmt:1;
252  unsigned int basic_block:1;
253  unsigned int end_sequence:1;
254  unsigned int prologue_end:1;
255  unsigned int epilogue_begin:1;
256  /* The remaining bit fields are not flags, but hold values presumed to be
257     small.  All the flags and other bit fields should add up to 48 bits
258     to give the whole struct a nice round size.  */
259  unsigned int op_index:8;
260  unsigned int isa:8;
261  unsigned int discriminator:24;
262};
263
264struct Dwarf_Lines_s
265{
266  size_t nlines;
267  struct Dwarf_Line_s info[0];
268};
269
270/* Representation of address ranges.  */
271struct Dwarf_Aranges_s
272{
273  Dwarf *dbg;
274  size_t naranges;
275
276  struct Dwarf_Arange_s
277  {
278    Dwarf_Addr addr;
279    Dwarf_Word length;
280    Dwarf_Off offset;
281  } info[0];
282};
283
284
285/* CU representation.  */
286struct Dwarf_CU
287{
288  Dwarf *dbg;
289  Dwarf_Off start;
290  Dwarf_Off end;
291  uint8_t address_size;
292  uint8_t offset_size;
293  uint16_t version;
294
295  /* Zero if this is a normal CU.  Nonzero if it is a type unit.  */
296  size_t type_offset;
297  uint64_t type_sig8;
298
299  /* Hash table for the abbreviations.  */
300  Dwarf_Abbrev_Hash abbrev_hash;
301  /* Offset of the first abbreviation.  */
302  size_t orig_abbrev_offset;
303  /* Offset past last read abbreviation.  */
304  size_t last_abbrev_offset;
305
306  /* The srcline information.  */
307  Dwarf_Lines *lines;
308
309  /* The source file information.  */
310  Dwarf_Files *files;
311
312  /* Known location lists.  */
313  void *locs;
314
315  /* Memory boundaries of this CU.  */
316  void *startp;
317  void *endp;
318};
319
320/* Compute the offset of a CU's first DIE from its offset.  This
321   is either:
322        LEN       VER     OFFSET    ADDR
323      4-bytes + 2-bytes + 4-bytes + 1-byte  for 32-bit dwarf
324     12-bytes + 2-bytes + 8-bytes + 1-byte  for 64-bit dwarf
325   or in .debug_types, 			     SIGNATURE TYPE-OFFSET
326      4-bytes + 2-bytes + 4-bytes + 1-byte + 8-bytes + 4-bytes  for 32-bit
327     12-bytes + 2-bytes + 8-bytes + 1-byte + 8-bytes + 8-bytes  for 64-bit
328
329   Note the trick in the computation.  If the offset_size is 4
330   the '- 4' term changes the '3 *' into a '2 *'.  If the
331   offset_size is 8 it accounts for the 4-byte escape value
332   used at the start of the length.  */
333#define DIE_OFFSET_FROM_CU_OFFSET(cu_offset, offset_size, type_unit)	\
334  ((type_unit) ? ((cu_offset) + 4 * (offset_size) - 4 + 3 + 8)		\
335   : ((cu_offset) + 3 * (offset_size) - 4 + 3))
336
337#define CUDIE(fromcu)							      \
338  ((Dwarf_Die)								      \
339   {									      \
340     .cu = (fromcu),							      \
341     .addr = ((char *) fromcu->dbg->sectiondata[cu_sec_idx (fromcu)]->d_buf   \
342	      + DIE_OFFSET_FROM_CU_OFFSET ((fromcu)->start,		      \
343					   (fromcu)->offset_size,	      \
344					   (fromcu)->type_offset != 0))	      \
345   })									      \
346
347
348/* Prototype of a single .debug_macro operator.  */
349typedef struct
350{
351  Dwarf_Word nforms;
352  unsigned char const *forms;
353} Dwarf_Macro_Op_Proto;
354
355/* Prototype table.  */
356typedef struct
357{
358  /* Offset of .debug_macro section.  */
359  Dwarf_Off offset;
360
361  /* Offset of associated .debug_line section.  */
362  Dwarf_Off line_offset;
363
364  /* The source file information.  */
365  Dwarf_Files *files;
366
367  /* If this macro unit was opened through dwarf_getmacros or
368     dwarf_getmacros_die, this caches value of DW_AT_comp_dir, if
369     present.  */
370  const char *comp_dir;
371
372  /* Header length.  */
373  Dwarf_Half header_len;
374
375  uint16_t version;
376  bool is_64bit;
377  uint8_t sec_index;	/* IDX_debug_macro or IDX_debug_macinfo.  */
378
379  /* Shows where in TABLE each opcode is defined.  Since opcode 0 is
380     never used, it stores index of opcode X in X-1'th element.  The
381     value of 0xff means not stored at all.  */
382  unsigned char opcodes[255];
383
384  /* Individual opcode prototypes.  */
385  Dwarf_Macro_Op_Proto table[];
386} Dwarf_Macro_Op_Table;
387
388struct Dwarf_Macro_s
389{
390  Dwarf_Macro_Op_Table *table;
391  Dwarf_Attribute *attributes;
392  uint8_t opcode;
393};
394
395static inline Dwarf_Word
396libdw_macro_nforms (Dwarf_Macro *macro)
397{
398  return macro->table->table[macro->table->opcodes[macro->opcode - 1]].nforms;
399}
400
401/* We have to include the file at this point because the inline
402   functions access internals of the Dwarf structure.  */
403#include "memory-access.h"
404
405
406/* Set error value.  */
407extern void __libdw_seterrno (int value) internal_function;
408
409
410/* Memory handling, the easy parts.  This macro does not do any locking.  */
411#define libdw_alloc(dbg, type, tsize, cnt) \
412  ({ struct libdw_memblock *_tail = (dbg)->mem_tail;			      \
413     size_t _required = (tsize) * (cnt);				      \
414     type *_result = (type *) (_tail->mem + (_tail->size - _tail->remaining));\
415     size_t _padding = ((__alignof (type)				      \
416			 - ((uintptr_t) _result & (__alignof (type) - 1)))    \
417			& (__alignof (type) - 1));			      \
418     if (unlikely (_tail->remaining < _required + _padding))		      \
419       _result = (type *) __libdw_allocate (dbg, _required, __alignof (type));\
420     else								      \
421       {								      \
422	 _required += _padding;						      \
423	 _result = (type *) ((char *) _result + _padding);		      \
424	 _tail->remaining -= _required;					      \
425       }								      \
426     _result; })
427
428#define libdw_typed_alloc(dbg, type) \
429  libdw_alloc (dbg, type, sizeof (type), 1)
430
431/* Callback to allocate more.  */
432extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align)
433     __attribute__ ((__malloc__)) __nonnull_attribute__ (1);
434
435/* Default OOM handler.  */
436extern void __libdw_oom (void) __attribute ((noreturn, visibility ("hidden")));
437
438/* Allocate the internal data for a unit not seen before.  */
439extern struct Dwarf_CU *__libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
440     __nonnull_attribute__ (1) internal_function;
441
442/* Find CU for given offset.  */
443extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset, bool tu)
444     __nonnull_attribute__ (1) internal_function;
445
446/* Get abbreviation with given code.  */
447extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu,
448					 unsigned int code)
449     __nonnull_attribute__ (1) internal_function;
450
451/* Get abbreviation at given offset.  */
452extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu,
453					Dwarf_Off offset, size_t *lengthp,
454					Dwarf_Abbrev *result)
455     __nonnull_attribute__ (1) internal_function;
456
457/* Get abbreviation of given DIE, and optionally set *READP to the DIE memory
458   just past the abbreviation code.  */
459static inline Dwarf_Abbrev *
460__nonnull_attribute__ (1)
461__libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp)
462{
463  /* Do we need to get the abbreviation, or need to read after the code?  */
464  if (die->abbrev == NULL || readp != NULL)
465    {
466      /* Get the abbreviation code.  */
467      unsigned int code;
468      const unsigned char *addr = die->addr;
469      get_uleb128 (code, addr, die->cu->endp);
470      if (readp != NULL)
471	*readp = addr;
472
473      /* Find the abbreviation.  */
474      if (die->abbrev == NULL)
475	die->abbrev = __libdw_findabbrev (die->cu, code);
476    }
477  return die->abbrev;
478}
479
480/* Helper functions for form handling.  */
481extern size_t __libdw_form_val_compute_len (struct Dwarf_CU *cu,
482					    unsigned int form,
483					    const unsigned char *valp)
484     __nonnull_attribute__ (1, 3) internal_function;
485
486/* Find the length of a form attribute.  */
487static inline size_t
488__nonnull_attribute__ (1, 3)
489__libdw_form_val_len (struct Dwarf_CU *cu, unsigned int form,
490		      const unsigned char *valp)
491{
492  /* Small lookup table of forms with fixed lengths.  Absent indexes are
493     initialized 0, so any truly desired 0 is set to 0x80 and masked.  */
494  static const uint8_t form_lengths[] =
495    {
496      [DW_FORM_flag_present] = 0x80,
497      [DW_FORM_data1] = 1, [DW_FORM_ref1] = 1, [DW_FORM_flag] = 1,
498      [DW_FORM_data2] = 2, [DW_FORM_ref2] = 2,
499      [DW_FORM_data4] = 4, [DW_FORM_ref4] = 4,
500      [DW_FORM_data8] = 8, [DW_FORM_ref8] = 8, [DW_FORM_ref_sig8] = 8,
501    };
502
503  /* Return immediately for forms with fixed lengths.  */
504  if (form < sizeof form_lengths / sizeof form_lengths[0])
505    {
506      uint8_t len = form_lengths[form];
507      if (len != 0)
508	{
509	  const unsigned char *endp = cu->endp;
510	  len &= 0x7f; /* Mask to allow 0x80 -> 0.  */
511	  if (unlikely (len > (size_t) (endp - valp)))
512	    {
513	      __libdw_seterrno (DWARF_E_INVALID_DWARF);
514	      return -1;
515	    }
516	  return len;
517	}
518    }
519
520  /* Other forms require some computation.  */
521  return __libdw_form_val_compute_len (cu, form, valp);
522}
523
524/* Helper function for DW_FORM_ref* handling.  */
525extern int __libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset)
526     __nonnull_attribute__ (1, 2) internal_function;
527
528
529/* Helper function to locate attribute.  */
530extern unsigned char *__libdw_find_attr (Dwarf_Die *die,
531					 unsigned int search_name,
532					 unsigned int *codep,
533					 unsigned int *formp)
534     __nonnull_attribute__ (1) internal_function;
535
536/* Helper function to access integer attribute.  */
537extern int __libdw_attr_intval (Dwarf_Die *die, int *valp, int attval)
538     __nonnull_attribute__ (1, 2) internal_function;
539
540/* Helper function to walk scopes.  */
541struct Dwarf_Die_Chain
542{
543  Dwarf_Die die;
544  struct Dwarf_Die_Chain *parent;
545  bool prune;			/* The PREVISIT function can set this.  */
546};
547extern int __libdw_visit_scopes (unsigned int depth,
548				 struct Dwarf_Die_Chain *root,
549				 struct Dwarf_Die_Chain *imports,
550				 int (*previsit) (unsigned int depth,
551						  struct Dwarf_Die_Chain *,
552						  void *arg),
553				 int (*postvisit) (unsigned int depth,
554						   struct Dwarf_Die_Chain *,
555						   void *arg),
556				 void *arg)
557  __nonnull_attribute__ (2, 4) internal_function;
558
559/* Parse a DWARF Dwarf_Block into an array of Dwarf_Op's,
560   and cache the result (via tsearch).  */
561extern int __libdw_intern_expression (Dwarf *dbg,
562				      bool other_byte_order,
563				      unsigned int address_size,
564				      unsigned int ref_size,
565				      void **cache, const Dwarf_Block *block,
566				      bool cfap, bool valuep,
567				      Dwarf_Op **llbuf, size_t *listlen,
568				      int sec_index)
569  __nonnull_attribute__ (5, 6, 9, 10) internal_function;
570
571extern Dwarf_Die *__libdw_offdie (Dwarf *dbg, Dwarf_Off offset,
572				  Dwarf_Die *result, bool debug_types)
573  internal_function;
574
575
576/* Return error code of last failing function call.  This value is kept
577   separately for each thread.  */
578extern int __dwarf_errno_internal (void);
579
580
581/* Reader hooks.  */
582
583/* Relocation hooks return -1 on error (in that case the error code
584   must already have been set), 0 if there is no relocation and 1 if a
585   relocation was present.*/
586
587static inline int
588__libdw_relocate_address (Dwarf *dbg __attribute__ ((unused)),
589			  int sec_index __attribute__ ((unused)),
590			  const void *addr __attribute__ ((unused)),
591			  int width __attribute__ ((unused)),
592			  Dwarf_Addr *val __attribute__ ((unused)))
593{
594  return 0;
595}
596
597static inline int
598__libdw_relocate_offset (Dwarf *dbg __attribute__ ((unused)),
599			 int sec_index __attribute__ ((unused)),
600			 const void *addr __attribute__ ((unused)),
601			 int width __attribute__ ((unused)),
602			 Dwarf_Off *val __attribute__ ((unused)))
603{
604  return 0;
605}
606
607static inline Elf_Data *
608__libdw_checked_get_data (Dwarf *dbg, int sec_index)
609{
610  Elf_Data *data = dbg->sectiondata[sec_index];
611  if (unlikely (data == NULL)
612      || unlikely (data->d_buf == NULL))
613    {
614      __libdw_seterrno (DWARF_E_INVALID_DWARF);
615      return NULL;
616    }
617  return data;
618}
619
620static inline int
621__libdw_offset_in_section (Dwarf *dbg, int sec_index,
622			   Dwarf_Off offset, size_t size)
623{
624  Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
625  if (data == NULL)
626    return -1;
627  if (unlikely (offset > data->d_size)
628      || unlikely (data->d_size - offset < size))
629    {
630      __libdw_seterrno (DWARF_E_INVALID_OFFSET);
631      return -1;
632    }
633
634  return 0;
635}
636
637static inline bool
638__libdw_in_section (Dwarf *dbg, int sec_index,
639		    const void *addr, size_t size)
640{
641  Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
642  if (data == NULL)
643    return false;
644  if (unlikely (addr < data->d_buf)
645      || unlikely (data->d_size - (addr - data->d_buf) < size))
646    {
647      __libdw_seterrno (DWARF_E_INVALID_OFFSET);
648      return false;
649    }
650
651  return true;
652}
653
654#define READ_AND_RELOCATE(RELOC_HOOK, VAL)				\
655  ({									\
656    if (!__libdw_in_section (dbg, sec_index, addr, width))		\
657      return -1;							\
658									\
659    const unsigned char *orig_addr = addr;				\
660    if (width == 4)							\
661      VAL = read_4ubyte_unaligned_inc (dbg, addr);			\
662    else								\
663      VAL = read_8ubyte_unaligned_inc (dbg, addr);			\
664									\
665    int status = RELOC_HOOK (dbg, sec_index, orig_addr, width, &VAL);	\
666    if (status < 0)							\
667      return status;							\
668    status > 0;								\
669   })
670
671static inline int
672__libdw_read_address_inc (Dwarf *dbg,
673			  int sec_index, const unsigned char **addrp,
674			  int width, Dwarf_Addr *ret)
675{
676  const unsigned char *addr = *addrp;
677  READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
678  *addrp = addr;
679  return 0;
680}
681
682static inline int
683__libdw_read_address (Dwarf *dbg,
684		      int sec_index, const unsigned char *addr,
685		      int width, Dwarf_Addr *ret)
686{
687  READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
688  return 0;
689}
690
691static inline int
692__libdw_read_offset_inc (Dwarf *dbg,
693			 int sec_index, const unsigned char **addrp,
694			 int width, Dwarf_Off *ret, int sec_ret,
695			 size_t size)
696{
697  const unsigned char *addr = *addrp;
698  READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
699  *addrp = addr;
700  return __libdw_offset_in_section (dbg, sec_ret, *ret, size);
701}
702
703static inline int
704__libdw_read_offset (Dwarf *dbg, Dwarf *dbg_ret,
705		     int sec_index, const unsigned char *addr,
706		     int width, Dwarf_Off *ret, int sec_ret,
707		     size_t size)
708{
709  READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
710  return __libdw_offset_in_section (dbg_ret, sec_ret, *ret, size);
711}
712
713static inline size_t
714cu_sec_idx (struct Dwarf_CU *cu)
715{
716  return cu->type_offset == 0 ? IDX_debug_info : IDX_debug_types;
717}
718
719static inline bool
720is_cudie (Dwarf_Die *cudie)
721{
722  return CUDIE (cudie->cu).addr == cudie->addr;
723}
724
725/* Read up begin/end pair and increment read pointer.
726    - If it's normal range record, set up *BEGINP and *ENDP and return 0.
727    - If it's base address selection record, set up *BASEP and return 1.
728    - If it's end of rangelist, don't set anything and return 2
729    - If an error occurs, don't set anything and return <0.  */
730int __libdw_read_begin_end_pair_inc (Dwarf *dbg, int sec_index,
731				     unsigned char **addr, int width,
732				     Dwarf_Addr *beginp, Dwarf_Addr *endp,
733				     Dwarf_Addr *basep)
734  internal_function;
735
736unsigned char * __libdw_formptr (Dwarf_Attribute *attr, int sec_index,
737				 int err_nodata, unsigned char **endpp,
738				 Dwarf_Off *offsetp)
739  internal_function;
740
741/* Fills in the given attribute to point at an empty location expression.  */
742void __libdw_empty_loc_attr (Dwarf_Attribute *attr)
743  internal_function;
744
745/* Load .debug_line unit at DEBUG_LINE_OFFSET.  COMP_DIR is a value of
746   DW_AT_comp_dir or NULL if that attribute is not available.  Caches
747   the loaded unit and optionally set *LINESP and/or *FILESP (if not
748   NULL) with loaded information.  Returns 0 for success or a negative
749   value for failure.  */
750int __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
751			 const char *comp_dir, unsigned address_size,
752			 Dwarf_Lines **linesp, Dwarf_Files **filesp)
753  internal_function
754  __nonnull_attribute__ (1);
755
756/* Load and return value of DW_AT_comp_dir from CUDIE.  */
757const char *__libdw_getcompdir (Dwarf_Die *cudie);
758
759
760/* Aliases to avoid PLTs.  */
761INTDECL (dwarf_aggregate_size)
762INTDECL (dwarf_attr)
763INTDECL (dwarf_attr_integrate)
764INTDECL (dwarf_begin)
765INTDECL (dwarf_begin_elf)
766INTDECL (dwarf_child)
767INTDECL (dwarf_dieoffset)
768INTDECL (dwarf_diename)
769INTDECL (dwarf_end)
770INTDECL (dwarf_entrypc)
771INTDECL (dwarf_errmsg)
772INTDECL (dwarf_formaddr)
773INTDECL (dwarf_formblock)
774INTDECL (dwarf_formref_die)
775INTDECL (dwarf_formsdata)
776INTDECL (dwarf_formstring)
777INTDECL (dwarf_formudata)
778INTDECL (dwarf_getalt)
779INTDECL (dwarf_getarange_addr)
780INTDECL (dwarf_getarangeinfo)
781INTDECL (dwarf_getaranges)
782INTDECL (dwarf_getlocation_die)
783INTDECL (dwarf_getsrcfiles)
784INTDECL (dwarf_getsrclines)
785INTDECL (dwarf_hasattr)
786INTDECL (dwarf_haschildren)
787INTDECL (dwarf_haspc)
788INTDECL (dwarf_highpc)
789INTDECL (dwarf_lowpc)
790INTDECL (dwarf_nextcu)
791INTDECL (dwarf_next_unit)
792INTDECL (dwarf_offdie)
793INTDECL (dwarf_peel_type)
794INTDECL (dwarf_ranges)
795INTDECL (dwarf_setalt)
796INTDECL (dwarf_siblingof)
797INTDECL (dwarf_srclang)
798INTDECL (dwarf_tag)
799
800#endif	/* libdwP.h */
801