summaryrefslogtreecommitdiff
path: root/libdw/libdw.h
blob: cd7f5d15e55a50c77dc63bc83a88fe37e1ed7310 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
/* Interfaces for libdw.
   Copyright (C) 2002-2010, 2013, 2014 Red Hat, Inc.
   This file is part of elfutils.

   This file is free software; you can redistribute it and/or modify
   it under the terms of either

     * the GNU Lesser General Public License as published by the Free
       Software Foundation; either version 3 of the License, or (at
       your option) any later version

   or

     * the GNU General Public License as published by the Free
       Software Foundation; either version 2 of the License, or (at
       your option) any later version

   or both in parallel, as here.

   elfutils is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received copies of the GNU General Public License and
   the GNU Lesser General Public License along with this program.  If
   not, see <http://www.gnu.org/licenses/>.  */

#ifndef _LIBDW_H
#define _LIBDW_H	1

#include <gelf.h>
#include <stdbool.h>
#include <stddef.h>


#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
# define __nonnull_attribute__(...) __attribute__ ((__nonnull__ (__VA_ARGS__)))
# define __deprecated_attribute__ __attribute__ ((__deprecated__))
#else
# define __nonnull_attribute__(args...)
# define __deprecated_attribute__
#endif


#ifdef __GNUC_STDC_INLINE__
# define __libdw_extern_inline extern __inline __attribute__ ((__gnu_inline__))
#else
# define __libdw_extern_inline extern __inline
#endif


/* Mode for the session.  */
typedef enum
  {
    DWARF_C_READ,		/* Read .. */
    DWARF_C_RDWR,		/* Read and write .. */
    DWARF_C_WRITE,		/* Write .. */
  }
Dwarf_Cmd;


/* Callback results.  */
enum
{
  DWARF_CB_OK = 0,
  DWARF_CB_ABORT
};


/* Error values.  */
enum
  {
    DW_TAG_invalid = 0
#define DW_TAG_invalid	DW_TAG_invalid
  };


/* Type for offset in DWARF file.  */
typedef GElf_Off Dwarf_Off;

/* Type for address in DWARF file.  */
typedef GElf_Addr Dwarf_Addr;

/* Integer types.  Big enough to hold any numeric value.  */
typedef GElf_Xword Dwarf_Word;
typedef GElf_Sxword Dwarf_Sword;
/* For the times we know we do not need that much.  */
typedef GElf_Half Dwarf_Half;


/* DWARF abbreviation record.  */
typedef struct Dwarf_Abbrev Dwarf_Abbrev;

/* Returned to show the last DIE has be returned.  */
#define DWARF_END_ABBREV ((Dwarf_Abbrev *) -1l)

/* Source code line information for CU.  */
typedef struct Dwarf_Lines_s Dwarf_Lines;

/* One source code line information.  */
typedef struct Dwarf_Line_s Dwarf_Line;

/* Source file information.  */
typedef struct Dwarf_Files_s Dwarf_Files;

/* One address range record.  */
typedef struct Dwarf_Arange_s Dwarf_Arange;

/* Address ranges of a file.  */
typedef struct Dwarf_Aranges_s Dwarf_Aranges;

/* CU representation.  */
struct Dwarf_CU;
typedef struct Dwarf_CU Dwarf_CU;

/* Macro information.  */
typedef struct Dwarf_Macro_s Dwarf_Macro;

/* Attribute representation.  */
typedef struct
{
  unsigned int code;
  unsigned int form;
  unsigned char *valp;
  struct Dwarf_CU *cu;
} Dwarf_Attribute;


/* Data block representation.  */
typedef struct
{
  Dwarf_Word length;
  unsigned char *data;
} Dwarf_Block;


/* DIE information.  */
typedef struct
{
  /* The offset can be computed from the address.  */
  void *addr;
  struct Dwarf_CU *cu;
  Dwarf_Abbrev *abbrev;
  // XXX We'll see what other information will be needed.
  long int padding__;
} Dwarf_Die;

/* Returned to show the last DIE has be returned.  */
#define DWARF_END_DIE ((Dwarf_Die *) -1l)


/* Global symbol information.  */
typedef struct
{
  Dwarf_Off cu_offset;
  Dwarf_Off die_offset;
  const char *name;
} Dwarf_Global;


/* One operation in a DWARF location expression.
   A location expression is an array of these.  */
typedef struct
{
  uint8_t atom;			/* Operation */
  Dwarf_Word number;		/* Operand */
  Dwarf_Word number2;		/* Possible second operand */
  Dwarf_Word offset;		/* Offset in location expression */
} Dwarf_Op;


/* This describes one Common Information Entry read from a CFI section.
   Pointers here point into the DATA->d_buf block passed to dwarf_next_cfi.  */
typedef struct
{
  Dwarf_Off CIE_id;	 /* Always DW_CIE_ID_64 in Dwarf_CIE structures.  */

  /* Instruction stream describing initial state used by FDEs.  If
     we did not understand the whole augmentation string and it did
     not use 'z', then there might be more augmentation data here
     (and in FDEs) before the actual instructions.  */
  const uint8_t *initial_instructions;
  const uint8_t *initial_instructions_end;

  Dwarf_Word code_alignment_factor;
  Dwarf_Sword data_alignment_factor;
  Dwarf_Word return_address_register;

  const char *augmentation;	/* Augmentation string.  */

  /* Augmentation data, might be NULL.  The size is correct only if
     we understood the augmentation string sufficiently.  */
  const uint8_t *augmentation_data;
  size_t augmentation_data_size;
  size_t fde_augmentation_data_size;
} Dwarf_CIE;

