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