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.  */
45 struct 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.  */
55 struct loc_block_s
56 {
57   void *addr;
58   unsigned char *data;
59   size_t length;
60 };
61 
62 /* Already decoded .debug_line units.  */
63 struct 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.  */
71 enum
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.  */
91 enum
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.  */
137 struct 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.  */
215 struct 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.  */
229 struct 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   };
241 typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo;
242 
243 
244 /* Representation of a row in the line table.  */
245 
246 struct 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 
267 struct Dwarf_Lines_s
268 {
269   size_t nlines;
270   struct Dwarf_Line_s info[0];
271 };
272 
273 /* Representation of address ranges.  */
274 struct 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.  */
289 struct 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.  */
352 typedef struct
353 {
354   Dwarf_Word nforms;
355   unsigned char const *forms;
356 } Dwarf_Macro_Op_Proto;
357 
358 /* Prototype table.  */
359 typedef 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 
391 struct Dwarf_Macro_s
392 {
393   Dwarf_Macro_Op_Table *table;
394   Dwarf_Attribute *attributes;
395   uint8_t opcode;
396 };
397 
398 static inline Dwarf_Word
libdw_macro_nforms(Dwarf_Macro * macro)399 libdw_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.  */
410 extern 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.  */
435 extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align)
436      __attribute__ ((__malloc__)) __nonnull_attribute__ (1);
437 
438 /* Default OOM handler.  */
439 extern void __libdw_oom (void) __attribute ((noreturn, visibility ("hidden")));
440 
441 #if USE_ZLIB
442 extern 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.  */
448 extern 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.  */
452 extern 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.  */
456 extern 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.  */
461 extern 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.  */
468 static inline Dwarf_Abbrev *
469 __nonnull_attribute__ (1)
__libdw_dieabbrev(Dwarf_Die * die,const unsigned char ** readp)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.  */
490 extern 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.  */
496 static inline size_t
497 __nonnull_attribute__ (1, 3)
__libdw_form_val_len(struct Dwarf_CU * cu,unsigned int form,const unsigned char * valp)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.  */
534 extern 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.  */
539 extern 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.  */
546 extern 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.  */
550 struct Dwarf_Die_Chain
551 {
552   Dwarf_Die die;
553   struct Dwarf_Die_Chain *parent;
554   bool prune;			/* The PREVISIT function can set this.  */
555 };
556 extern 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).  */
569 extern 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 
579 extern 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.  */
586 extern 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 
595 static inline int
__libdw_relocate_address(Dwarf * dbg,int sec_index,const void * addr,int width,Dwarf_Addr * val)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 
605 static inline int
__libdw_relocate_offset(Dwarf * dbg,int sec_index,const void * addr,int width,Dwarf_Off * val)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 
615 static inline Elf_Data *
__libdw_checked_get_data(Dwarf * dbg,int sec_index)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 
628 static inline int
__libdw_offset_in_section(Dwarf * dbg,int sec_index,Dwarf_Off offset,size_t size)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 
645 static inline bool
__libdw_in_section(Dwarf * dbg,int sec_index,const void * addr,size_t size)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 
679 static inline int
__libdw_read_address_inc(Dwarf * dbg,int sec_index,const unsigned char ** addrp,int width,Dwarf_Addr * ret)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 
690 static inline int
__libdw_read_address(Dwarf * dbg,int sec_index,const unsigned char * addr,int width,Dwarf_Addr * ret)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 
699 static inline int
__libdw_read_offset_inc(Dwarf * dbg,int sec_index,const unsigned char ** addrp,int width,Dwarf_Off * ret,int sec_ret,size_t size)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 
711 static inline int
__libdw_read_offset(Dwarf * dbg,Dwarf * dbg_ret,int sec_index,const unsigned char * addr,int width,Dwarf_Off * ret,int sec_ret,size_t size)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 
721 static inline size_t
cu_sec_idx(struct Dwarf_CU * cu)722 cu_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.  */
732 int __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 
738 unsigned 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.  */
744 void __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.  */
752 int __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.  */
759 const char *__libdw_getcompdir (Dwarf_Die *cudie);
760 
761 
762 /* Aliases to avoid PLTs.  */
763 INTDECL (dwarf_aggregate_size)
764 INTDECL (dwarf_attr)
765 INTDECL (dwarf_attr_integrate)
766 INTDECL (dwarf_begin)
767 INTDECL (dwarf_begin_elf)
768 INTDECL (dwarf_child)
769 INTDECL (dwarf_dieoffset)
770 INTDECL (dwarf_diename)
771 INTDECL (dwarf_end)
772 INTDECL (dwarf_entrypc)
773 INTDECL (dwarf_errmsg)
774 INTDECL (dwarf_formaddr)
775 INTDECL (dwarf_formblock)
776 INTDECL (dwarf_formref_die)
777 INTDECL (dwarf_formsdata)
778 INTDECL (dwarf_formstring)
779 INTDECL (dwarf_formudata)
780 INTDECL (dwarf_getalt)
781 INTDECL (dwarf_getarange_addr)
782 INTDECL (dwarf_getarangeinfo)
783 INTDECL (dwarf_getaranges)
784 INTDECL (dwarf_getlocation_die)
785 INTDECL (dwarf_getsrcfiles)
786 INTDECL (dwarf_getsrclines)
787 INTDECL (dwarf_hasattr)
788 INTDECL (dwarf_haschildren)
789 INTDECL (dwarf_haspc)
790 INTDECL (dwarf_highpc)
791 INTDECL (dwarf_lowpc)
792 INTDECL (dwarf_nextcu)
793 INTDECL (dwarf_next_unit)
794 INTDECL (dwarf_offdie)
795 INTDECL (dwarf_peel_type)
796 INTDECL (dwarf_ranges)
797 INTDECL (dwarf_setalt)
798 INTDECL (dwarf_siblingof)
799 INTDECL (dwarf_srclang)
800 INTDECL (dwarf_tag)
801 
802 #endif	/* libdwP.h */
803