/* This describes one Frame Description Entry read from a CFI section.
   Pointers here point into the DATA->d_buf block passed to dwarf_next_cfi.  */
typedef struct
{
  /* Section offset of CIE this FDE refers to.  This will never be
     DW_CIE_ID_64 in an FDE.  If this value is DW_CIE_ID_64, this is
     actually a Dwarf_CIE structure.  */
  Dwarf_Off CIE_pointer;

  /* We can't really decode anything further without looking up the CIE
     and checking its augmentation string.  Here follows the encoded
     initial_location and address_range, then any augmentation data,
     then the instruction stream.  This FDE describes PC locations in
     the byte range [initial_location, initial_location+address_range).
     When the CIE augmentation string uses 'z', the augmentation data is
     a DW_FORM_block (self-sized).  Otherwise, when we understand the
     augmentation string completely, fde_augmentation_data_size gives
     the number of bytes of augmentation data before the instructions.  */
  const uint8_t *start;
  const uint8_t *end;
} Dwarf_FDE;

/* Each entry in a CFI section is either a CIE described by Dwarf_CIE or
   an FDE described by Dward_FDE.  Check CIE_id to see which you have.  */
typedef union
{
  Dwarf_Off CIE_id;	 /* Always DW_CIE_ID_64 in Dwarf_CIE structures.  */
  Dwarf_CIE cie;
  Dwarf_FDE fde;
} Dwarf_CFI_Entry;

#define dwarf_cfi_cie_p(entry)	((entry)->cie.CIE_id == DW_CIE_ID_64)

/* Opaque type representing a frame state described by CFI.  */
typedef struct Dwarf_Frame_s Dwarf_Frame;

/* Opaque type representing a CFI section found in a DWARF or ELF file.  */
typedef struct Dwarf_CFI_s Dwarf_CFI;


/* Handle for debug sessions.  */
typedef struct Dwarf Dwarf;


/* Out-Of-Memory handler.  */
#if __GNUC__ < 4
typedef void (*Dwarf_OOM) (void);
#else
typedef void (*__attribute__ ((noreturn)) Dwarf_OOM) (void);
#endif


#ifdef __cplusplus
extern "C" {
#endif

/* Create a handle for a new debug session.  */
extern Dwarf *dwarf_begin (int fildes, Dwarf_Cmd cmd);

/* Create a handle for a new debug session for an ELF file.  */
extern Dwarf *dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp);

/* Retrieve ELF descriptor used for DWARF access.  */
extern Elf *dwarf_getelf (Dwarf *dwarf);

/* Retieve DWARF descriptor used for a Dwarf_Die or Dwarf_Attribute.
   A Dwarf_Die or a Dwarf_Attribute is associated with a particular
   Dwarf_CU handle.  This function returns the DWARF descriptor for
   that Dwarf_CU.  */
extern Dwarf *dwarf_cu_getdwarf (Dwarf_CU *cu);

/* Retrieves the DWARF descriptor for debugaltlink data.  Returns NULL
   if no alternate debug data has been supplied.  */
extern Dwarf *dwarf_getalt (Dwarf *main);

/* Provides the data referenced by the .gnu_debugaltlink section.  The
   caller should check that MAIN and ALT match (i.e., they have the
   same build ID).  It is the responsibility of the caller to ensure
   that the data referenced by ALT stays valid while it is used by
   MAIN, until dwarf_setalt is called on MAIN with a different
   descriptor, or dwarf_end.  */
extern void dwarf_setalt (Dwarf *main, Dwarf *alt);

/* Release debugging handling context.  */
extern int dwarf_end (Dwarf *dwarf);


/* Get the data block for the .debug_info section.  */
extern Elf_Data *dwarf_getscn_info (Dwarf *dwarf);

/* Read the header for the DWARF CU.  */
extern int dwarf_nextcu (Dwarf *dwarf, Dwarf_Off off, Dwarf_Off *next_off,
			 size_t *header_sizep, Dwarf_Off *abbrev_offsetp,
			 uint8_t *address_sizep, uint8_t *offset_sizep)
     __nonnull_attribute__ (3);

/* Read the header of a DWARF CU or type unit.  If TYPE_SIGNATUREP is not
   null, this reads a type unit from the .debug_types section; otherwise
   this reads a CU from the .debug_info section.  */
extern int dwarf_next_unit (Dwarf *dwarf, Dwarf_Off off, Dwarf_Off *next_off,
			    size_t *header_sizep, Dwarf_Half *versionp,
			    Dwarf_Off *abbrev_offsetp,
			    uint8_t *address_sizep, uint8_t *offset_sizep,
			    uint64_t *type_signaturep, Dwarf_Off *type_offsetp)
     __nonnull_attribute__ (3);


