File: libdwarf.dox

package info (click to toggle)
dwarfutils 1%3A0.11.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 11,732 kB
  • sloc: ansic: 119,558; cpp: 6,689; xml: 4,736; sh: 1,674; python: 1,117; makefile: 1,099
file content (1527 lines) | stat: -rw-r--r-- 54,493 bytes parent folder | download
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
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
/*!
    @mainpage A Consumer Library Interface to DWARF
    @tableofcontents{HTML:3,LaTeX:3}
    @author David Anderson
    @copyright  This work is licensed under the Creative Commons Attribution 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
    @date 2024-08-15 v0.11.1

    @section draft Suggestions for improvement are welcome.

    Your thoughts on the document?

    A) Are the section and subsection titles on Main Page
    meaningful to you?

    B) Are the titles on the Modules page  meaningful to you?

    Anything else you find misleading or confusing?
    Send suggestions to ( libdwarf-list (at)
    prevanders with final characters .org ) Sorry
    about the simple obfuscation to keep bots
    away. It's actually a simple email address,
    not a list.

    Thanks in advance for any suggestions.

    @section dwsec_intro Introduction

    This document describes an interface to @e libdwarf,
    a library of functions to provide
    access to DWARF debugging information records,
    DWARF line number information, DWARF address
    range and global names information, weak
    names information, DWARF frame description
    information, DWARF static function names, DWARF
    static variables, and DWARF type information.
    In addition the library provides access to
    several object sections (created by compiler
    writers and for debuggers) related to debugging
    but not mentioned in any DWARF standard.

    The DWARF Standard has long mentioned the "Unix
    International Programming Languages Special
    Interest Group" (PLSIG), under whose auspices the
    DWARF committee was formed around 1991. "Unix
    International" was disbanded in the 1990s and
    no longer exists.

    The DWARF committee published DWARF2 July 27,
    1993, DWARF3 in 2005, DWARF4 in 2010, and DWARF5
    in 2017.

    In the mid 1990s this document and the library it
    describes (which the committee never endorsed,
    having decided not to endorse or approve any
    particular library interface) was made available
    on the internet by Silicon Graphics, Inc.

    In 2005 the DWARF committee began an affiliation
    with FreeStandards.org. In 2007 FreeStandards.org
    merged with The Linux Foundation. The
    DWARF committee dropped its affiliation with
    FreeStandards.org in 2007 and established the
    dwarfstd.org website.

    @see https://www.dwarfstd.org for current information on
    standardization activities and a copy of the standard.

    @section dwsec_threadsafety Thread Safety

    Libdwarf can safely open multiple Dwarf_Debug
    pointers simultaneously but all such Dwarf_Debug
    pointers must be opened within the same thread.
    And all @e libdwarf calls must be made from within
    that single (same) thread.

    @section dwsec_error Error Handling in libdwarf

    Essentially every @e libdwarf call could involve dealing
    with an error (possibly data corruption in
    the object file).  Here we explain the two main
    approaches the library provides (though we think
    only one of them is truly appropriate except
    in toy programs).
    In all cases where the library
    returns an error code (almost every
    library function does) the caller should
    check whether the returned integer is
    DW_DLV_OK, DW_DLV_ERROR, or DW_DLV_NO_ENTRY
    and then act accordingly.

    <b>A) The recommended approach</b> is to
    define a Dwarf_Error and initialize it to 0.

    @code
    Dwarf_Error error = 0;
    @endcode
    Then, in every call where there is a Dwarf_Error argument
    pass its address. For example:
    @code
    int res = dwarf_tag(die,DW_TAG_compile_unit,&error);
    @endcode

    The possible return values to res are, in general:
    @code
    DW_DLV_OK
    DW_DLV_NO_ENTRY
    DW_DLV_ERROR
    @endcode

    If <b>DW_DLV_ERROR</b> is returned then error is set
    (by the library) to a pointer to important
    details about the error and
    the library will not pass back any data through
    other pointer arguments.
    If <b>DW_DLV_NO_ENTRY</b> is
    returned the error argument is ignored by the library
    and
    the library will not pass back any data through
    pointer arguments.
    If <b>DW_DLV_OK</b> is returned argument pointers that
    are defined as ways to return data to your code
    are used and values are set in your data by
    the library.

    Some functions cannot possibly return some of these
    three values. As defined later for each function.

    <b>B) An alternative (not recommended)</b> approach is
    to pass NULL to the error argument.

    @code
    int res = dwarf_tag(die,DW_TAG_compile_unit,NULL);
    @endcode

    If your initialization provided an 'errhand'
    function pointer argument (see below) the
    library will call errhand if an error is encountered.
    (Your errhand function could exit if you so choose.)

    The the library will then return DW_DLV_ERROR, though
    you will have no way to identify what the error was.
    Could be a malloc fail or data corruption or an
    invalid argument to the call, or something else.

    That is the whole picture. The library never
    calls exit() under any circumstances.

    @subsection dw_errorinit Error Handling at Initialization

    Each initialization call (for example)
    @code
    Dwarf_Debug   dbg = 0;
    const char   *path = "myobjectfile";
    char         *true_path = 0;
    unsigned int  true_pathlen = 0;
    Dwarf_Handler errhand = 0;
    Dwarf_Ptr     errarg = 0;
    Dwarf_Error   error = 0;
    int           res = 0;

    res = dwarf_init_path(path,true_path,true_pathlen,
        DW_GROUPNUMBER_ANY,errhand,errarg,&dbg,&error);
    @endcode
    has two arguments that appear nowhere
    else in the library.
    @code
    Dwarf_Handler errhand
    Dwarf_Ptr     errarg
    @endcode

    For the <b>recommended A)</b> approach:

    Just pass NULL to both those arguments.
    If the initialization call returns DW_DLV_ERROR
    you should then call
    @code
    dwarf_dealloc_error(dbg,error);
    @endcode
    to free the Dwarf_Error data because
    dwarf_finish() does not clean up
    a dwarf-init error.
    This works even though <i>dbg</i> will be NULL.

    For the <b>not recommended B)</b> approach:

    Because dw_errarg is a general pointer one could
    create a struct with data of interest and use
    a pointer to the struct as the dw_errarg.
    Or one could use an integer or NULL,
    it just depends what you want to do in the
    Dwarf_Handler function you write.

    If you wish to provide a dw_errhand, define a function
    (this first example is not a good choice as it
    terminates the application!).
    @code
    void bad_dw_errhandler(Dwarf_Error error,Dwarf_Ptr ptr)
    {
        printf("ERROR Exit on %lx due to error 0x%lx %s\n",
            (unsigned long)ptr,
            (unsigned long)dwarf_errno(error),
            dwarf_errmsg(error));
        exit(1)
    }
    @endcode
    and pass bad_dw_errhandler (as a function pointer,
    no parentheses).

    The Dwarf_Ptr argument your error handler
    function receives is the value you passed in as dw_errarg,
    and can be anything, it allows you to associate
    the callback with a particular dwarf_init* call
    if you wish to make such an association.

    By doing an exit() you guarantee that your application
    abruptly stops.  This is only acceptable in toy
    or practice programs.

    A better dw_errhand function is
    @code
    void my_dw_errhandler(Dwarf_Error error,Dwarf_Ptr ptr)
    {
        /*  Clearly one could write to a log file or do
            whatever the application finds useful. */
        printf("ERROR on %lx due to error 0x%lx %s\n",
            (unsigned long)ptr,
            (unsigned long)dwarf_errno(error),
            dwarf_errmsg(error));
    }
    @endcode
    because it returns rather than exiting.
    It is not ideal.  The DW_DLV_ERROR code
    is returned from @e libdwarf and your code
    can do what it likes with the error situation.
    The library will continue from the error and
    will return an error code on returning to your
    @elibdwarf call ... but the calling function will not
    know what the error was.

    @code
    Dwarf_Ptr x = address of some struct I want in the errhandler;
    res = dwarf_init_path(...,my_dw_errhandler,x,... );
    if (res == ...)
    @endcode
    If you do not wish to provide a dw_errhand, just pass
    both arguments as NULL.

    @subsection dw_errorcall Error Handling Everywhere

    So let us examine a simple case where anything could
    happen.  We are taking the
    <b>recommended A)</b>
    method of using a non-null Dwarf_Error*:

    @code
    int func(Dwarf_Dbg dbg,Dwarf_Die die, Dwarf_Error* error) {
        Dwarf_Die newdie = 0;
        int       res = 0;

        res = dwarf_siblingof_c(die,&newdie,error);
        if (res != DW_DLV_OK) {
            /*  Whether DW_DLV_ERROR or DW_DLV_NO_ENTRY
                (the latter is actually impossible
                for this function) returning res is the
                appropriate default thing to do. */
            return res;
        }
        /*  Do something with newdie. */
        dwarf_dealloc_die(newdie);
        newdie = 0; /* A good habit... */
        return DW_DLV_OK;
    }
    @endcode

    @subsubsection DW_DLV_OK

    When res == DW_DLV_OK
    newdie is a valid pointer and when appropriate we should do
    dwarf_dealloc_die(newdie).
    For other @e libdwarf calls
    the meaning depends on the function called,
    so read the description of the function
    you called for more information.

    @subsubsection DW_DLV_NO_ENTRY

    When res == DW_DLV_NO_ENTRY
    then newdie is not
    set and there is no error. It means
    die was the last of a siblinglist.
    For other @e libdwarf calls the
    meaning  depends on the function called,
    so read the description of the function
    you called for more information.

    @subsubsection DW_DLV_ERROR

    When res == DW_DLV_ERROR
    Something bad happened.
    The only way to know what happened is to examine
    the *error as in
    @code
    int ev = dwarf_errno(*error);
    or
    char * msg  = dwarf_errmsg(*error);
    @endcode
    or both and report that somehow.

    The above three values are the only returns possible
    from the great majority of @e libdwarf functions, and
    for these functions the return type is always @b int .

    If it is a decently large
    or long-running program then you want to
    free any local memory you
    allocated and return res.
    If it is a small
    or experimental program print something and exit
    (possibly leaking memory).

    If you want to discard the error report from the
    dwarf_siblingof_c() call then possibly do
    @code
        dwarf_dealloc_error(dbg,*error);
        *error = 0;
        return DW_DLV_OK;
    @endcode

    Except in a special case involving function
    dwarf_set_de_alloc_flag() (which you will not usually
    call), any dwarf_dealloc() that is needed will
    happen automatically when you call dwarf_finish().

    @subsubsection A Slight Performance Enhancement
    Very long running library access programs
    using relevant appropriate dwarf_dealloc calls
    should consider calling dwarf_set_de_alloc_flag(0).
    Using this one could get a performance enhancement
    of perhaps five percent in @e libdwarf CPU time and a
    reduction in memory use.

    Be sure to test using valgrind or -fsanitize to ensure your
    code really does the extra dwarf_dealloc calls
    needed since when using dwarf_set_de_alloc_flag(0)
    dwarf_finish() does only limited cleanup.

    @section dwsec_cuplan Extracting Data Per Compilation Unit

    The library is designed to run a single pass
    through the set of Compilation Units (CUs), via
    a sequence of calls to dwarf_next_cu_header_e().
    (dwarf_next_cu_header_d() is supported but
    its use requires that it be immediately followed
    by a call to dwarf_siblingof_b().
    see dwarf_next_cu_header_d(). )

    Within a CU opened with dwarf_next_cu_header_e()
    do something (if desired) on the CU_DIE
    returned, and call dwarf_child() on the CU_DIE
    to begin recursing through all DIEs.
    If you save the CU_DIE you can repeat  passes
    beginning with dwarf_child() on the CU_DIE,
    though it almost certainly faster to remember,
    in your data structures,
    what you need from the first pass.

    The general plan:

    @code
        create your local data structure(s)

        A.  Check your local data structures to see if
            you have what you need
        B.  If sufficient data present act on it,
            ensuring your data structures are kept for
            further use.
        C.  Otherwise Read a CU, recording relevant data
            in your structures and loop back to A.
    @endcode

    For an example (best approach)
    @see examplecuhdre
    or (second-best approach)
    @see examplecuhdrd
    Write your code to record relevant (to you)
    information from each CU as you go so your code
    has no need for a second pass through the CUs.
    This is much much faster than allowing multiple
    passes would be.

    @section dwsec_linetabreg Line Table Registers

    Line Table Registers

    Please refer to the DWARF5 Standard for details.
    The line table registers are named in Section
    6.2.2 State Machine Registers and are
    not much changed from DWARF2.

    Certain functions on Dwarf_Line data
    return values for these 'registers'
    as these are the data available for
    debuggers and other tools to relate
    a code address to a source file name and
    possibly also to a line number and column-number
    within the source file.

    @code
    address
    op_index
    file
    line
    column
    is_stmt
    basic_block
    end_sequence
    prologue_end
    epilogue_begin
    isa
    discriminator
    @endcode

    @section dwsec_independentsec Reading Special Sections Independently

    DWARF defines (in each version of DWARF)
    sections which have a somewhat special character.
    These are referenced from compilation units and
    other places and the Standard does not forbid
    blocks of random bytes at the start or end or
    between the areas referenced from elsewhere.

    Sometimes compilers (or linkers) leave trash
    behind as a result of optimizations.  If there
    is a lot of space wasted that way it is quality
    of implementation issue.  But usually the wasted
    space, if any, is small.

    Compiler writers or others may be interested
    in looking at these sections independently
    so @e libdwarf provides functions that allow
    reading the sections without reference to what
    references them.

    @link abbrev Abbreviations can be read independently @endlink

    @link string Strings can be read independently @endlink

    @link str_offsets String Offsets can be read independently @endlink

    @link debugaddr The addr table can be read independently @endlink

    Those functions allow starting at byte 0 of the
    section and provide a length so you can calculate
    the next section offset to call or refer to.

    Usually that works fine.  If there is some
    random data somewhere outside of referenced
    areas or the data format is a gcc extension
    of an early DWARF version the reader
    function may fail, returning
    DW_DLV_ERROR.  Such an error is neither a
    compiler bug nor a @e libdwarf bug.

    @section frameregs Special Frame Registers

    In dealing with .debug_frame or .eh_frame there
    are five values that must be set unless
    one has relatively few registers in the target
    ABI (anything under 188 registers, see dwarf.h
    DW_FRAME_LAST_REG_NUM for this default).

    The requirements stem from the design of the
    section.  See the DWARF5 Standard for details.
    The .debug_frame section is basically
    the same  from DWARF2 on.
    The .eh_frame  section is similar to .debug_frame
    but is intended to support exception handling
    and has fields and data not present in .debug_frame.

    Keep in mind that register values correspond
    to columns in the theoretical fully complete
    line table of a row per pc and a column per register.

    There is no time or space penalty in setting
    <b>Undefined_Value,</b> <b>Same_Value,</b> and  <b>CFA_Column</b>
    much larger than the <b>Table_Size</b>.

    Here are the five values.

    @b Table_Size: This sets the number of columns
        in the theoretical table.  It starts at
        DW_FRAME_LAST_REG_NUM which defaults to 188.
        This is the only value you
        might need to change, given the defaults
        of the others are set reasonably large by
        default.

    @b Undefined_Value: A register number that means
        the register value is undefined. For example due
        to a call clobbering the register.
        DW_FRAME_UNDEFINED_VAL defaults to  12288.
        There no such column in the table.

    @b Same_Value: A register number that means
        the register value is the same as the value
        at the call. Nothing can have clobbered it.
        DW_FRAME_SAME_VAL defaults to 12289.
        There no such column in the table.

    @b Initial_Value:    The value must be either
        DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL to represent
        how most registers are to be thought of at a function call.
        This is a property of the ABI and instruction set.
        Specific frame instructions in the CIE or FDE
        will override this for registers not matching
        this value.

    @b CFA_Column:       A number for the CFA.
        Defined so we can use a register number
        to refer to it.
        DW_FRAME_CFA_COL defaults to 12290.
        There no such column in the table.
        See libdwarf.h struct Dwarf_Regtable3_s member rt3_cfa_rule
        or function dwarf_get_fde_info_for_cfa_reg3_b()
        or function dwarf_get_fde_info_for_cfa_reg3_c() .

    A set of functions allow these to be changed at
    runtime. The set should be called (if needed)
    immediately after initializing a Dwarf_Debug
    and before any other calls on that Dwarf_Debug.
    If just one value (for example, Table_Size) needs
    altering, then just call that single function.

    For the library accessing frame data to work
    properly there are certain invariants that
    must be true once the set of functions have
    been called.

    REQUIRED:
    @code
    Table_Size      > the number of registers in the ABI.
    Undefined_Value != Same_Value
    CFA_Column      != Undefined_value
    CFA_Column      != Same_value
    Initial_Value   == Same_Value ||
        (Initial_Value == Undefined_value)
    Undefined_Value > Table_Size
    Same_Value      > Table_Size
    CFA_Column      > Table_Size
    @endcode

    @section dwsec_pubnames .debug_pubnames etc DWARF2-DWARF4

    Each section consists of a header for a specific
    compilation unit (CU) followed by an a set of
    tuples, each tuple consisting of an offset of a
    compilation unit followed by a null-terminated
    namestring. The tuple set is ended by a 0,0
    pair. Then followed with the data for the next
    CU and so on.

    The function set provided for each such section
    allows one to print all the section data as it
    literally appears in the section (with headers
    and tuples) or to treat it as a single array
    with CU data columns.

    Each has a set of 6 functions.

    @code
    Section          typename      Standard
    .debug_pubnames  Dwarf_Global  DWARF2-DWARF4
    .debug_pubtypes  Dwarf_Global  DWARF3,DWARF4
    @endcode

    These sections are accessed calling dwarf_globals_by_type()
    using type of  DW_GL_GLOBALS or DW_GL_PUBTYPES.
    Or call dwarf_get_pubtypes().

    The following four were defined in SGI/IRIX
    compilers in the 1990s but were never part of the
    DWARF standard.
    These sections are accessed calling dwarf_globals_by_type()
    using type of DW_GL_FUNCS,DW_GL_TYPES,DW_GL_VARS, or
    DW_GL_WEAKS.

    It not likely you will encounter these four sections.

    @code
    .debug_funcs
    .debug_typenames
    .debug_vars
    .debug_weaks
    @endcode

    @section dwsec_noobj Reading DWARF with no object file present

    This most commonly happens with just-in-time
    compilation, and someone working on the
    code wants do debug this on-the-fly code in a
    situation where nothing can be written to disc,
    but DWARF can be constructed in memory.

    For a simple example of this
    @see jitreader

    But the @e libdwarf feature can be used in a wide variety of ways.

    For example, the DWARF data could be kept in
    simple files of bytes on the internet.  Or on the
    local net. Or if files can be written locally
    each section could be kept in a simple stream
    of bytes in the local file system.

    Another example is a non-standard file system,
    or file format, with the intent of obfuscating
    the file or the DWARF.

    For this to work the code generator must generate
    standard DWARF.

    Overall the idea is a simple one: You write a
    small handful of functions and supply function
    pointers and code implementing the functions.
    These are part of your application or library,
    not part of @e libdwarf.

    You set up a little bit of data with that
    code (all described below) and then you
    have essentially written the dwarf_init_path
    equivalent and you can access compilation units,
    line tables etc and the standard @e libdwarf
    function calls work.

    Data you need to create involves these types.
    What follows describes how to fill them in and
    how to make them work for you.

    @code
    typedef struct Dwarf_Obj_Access_Interface_a_s
        Dwarf_Obj_Access_Interface_a;
    struct Dwarf_Obj_Access_Interface_a_s {
        void*                             ai_object;
        const Dwarf_Obj_Access_Methods_a *ai_methods;
    };

    typedef struct Dwarf_Obj_Access_Methods_a_s
        Dwarf_Obj_Access_Methods_a
    struct Dwarf_Obj_Access_Methods_a_s {
        int    (*om_get_section_info)(void* obj,
            Dwarf_Unsigned section_index,
            Dwarf_Obj_Access_Section_a* return_section,
            int* error);
        Dwarf_Small      (*om_get_byte_order)(void* obj);
        Dwarf_Small      (*om_get_length_size)(void* obj);
        Dwarf_Small      (*om_get_pointer_size)(void* obj);
        Dwarf_Unsigned   (*om_get_filesize)(void* obj);

        Dwarf_Unsigned   (*om_get_section_count)(void* obj);
        int              (*om_load_section)(void* obj,
            Dwarf_Unsigned section_index,
            Dwarf_Small** return_data, int* error);
        int              (*om_relocate_a_section)(void* obj,
            Dwarf_Unsigned section_index,
            Dwarf_Debug dbg,
            int* error);
    };

    typedef struct Dwarf_Obj_Access_Section_a_s
        Dwarf_Obj_Access_Section_a
    struct Dwarf_Obj_Access_Section_a_s {
        const char*    as_name;
        Dwarf_Unsigned as_type;
        Dwarf_Unsigned as_flags;
        Dwarf_Addr     as_addr;
        Dwarf_Unsigned as_offset;
        Dwarf_Unsigned as_size;
        Dwarf_Unsigned as_link;
        Dwarf_Unsigned as_info;
        Dwarf_Unsigned as_addralign;
        Dwarf_Unsigned as_entrysize;
    };
    @endcode

    @b Dwarf_Obj_Access_Section_a:
    Your implementation of a @b om_get_section_info
    must fill in a few fields for @e libdwarf.
    The fields here are
    standard Elf, but for most you can just use
    the value zero.  We assume here you will not be
    doing relocations at runtime.

    @b as_name: Here you set a section name via
    the pointer.  The section names must be names
    as defined in the DWARF standard, so if such do
    not appear in your data you have to create the
    strings yourself.

    @b as_type: Fill in zero.

    @b as_flags: Fill in zero.

    @b as_addr: Fill in the address, in local memory,
    where the bytes of the section are.

    @b as_offset: Fill in zero.

    @b as_size: Fill in the size, in bytes,
    of the section you are telling @e libdwarf about.

    @b as_link: Fill in zero.

    @b as_info: Fill in zero.

    @b as_addralign: Fill in zero.

    @b as_entrysize: Fill in one(1).

    @b Dwarf_Obj_Access_Methods_a_s:
    The functions we need to access object data
    from @e 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 is not
    required that one handles multiple such in a
    single @e libdwarf archive/shared-library
    (but not ruled out either).  See
    dwarf_elf_object_access_internals_t and
    dwarf_elf_access.c for an example.

    Usually the struct @b Dwarf_Obj_Access_Methods_a_s is
    statically defined
    and the function pointers are set at
    compile time.

    The om_get_filesize member is new September 4, 2021.
    Its position is NOT at the end of the list.
    The member names all now have om_ prefix.

    @section dwsec_sectiongroup Section Groups: Split Dwarf, COMDAT groups

    A typical executable or shared object is unlikely
    to have any section groups, and in that case
    what follows is irrelevant and unimportant.

    @b COMDAT groups are defined by the Elf ABI and 
    enable compilers and linkers
    to work together to eliminate blocks
    of duplicate DWARF and duplicate CODE.

    @b Split @b Dwarf (sometimes referred to as
    Debug Fission) allows compilers and linkers
    to separate large amounts of DWARF from
    the executable, shrinking disk space
    needed in the executable while allowing
    full debugging (also applies to shared objects).

    See the DWARF5 Standard, Section E.1
    Using Compilation Units    page 364.

    To name COMDAT groups (defined later here) we add
    the following defines to libdwarf.h (the 
    DWARF standard does not specify how to do any of this).

    @code
    /*  These support opening DWARF5 split dwarf objects and
        Elf SHT_GROUP blocks of DWARF sections. */
    #define DW_GROUPNUMBER_ANY  0
    #define DW_GROUPNUMBER_BASE 1
    #define DW_GROUPNUMBER_DWO  2
    @endcode

    The DW_GROUPNUMBER_  are used in @e libdwarf functions
    dwarf_init_path(), dwarf_init_path_dl() and
    dwarf_init_b().  In all those cases unless
    you know there is any complexity in your object file,
    pass in DW_GROUPNUMBER_ANY.

    To see section groups usage, see the example
    source:
    @see showsecgroups

    @see examplesecgroup

    The function interface declarations:

    @see dwarf_sec_group_sizes
    @see dwarf_sec_group_map

    If an object file has multiple groups
    @e libdwarf will not reveal contents of more
    than the single requested group with a given
    dwarf_init_path() call.
    One must pass in another groupnumber
    to another dwarf_init_path(), meaning initialize
    a new Dwarf_Debug,  to get @e libdwarf to
    access that group.

    When opening a Dwarf_Debug the following applies:

    If DW_GROUPNUMBER_ANY is passed in @e libdwarf will
    choose either of DW_GROUPNUMBER_BASE(1) or
    DW_GROUPNUMBER_DWO (2) depending on the object
    content. If both groups one and two are in the
    object @e libdwarf will chose DW_GROUPNUMBER_BASE.

    If DW_GROUPNUMBER_BASE is passed in @e libdwarf
    will choose it if non-split DWARF is in the object, else
    the init call will return DW_DLV_NO_ENTRY.

    If DW_GROUPNUMBER_DWO is passed in @e libdwarf
    will choose it if .dwo sections are in the object, else
    the init will call return DW_DLV_NO_ENTRY.

    If a groupnumber greater than two is passed in
    @e libdwarf accepts it, whether any sections
    corresponding to that groupnumber exist or not.
    If the groupnumber is not an actual group
    the init will call return DW_DLV_NO_ENTRY.

    For information on groups  "dwarfdump -i"
    on an object file will show all section group
    information @b unless the object file is a simple
    standard object with no .dwo sections and no
    COMDAT groups (in which case the output will be
    silent on groups). Look for <b> Section Groups
    data </b> in the dwarfdump output.  The groups
    information will be appearing very early in the
    dwarfdump output.

    Sections that are part of an Elf COMDAT GROUP are
    assigned a group number > 2.  There can be many
    such COMDAT groups in an object file (but none
    in an executable or shared object).  Each such
    COMDAT group will have a small set of sections
    in it and each section in such a group will be
    assigned the same group number by @e libdwarf.

    Sections that are in a .dwp .dwo object file
    are assigned to DW_GROUPNUMBER_DWO,

    Sections not part of a .dwp package file or
    a.dwo section, or a COMDAT group are assigned
    DW_GROUPNUMBER_BASE.

    At least one compiler relies on relocations to
    identify COMDAT groups, but the compiler authors
    do not publicly document how this works so we
    ignore such (these COMDAT groups will result in
    @e libdwarf returning DW_DLV_ERROR).

    Popular compilers and tools are using such
    sections. There is no detailed documentation that
    we can find (so far) on how the COMDAT section
    groups are used, so @e libdwarf is based on
    observations of what compilers generate.

    @section dwsec_separatedebug  Details on separate DWARF object access

    There are, at present, three distinct approaches
    in use to put DWARF information into separate
    objects to significantly shrink the size of
    the executable. All of them involve identifying
    a separate file.

    Split Dwarf is one method. It defines the attribute
    @b DW_AT_dwo_name (if present) as having 
    a file-system appropriate
    name of the split object with most of the DWARF.

    The second is Macos dSYM.  It is a convention of placing
    the DWARF-containing object (separate from the
    object containing code) in a specific subdirectory
    tree. 

    The third involves GNU debuglink and GNU
    debug_id. These are two distinct ways (outside
    of DWARF) to provide
    names of alternative DWARF-containing objects
    elsewhere in a file system.

    If one initializes a Dwarf_Debug object with
    dwarf_init_path()  or dwarf_init_path_dl()
    appropriately @e libdwarf will automatically
    open the alternate dSYM or
    debuglink/debug_id object on the object with
    most of the DWARF.

    @see https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html

    @e libdwarf provides means to automatically read
    the alternate object (in place of the one named
    in the init call) or to suppress that and read
    the named object file.

    @code
    int dwarf_init_path(const char * dw_path,
    char *            dw_true_path_out_buffer,
    unsigned int      dw_true_path_bufferlen,
    unsigned int      dw_groupnumber,
    Dwarf_Handler     dw_errhand,
    Dwarf_Ptr         dw_errarg,
    Dwarf_Debug*      dw_dbg,
    Dwarf_Error*      dw_error);

    int dwarf_init_path_dl(const char *dw_path,
    char            * true_path_out_buffer,
    unsigned        true_path_bufferlen,
    unsigned        groupnumber,
    Dwarf_Handler   errhand,
    Dwarf_Ptr       errarg,
    Dwarf_Debug     * ret_dbg,
    char            ** dl_path_array,
    unsigned int    dl_path_count,
    unsigned char   * path_source,
    Dwarf_Error     * error);
    @endcode

    Case 1:

    If @e dw_true_path_out_buffer or
    @e dw_true_path_bufferlen is passed in as zero
    then the library will not look for an alternative
    object.

    Case 2:

    If @e dw_true_path_out_buffer passes a pointer to
    space you provide and @e dw_true_path_bufferlen passes in
    the length, in bytes, of the  buffer, @e libdwarf will
    look for alternate DWARF-containing objects.
    We advise that the caller zero all the
    bytes in @e dw_true_path_out_buffer before calling.

    If the alternate object name (with its
    null-terminator) is too long to fit
    in the buffer the call will return DW_DLV_ERROR
    with dw_error providing error code
    DW_DLE_PATH_SIZE_TOO_SMALL.

    If the alternate object name fits in the buffer
    @e libdwarf will open and use that alternate file
    in the returned Dwarf_Dbg.

    It is up to callers to notice that
    @e dw_true_path_out_buffer now contains a string
    and callers will probably wish to do something
    with the string.

    If the initial byte of @e dw_true_path_out_buffer
    is a non-null when the call returns
    then an alternative object was found and opened.

    The second function, dwarf_init_path_dl(),
    is the same as dwarf_init_path() except
    the _dl version has three additional arguments,
    as follows:

    Pass in NULL or @e dw_dl_path_array, an array of pointers
    to strings with alternate GNU debuglink paths you
    want searched. For most people, passing in NULL
    suffices.

    Pass in @e dw_dl_path_array_size, the number of elements
    in @e dw_dl_path_array.

    Pass in @e dw_dl_path_source as NULL or a pointer to char.
    If non-null @e libdwarf will set it to one of three values:

    - DW_PATHSOURCE_basic which means the original input
      @e dw_path is the one opened in dw_dbg.
    - DW_PATHSOURCE_dsym which means a Macos dSYM object
      was found and is the one opened in dw_dbg.
      @e dw_true_path_out_buffer contains the dSYM
      object path.
    - DW_PATHSOURCE_debuglink which means a GNU debuglink
      or GNU debug-id
      path was found and names the one opened in dw_dbg.
      @e dw_true_path_out_buffer contains the
      object path.

    @section dwsec_shared Linking against libdwarf.so (or dll or dylib)

    If you wish to do the basic @e libdwarf tests and are linking
    against a shared library @e libdwarf you must do an install
    for the tests to succeed (in some environments it is
    not strictly necessary).

    For example, if building with configure, do
    @code
    make
    make install
    make check
    @endcode

    You can install anywhere, there is no need to install
    in a system directory! Creating a temporary directory
    and installing there suffices. If installed
    in appropriate system directories that works too.

    When compiling to link against a shared library @e libdwarf
    you <b>must not define LIBDWARF_STATIC</b>.

    For examples of this for all three build systems
    read the project shell script
    @code
    scripts/allsimplebuilds.sh
    @endcode

    @section dwsec_static Linking against libdwarf.a

    - If you are building an application
    - And are linking your application against a
      static library libdwarf.a
    - Then you must ensure that each source file
      compilation with an include
      of libdwarf.h has the macro <b>LIBDWARF_STATIC</b> defined
      to your source compilation.
    - If @e libdwarf was built with zlib and zstd decompression library
      enabled you must add -lz -lzstd to the link line of the build
      of your application.

    To pass <b>LIBDWARF_STATIC</b> to the preprocessor with Visual
    Studio:

    - Right click on a project name
    - In the contextual menu, click on <b>Properties</b> at the very bottom.
    - In the new window, double click on <b>C/C++</b>
    - On the right, click on <b>Preprocessor definitions</b>
    - There is a small down arrow on the right, click on it then click on <b>Modify</b>
    - Add <b>LIBDWARF_STATIC</b> to the values
    - Click on <b>OK</b> to close the windows

    @section dwsec_dbglink Suppressing CRC calculation for debuglink

    GNU Debuglink-specific issue:

    If GNU debuglink is present and considered by
    dwarf_init_path() or dwarf_init_path_dl()
    the library may be required to compute a 32bit
    crc (Cyclic Redundancy Check) on the file
    found via GNU debuglink.

    @see https://en.wikipedia.org/wiki/Cyclic_redundancy_check

    For people doing repeated builds of objects using
    such the crc check is a waste of time as they
    know the crc comparison will pass.

    For such situations a special interface function
    lets the
    dwarf_init_path() or dwarf_init_path_dl()
    caller suppress the crc check without having
    any effect on anything else in @e libdwarf.

    It might be used as follows (the same pattern
    applies to dwarf_init_path_dl() ) for any program
    that might do multiple
    dwarf_init_path() or dwarf_init_path_dl()
    calls in a single program execution.

    @code
    int res      = 0;
    int crc_check= 0;

    crc_check = dwarf_suppress_debuglink_crc(1);
    res = dwarf_init_path(..usual arguments);
    /*  Reset the crc flag to previous value. */
    dwarf_suppress_debuglink_crc(crc_check);
    /*  Now check res in the usual way. */
    @endcode

    This pattern ensures the crc check is suppressed for this
    single dwarf_init_path() or dwarf_init_path_dl()
    call while leaving the setting unchanged for further
    dwarf_init_path() or dwarf_init_path_dl()
    calls in the running program.

    @section dwsec_changes Recent Changes

    We list these with newest first.

    <b>Changes 0.10.1 to 0.11.0</b>

    Added function dwarf_get_ranges_baseaddress()
    to the api to allow dwarfdump and other library callers
    to easily derive the (cooked) address from 
    the raw data in the DWARF2, DWARF3, DWARF4 .debug_ranges
    section.
    An example of use is in doc/checkexamples.c (see examplev).

    <b>Changes 0.9.2 to 0.10.1</b>

    Released 01 July 2024
    (Release 0.10.0 was missing a CMakeLists.txt file
    and is withdrawn).

    Added API function
    dwarf_get_locdesc_entry_e() to allow dwarfdump
    to report some data from .debug_loclists more
    completely -- it reports a byte length of each
    loclist item. This is of little interest to anyone,
    surely.  dwarf_get_locdesc_entry_d() is still
    what you should be using.

    dwarf_debug_addr_table() now supports reading
    the DWARF4 GNU extension .debug_addr table.

    A heuristic sanity check for PE object files was too conservative
    in limiting VirtualSize to 200MB.  A library user has
    an exe with .debug_info size of over 200MB.
    Increased the limit to be 2000MB and changed the names of the
    errors for the three heuristic checks to include _HEURISTIC_ so it is
    easier to know the kind of error/failure it is.

    When doing a shared-library build with cmake we were not emitting
    the correct .so version names nor setting SONAME with the
    correct version name. This long-standing mistake is now fixed.

    <b>Changes 0.9.1 to 0.9.2</b>

    Version 0.9.2 released 2 April 2024

    Vulnerabilities DW202402-001, DW202402-002,DW202402-003,
    and DW202403-001 could crash @e libdwarf given
    a carefully corrupted (fuzzed) DWARF object file.
    Now the library returns an error 
    for these corruptions.
    DW_CFA_high_user (in dwarf.h) was a misspelling.
    Added the correct spelling DW_CFA_hi_user and
    a comment on the incorrect spelling.

    <b>Changes 0.9.0 to 0.9.1</b>

    Version 0.9.1 released 27 January 2024

    The abbreviation code type returned by
    dwarf_die_abbrev_code() changed from <b>int</b>
    to <b>Dwarf_Unsigned</b> as abbrev codes are
    not constrained by the DWARF Standard.

    The section count returned by dwarf_get_section_count()
    is now of type <b>Dwarf_Unsigned</b>. The previous type
    of <b>int</b> never made sense in @e libdwarf.
    Callers will, in practice, see the same value as before.

    All type-warnings issued by MSVC have been fixed.

    Problems reading Macho (Apple) relocatable
    object files have been fixed.

    Each of the build systems available now has an option
    which eliminates @e libdwarf references to the
    object section decompression libraries.
    See the respective READMEs.

    <b>Changes 0.8.0 to 0.9.0</b>

    Version 0.9.0 released 8 December 2023

    Adding functions (rarely needed) for callers
    with special requirements.
    Added dwarf_get_section_info_by_name_a() and
    dwarf_get_section_info_by_index_a() which add
    dw_section_flags pointer argument to return
    the object section file flags (whose meaning
    depends entirely on the object file format),
    and dw_section_offset pointer argument to return
    the object-relevant offset of the section
    (here too the meaning depends on the object format).
    Also added  dwarf_machine_architecture() which returns
    a few top level data items about the object
    @e libdwarf has opened, including the 'machine' and 'flags'
    from object headers (all supported object types).

    This adds new library functions
    dwarf_next_cu_header_e()
    and dwarf_siblingof_c().
    Used exactly as documented dwarf_next_cu_header_d()
    and  dwarf_siblingof_b() work fine and continue to
    be supported for the forseeable future. However
    it would be easy to misuse as the requirement that
    dwarf_siblingof_b() be called immediately after
    a successful call to dwarf_next_cu_header_d()
    was never stated and that dependency was impossible
    to enforce. The dependency was an API mistake
    made in 1992.

    So dwarf_next_cu_header_e() now returns the
    compilation-unit DIE as well as header
    data and dwarf_siblingof_c() is not needed
    except to traverse sibling DIEs.
    (the compilation-unit DIE by definition has no siblings).

    Changes were required to support Mach-O (Apple)
    universal binaries,
    which were not readable by earlier versions of the library.

    We have new library functions
    dwarf_init_path_a(),
    dwarf_init_path_dl_a(), and
    dwarf_get_universalbinary_count().

    The first two allow a caller to specify which
    (numbering from zero) object file to
    report on by adding a new argument dw_universalnumber.
    Passing zero as the dw_universalnumber argument
    is always safe.

    The third lets callers retrieve the number
    being used.

    These new calls do not replace anything so existing
    code will work fine.

    Applying the previously
    existing calls dwarf_init_path() dwarf_init_path_dl()
    to a Mach-O universal binary works, but the library
    will return data on the first (index zero)
    as a default since there is no dw_universalnumber
    argument possible.

    For improved performance in reading Fde data
    when iterating though all usable pc values
    we add dwarf_get_fde_info_for_all_regs3_b(), which
    returns the next pc value with actual frame data.
    We retain dwarf_get_fde_info_for_all_regs3() so
    existing code need not change.

    <b>Changes 0.7.0 to 0.8.0</b>

    v0.8.0 released 2023-09-20

    New functions dwarf_get_fde_info_for_reg3_c(),
    dwarf_get_fde_info_for_cfa_reg3_c() are defined.
    The advantage of the new versions is they correctly
    type the dw_offset argument return value
    as Dwarf_Signed instead of the earlier and incorrect type
    Dwarf_Unsigned.

    The original functions dwarf_get_fde_info_for_reg3_b() and
    dwarf_get_fde_info_for_cfa_reg3_b()
    continue to exist and work for compatibility with
    the previous release.

    For all open() calls for which the O_CLOEXEC flag exists
    we now add that flag to the open() call.

    Vulnerabilities involving reading
    corrupt object files (created by fuzzing)
    have been fixed:
    DW202308-001 (ossfuzz 59576),
    DW202307-001 (ossfuzz 60506),
    DW202306-011 (ossfuzz 59950),
    DW202306-009 (ossfuzz 59755),
    DW202306-006 (ossfuzz 59727),
    DW202306-005 (ossfuzz 59717),
    DW202306-004 (ossfuzz 59695),
    DW202306-002 (ossfuzz 59519),
    DW202306-001 (ossfuzz 59597).
    DW202305-010 (ossfuzz 59478).
    DW202305-009 (ossfuzz 56451).
    DW202305-008 (ossfuzz 56451),
    DW202305-007 (ossfuzz 56474),
    DW202305-006 (ossfuzz 56472),
    DW202305-005 (ossfuzz 56462),
    DW202305-004 (ossfuzz 56446).

    <b>Changes 0.6.0 to 0.7.0</b>

    v0.7.0 released 2023-05-20

    Elf section counts can exceed 16 bits
    (on linux see <b>man 5 elf</b>)
    so some function prototype members
    of struct <b>Dwarf_Obj_Access_Methods_a_s</b>
    changed.
    Specifically, om_get_section_info()
    om_load_section(), and
    om_relocate_a_section()
    now pass section indexes as Dwarf_Unsigned
    instead of Dwarf_Half.
    Without this change executables/objects
    with more than 64K sections cannot
    be read by @e libdwarf.  This is unlikely
    to affect your code since for most users
    @e libdwarf takes care of this and dwarfdump
    is aware of this change.

    Two functions have been removed from libdwarf.h
    and the library: dwarf_dnames_abbrev_by_code()
    and dwarf_dnames_abbrev_form_by_index().

    dwarf_dnames_abbrev_by_code() is slow and pointless.
    Use either dwarf_dnames_name() or
    dwarf_dnames_abbrevtable() instead, depending
    on what you want to accomplish.

    dwarf_dnames_abbrev_form_by_index() is not needed,
    was difficult to call due to argument list
    requirements, and never worked.

    <b>Changes 0.5.0 to 0.6.0</b>

    v0.6.0 released 2023-02-20
    The dealloc required by dwarf_offset_list()
    was wrong. The call could crash @e libdwarf
    on systems with 32bit pointers.
    The new and proper dealloc (for all
    pointer sizes) is
    dwarf_dealloc(dbg,offsetlistptr,DW_DLA_UARRAY);

    A memory leak from dwarf_load_loclists()
    and dwarf_load_rnglists() is fixed and the
    libdwarf-regressiontests error that hid the leak
    has also been fixed.

    A <b>compatibility</b> change affects callers of
    dwarf_dietype_offset(), which on success returns
    the offset of the target of the DW_AT_type attribute
    (if such exists in the Dwarf_Die).  Added a pointer
    argument so the function can (when
    appropriate) return a FALSE argument
    indicating the offset refers to DWARF4 .debug_types
    section, rather than TRUE value when .debug_info
    is the section the offset refers to.
    If anyone was using this function it would fail
    badly (while pretending success)
    with a DWARF4 DW_FORM_ref_sig8 on a DW_AT_type
    attribute from the Dwarf_Die argument.  One will likely
    encounter DWARF4 content so a single correct function
    seemed necessary. New regression tests will ensure
    this will continue to work.

    A <b>compatibility</b> change affects callers of
    dwarf_get_pubtypes().  If an application reads
    .debug_pubtypes there is a <b>compatibility
    break</b>. Such applications must be recompiled
    with latest @e libdwarf, change Dwarf_Type
    declarations to use Dwarf_Global, and can only
    use the latest @e libdwarf.  We are correcting a
    1993 library design mistake that created extra
    work and documentation for library users and
    inflated the @e libdwarf API and documentation for
    no good reason.

    The changes are: the data type Dwarf_Type
    disappears as do dwarf_pubtypename()
    dwarf_pubtype_die_offset(),
    dwarf_pubtype_cu_offset(),
    dwarf_pubtype_name_offsets() and
    dwarf_pubtypes_dealloc(). Instead the type is
    Dwarf_Global, the type and functions used for
    dwarf_get_globals().  The existing read/dealloc
    functions for Dwarf_Global apply to pubtypes
    data too.

    No one should be referring to the 1990s SGI/IRIX
    sections .debug_weaknames, .debug_funcnames,
    .debug_varnames, or .debug_typenames as they
    are not emitted by any compiler except from
    SGI/IRIX/MIPS in that period.  There is (revised)
    support in @e libdwarf to read these sections,
    but we will not mention details here.

    Any use of DW_FORM_strx3 or DW_FORM_addrx3 in
    DWARF would, in 0.5.0 and earlier, result in
    @e libdwarf reporting erroneous data.  A copy-paste
    error in libdwarf/dwarf_util.c was noticed
    and fixed 24 January 2023 for 0.6.0.
    Bug <b>DW202301-001</b>.

    <b>Changes 0.4.2 to 0.5.0</b>

    v0.5.0 released 2022-11-22
    The handling of the .debug_abbrev data in
    @e libdwarf is now more cpu-efficient (measurably
    faster) so access to DIEs and attribute lists
    is faster.  The changes are library-internal so
    are not visible in the API.

    Corrects CU and TU indexes in the .debug_names
    (fast access) section to be zero-based.  The code
    for that section was previously unusable as it
    did not follow the DWARF5 documentation.

    dwarf_get_globals() now returns a list of
    Dwarf_Global names and DIE offsets whether
    such are defined in the .debug_names  or
    .debug_pubnames section or both.  Previously it
    only read .debug_pubnames.

    A new function, dwarf_global_tag_number(),
    returns the DW_TAG of any Dwarf_Global that was
    derived from the .debug_names section.

    Three new functions enable printing of the
    .debug_addr table.  dwarf_debug_addr_table(),
    dwarf_debug_addr_by_index(), and
    dwarf_dealloc_debug_addr_table(). Actual use of
    the table(s) in .debug_addr is handled for you
    when an attribute invoking such is encountered
    (see DW_FORM_addrx, DW_FORM_addrx1 etc).

    Added doc/libdwarf.dox to the distribution
    (left out by accident earlier).

    <b>Changes 0.4.1 to 0.4.2</b>

    0.4.2 released 2022-09-13.
    No API changes. No API additions.  Corrected
    a bug in dwarf_tsearchhash.c where a delete
    request was accidentally assumed in all hash tree
    searches.  It was invisible to @e libdwarf uses.
    Vulnerabilities DW202207-001 and DW202208-001
    were fixed so error conditions when reading
    fuzzed object files can no longer crash @e libdwarf
    (the crash was possible but not certain before
    the fixes).  In this release we believe neither
    @e libdwarf nor dwarfdump leak memory even when
    there are malloc failures.  Any GNU debuglink or
    build-id section contents were not being properly
    freed (if malloced, meaning a compressed section)
    until 9 September 2022.

    It is now possible to run the build
    sanity tests in all three build mechanisms
    (configure,cmake,meson) on linux, MacOS, FreeBSD,
    and mingw msys2 (windows).  @e libdwarf README.md
    (or README) and README.cmake document how to
    do builds for each supported platform and build
    mechanism.

    <b>Changes 0.4.0 to 0.4.1</b>

    Reading a carefully corrupted DIE with form DW_FORM_ref_sig8
    could result in reading memory outside any section, possibly
    leading to a segmentation violation or other crash. Fixed.
    @see https://www.prevanders.net/dwarfbug.xml  DW202206-001

    Reading a carefully corrupted .debug_pubnames/.debug_pubtypes
    could lead to reading memory outside the section being
    read, possibly leading to a segmentation violation or
    other crash. Fixed.
    @see https://www.prevanders.net/dwarfbug.xml  DW202205-001

    @e libdwarf accepts DW_AT_entry_pc in a compilation unit
    DIE as a base address for location lists (though it will
    prefer DW_AT_low_pc if present, per DWARF3).  A particular
    compiler emits DW_AT_entry_pc in a DWARF2 object,
    requiring this change.

    @e libdwarf adds dwarf_suppress_debuglink_crc() so that
    library callers can suppress crc calculations.
    (useful to save the time of crc when building and testing
    the same thing(s) over and over; it just loses a little
    checking.) Additionally, @e libdwarf now properly handles
    objects with only GNU debug-id or only GNU debuglink.

    dwarfdump adds \--show-args, an option to print its
    arguments and version.
    Without that new option the version and arguments are not
    shown. The output of \-v (\--version) is a little more complete.

    dwarfdump adds \--suppress-debuglink-crc, an option to avoid
    crc calculations when rebuilding and rerunning tests
    depending on GNU .note.gnu.buildid or .gnu_debuglink
    sections. The help text and the dwarfdump.1 man page
    are more specific documenting \--suppress-debuglink-crc
    and \--no-follow-debuglink

    <b>Changes 0.3.4 to 0.4.0</b>

    Removed the unused Dwarf_Error argument from
    dwarf_return_empty_pubnames() as the function can only
    return DW_DLV_OK.
    dwarf_xu_header_free() renamed to dwarf_dealloc_xu_header().
    dwarf_gdbindex_free() renamed to dwarf_dealloc_gdbindex().
    dwarf_loc_head_c_dealloc renamed to dwarf_dealloc_loc_head_c().

    dwarf_get_location_op_value_d() renamed to
    dwarf_get_location_op_value_c(), and 3 pointless
    arguments removed. The dwarf_get_location_op_value_d
    version and the three arguments were added for DWARF5
    in libdwarf-20210528 but the change was a mistake.
    Now reverted to the previous version.

    The .debug_names section interfaces have changed.
    Added dwarf_dnames_offsets() to provide details
    of facts useful in problems reading the section.
    dwarf_dnames_name() now does work and the interface
    was changed to make it easier to use.

    <b>Changes 0.3.3 to 0.3.4</b>

    Replaced the groff -mm based libdwarf.pdf
    with a libdwarf.pdf
    generated by doxygen and latex.

    Added support for the meson build system.

    Updated an include in libdwarfp source files.
    Improved doxygen documentation of @e libdwarf.
    Now 'make check -j8' and the like works correctly.
    Fixed a bug where reading a PE (Windows)
    object could fail for certain section
    virtual size values.
    Added initializers to two uninitialized
    local variables in dwarfdump source so a compiler
    warning cannot not kill a --enable-wall build.

    Added src/bin/dwarfexample/showsectiongroups.c so
    it is easy to see what groups are present in an
    object without all the other dwarfdump output.

    <b>Changes 20210528 to 0.3.3 (28 January 2022) </b>

    There were major revisions in going from date versioning
    to Semantic Versioning.  Many functions were deleted and
    various functions changed their list of arguments.
    Many many filenames changed.  Include lists were
    simplified. Far too much changed to list here.
*/