/
generated_libdwarf.h.in
5651 lines (4934 loc) · 210 KB
/
generated_libdwarf.h.in
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
999
1000
/*
Copyright (C) 2000-2010 Silicon Graphics, Inc. All Rights Reserved.
Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
Portions Copyright 2008-2018 David Anderson. All rights reserved.
Portions Copyright 2008-2010 Arxan Technologies, Inc. All rights reserved.
Portions Copyright 2010-2012 SN Systems Ltd. All rights reserved.
This program is free software; you can redistribute it
and/or modify it under the terms of version 2.1 of the
GNU Lesser General Public License as published by the Free
Software Foundation.
This program is distributed in the hope that it would be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.
Further, this software is distributed without any warranty
that it is free of the rightful claim of any third person
regarding infringement or the like. Any license provided
herein, whether implied or otherwise, applies only to this
software file. Patent licenses, if any, provided herein
do not apply to combinations of this program with other
software, or any other product whatsoever.
You should have received a copy of the GNU Lesser General
Public License along with this program; if not, write the
Free Software Foundation, Inc., 51 Franklin Street - Fifth
Floor, Boston MA 02110-1301, USA.
*/
#ifndef _LIBDWARF_H
#define _LIBDWARF_H
#ifdef __cplusplus
extern "C" {
#endif
/*
libdwarf.h
$Revision: #9 $ $Date: 2008/01/17 $
For libdwarf producers and consumers
The interface is defined as having 8-byte signed and unsigned
values so it can handle 64-or-32bit target on 64-or-32bit host.
Dwarf_Ptr is the native size: it represents pointers on
the host machine (not the target!).
This contains declarations for types and all producer
and consumer functions.
Function declarations are written on a single line each here
so one can use grep to each declaration in its entirety.
The declarations are a little harder to read this way, but...
The seeming duplication of the Elf typedef allows
both verification we have the right struct name (when
libelf.h included before this) and
creation of a local handle so we have the struct pointer
here (if libelf.h is not included before this file).
*/
typedef struct _Elf Elf;
typedef struct _Elf* dwarf_elf_handle;
/* To enable printing with printf regardless of the
actual underlying data type, we define the DW_PR_xxx macros.
To ensure uses of DW_PR_DUx or DW_PR_DSx look the way you want
ensure the right DW_PR_XZEROS define is uncommented.
*/
/*#define DW_PR_XZEROS "" */
#define DW_PR_XZEROS "08"
typedef unsigned long long Dwarf_Unsigned;
typedef signed long long Dwarf_Signed;
typedef unsigned long long Dwarf_Off;
typedef unsigned long long Dwarf_Addr;
/* Dwarf_Bool as int is wasteful, but for compatibility
it must stay as int, not unsigned char. */
typedef int Dwarf_Bool; /* boolean type */
typedef unsigned short Dwarf_Half; /* 2 byte unsigned value */
typedef unsigned char Dwarf_Small; /* 1 byte unsigned value */
/* If sizeof(Dwarf_Half) is greater than 2
we believe libdwarf still works properly. */
#if defined(_WIN32) && defined(HAVE_NONSTANDARD_PRINTF_64_FORMAT)
#define DW_PR_DUx "I64x"
#define DW_PR_DSx "I64x"
#define DW_PR_DUu "I64u"
#define DW_PR_DSd "I64d"
#else
#define DW_PR_DUx "llx"
#define DW_PR_DSx "llx"
#define DW_PR_DUu "llu"
#define DW_PR_DSd "lld"
#endif /* DW_PR defines */
typedef void* Dwarf_Ptr; /* host machine pointer */
/* DWARF5: a container for a DW_FORM_data16 data item.
We have no integer types suitable so this special
struct is used instead. It is up to consumers/producers
to deal with the contents.
New October 18, 2017 . */
typedef struct Dwarf_Form_Data16_s {
unsigned char fd_data[16];
} Dwarf_Form_Data16;
/* Used for signatures where ever they appear.
It is not a string, it
is 8 bytes of a signature one would use to find
a type unit. See dwarf_formsig8()
Sometimes it is used in calculations as
Dwarf_Unsigned, but that is done inside libdwarf
and the endianness question makes it a bit sketchy.
*/
struct Dwarf_Sig8_s {
char signature[8];
};
typedef struct Dwarf_Sig8_s Dwarf_Sig8;
/* Contains info on an uninterpreted block of data
Used with certain frame information functions and
also used with DW_FORM_block<>.
*/
typedef struct {
Dwarf_Unsigned bl_len; /* length of block bl_data points at */
Dwarf_Ptr bl_data; /* uninterpreted data */
/* See libdwarf.h DW_LKIND* */
Dwarf_Small bl_from_loclist;
/* Section (not CU) offset which 'data' comes from. */
Dwarf_Unsigned bl_section_offset;
} Dwarf_Block;
/* NEW October 2015. */
/* This provides access to Dwarf_Locdesc_c, a single
location description */
struct Dwarf_Locdesc_c_s;
typedef struct Dwarf_Locdesc_c_s * Dwarf_Locdesc_c;
/* NEW October 2015. */
/* This provides access to Dwarf_Locdesc_c, a single
location list entry (or for a locexpr, the fake
Loc_Head for the locexpr) */
struct Dwarf_Loc_Head_c_s;
typedef struct Dwarf_Loc_Head_c_s * Dwarf_Loc_Head_c;
/* NEW July 2020. */
/* This provides access to data from sections
.debug_gnu_pubtypes or .debug_gnu_pubnames.
These are not standard DWARF, and can appear
with gcc -gdwarf-5
*/
struct Dwarf_Gnu_Index_Head_s;
typedef struct Dwarf_Gnu_Index_Head_s * Dwarf_Gnu_Index_Head;
/* NEW November 2015. For DWARF5 .debug_macro section */
struct Dwarf_Macro_Context_s;
typedef struct Dwarf_Macro_Context_s * Dwarf_Loc_Macro_Context;
/* NEW September 2016. Allows easy access to DW_AT_discr_list
array of discriminant values. Input in blockpointer
is a block with a list of uleb or sleb numbers
(all one or the other, lebunsignedflag instructs
how to read the leb values properly) */
typedef struct Dwarf_Dsc_Head_s * Dwarf_Dsc_Head;
/* Location record. Records up to 2 operand values.
Not usable with DWARF5 or DWARF4 with location
operator extensions. */
typedef struct {
Dwarf_Small lr_atom; /* location operation */
Dwarf_Unsigned lr_number; /* operand */
Dwarf_Unsigned lr_number2; /* for OP_BREGx and DW_OP_GNU_const_type*/
Dwarf_Unsigned lr_offset; /* offset in locexpr for OP_BRA etc */
} Dwarf_Loc;
/* Location description. DWARF 2,3,4.
When this is from a split-dwarf loclist (.debug_loc.dwo)
and no tied object is present
then ld_lowpc and ld_highpc are actually indices in
the .debug_addr section of the tied object).
If there is a tied object then these fields are actuall
addresses and DW_AT_addr_base in the skeleton CU DIE applies to
that .debug_addr.
Location record. Records up to 2 operand values.
Not usable with DWARF5 or DWARF4 with extensions.
If from DWARF2,3,4 non-split dwarf then things operate as
in DWARF2.
See dwarf_get_loclist_b() and the other related
new functions that
avoid using public structures Dwarf_Loc and Dwarf_Locdesc.
*/
typedef struct {
/* Beginning of active range. This is actually an offset
of an applicable base address, not a pc value. */
Dwarf_Addr ld_lopc;
/* End of active range. This is actually an offset
of an applicable base address, not a pc value. */
Dwarf_Addr ld_hipc;
Dwarf_Half ld_cents; /* count of location records */
Dwarf_Loc* ld_s; /* pointer to list of same */
/* non-0 if loclist, 1 if non-split (dwarf 2,3,4) */
Dwarf_Small ld_from_loclist;
Dwarf_Unsigned ld_section_offset; /* Section (not CU) offset
where loc-expr begins*/
} Dwarf_Locdesc;
/* First appears in DWARF3, and only ranges entries exist.
The dwr_addr1/addr2 data is either an offset (DW_RANGES_ENTRY)
or an address (dwr_addr2 in DW_RANGES_ADDRESS_SELECTION) or
both are zero (DW_RANGES_END).
For DWARF5 each table starts with a header
followed by range list entries defined
as here.
*/
enum Dwarf_Ranges_Entry_Type { DW_RANGES_ENTRY,
DW_RANGES_ADDRESS_SELECTION,
DW_RANGES_END
};
typedef struct {
Dwarf_Addr dwr_addr1;
Dwarf_Addr dwr_addr2;
enum Dwarf_Ranges_Entry_Type dwr_type;
} Dwarf_Ranges;
/* Frame description instructions expanded.
*/
typedef struct {
Dwarf_Small fp_base_op;
Dwarf_Small fp_extended_op;
Dwarf_Half fp_register;
/* Value may be signed, depends on op.
Any applicable data_alignment_factor has
not been applied, this is the raw offset. */
Dwarf_Unsigned fp_offset;
Dwarf_Off fp_instr_offset;
} Dwarf_Frame_Op; /* DWARF2 */
/* ***IMPORTANT NOTE, TARGET DEPENDENCY ****
DW_REG_TABLE_SIZE must be at least as large as
the number of registers
(DW_FRAME_LAST_REG_NUM) as defined in dwarf.h
Preferably identical to DW_FRAME_LAST_REG_NUM.
Ensure [0-DW_REG_TABLE_SIZE] does not overlap
DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL.
Also ensure DW_FRAME_REG_INITIAL_VALUE is set to what
is appropriate to your cpu.
For various CPUs DW_FRAME_UNDEFINED_VAL is correct
as the value for DW_FRAME_REG_INITIAL_VALUE.
For consumer apps, this can be set dynamically: see
dwarf_set_frame_rule_table_size(); */
#ifndef DW_REG_TABLE_SIZE
#define DW_REG_TABLE_SIZE 66
#endif
/* For MIPS, DW_FRAME_SAME_VAL is the correct default value
for a frame register value. For other CPUS another value
may be better, such as DW_FRAME_UNDEFINED_VAL.
See dwarf_set_frame_rule_table_size
*/
#ifndef DW_FRAME_REG_INITIAL_VALUE
#define DW_FRAME_REG_INITIAL_VALUE DW_FRAME_SAME_VAL
#endif
/* Taken as meaning 'undefined value', this is not
a column or register number.
Only present at libdwarf runtime in the consumer
interfaces. Never on disk.
DW_FRAME_* Values present on disk are in dwarf.h
Ensure this is > DW_REG_TABLE_SIZE (the reg table
size is changeable at runtime with the *reg3() interfaces,
and this value must be greater than the reg table size).
*/
#define DW_FRAME_UNDEFINED_VAL 1034
/* Taken as meaning 'same value' as caller had, not a column
or register number.
Only present at libdwarf runtime in the consumer
interfaces. Never on disk.
DW_FRAME_* Values present on disk are in dwarf.h
Ensure this is > DW_REG_TABLE_SIZE (the reg table
size is changeable at runtime with the *reg3() interfaces,
and this value must be greater than the reg table size).
*/
#define DW_FRAME_SAME_VAL 1035
/* For DWARF3 consumer interfaces, make the CFA a column with no
real table number. This is what should have been done
for the DWARF2 interfaces. This actually works for
both DWARF2 and DWARF3, but see the libdwarf documentation
on Dwarf_Regtable3 and dwarf_get_fde_info_for_reg3()
and dwarf_get_fde_info_for_all_regs3()
Do NOT use this with the older dwarf_get_fde_info_for_reg()
or dwarf_get_fde_info_for_all_regs() consumer interfaces.
Must be higher than any register count for *any* ABI
(ensures maximum applicability with minimum effort).
Ensure this is > DW_REG_TABLE_SIZE (the reg table
size is changeable at runtime with the *reg3() interfaces,
and this value must be greater than the reg table size).
Only present at libdwarf runtime in the consumer
interfaces. Never on disk.
*/
#define DW_FRAME_CFA_COL3 1436
/* The following are all needed to evaluate DWARF3 register rules.
*/
#define DW_EXPR_OFFSET 0 /* DWARF2 only sees this. */
#define DW_EXPR_VAL_OFFSET 1
#define DW_EXPR_EXPRESSION 2
#define DW_EXPR_VAL_EXPRESSION 3
typedef struct Dwarf_Regtable_Entry_s {
/* For each index i (naming a hardware register with dwarf number
i) the following is true and defines the value of that register:
If dw_regnum is Register DW_FRAME_UNDEFINED_VAL
it is not DWARF register number but
a place holder indicating the register has no defined value.
If dw_regnum is Register DW_FRAME_SAME_VAL
it is not DWARF register number but
a place holder indicating the register has the same
value in the previous frame.
DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL are
only present at libdwarf runtime. Never on disk.
DW_FRAME_* Values present on disk are in dwarf.h
Otherwise: the register number is a DWARF register number
(see ABI documents for how this translates to hardware/
software register numbers in the machine hardware)
and the following applies:
if dw_value_type == DW_EXPR_OFFSET (the only case for dwarf2):
If dw_offset_relevant is non-zero, then
the value is stored at at the address CFA+N where
N is a signed offset.
Rule: Offset(N)
If dw_offset_relevant is zero, then the value of the register
is the value of (DWARF) register number dw_regnum.
Rule: register(F)
Other values of dw_value_type are an error.
*/
Dwarf_Small dw_offset_relevant;
/* For DWARF2, always 0 */
Dwarf_Small dw_value_type;
Dwarf_Half dw_regnum;
/* The data type here should the larger of Dwarf_Addr
and Dwarf_Unsigned and Dwarf_Signed. */
Dwarf_Addr dw_offset;
} Dwarf_Regtable_Entry;
typedef struct Dwarf_Regtable_s {
struct Dwarf_Regtable_Entry_s rules[DW_REG_TABLE_SIZE];
} Dwarf_Regtable;
/* opaque type. Functional interface shown later. */
struct Dwarf_Reg_value3_s;
typedef struct Dwarf_Reg_value3_s Dwarf_Reg_Value3;
typedef struct Dwarf_Regtable_Entry3_s {
/* For each index i (naming a hardware register with dwarf number
i) the following is true and defines the value of that register:
If dw_regnum is Register DW_FRAME_UNDEFINED_VAL
it is not DWARF register number but
a place holder indicating the register has no defined value.
If dw_regnum is Register DW_FRAME_SAME_VAL
it is not DWARF register number but
a place holder indicating the register has the same
value in the previous frame.
DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL and
DW_FRAME_CFA_COL3 are only present at libdwarf runtime.
Never on disk.
DW_FRAME_* Values present on disk are in dwarf.h
Because DW_FRAME_SAME_VAL and DW_FRAME_UNDEFINED_VAL
and DW_FRAME_CFA_COL3 are definable at runtime
consider the names symbolic in this comment, not absolute.
Otherwise: the register number is a DWARF register number
(see ABI documents for how this translates to hardware/
software register numbers in the machine hardware)
and the following applies:
In a cfa-defining entry (rt3_cfa_rule) the regnum is the
CFA 'register number'. Which is some 'normal' register,
not DW_FRAME_CFA_COL3, nor DW_FRAME_SAME_VAL, nor
DW_FRAME_UNDEFINED_VAL.
If dw_value_type == DW_EXPR_OFFSET (the only possible case for
dwarf2):
If dw_offset_relevant is non-zero, then
the value is stored at at the address
CFA+N where N is a signed offset.
dw_regnum is the cfa register rule which means
one ignores dw_regnum and uses the CFA appropriately.
So dw_offset_or_block_len is a signed value, really,
and must be printed/evaluated as such.
Rule: Offset(N)
If dw_offset_relevant is zero, then the value of the register
is the value of (DWARF) register number dw_regnum.
Rule: register(R)
If dw_value_type == DW_EXPR_VAL_OFFSET
the value of this register is CFA +N where N is a signed offset.
dw_regnum is the cfa register rule which means
one ignores dw_regnum and uses the CFA appropriately.
Rule: val_offset(N)
If dw_value_type == DW_EXPR_EXPRESSION
The value of the register is the value at the address
computed by evaluating the DWARF expression E.
Rule: expression(E)
The expression E byte stream is pointed to by dw_block_ptr.
The expression length in bytes is given by
dw_offset_or_block_len.
If dw_value_type == DW_EXPR_VAL_EXPRESSION
The value of the register is the value
computed by evaluating the DWARF expression E.
Rule: val_expression(E)
The expression E byte stream is pointed to by dw_block_ptr.
The expression length in bytes is given by
dw_offset_or_block_len.
Other values of dw_value_type are an error.
*/
Dwarf_Small dw_offset_relevant;
Dwarf_Small dw_value_type;
Dwarf_Half dw_regnum;
Dwarf_Unsigned dw_offset_or_block_len;
Dwarf_Ptr dw_block_ptr;
}Dwarf_Regtable_Entry3;
/* For the DWARF3 version, moved the DW_FRAME_CFA_COL
out of the array and into its own struct.
Having it part of the array is not very easy to work
with from a portability point of view: changing
the number for every architecture is a pain (if one fails
to set it correctly a register rule gets clobbered when
setting CFA). With MIPS it just happened to be easy to use
DW_FRAME_CFA_COL (it was wrong conceptually but it was easy...).
rt3_rules and rt3_reg_table_size must be filled in before
calling libdwarf. Filled in with a pointer to an array
(pointer and array set up by the calling application)
of rt3_reg_table_size Dwarf_Regtable_Entry3_s structs.
libdwarf does not allocate or deallocate space for the
rules, you must do so. libdwarf will initialize the
contents rules array, you do not need to do so (though
if you choose to initialize the array somehow that is ok:
libdwarf will overwrite your initializations with its own).
*/
typedef struct Dwarf_Regtable3_s {
struct Dwarf_Regtable_Entry3_s rt3_cfa_rule;
Dwarf_Half rt3_reg_table_size;
struct Dwarf_Regtable_Entry3_s * rt3_rules;
} Dwarf_Regtable3;
/* Use for DW_EPXR_STANDARD., DW_EXPR_VAL_OFFSET.
Returns DW_DLV_OK if the value is available.
If DW_DLV_OK returns the regnum and offset thru the pointers
(which the consumer must use appropriately).
*/
int dwarf_frame_get_reg_register(struct Dwarf_Regtable_Entry3_s *reg_in,
Dwarf_Small *offset_relevant,
Dwarf_Half *regnum_out,
Dwarf_Signed *offset_out);
/* Use for DW_EXPR_EXPRESSION, DW_EXPR_VAL_EXPRESSION.
Returns DW_DLV_OK if the value is available.
The caller must pass in the address of a valid
Dwarf_Block (the caller need not initialize it).
*/
int dwarf_frame_get_reg_expression(struct Dwarf_Regtable_Entry3_s *reg_in,
Dwarf_Block *block_out);
/* For DW_DLC_SYMBOLIC_RELOCATIONS output to caller
v2, adding drd_length: some relocations are 4 and
some 8 bytes (pointers are 8, section offsets 4) in
some dwarf environments. (MIPS relocations are all one
size in any given ABI.) Changing drd_type to an unsigned char
to keep struct size down.
*/
enum Dwarf_Rel_Type {
dwarf_drt_none, /* Should not get to caller */
dwarf_drt_data_reloc, /* Simple normal relocation. */
dwarf_drt_segment_rel, /* Special reloc, exceptions. */
/* dwarf_drt_first_of_length_pair and drt_second
are for for the .word end - begin case. */
dwarf_drt_first_of_length_pair,
dwarf_drt_second_of_length_pair
};
typedef struct Dwarf_P_Marker_s * Dwarf_P_Marker;
struct Dwarf_P_Marker_s {
Dwarf_Unsigned ma_marker;
Dwarf_Unsigned ma_offset;
};
typedef struct Dwarf_Relocation_Data_s * Dwarf_Relocation_Data;
struct Dwarf_Relocation_Data_s {
unsigned char drd_type; /* Cast to/from Dwarf_Rel_Type
to keep size small in struct. */
unsigned char drd_length; /* Length in bytes of data being
relocated. 4 for 32bit data,
8 for 64bit data. */
Dwarf_Unsigned drd_offset; /* Where the data to reloc is. */
Dwarf_Unsigned drd_symbol_index;
};
typedef struct Dwarf_P_String_Attr_s * Dwarf_P_String_Attr;
struct Dwarf_P_String_Attr_s {
Dwarf_Unsigned sa_offset; /* Offset of string attribute data */
Dwarf_Unsigned sa_nbytes;
};
/* Opaque types for Consumer Library. */
typedef struct Dwarf_Debug_s* Dwarf_Debug;
typedef struct Dwarf_Die_s* Dwarf_Die;
typedef struct Dwarf_Line_s* Dwarf_Line;
typedef struct Dwarf_Global_s* Dwarf_Global;
typedef struct Dwarf_Func_s* Dwarf_Func;
typedef struct Dwarf_Type_s* Dwarf_Type;
typedef struct Dwarf_Var_s* Dwarf_Var;
typedef struct Dwarf_Weak_s* Dwarf_Weak;
typedef struct Dwarf_Error_s* Dwarf_Error;
typedef struct Dwarf_Attribute_s* Dwarf_Attribute;
typedef struct Dwarf_Abbrev_s* Dwarf_Abbrev;
typedef struct Dwarf_Fde_s* Dwarf_Fde;
typedef struct Dwarf_Cie_s* Dwarf_Cie;
typedef struct Dwarf_Arange_s* Dwarf_Arange;
typedef struct Dwarf_Gdbindex_s* Dwarf_Gdbindex;
struct Dwarf_Xu_Index_Header_s;
typedef struct Dwarf_Xu_Index_Header_s *Dwarf_Xu_Index_Header;
struct Dwarf_Line_Context_s;
typedef struct Dwarf_Line_Context_s *Dwarf_Line_Context;
struct Dwarf_Macro_Context_s;
typedef struct Dwarf_Macro_Context_s *Dwarf_Macro_Context;
struct Dwarf_Dnames_Head_s;
typedef struct Dwarf_Dnames_Head_s *Dwarf_Dnames_Head;
/* Opaque types for Producer Library. */
typedef struct Dwarf_P_Debug_s* Dwarf_P_Debug;
typedef struct Dwarf_P_Die_s* Dwarf_P_Die;
typedef struct Dwarf_P_Attribute_s* Dwarf_P_Attribute;
typedef struct Dwarf_P_Fde_s* Dwarf_P_Fde;
typedef struct Dwarf_P_Expr_s* Dwarf_P_Expr;
typedef Dwarf_Unsigned Dwarf_Tag;
/* error handler function
*/
typedef void (*Dwarf_Handler)(Dwarf_Error /*error*/, Dwarf_Ptr /*errarg*/);
/* Begin libdwarf Object File Interface declarations.
As of February 2008 there are multiple dwarf_reader object access
initialization methods available:
The traditional dwarf_elf_init() and dwarf_init() and dwarf_finish()
which assume libelf and POSIX file access.
An object-file and library agnostic dwarf_object_init() and dwarf_object_finish()
which allow the coder to provide object access routines
abstracting away the elf interface. So there is no dependence in the
reader code on the object format and no dependence on libelf.
See the code in dwarf_elf_access.c and dwarf_original_elf_init.c
to see an example of initializing the structures mentioned below.
Projects using dwarf_elf_init() or dwarf_init() can ignore
the Dwarf_Obj_Access* structures entirely as all these details
are completed for you.
As of March 2017 additional
functions dwarf_elf_init_b
and dwarf_init_b
and dwarf_object_init_b
add a groupnumber argument so DWARF5
split-dwarf sections can be accessed.
*/
typedef struct Dwarf_Obj_Access_Interface_s Dwarf_Obj_Access_Interface;
typedef struct Dwarf_Obj_Access_Methods_s Dwarf_Obj_Access_Methods;
typedef struct Dwarf_Obj_Access_Section_s Dwarf_Obj_Access_Section;
/* Used in the get_section interface function
in Dwarf_Obj_Access_Section_s. Since libdwarf
depends on standard DWARF section names an object
format that has no such names (but has some
method of setting up 'sections equivalents')
must arrange to return standard DWARF section
names in the 'name' field. libdwarf does
not free the strings in 'name'. */
struct Dwarf_Obj_Access_Section_s {
/* addr is the virtual address of the first byte of
the section data. Usually zero when the address
makes no sense for a given section. */
Dwarf_Addr addr;
/* Section type. */
Dwarf_Unsigned type;
/* Size in bytes of the section. */
Dwarf_Unsigned size;
/* Having an accurate section name makes debugging of libdwarf easier.
and is essential to find the .debug_ sections. */
const char* name;
/* Set link to zero if it is meaningless. If non-zero
it should be a link to a rela section or from symtab
to strtab. In Elf it is sh_link. */
Dwarf_Unsigned link;
/* The section header index of the section to which the
relocation applies. In Elf it is sh_info. */
Dwarf_Unsigned info;
/* Elf sections that are tables have a non-zero entrysize so
the count of entries can be calculated even without
the right structure definition. If your object format
does not have this data leave this zero. */
Dwarf_Unsigned entrysize;
};
/* Returned by the get_endianness function in
Dwarf_Obj_Access_Methods_s. */
typedef enum {
DW_OBJECT_MSB,
DW_OBJECT_LSB
} Dwarf_Endianness;
/* The functions we need to access object data from libdwarf are declared here.
In these function pointer declarations
'void *obj' is intended to be a pointer (the object field in
Dwarf_Obj_Access_Interface_s)
that hides the library-specific and object-specific data that makes
it possible to handle multiple object formats and multiple libraries.
It's not required that one handles multiple such in a single libdwarf
archive/shared-library (but not ruled out either).
See dwarf_elf_object_access_internals_t and dwarf_elf_access.c
for an example.
*/
struct Dwarf_Obj_Access_Methods_s {
/*
get_section_info
Get address, size, and name info about a section.
Parameters
section_index - Zero-based index.
return_section - Pointer to a structure in which section info
will be placed. Caller must provide a valid pointer to a
structure area. The structure's contents will be overwritten
by the call to get_section_info.
error - A pointer to an integer in which an error code may be stored.
Return
DW_DLV_OK - Everything ok.
DW_DLV_ERROR - Error occurred. Use 'error' to determine the
libdwarf defined error.
DW_DLV_NO_ENTRY - No such section. */
int (*get_section_info)(void* obj, Dwarf_Half section_index,
Dwarf_Obj_Access_Section* return_section, int* error);
/*
get_byte_order
Get whether the object file represented by this interface is big-endian
(DW_OBJECT_MSB) or little endian (DW_OBJECT_LSB).
Parameters
obj - Equivalent to 'this' in OO languages.
Return
Endianness of object. Cannot fail. */
Dwarf_Endianness (*get_byte_order)(void* obj);
/*
get_length_size
Get the size of a length field in the underlying object file.
libdwarf currently supports * 4 and 8 byte sizes, but may
support larger in the future.
Perhaps the return type should be an enumeration?
Parameters
obj - Equivalent to 'this' in OO languages.
Return
Size of length. Cannot fail. */
Dwarf_Small (*get_length_size)(void* obj);
/*
get_pointer_size
Get the size of a pointer field in the underlying object file.
libdwarf currently supports 4 and 8 byte sizes.
Perhaps the return type should be an enumeration?
Return
Size of pointer. Cannot fail. */
Dwarf_Small (*get_pointer_size)(void* obj);
/*
get_section_count
Get the number of sections in the object file.
Parameters
Return
Number of sections */
Dwarf_Unsigned (*get_section_count)(void* obj);
/*
load_section
Get a pointer to an array of bytes that represent the section.
Parameters
section_index - Zero-based index.
return_data - The address of a pointer to which the section data block
will be assigned.
error - Pointer to an integer for returning libdwarf-defined
error numbers.
Return
DW_DLV_OK - No error.
DW_DLV_ERROR - Error. Use 'error' to indicate a libdwarf-defined
error number.
DW_DLV_NO_ENTRY - No such section. */
int (*load_section)(void* obj, Dwarf_Half section_index,
Dwarf_Small** return_data, int* error);
/**
relocate_a_section
If relocations are not supported leave this pointer NULL.
Get a pointer to an array of bytes that represent the section.
Parameters
section_index - Zero-based index of the section to be relocated.
error - Pointer to an integer for returning libdwarf-defined
error numbers.
Return
DW_DLV_OK - No error.
DW_DLV_ERROR - Error. Use 'error' to indicate a libdwarf-defined
error number.
DW_DLV_NO_ENTRY - No such section. */
int (*relocate_a_section)(void* obj, Dwarf_Half section_index,
Dwarf_Debug dbg,
int* error);
};
/* These structures are allocated and deallocated by your code
when you are using the libdwarf Object File Interface
[dwarf_object_init and dwarf_object_finish)] directly.
dwarf_object_finish) does not free
struct Dwarf_Obj_Access_Interface_s or its content.
(libdwarf does record a pointer to this struct: you must
ensure that pointer remains valid for as long as
a libdwarf instance is open (meaning
after dwarf_init) and before dwarf_finish)).
If you are reading Elf objects and libelf use dwarf_init()
or dwarf_elf_init() which take care of these details.
*/
struct Dwarf_Obj_Access_Interface_s {
/* object is a void* as it hides the data the object access routines
need (which varies by library in use and object format).
*/
void* object;
const Dwarf_Obj_Access_Methods * methods;
};
/* End libdwarf Object File Interface */
/*
Dwarf_dealloc() alloc_type arguments.
Argument points to:
*/
#define DW_DLA_STRING 0x01 /* char* */
#define DW_DLA_LOC 0x02 /* Dwarf_Loc */
#define DW_DLA_LOCDESC 0x03 /* Dwarf_Locdesc */
#define DW_DLA_ELLIST 0x04 /* Dwarf_Ellist (not used)*/
#define DW_DLA_BOUNDS 0x05 /* Dwarf_Bounds (not used) */
#define DW_DLA_BLOCK 0x06 /* Dwarf_Block */
#define DW_DLA_DEBUG 0x07 /* Dwarf_Debug */
#define DW_DLA_DIE 0x08 /* Dwarf_Die */
#define DW_DLA_LINE 0x09 /* Dwarf_Line */
#define DW_DLA_ATTR 0x0a /* Dwarf_Attribute */
#define DW_DLA_TYPE 0x0b /* Dwarf_Type (not used) */
#define DW_DLA_SUBSCR 0x0c /* Dwarf_Subscr (not used) */
#define DW_DLA_GLOBAL 0x0d /* Dwarf_Global */
#define DW_DLA_ERROR 0x0e /* Dwarf_Error */
#define DW_DLA_LIST 0x0f /* a list */
#define DW_DLA_LINEBUF 0x10 /* Dwarf_Line* (not used) */
#define DW_DLA_ARANGE 0x11 /* Dwarf_Arange */
#define DW_DLA_ABBREV 0x12 /* Dwarf_Abbrev */
#define DW_DLA_FRAME_OP 0x13 /* Dwarf_Frame_Op */
#define DW_DLA_CIE 0x14 /* Dwarf_Cie */
#define DW_DLA_FDE 0x15 /* Dwarf_Fde */
#define DW_DLA_LOC_BLOCK 0x16 /* Dwarf_Loc */
#define DW_DLA_FRAME_BLOCK 0x17 /* Dwarf_Frame Block (not used) */
#define DW_DLA_FUNC 0x18 /* Dwarf_Func */
#define DW_DLA_TYPENAME 0x19 /* Dwarf_Type */
#define DW_DLA_VAR 0x1a /* Dwarf_Var */
#define DW_DLA_WEAK 0x1b /* Dwarf_Weak */
#define DW_DLA_ADDR 0x1c /* Dwarf_Addr sized entries */
#define DW_DLA_RANGES 0x1d /* Dwarf_Ranges */
/* 0x1e (30) to 0x34 (52) reserved for internal to libdwarf types. */
#define DW_DLA_GNU_INDEX_HEAD 0x35 /* .debug_gnu_typenames/pubnames, 2020 */
#define DW_DLA_RNGLISTS_HEAD 0x36 /* .debug_rnglists DW5 */
#define DW_DLA_GDBINDEX 0x37 /* Dwarf_Gdbindex */
#define DW_DLA_XU_INDEX 0x38 /* Dwarf_Xu_Index_Header */
#define DW_DLA_LOC_BLOCK_C 0x39 /* Dwarf_Loc_c*/
#define DW_DLA_LOCDESC_C 0x3a /* Dwarf_Locdesc_c */
#define DW_DLA_LOC_HEAD_C 0x3b /* Dwarf_Loc_Head_c */
#define DW_DLA_MACRO_CONTEXT 0x3c /* Dwarf_Macro_Context */
/* 0x3d (61) is for libdwarf internal use. */
#define DW_DLA_DSC_HEAD 0x3e /* Dwarf_Dsc_Head */
#define DW_DLA_DNAMES_HEAD 0x3f /* Dwarf_Dnames_Head */
#define DW_DLA_STR_OFFSETS 0x40 /* struct Dwarf_Str_Offsets_Table_s */
/* The augmenter string for CIE */
#define DW_CIE_AUGMENTER_STRING_V0 "z"
/* dwarf_init() 'access' argument values.
Used for reading/consuming DWARF, not
relevant to the producer portion of libdwarf.
None of the following three arguments do anything.
The following short set is useless.
Only DW_DLC_READ has a documented effect but...
it is useless and irrelevant as it means
'do the default'.
In the 1990's there was an option DW_DLC_MMAP
(deleted from libdwarf.h many years ago).
The old option libdwarf told IRIX libelf to mmap
the object file.
*/
#define DW_DLC_READ 0 /* Pointless. Ok to use. */
#define DW_DLC_WRITE 1 /* DO NOT USE */
#define DW_DLC_RDWR 2 /* DO NOT USE */
/* ===== the following DW_DLC options are for producing DWARF,
not used for reading/consuming DWARF. */
/* dwarf_producer_init* access flag modifiers
No longer depends on compile-time settings for
how to produce 64bit offset. See DW_DLC_IRIX_OFFSET64.
Historic versions. One of
If DW_DLC_POINTER64 is not set DW_DLC_POINTER32 is assumed.
If DW_DLC_OFFSET64 or DW_DLC_IRIX_OFFSET64 is not
set 32bit offset DWARF is assumed.
Non-MIPS Non IA64 should use DW_DLC_SYMBOLIC_RELOCATIONS
and handle the relocation creation for the target
itself using the symbolic relocations to do so.
See the Dwarf_Rel_Type enum relocation indicators.
*/
/* 64-bit address-size target */
#define DW_DLC_SIZE_64 0x40000000 /* old spelling */
#define DW_DLC_POINTER64 0x40000000 /* correct spelling */
/* 32-bit address-size target */
#define DW_DLC_SIZE_32 0x20000000 /* old spelling */
#define DW_DLC_POINTER32 0x20000000 /* correct spelling */
/* 32-bit offset-size ELF object (ELFCLASS32) */
#define DW_DLC_ELF_OFFSET_SIZE_32 0x00400000 /* DO NOT USE */
/* DW_DLC_OFFSET32 is the default, the bit is not checked. */
#define DW_DLC_OFFSET32 0x00010000 /* default offset size */
/* 64-bit offset-size DWARF offsets */
#define DW_DLC_OFFSET_SIZE_64 0x10000000 /* old spelling */
#define DW_DLC_OFFSET64 0x10000000 /* correct spelling */
/* 64-bit offset-size ELF object (ELFCLASS64) */
#define DW_DLC_ELF_OFFSET_SIZE_64 0x00020000 /* DO NOT USE. */
/* Special for IRIX only. For producing DWARF with
Elf 64bit offset headers and non-standard IRIX
64bit offset DWARF .debug_info etc compilation unit headers. */
#define DW_DLC_IRIX_OFFSET64 0x00200000
/* Old style Elf binary relocation (.rel) records. The default.
For producing DWARF */
#define DW_DLC_STREAM_RELOCATIONS 0x02000000
/* Usable with assembly output because it is up to the producer to
deal with locations in whatever manner the calling producer
code wishes. For example, when the libdwarf caller wishes
to produce relocations differently than the binary
relocation bits that libdwarf Stream Relocations generate.
*/
#define DW_DLC_SYMBOLIC_RELOCATIONS 0x04000000
#define DW_DLC_TARGET_BIGENDIAN 0x08000000
#define DW_DLC_TARGET_LITTLEENDIAN 0x00100000
/* ===== END DW_DLC options LIBDWARF */
/* dwarf_pcline function, slide arguments
*/
#define DW_DLS_BACKWARD -1 /* slide backward to find line */
#define DW_DLS_NOSLIDE 0 /* match exactly without sliding */
#define DW_DLS_FORWARD 1 /* slide forward to find line */
/* libdwarf error numbers
*/
#define DW_DLE_NE 0 /* no error */
#define DW_DLE_VMM 1 /* dwarf format/library version mismatch */
#define DW_DLE_MAP 2 /* memory map failure */
#define DW_DLE_LEE 3 /* libelf error */
#define DW_DLE_NDS 4 /* no debug section */
#define DW_DLE_NLS 5 /* no line section */
#define DW_DLE_ID 6 /* invalid descriptor for query */
#define DW_DLE_IOF 7 /* I/O failure */
#define DW_DLE_MAF 8 /* memory allocation failure */
#define DW_DLE_IA 9 /* invalid argument */
#define DW_DLE_MDE 10 /* mangled debugging entry */
#define DW_DLE_MLE 11 /* mangled line number entry */
#define DW_DLE_FNO 12 /* file not open */
#define DW_DLE_FNR 13 /* file not a regular file */
#define DW_DLE_FWA 14 /* file open with wrong access */
#define DW_DLE_NOB 15 /* not an object file */
#define DW_DLE_MOF 16 /* mangled object file header */
#define DW_DLE_EOLL 17 /* end of location list entries */
#define DW_DLE_NOLL 18 /* no location list section */
#define DW_DLE_BADOFF 19 /* Invalid offset */
#define DW_DLE_EOS 20 /* end of section */
#define DW_DLE_ATRUNC 21 /* abbreviations section appears truncated*/
#define DW_DLE_BADBITC 22 /* Address size passed to dwarf bad*/
/* It is not an allowed size (64 or 32) */
/* Error codes defined by the current Libdwarf Implementation. */
#define DW_DLE_DBG_ALLOC 23
#define DW_DLE_FSTAT_ERROR 24
#define DW_DLE_FSTAT_MODE_ERROR 25
#define DW_DLE_INIT_ACCESS_WRONG 26
#define DW_DLE_ELF_BEGIN_ERROR 27
#define DW_DLE_ELF_GETEHDR_ERROR 28
#define DW_DLE_ELF_GETSHDR_ERROR 29
#define DW_DLE_ELF_STRPTR_ERROR 30
#define DW_DLE_DEBUG_INFO_DUPLICATE 31
#define DW_DLE_DEBUG_INFO_NULL 32
#define DW_DLE_DEBUG_ABBREV_DUPLICATE 33
#define DW_DLE_DEBUG_ABBREV_NULL 34
#define DW_DLE_DEBUG_ARANGES_DUPLICATE 35
#define DW_DLE_DEBUG_ARANGES_NULL 36
#define DW_DLE_DEBUG_LINE_DUPLICATE 37
#define DW_DLE_DEBUG_LINE_NULL 38
#define DW_DLE_DEBUG_LOC_DUPLICATE 39
#define DW_DLE_DEBUG_LOC_NULL 40
#define DW_DLE_DEBUG_MACINFO_DUPLICATE 41
#define DW_DLE_DEBUG_MACINFO_NULL 42
#define DW_DLE_DEBUG_PUBNAMES_DUPLICATE 43
#define DW_DLE_DEBUG_PUBNAMES_NULL 44
#define DW_DLE_DEBUG_STR_DUPLICATE 45
#define DW_DLE_DEBUG_STR_NULL 46
#define DW_DLE_CU_LENGTH_ERROR 47
#define DW_DLE_VERSION_STAMP_ERROR 48
#define DW_DLE_ABBREV_OFFSET_ERROR 49
#define DW_DLE_ADDRESS_SIZE_ERROR 50
#define DW_DLE_DEBUG_INFO_PTR_NULL 51
#define DW_DLE_DIE_NULL 52
#define DW_DLE_STRING_OFFSET_BAD 53
#define DW_DLE_DEBUG_LINE_LENGTH_BAD 54
#define DW_DLE_LINE_PROLOG_LENGTH_BAD 55
#define DW_DLE_LINE_NUM_OPERANDS_BAD 56
#define DW_DLE_LINE_SET_ADDR_ERROR 57 /* No longer used. */
#define DW_DLE_LINE_EXT_OPCODE_BAD 58
#define DW_DLE_DWARF_LINE_NULL 59