/* Decode one DWARF CFI entry (CIE or FDE) from the raw section data.
   The E_IDENT from the originating ELF file indicates the address
   size and byte order used in the CFI section contained in DATA;
   EH_FRAME_P should be true for .eh_frame format and false for
   .debug_frame format.  OFFSET is the byte position in the section
   to start at; on return *NEXT_OFFSET is filled in with the byte
   position immediately after this entry.

   On success, returns 0 and fills in *ENTRY; use dwarf_cfi_cie_p to
   see whether ENTRY->cie or ENTRY->fde is valid.

   On errors, returns -1.  Some format errors will permit safely
   skipping to the next CFI entry though the current one is unusable.
   In that case, *NEXT_OFF will be updated before a -1 return.

   If there are no more CFI entries left in the section,
   returns 1 and sets *NEXT_OFFSET to (Dwarf_Off) -1.  */
extern int dwarf_next_cfi (const unsigned char e_ident[],
			   Elf_Data *data, bool eh_frame_p,
			   Dwarf_Off offset, Dwarf_Off *next_offset,
			   Dwarf_CFI_Entry *entry)
  __nonnull_attribute__ (1, 2, 5, 6);

/* Use the CFI in the DWARF .debug_frame section.
   Returns NULL if there is no such section (not an error).
   The pointer returned can be used until dwarf_end is called on DWARF,
   and must not be passed to dwarf_cfi_end.
   Calling this more than once returns the same pointer.  */
extern Dwarf_CFI *dwarf_getcfi (Dwarf *dwarf);

/* Use the CFI in the ELF file's exception-handling data.
   Returns NULL if there is no such data.
   The pointer returned can be used until elf_end is called on ELF,
   and must be passed to dwarf_cfi_end before then.
   Calling this more than once allocates independent data structures.  */
extern Dwarf_CFI *dwarf_getcfi_elf (Elf *elf);

/* Release resources allocated by dwarf_getcfi_elf.  */
extern int dwarf_cfi_end (Dwarf_CFI *cache);


/* Return DIE at given offset in .debug_info section.  */
extern Dwarf_Die *dwarf_offdie (Dwarf *dbg, Dwarf_Off offset,
				Dwarf_Die *result) __nonnull_attribute__ (3);

/* Return DIE at given offset in .debug_types section.  */
extern Dwarf_Die *dwarf_offdie_types (Dwarf *dbg, Dwarf_Off offset,
				      Dwarf_Die *result)
     __nonnull_attribute__ (3);

/* Return offset of DIE.  */
extern Dwarf_Off dwarf_dieoffset (Dwarf_Die *die);

/* Return offset of DIE in CU.  */
extern Dwarf_Off dwarf_cuoffset (Dwarf_Die *die);

/* Return CU DIE containing given DIE.  */
extern Dwarf_Die *dwarf_diecu (Dwarf_Die *die, Dwarf_Die *result,
			       uint8_t *address_sizep, uint8_t *offset_sizep)
     __nonnull_attribute__ (2);

/* Return the CU DIE and the header info associated with a Dwarf_Die
   or Dwarf_Attribute.  A Dwarf_Die or a Dwarf_Attribute is associated
   with a particular Dwarf_CU handle.  This function returns the CU or
   type unit DIE and header information for that Dwarf_CU.  The
   returned DIE is either a compile_unit, partial_unit or type_unit.
   If it is a type_unit, then the type signature and type offset are
   also provided, otherwise type_offset will be set to zero.  See also
   dwarf_diecu and dwarf_next_unit.  */
extern Dwarf_Die *dwarf_cu_die (Dwarf_CU *cu, Dwarf_Die *result,
				Dwarf_Half *versionp,
				Dwarf_Off *abbrev_offsetp,
				uint8_t *address_sizep,
				uint8_t *offset_sizep,
				uint64_t *type_signaturep,
				Dwarf_Off *type_offsetp)
     __nonnull_attribute__ (2);

/* Return CU DIE containing given address.  */
extern Dwarf_Die *dwarf_addrdie (Dwarf *dbg, Dwarf_Addr addr,
				 Dwarf_Die *result) __nonnull_attribute__ (3);

/* Return child of current DIE.  */
extern int dwarf_child (Dwarf_Die *die, Dwarf_Die *result)
     __nonnull_attribute__ (2);

/* Locates the first sibling of DIE and places it in RESULT.
   Returns 0 if a sibling was found, -1 if something went wrong.
   Returns 1 if no sibling could be found and, if RESULT is not
   the same as DIE, it sets RESULT->addr to the address of the
   (non-sibling) DIE that follows this one, or NULL if this DIE
   was the last one in the compilation unit.  */
extern int dwarf_siblingof (Dwarf_Die *die, Dwarf_Die *result)
     __nonnull_attribute__ (2);

/* Check whether the DIE has children.  */
extern int dwarf_haschildren (Dwarf_Die *die) __nonnull_attribute__ (1);

/* Walks the attributes of DIE, starting at the one OFFSET bytes in,
   calling the CALLBACK function for each one.  Stops if the callback
   function ever returns a value other than DWARF_CB_OK and returns the
   offset of the offending attribute.  If the end of the attributes
   is reached 1 is returned.  If something goes wrong -1 is returned and
   the dwarf error number is set.  */
extern ptrdiff_t dwarf_getattrs (Dwarf_Die *die,
				 int (*callback) (Dwarf_Attribute *, void *),
				 void *arg, ptrdiff_t offset)
     __nonnull_attribute__ (2);

/* Return tag of given DIE.  */
extern int dwarf_tag (Dwarf_Die *die) __nonnull_attribute__ (1);


/* Return specific attribute of DIE.  */
extern Dwarf_Attribute *dwarf_attr (Dwarf_Die *die, unsigned int search_name,
				    Dwarf_Attribute *result)
     __nonnull_attribute__ (3);

/* Check whether given DIE has specific attribute.  */
extern int dwarf_hasattr (Dwarf_Die *die, unsigned int search_name);

/* These are the same as dwarf_attr and dwarf_hasattr, respectively,
   but they resolve an indirect attribute through DW_AT_abstract_origin.  */
extern Dwarf_Attribute *dwarf_attr_integrate (Dwarf_Die *die,
					      unsigned int search_name,
					      Dwarf_Attribute *result)
     __nonnull_attribute__ (3);
extern int dwarf_hasattr_integrate (Dwarf_Die *die, unsigned int search_name);




/* Check whether given attribute has specific form.  */
extern int dwarf_hasform (Dwarf_Attribute *attr, unsigned int search_form);

/* Return attribute code of given attribute.  */
extern unsigned int dwarf_whatattr (Dwarf_Attribute *attr);

/* Return form code of given attribute.  */
extern unsigned int dwarf_whatform (Dwarf_Attribute *attr);


/* Return string associated with given attribute.  */
extern const char *dwarf_formstring (Dwarf_Attribute *attrp);

/* Return unsigned constant represented by attribute.  */
extern int dwarf_formudata (Dwarf_Attribute *attr, Dwarf_Word *return_uval)
     __nonnull_attribute__ (2);

/* Return signed constant represented by attribute.  */
extern int dwarf_formsdata (Dwarf_Attribute *attr, Dwarf_Sword *return_uval)
     __nonnull_attribute__ (2);

/* Return address represented by attribute.  */
extern int dwarf_formaddr (Dwarf_Attribute *attr, Dwarf_Addr *return_addr)
     __nonnull_attribute__ (2);

/* This function is deprecated.  Always use dwarf_formref_die instead.
   Return reference offset represented by attribute.  */
extern int dwarf_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset)
     __nonnull_attribute__ (2) __deprecated_attribute__;

/* Look up the DIE in a reference-form attribute.  */
extern Dwarf_Die *dwarf_formref_die (Dwarf_Attribute *attr, Dwarf_Die *die_mem)
     __nonnull_attribute__ (2);

/* Return block represented by attribute.  */
extern int dwarf_formblock (Dwarf_Attribute *attr, Dwarf_Block *return_block)
     __nonnull_attribute__ (2);

/* Return flag represented by attribute.  */
extern int dwarf_formflag (Dwarf_Attribute *attr, bool *return_bool)
     __nonnull_attribute__ (2);


/* Simplified attribute value access functions.  */

/* Return string in name attribute of DIE.  */
extern const char *dwarf_diename (Dwarf_Die *die);

/* Return high PC attribute of DIE.  */
extern int dwarf_highpc (Dwarf_Die *die, Dwarf_Addr *return_addr)
     __nonnull_attribute__ (2);

/* Return low PC attribute of DIE.  */
extern int dwarf_lowpc (Dwarf_Die *die, Dwarf_Addr *return_addr)
     __nonnull_attribute__ (2);

/* Return entry_pc or low_pc attribute of DIE.  */
extern int dwarf_entrypc (Dwarf_Die *die, Dwarf_Addr *return_addr)
     __nonnull_attribute__ (2);

/* Return 1 if DIE's lowpc/highpc or ranges attributes match the PC address,
   0 if not, or -1 for errors.  */
extern int dwarf_haspc (Dwarf_Die *die, Dwarf_Addr pc);

/* Enumerate the PC address ranges covered by this DIE, covering all
   addresses where dwarf_haspc returns true.  In the first call OFFSET
   should be zero and *BASEP need not be initialized.  Returns -1 for
   errors, zero when there are no more address ranges to report, or a
   nonzero OFFSET value to pass to the next call.  Each subsequent call
   must preserve *BASEP from the prior call.  Successful calls fill in
   *STARTP and *ENDP with a contiguous address range.  */
extern ptrdiff_t dwarf_ranges (Dwarf_Die *die,
			       ptrdiff_t offset, Dwarf_Addr *basep,
			       Dwarf_Addr *startp, Dwarf_Addr *endp);


/* Return byte size attribute of DIE.  */
extern int dwarf_bytesize (Dwarf_Die *die);

/* Return bit size attribute of DIE.  */
extern int dwarf_bitsize (Dwarf_Die *die);

/* Return bit offset attribute of DIE.  */
extern int dwarf_bitoffset (Dwarf_Die *die);

/* Return array order attribute of DIE.  */
extern int dwarf_arrayorder (Dwarf_Die *die);

/* Return source language attribute of DIE.  */
extern int dwarf_srclang (Dwarf_Die *die);


/* Get abbreviation at given offset for given DIE.  */
extern Dwarf_Abbrev *dwarf_getabbrev (Dwarf_Die *die, Dwarf_Off offset,
				      size_t *lengthp);

/* Get abbreviation at given offset in .debug_abbrev section.  */
extern int dwarf_offabbrev (Dwarf *dbg, Dwarf_Off offset, size_t *lengthp,
			    Dwarf_Abbrev *abbrevp)
     __nonnull_attribute__ (4);

/* Get abbreviation code.  */
extern unsigned int dwarf_getabbrevcode (Dwarf_Abbrev *abbrev);

/* Get abbreviation tag.  */
extern unsigned int dwarf_getabbrevtag (Dwarf_Abbrev *abbrev);

/* Return true if abbreviation is children flag set.  */
extern int dwarf_abbrevhaschildren (Dwarf_Abbrev *abbrev);

/* Get number of attributes of abbreviation.  */
extern int dwarf_getattrcnt (Dwarf_Abbrev *abbrev, size_t *attrcntp)
     __nonnull_attribute__ (2);

/* Get specific attribute of abbreviation.  */
extern int dwarf_getabbrevattr (Dwarf_Abbrev *abbrev, size_t idx,
				unsigned int *namep, unsigned int *formp,
				Dwarf_Off *offset);


/* Get string from-debug_str section.  */
extern const char *dwarf_getstring (Dwarf *dbg, Dwarf_Off offset,
				    size_t *lenp);


/* Get public symbol information.  */
extern ptrdiff_t dwarf_getpubnames (Dwarf *dbg,
				    int (*callback) (Dwarf *, Dwarf_Global *,
						     void *),
				    void *arg, ptrdiff_t offset)
     __nonnull_attribute__ (2);


/* Get source file information for CU.  */
extern int dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines,
			      size_t *nlines) __nonnull_attribute__ (2, 3);

/* Return one of the source lines of the CU.  */
extern Dwarf_Line *dwarf_onesrcline (Dwarf_Lines *lines, size_t idx);

/* Get the file source files used in the CU.  */
extern int dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files,
			      size_t *nfiles)
     __nonnull_attribute__ (2);


/* Get source for address in CU.  */
extern Dwarf_Line *dwarf_getsrc_die (Dwarf_Die *cudie, Dwarf_Addr addr);

/* Get source for file and line number.  */
extern int dwarf_getsrc_file (Dwarf *dbg, const char *fname, int line, int col,
			      Dwarf_Line ***srcsp, size_t *nsrcs)
     __nonnull_attribute__ (2, 5, 6);


/* Return line address.  */
extern int dwarf_lineaddr (Dwarf_Line *line, Dwarf_Addr *addrp);

/* Return line VLIW operation index.  */
extern int dwarf_lineop_index (Dwarf_Line *line, unsigned int *op_indexp);

/* Return line number.  */
extern int dwarf_lineno (Dwarf_Line *line, int *linep)
     __nonnull_attribute__ (2);

/* Return column in line.  */
extern int dwarf_linecol (Dwarf_Line *line, int *colp)
     __nonnull_attribute__ (2);

/* Return true if record is for beginning of a statement.  */
extern int dwarf_linebeginstatement (Dwarf_Line *line, bool *flagp)
     __nonnull_attribute__ (2);

/* Return true if record is for end of sequence.  */
extern int dwarf_lineendsequence (Dwarf_Line *line, bool *flagp)
     __nonnull_attribute__ (2);

/* Return true if record is for beginning of a basic block.  */
extern int dwarf_lineblock (Dwarf_Line *line, bool *flagp)
     __nonnull_attribute__ (2);

/* Return true if record is for end of prologue.  */
extern int dwarf_lineprologueend (Dwarf_Line *line, bool *flagp)
     __nonnull_attribute__ (2);

/* Return true if record is for beginning of epilogue.  */
extern int dwarf_lineepiloguebegin (Dwarf_Line *line, bool *flagp)
     __nonnull_attribute__ (2);

/* Return instruction-set architecture in this record.  */
extern int dwarf_lineisa (Dwarf_Line *line, unsigned int *isap)
     __nonnull_attribute__ (2);

/* Return code path discriminator in this record.  */
extern int dwarf_linediscriminator (Dwarf_Line *line, unsigned int *discp)
     __nonnull_attribute__ (2);


/* Find line information for address.  */
extern const char *dwarf_linesrc (Dwarf_Line *line,
				  Dwarf_Word *mtime, Dwarf_Word *length);

/* Return file information.  */
extern const char *dwarf_filesrc (Dwarf_Files *file, size_t idx,
				  Dwarf_Word *mtime, Dwarf_Word *length);

/* Return the directory list used in the file information extracted.
   (*RESULT)[0] is the CU's DW_AT_comp_dir value, and may be null.
   (*RESULT)[0..*NDIRS-1] are the compile-time include directory path
   encoded by the compiler.  */
extern int dwarf_getsrcdirs (Dwarf_Files *files,
			     const char *const **result, size_t *ndirs)
  __nonnull_attribute__ (2, 3);


/* Return location expression, decoded as a list of operations.  */
extern int dwarf_getlocation (Dwarf_Attribute *attr, Dwarf_Op **expr,
			      size_t *exprlen) __nonnull_attribute__ (2, 3);

/* Return location expressions.  If the attribute uses a location list,
   ADDRESS selects the relevant location expressions from the list.
   There can be multiple matches, resulting in multiple expressions to
   return.  EXPRS and EXPRLENS are parallel arrays of NLOCS slots to
   fill in.  Returns the number of locations filled in, or -1 for
   errors.  If EXPRS is a null pointer, stores nothing and returns the
   total number of locations.  A return value of zero means that the
   location list indicated no value is accessible.  */
extern int dwarf_getlocation_addr (Dwarf_Attribute *attr, Dwarf_Addr address,
				   Dwarf_Op **exprs, size_t *exprlens,
				   size_t nlocs);

/* Enumerate the locations ranges and descriptions covered by the
   given attribute.  In the first call OFFSET should be zero and
   *BASEP need not be initialized.  Returns -1 for errors, zero when
   there are no more locations to report, or a nonzero OFFSET
   value to pass to the next call.  Each subsequent call must preserve
   *BASEP from the prior call.  Successful calls fill in *STARTP and
   *ENDP with a contiguous address range and *EXPR with a pointer to
   an array of operations with length *EXPRLEN.  If the attribute
   describes a single location description and not a location list the
   first call (with OFFSET zero) will return the location description
   in *EXPR with *STARTP set to zero and *ENDP set to minus one.  */
extern ptrdiff_t dwarf_getlocations (Dwarf_Attribute *attr,
				     ptrdiff_t offset, Dwarf_Addr *basep,
				     Dwarf_Addr *startp, Dwarf_Addr *endp,
				     Dwarf_Op **expr, size_t *exprlen);

/* Return the block associated with a DW_OP_implicit_value operation.
   The OP pointer must point into an expression that dwarf_getlocation
   or dwarf_getlocation_addr has returned given the same ATTR.  */
extern int dwarf_getlocation_implicit_value (Dwarf_Attribute *attr,
					     const Dwarf_Op *op,
					     Dwarf_Block *return_block)
  __nonnull_attribute__ (2, 3);

/* Return the attribute indicated by a DW_OP_GNU_implicit_pointer operation.
   The OP pointer must point into an expression that dwarf_getlocation
   or dwarf_getlocation_addr has returned given the same ATTR.
   The result is the DW_AT_location or DW_AT_const_value attribute
   of the OP->number DIE.  */
extern int dwarf_getlocation_implicit_pointer (Dwarf_Attribute *attr,
					       const Dwarf_Op *op,
					       Dwarf_Attribute *result)
  __nonnull_attribute__ (2, 3);

/* Return the DIE associated with an operation such as
   DW_OP_GNU_implicit_pointer, DW_OP_GNU_parameter_ref, DW_OP_GNU_convert,
   DW_OP_GNU_reinterpret, DW_OP_GNU_const_type, DW_OP_GNU_regval_type or
   DW_OP_GNU_deref_type.  The OP pointer must point into an expression that
   dwarf_getlocation or dwarf_getlocation_addr has returned given the same
   ATTR.  The RESULT is a DIE that expresses a type or value needed by the
   given OP.  */
extern int dwarf_getlocation_die (Dwarf_Attribute *attr,
				  const Dwarf_Op *op,
				  Dwarf_Die *result)
  __nonnull_attribute__ (2, 3);

/* Return the attribute expressing a value associated with an operation such
   as DW_OP_implicit_value, DW_OP_GNU_entry_value or DW_OP_GNU_const_type.
   The OP pointer must point into an expression that dwarf_getlocation
   or dwarf_getlocation_addr has returned given the same ATTR.
   The RESULT is a value expressed by an attribute such as DW_AT_location
   or DW_AT_const_value.  */
extern int dwarf_getlocation_attr (Dwarf_Attribute *attr,
				   const Dwarf_Op *op,
				   Dwarf_Attribute *result)
  __nonnull_attribute__ (2, 3);


/* Compute the byte-size of a type DIE according to DWARF rules.
   For most types, this is just DW_AT_byte_size.
   For DW_TAG_array_type it can apply much more complex rules.  */
extern int dwarf_aggregate_size (Dwarf_Die *die, Dwarf_Word *size);


/* Return scope DIEs containing PC address.
   Sets *SCOPES to a malloc'd array of Dwarf_Die structures,
   and returns the number of elements in the array.
   (*SCOPES)[0] is the DIE for the innermost scope containing PC,
   (*SCOPES)[1] is the DIE for the scope containing that scope, and so on.
   Returns -1 for errors or 0 if no scopes match PC.  */
extern int dwarf_getscopes (Dwarf_Die *cudie, Dwarf_Addr pc,
			    Dwarf_Die **scopes);

/* Return scope DIEs containing the given DIE.
   Sets *SCOPES to a malloc'd array of Dwarf_Die structures,
   and returns the number of elements in the array.
   (*SCOPES)[0] is a copy of DIE.
   (*SCOPES)[1] is the DIE for the scope containing that scope, and so on.
   Returns -1 for errors or 0 if DIE is not found in any scope entry.  */
extern int dwarf_getscopes_die (Dwarf_Die *die, Dwarf_Die **scopes);


/* Search SCOPES[0..NSCOPES-1] for a variable called NAME.
   Ignore the first SKIP_SHADOWS scopes that match the name.
   If MATCH_FILE is not null, accept only declaration in that source file;
   if MATCH_LINENO or MATCH_LINECOL are also nonzero, accept only declaration
   at that line and column.

   If successful, fill in *RESULT with the DIE of the variable found,
   and return N where SCOPES[N] is the scope defining the variable.
   Return -1 for errors or -2 for no matching variable found.  */
extern int dwarf_getscopevar (Dwarf_Die *scopes, int nscopes,
			      const char *name, int skip_shadows,
			      const char *match_file,
			      int match_lineno, int match_linecol,
			      Dwarf_Die *result);



/* Return list address ranges.  */
extern int dwarf_getaranges (Dwarf *dbg, Dwarf_Aranges **aranges,
			     size_t *naranges)
     __nonnull_attribute__ (2);

/* Return one of the address range entries.  */
extern Dwarf_Arange *dwarf_onearange (Dwarf_Aranges *aranges, size_t idx);

/* Return information in address range record.  */
extern int dwarf_getarangeinfo (Dwarf_Arange *arange, Dwarf_Addr *addrp,
				Dwarf_Word *lengthp, Dwarf_Off *offsetp);

/* Get address range which includes given address.  */
extern Dwarf_Arange *dwarf_getarange_addr (Dwarf_Aranges *aranges,
					   Dwarf_Addr addr);



/* Get functions in CUDIE.  The given callback will be called for all
   defining DW_TAG_subprograms in the CU DIE tree.  If the callback
   returns DWARF_CB_ABORT the return value can be used as offset argument
   to resume the function to find all remaining functions (this is not
   really recommended, since it needs to rewalk the CU DIE tree first till
   that offset is found again).  If the callback returns DWARF_CB_OK
   dwarf_getfuncs will not return but keep calling the callback for each
   function DIE it finds.  Pass zero for offset on the first call to walk
   the full CU DIE tree.  If no more functions can be found and the callback
   returned DWARF_CB_OK then the function returns zero.  */
extern ptrdiff_t dwarf_getfuncs (Dwarf_Die *cudie,
				 int (*callback) (Dwarf_Die *, void *),
				 void *arg, ptrdiff_t offset);


/* Return file name containing definition of the given declaration.  */
extern const char *dwarf_decl_file (Dwarf_Die *decl);

/* Get line number of beginning of given declaration.  */
extern int dwarf_decl_line (Dwarf_Die *decl, int *linep)
     __nonnull_attribute__ (2);

/* Get column number of beginning of given declaration.  */
extern int dwarf_decl_column (Dwarf_Die *decl, int *colp)
     __nonnull_attribute__ (2);


/* Return nonzero if given function is an abstract inline definition.  */
extern int dwarf_func_inline (Dwarf_Die *func);

/* Find each concrete inlined instance of the abstract inline definition.  */
extern int dwarf_func_inline_instances (Dwarf_Die *func,
					int (*callback) (Dwarf_Die *, void *),
					void *arg);


/* Find the appropriate PC location or locations for function entry
   breakpoints for the given DW_TAG_subprogram DIE.  Returns -1 for errors.
   On success, returns the number of breakpoint locations (never zero)
   and sets *BKPTS to a malloc'd vector of addresses.  */
extern int dwarf_entry_breakpoints (Dwarf_Die *die, Dwarf_Addr **bkpts);


/* Iterate through the macro unit referenced by CUDIE and call
   CALLBACK for each macro information entry.  Keeps iterating while
   CALLBACK returns DWARF_CB_OK.  If the callback returns
   DWARF_CB_ABORT, it stops iterating and returns a continuation
   token, which can be used to restart the iteration at the point
   where it ended.  Returns -1 for errors or 0 if there are no more
   macro entries.

   Note that the Dwarf_Macro pointer passed to the callback is only
   valid for the duration of the callback invocation.

   Note that this interface will refuse to serve opcode 0xff from
   .debug_macro sections.  Such opcode is considered invalid and will
   cause dwarf_getmacros to return with error.  Note that this should
   be no limitation as of now, as DW_MACRO_GNU_* domain doesn't
   allocate 0xff.  It is however a theoretical possibility with future
   Dwarf standards.  */
extern ptrdiff_t dwarf_getmacros (Dwarf_Die *cudie,
				  int (*callback) (Dwarf_Macro *, void *),
				  void *arg, ptrdiff_t token)
     __nonnull_attribute__ (2);

/* This is similar in operation to dwarf_getmacros, but selects the
   unit to iterate through by offset instead of by CU.  This can be
   used for handling DW_MACRO_GNU_transparent_include's or similar
   opcodes.  Note that with TOKEN of 0, this will always choose to
   iterate through .debug_macro, never .debug_macinfo.

   It is not appropriate to obtain macro unit offset by hand from a CU
   DIE and then request iteration through this interface.  The reason
   for this is that if a dwarf_macro_getsrcfiles is later called,
   there would be no way to figure out what DW_AT_comp_dir was present
   on the CU DIE, and file names referenced in either the macro unit
   itself, or the .debug_line unit that it references, might be wrong.
   Use dwarf_getmacro.  */
extern ptrdiff_t dwarf_getmacros_off (Dwarf *dbg, Dwarf_Off macoff,
				      int (*callback) (Dwarf_Macro *, void *),
				      void *arg, ptrdiff_t token)
  __nonnull_attribute__ (3);

/* Get the source files used by the macro entry.  You shouldn't assume
   that Dwarf_Files references will remain valid after MACRO becomes
   invalid.  (Which is to say it's only valid within the
   dwarf_getmacros* callback.)  Returns 0 for success or a negative
   value in case of an error.  */
extern int dwarf_macro_getsrcfiles (Dwarf *dbg, Dwarf_Macro *macro,
				    Dwarf_Files **files, size_t *nfiles)
  __nonnull_attribute__ (2, 3, 4);

/* Return macro opcode.  That's a constant that can be either from
   DW_MACINFO_* domain if version of MACRO is 0, or from
   DW_MACRO_GNU_* domain if the version is 4.  */
extern int dwarf_macro_opcode (Dwarf_Macro *macro, unsigned int *opcodep)
     __nonnull_attribute__ (2);

/* Get number of parameters of MACRO and store it to *PARAMCNTP.  */
extern int dwarf_macro_getparamcnt (Dwarf_Macro *macro, size_t *paramcntp);

/* Get IDX-th parameter of MACRO, and stores it to *ATTRIBUTE.
   Returns 0 on success or -1 for errors.

   After a successful call, you can query ATTRIBUTE by dwarf_whatform
   to determine which of the dwarf_formX calls to make to get actual
   value out of ATTRIBUTE.  Note that calling dwarf_whatattr is not
   meaningful for pseudo-attributes formed this way.  */
extern int dwarf_macro_param (Dwarf_Macro *macro, size_t idx,
			      Dwarf_Attribute *attribute);

/* Return first macro parameter.  This will return -1 if the parameter
   is not an integral value.  Use dwarf_macro_param for more general
   access.  */
extern int dwarf_macro_param1 (Dwarf_Macro *macro, Dwarf_Word *paramp)
     __nonnull_attribute__ (2);

/* Return second macro parameter.  This will return -1 if the
   parameter is not an integral or string value.  Use
   dwarf_macro_param for more general access.  */
extern int dwarf_macro_param2 (Dwarf_Macro *macro, Dwarf_Word *paramp,
			       const char **strp);

/* Compute what's known about a call frame when the PC is at ADDRESS.
   Returns 0 for success or -1 for errors.
   On success, *FRAME is a malloc'd pointer.  */
extern int dwarf_cfi_addrframe (Dwarf_CFI *cache,
				Dwarf_Addr address, Dwarf_Frame **frame)
  __nonnull_attribute__ (3);

/* Return the DWARF register number used in FRAME to denote
   the return address in FRAME's caller frame.  The remaining
   arguments can be non-null to fill in more information.

   Fill [*START, *END) with the PC range to which FRAME's information applies.
   Fill in *SIGNALP to indicate whether this is a signal-handling frame.
   If true, this is the implicit call frame that calls a signal handler.
   This frame's "caller" is actually the interrupted state, not a call;
   its return address is an exact PC, not a PC after a call instruction.  */
extern int dwarf_frame_info (Dwarf_Frame *frame,
			     Dwarf_Addr *start, Dwarf_Addr *end, bool *signalp);

/* Return a DWARF expression that yields the Canonical Frame Address at
   this frame state.  Returns -1 for errors, or zero for success, with
   *NOPS set to the number of operations stored at *OPS.  That pointer
   can be used only as long as FRAME is alive and unchanged.  *NOPS is
   zero if the CFA cannot be determined here.  Note that if nonempty,
   *OPS is a DWARF expression, not a location description--append
   DW_OP_stack_value to a get a location description for the CFA.  */
extern int dwarf_frame_cfa (Dwarf_Frame *frame, Dwarf_Op **ops, size_t *nops)
  __nonnull_attribute__ (2);

/* Deliver a DWARF location description that yields the location or
   value of DWARF register number REGNO in the state described by FRAME.

   Returns -1 for errors or zero for success, setting *NOPS to the
   number of operations in the array stored at *OPS.  Note the last
   operation is DW_OP_stack_value if there is no mutable location but
   only a computable value.

   *NOPS zero with *OPS set to OPS_MEM means CFI says the caller's
   REGNO is "undefined", i.e. it's call-clobbered and cannot be recovered.

   *NOPS zero with *OPS set to a null pointer means CFI says the
   caller's REGNO is "same_value", i.e. this frame did not change it;
   ask the caller frame where to find it.

   For common simple expressions *OPS is OPS_MEM.  For arbitrary DWARF
   expressions in the CFI, *OPS is an internal pointer that can be used as
   long as the Dwarf_CFI used to create FRAME remains alive.  */
extern int dwarf_frame_register (Dwarf_Frame *frame, int regno,
				 Dwarf_Op ops_mem[3],
				 Dwarf_Op **ops, size_t *nops)
  __nonnull_attribute__ (3, 4, 5);


/* Return error code of last failing function call.  This value is kept
   separately for each thread.  */
extern int dwarf_errno (void);

/* Return error string for ERROR.  If ERROR is zero, return error string
   for most recent error or NULL is none occurred.  If ERROR is -1 the
   behaviour is similar to the last case except that not NULL but a legal
   string is returned.  */
extern const char *dwarf_errmsg (int err);


/* Register new Out-Of-Memory handler.  The old handler is returned.  */
extern Dwarf_OOM dwarf_new_oom_handler (Dwarf *dbg, Dwarf_OOM handler);


/* Inline optimizations.  */
#ifdef __OPTIMIZE__
/* Return attribute code of given attribute.  */
__libdw_extern_inline unsigned int
dwarf_whatattr (Dwarf_Attribute *attr)
{
  return attr == NULL ? 0 : attr->code;
}

/* Return attribute code of given attribute.  */
__libdw_extern_inline unsigned int
dwarf_whatform (Dwarf_Attribute *attr)
{
  return attr == NULL ? 0 : attr->form;
}
#endif	/* Optimize.  */

#ifdef __cplusplus
}
#endif

#endif	/* libdw.h */