The FreeRADIUS server $Id: f3670dba8951ca10eb4948feb3dc3db9423a334f $
Loading...
Searching...
No Matches
dwarf.c
Go to the documentation of this file.
1/* dwarf.c -- Get file/line information from DWARF for backtraces.
2 Copyright (C) 2012-2024 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Google.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are
7met:
8
9 (1) Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 (2) Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the
15 distribution.
16
17 (3) The name of the author may not be used to
18 endorse or promote products derived from this software without
19 specific prior written permission.
20
21THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31POSSIBILITY OF SUCH DAMAGE. */
32
33#include "config.h"
34
35#include <errno.h>
36#include <stdlib.h>
37#include <string.h>
38#include <sys/types.h>
39
40#include "filenames.h"
41
42#include "backtrace.h"
43#include "internal.h"
44
45/* DWARF constants. */
46
54
104
322 DW_AT_APPLE_property = 0x3fed
324
340
347
357
368
379
380#if !defined(HAVE_DECL_STRNLEN) || !HAVE_DECL_STRNLEN
381
382/* If strnlen is not declared, provide our own version. */
383
384static size_t
385xstrnlen (const char *s, size_t maxlen)
386{
387 size_t i;
388
389 for (i = 0; i < maxlen; ++i)
390 if (s[i] == '\0')
391 break;
392 return i;
393}
394
395#define strnlen xstrnlen
396
397#endif
398
399/* A buffer to read DWARF info. */
400
402{
403 /* Buffer name for error messages. */
404 const char *name;
405 /* Start of the buffer. */
406 const unsigned char *start;
407 /* Next byte to read. */
408 const unsigned char *buf;
409 /* The number of bytes remaining. */
410 size_t left;
411 /* Whether the data is big-endian. */
413 /* Error callback routine. */
415 /* Data for error_callback. */
416 void *data;
417 /* Non-zero if we've reported an underflow error. */
419};
420
421/* A single attribute in a DWARF abbreviation. */
422
423struct attr
424{
425 /* The attribute name. */
427 /* The attribute form. */
429 /* The attribute value, for DW_FORM_implicit_const. */
430 int64_t val;
431};
432
433/* A single DWARF abbreviation. */
434
435struct abbrev
436{
437 /* The abbrev code--the number used to refer to the abbrev. */
438 uint64_t code;
439 /* The entry tag. */
441 /* Non-zero if this abbrev has child entries. */
443 /* The number of attributes. */
444 size_t num_attrs;
445 /* The attributes. */
446 struct attr *attrs;
447};
448
449/* The DWARF abbreviations for a compilation unit. This structure
450 only exists while reading the compilation unit. Most DWARF readers
451 seem to a hash table to map abbrev ID's to abbrev entries.
452 However, we primarily care about GCC, and GCC simply issues ID's in
453 numerical order starting at 1. So we simply keep a sorted vector,
454 and try to just look up the code. */
455
457{
458 /* The number of abbrevs in the vector. */
460 /* The abbrevs, sorted by the code field. */
462};
463
464/* The different kinds of attribute values. */
465
467{
468 /* No attribute value. */
470 /* An address. */
472 /* An index into the .debug_addr section, whose value is relative to
473 the DW_AT_addr_base attribute of the compilation unit. */
475 /* A unsigned integer. */
477 /* A sigd integer. */
479 /* A string. */
481 /* An index into the .debug_str_offsets section. */
483 /* An offset to other data in the containing unit. */
485 /* An offset to other data within the .debug_info section. */
487 /* An offset to other data within the alt .debug_info section. */
489 /* An offset to data in some other section. */
491 /* A type signature. */
493 /* An index into the .debug_rnglists section. */
495 /* A block of data (not represented). */
497 /* An expression (not represented). */
499};
500
501/* An attribute value. */
502
504{
505 /* How the value is stored in the field u. */
507 union
508 {
509 /* ATTR_VAL_ADDRESS*, ATTR_VAL_UINT, ATTR_VAL_REF*. */
510 uint64_t uint;
511 /* ATTR_VAL_SINT. */
512 int64_t sint;
513 /* ATTR_VAL_STRING. */
514 const char *string;
515 /* ATTR_VAL_BLOCK not stored. */
516 } u;
517};
518
519/* The line number program header. */
520
522{
523 /* The version of the line number information. */
525 /* Address size. */
527 /* The minimum instruction length. */
528 unsigned int min_insn_len;
529 /* The maximum number of ops per instruction. */
530 unsigned int max_ops_per_insn;
531 /* The line base for special opcodes. */
533 /* The line range for special opcodes. */
534 unsigned int line_range;
535 /* The opcode base--the first special opcode. */
536 unsigned int opcode_base;
537 /* Opcode lengths, indexed by opcode - 1. */
538 const unsigned char *opcode_lengths;
539 /* The number of directory entries. */
541 /* The directory entries. */
542 const char **dirs;
543 /* The number of filenames. */
545 /* The filenames. */
546 const char **filenames;
547};
548
549/* A format description from a line header. */
550
552{
553 int lnct; /* LNCT code. */
554 enum dwarf_form form; /* Form of entry data. */
555};
556
557/* Map a single PC value to a file/line. We will keep a vector of
558 these sorted by PC value. Each file/line will be correct from the
559 PC up to the PC of the next entry if there is one. We allocate one
560 extra entry at the end so that we can use bsearch. */
561
562struct line
563{
564 /* PC. */
565 uintptr_t pc;
566 /* File name. Many entries in the array are expected to point to
567 the same file name. */
568 const char *filename;
569 /* Line number. */
571 /* Index of the object in the original array read from the DWARF
572 section, before it has been sorted. The index makes it possible
573 to use Quicksort and maintain stability. */
574 int idx;
575};
576
577/* A growable vector of line number information. This is used while
578 reading the line numbers. */
579
581{
582 /* Memory. This is an array of struct line. */
584 /* Number of valid mappings. */
585 size_t count;
586};
587
588/* A function described in the debug info. */
589
591{
592 /* The name of the function. */
593 const char *name;
594 /* If this is an inlined function, the filename of the call
595 site. */
596 const char *caller_filename;
597 /* If this is an inlined function, the line number of the call
598 site. */
600 /* Map PC ranges to inlined functions. */
603};
604
605/* An address range for a function. This maps a PC value to a
606 specific function. */
607
609{
610 /* Range is LOW <= PC < HIGH. */
611 uintptr_t low;
612 uintptr_t high;
613 /* Function for this address range. */
615};
616
617/* A growable vector of function address ranges. */
618
620{
621 /* Memory. This is an array of struct function_addrs. */
623 /* Number of address ranges present. */
624 size_t count;
625};
626
627/* A DWARF compilation unit. This only holds the information we need
628 to map a PC to a file and line. */
629
630struct unit
631{
632 /* The first entry for this compilation unit. */
633 const unsigned char *unit_data;
634 /* The length of the data for this compilation unit. */
636 /* The offset of UNIT_DATA from the start of the information for
637 this compilation unit. */
639 /* Offset of the start of the compilation unit from the start of the
640 .debug_info section. */
642 /* Offset of the end of the compilation unit from the start of the
643 .debug_info section. */
645 /* DWARF version. */
647 /* Whether unit is DWARF64. */
649 /* Address size. */
651 /* Offset into line number information. */
653 /* Offset of compilation unit in .debug_str_offsets. */
655 /* Offset of compilation unit in .debug_addr. */
656 uint64_t addr_base;
657 /* Offset of compilation unit in .debug_rnglists. */
659 /* Primary source file. */
660 const char *filename;
661 /* Compilation command working directory. */
662 const char *comp_dir;
663 /* Absolute file name, only set if needed. */
664 const char *abs_filename;
665 /* The abbreviations for this unit. */
667
668 /* The fields above this point are read in during initialization and
669 may be accessed freely. The fields below this point are read in
670 as needed, and therefore require care, as different threads may
671 try to initialize them simultaneously. */
672
673 /* PC to line number mapping. This is NULL if the values have not
674 been read. This is (struct line *) -1 if there was an error
675 reading the values. */
676 struct line *lines;
677 /* Number of entries in lines. */
679 /* PC ranges to function. */
682};
683
684/* An address range for a compilation unit. This maps a PC value to a
685 specific compilation unit. Note that we invert the representation
686 in DWARF: instead of listing the units and attaching a list of
687 ranges, we list the ranges and have each one point to the unit.
688 This lets us do a binary search to find the unit. */
689
691{
692 /* Range is LOW <= PC < HIGH. */
693 uintptr_t low;
694 uintptr_t high;
695 /* Compilation unit for this address range. */
696 struct unit *u;
697};
698
699/* A growable vector of compilation unit address ranges. */
700
702{
703 /* Memory. This is an array of struct unit_addrs. */
705 /* Number of address ranges present. */
706 size_t count;
707};
708
709/* A growable vector of compilation unit pointer. */
710
712{
714 size_t count;
715};
716
717/* The information we need to map a PC to a file and line. */
718
720{
721 /* The data for the next file we know about. */
723 /* The data for .gnu_debugaltlink. */
725 /* The base address mapping for this file. */
727 /* A sorted list of address ranges. */
729 /* Number of address ranges in list. */
731 /* A sorted list of units. */
732 struct unit **units;
733 /* Number of units in the list. */
735 /* The unparsed DWARF debug data. */
737 /* Whether the data is big-endian or not. */
739 /* A vector used for function addresses. We keep this here so that
740 we can grow the vector as we read more functions. */
742};
743
744/* Report an error for a DWARF buffer. */
745
746static void
747dwarf_buf_error (struct dwarf_buf *buf, const char *msg, int errnum)
748{
749 char b[200];
750
751 snprintf (b, sizeof b, "%s in %s at %d",
752 msg, buf->name, (int) (buf->buf - buf->start));
753 buf->error_callback (buf->data, b, errnum);
754}
755
756/* Require at least COUNT bytes in BUF. Return 1 if all is well, 0 on
757 error. */
758
759static int
760require (struct dwarf_buf *buf, size_t count)
761{
762 if (buf->left >= count)
763 return 1;
764
765 if (!buf->reported_underflow)
766 {
767 dwarf_buf_error (buf, "DWARF underflow", 0);
768 buf->reported_underflow = 1;
769 }
770
771 return 0;
772}
773
774/* Advance COUNT bytes in BUF. Return 1 if all is well, 0 on
775 error. */
776
777static int
778advance (struct dwarf_buf *buf, size_t count)
779{
780 if (!require (buf, count))
781 return 0;
782 buf->buf += count;
783 buf->left -= count;
784 return 1;
785}
786
787/* Read one zero-terminated string from BUF and advance past the string. */
788
789static const char *
791{
792 const char *p = (const char *)buf->buf;
793 size_t len = strnlen (p, buf->left);
794
795 /* - If len == left, we ran out of buffer before finding the zero terminator.
796 Generate an error by advancing len + 1.
797 - If len < left, advance by len + 1 to skip past the zero terminator. */
798 size_t count = len + 1;
799
800 if (!advance (buf, count))
801 return NULL;
802
803 return p;
804}
805
806/* Read one byte from BUF and advance 1 byte. */
807
808static unsigned char
809read_byte (struct dwarf_buf *buf)
810{
811 const unsigned char *p = buf->buf;
812
813 if (!advance (buf, 1))
814 return 0;
815 return p[0];
816}
817
818/* Read a signed char from BUF and advance 1 byte. */
819
820static signed char
822{
823 const unsigned char *p = buf->buf;
824
825 if (!advance (buf, 1))
826 return 0;
827 return (*p ^ 0x80) - 0x80;
828}
829
830/* Read a uint16 from BUF and advance 2 bytes. */
831
832static uint16_t
834{
835 const unsigned char *p = buf->buf;
836
837 if (!advance (buf, 2))
838 return 0;
839 if (buf->is_bigendian)
840 return ((uint16_t) p[0] << 8) | (uint16_t) p[1];
841 else
842 return ((uint16_t) p[1] << 8) | (uint16_t) p[0];
843}
844
845/* Read a 24 bit value from BUF and advance 3 bytes. */
846
847static uint32_t
849{
850 const unsigned char *p = buf->buf;
851
852 if (!advance (buf, 3))
853 return 0;
854 if (buf->is_bigendian)
855 return (((uint32_t) p[0] << 16) | ((uint32_t) p[1] << 8)
856 | (uint32_t) p[2]);
857 else
858 return (((uint32_t) p[2] << 16) | ((uint32_t) p[1] << 8)
859 | (uint32_t) p[0]);
860}
861
862/* Read a uint32 from BUF and advance 4 bytes. */
863
864static uint32_t
866{
867 const unsigned char *p = buf->buf;
868
869 if (!advance (buf, 4))
870 return 0;
871 if (buf->is_bigendian)
872 return (((uint32_t) p[0] << 24) | ((uint32_t) p[1] << 16)
873 | ((uint32_t) p[2] << 8) | (uint32_t) p[3]);
874 else
875 return (((uint32_t) p[3] << 24) | ((uint32_t) p[2] << 16)
876 | ((uint32_t) p[1] << 8) | (uint32_t) p[0]);
877}
878
879/* Read a uint64 from BUF and advance 8 bytes. */
880
881static uint64_t
883{
884 const unsigned char *p = buf->buf;
885
886 if (!advance (buf, 8))
887 return 0;
888 if (buf->is_bigendian)
889 return (((uint64_t) p[0] << 56) | ((uint64_t) p[1] << 48)
890 | ((uint64_t) p[2] << 40) | ((uint64_t) p[3] << 32)
891 | ((uint64_t) p[4] << 24) | ((uint64_t) p[5] << 16)
892 | ((uint64_t) p[6] << 8) | (uint64_t) p[7]);
893 else
894 return (((uint64_t) p[7] << 56) | ((uint64_t) p[6] << 48)
895 | ((uint64_t) p[5] << 40) | ((uint64_t) p[4] << 32)
896 | ((uint64_t) p[3] << 24) | ((uint64_t) p[2] << 16)
897 | ((uint64_t) p[1] << 8) | (uint64_t) p[0]);
898}
899
900/* Read an offset from BUF and advance the appropriate number of
901 bytes. */
902
903static uint64_t
904read_offset (struct dwarf_buf *buf, int is_dwarf64)
905{
906 if (is_dwarf64)
907 return read_uint64 (buf);
908 else
909 return read_uint32 (buf);
910}
911
912/* Read an address from BUF and advance the appropriate number of
913 bytes. */
914
915static uint64_t
916read_address (struct dwarf_buf *buf, int addrsize)
917{
918 switch (addrsize)
919 {
920 case 1:
921 return read_byte (buf);
922 case 2:
923 return read_uint16 (buf);
924 case 4:
925 return read_uint32 (buf);
926 case 8:
927 return read_uint64 (buf);
928 default:
929 dwarf_buf_error (buf, "unrecognized address size", 0);
930 return 0;
931 }
932}
933
934/* Return whether a value is the highest possible address, given the
935 address size. */
936
937static int
938is_highest_address (uint64_t address, int addrsize)
939{
940 switch (addrsize)
941 {
942 case 1:
943 return address == (unsigned char) -1;
944 case 2:
945 return address == (uint16_t) -1;
946 case 4:
947 return address == (uint32_t) -1;
948 case 8:
949 return address == (uint64_t) -1;
950 default:
951 return 0;
952 }
953}
954
955/* Read an unsigned LEB128 number. */
956
957static uint64_t
959{
960 uint64_t ret;
961 unsigned int shift;
962 int overflow;
963 unsigned char b;
964
965 ret = 0;
966 shift = 0;
967 overflow = 0;
968 do
969 {
970 const unsigned char *p;
971
972 p = buf->buf;
973 if (!advance (buf, 1))
974 return 0;
975 b = *p;
976 if (shift < 64)
977 ret |= ((uint64_t) (b & 0x7f)) << shift;
978 else if (!overflow)
979 {
980 dwarf_buf_error (buf, "LEB128 overflows uint64_t", 0);
981 overflow = 1;
982 }
983 shift += 7;
984 }
985 while ((b & 0x80) != 0);
986
987 return ret;
988}
989
990/* Read a signed LEB128 number. */
991
992static int64_t
994{
995 uint64_t val;
996 unsigned int shift;
997 int overflow;
998 unsigned char b;
999
1000 val = 0;
1001 shift = 0;
1002 overflow = 0;
1003 do
1004 {
1005 const unsigned char *p;
1006
1007 p = buf->buf;
1008 if (!advance (buf, 1))
1009 return 0;
1010 b = *p;
1011 if (shift < 64)
1012 val |= ((uint64_t) (b & 0x7f)) << shift;
1013 else if (!overflow)
1014 {
1015 dwarf_buf_error (buf, "signed LEB128 overflows uint64_t", 0);
1016 overflow = 1;
1017 }
1018 shift += 7;
1019 }
1020 while ((b & 0x80) != 0);
1021
1022 if ((b & 0x40) != 0 && shift < 64)
1023 val |= ((uint64_t) -1) << shift;
1024
1025 return (int64_t) val;
1026}
1027
1028/* Return the length of an LEB128 number. */
1029
1030static size_t
1031leb128_len (const unsigned char *p)
1032{
1033 size_t ret;
1034
1035 ret = 1;
1036 while ((*p & 0x80) != 0)
1037 {
1038 ++p;
1039 ++ret;
1040 }
1041 return ret;
1042}
1043
1044/* Read initial_length from BUF and advance the appropriate number of bytes. */
1045
1046static uint64_t
1047read_initial_length (struct dwarf_buf *buf, int *is_dwarf64)
1048{
1049 uint64_t len;
1050
1051 len = read_uint32 (buf);
1052 if (len == 0xffffffff)
1053 {
1054 len = read_uint64 (buf);
1055 *is_dwarf64 = 1;
1056 }
1057 else
1058 *is_dwarf64 = 0;
1059
1060 return len;
1061}
1062
1063/* Free an abbreviations structure. */
1064
1065static void
1068{
1069 size_t i;
1070
1071 for (i = 0; i < abbrevs->num_abbrevs; ++i)
1073 abbrevs->abbrevs[i].num_attrs * sizeof (struct attr),
1076 abbrevs->num_abbrevs * sizeof (struct abbrev),
1078 abbrevs->num_abbrevs = 0;
1079 abbrevs->abbrevs = NULL;
1080}
1081
1082/* Read an attribute value. Returns 1 on success, 0 on failure. If
1083 the value can be represented as a uint64_t, sets *VAL and sets
1084 *IS_VALID to 1. We don't try to store the value of other attribute
1085 forms, because we don't care about them. */
1086
1087static int
1088read_attribute (enum dwarf_form form, uint64_t implicit_val,
1089 struct dwarf_buf *buf, int is_dwarf64, int version,
1090 int addrsize, const struct dwarf_sections *dwarf_sections,
1091 struct dwarf_data *altlink, struct attr_val *val)
1092{
1093 /* Avoid warnings about val.u.FIELD may be used uninitialized if
1094 this function is inlined. The warnings aren't valid but can
1095 occur because the different fields are set and used
1096 conditionally. */
1097 memset (val, 0, sizeof *val);
1098
1099 switch (form)
1100 {
1101 case DW_FORM_addr:
1103 val->u.uint = read_address (buf, addrsize);
1104 return 1;
1105 case DW_FORM_block2:
1106 val->encoding = ATTR_VAL_BLOCK;
1107 return advance (buf, read_uint16 (buf));
1108 case DW_FORM_block4:
1109 val->encoding = ATTR_VAL_BLOCK;
1110 return advance (buf, read_uint32 (buf));
1111 case DW_FORM_data2:
1112 val->encoding = ATTR_VAL_UINT;
1113 val->u.uint = read_uint16 (buf);
1114 return 1;
1115 case DW_FORM_data4:
1116 val->encoding = ATTR_VAL_UINT;
1117 val->u.uint = read_uint32 (buf);
1118 return 1;
1119 case DW_FORM_data8:
1120 val->encoding = ATTR_VAL_UINT;
1121 val->u.uint = read_uint64 (buf);
1122 return 1;
1123 case DW_FORM_data16:
1124 val->encoding = ATTR_VAL_BLOCK;
1125 return advance (buf, 16);
1126 case DW_FORM_string:
1128 val->u.string = read_string (buf);
1129 return val->u.string == NULL ? 0 : 1;
1130 case DW_FORM_block:
1131 val->encoding = ATTR_VAL_BLOCK;
1132 return advance (buf, read_uleb128 (buf));
1133 case DW_FORM_block1:
1134 val->encoding = ATTR_VAL_BLOCK;
1135 return advance (buf, read_byte (buf));
1136 case DW_FORM_data1:
1137 val->encoding = ATTR_VAL_UINT;
1138 val->u.uint = read_byte (buf);
1139 return 1;
1140 case DW_FORM_flag:
1141 val->encoding = ATTR_VAL_UINT;
1142 val->u.uint = read_byte (buf);
1143 return 1;
1144 case DW_FORM_sdata:
1145 val->encoding = ATTR_VAL_SINT;
1146 val->u.sint = read_sleb128 (buf);
1147 return 1;
1148 case DW_FORM_strp:
1149 {
1150 uint64_t offset;
1151
1152 offset = read_offset (buf, is_dwarf64);
1153 if (offset >= dwarf_sections->size[DEBUG_STR])
1154 {
1155 dwarf_buf_error (buf, "DW_FORM_strp out of range", 0);
1156 return 0;
1157 }
1159 val->u.string =
1160 (const char *) dwarf_sections->data[DEBUG_STR] + offset;
1161 return 1;
1162 }
1163 case DW_FORM_line_strp:
1164 {
1165 uint64_t offset;
1166
1167 offset = read_offset (buf, is_dwarf64);
1168 if (offset >= dwarf_sections->size[DEBUG_LINE_STR])
1169 {
1170 dwarf_buf_error (buf, "DW_FORM_line_strp out of range", 0);
1171 return 0;
1172 }
1174 val->u.string =
1175 (const char *) dwarf_sections->data[DEBUG_LINE_STR] + offset;
1176 return 1;
1177 }
1178 case DW_FORM_udata:
1179 val->encoding = ATTR_VAL_UINT;
1180 val->u.uint = read_uleb128 (buf);
1181 return 1;
1182 case DW_FORM_ref_addr:
1184 if (version == 2)
1185 val->u.uint = read_address (buf, addrsize);
1186 else
1187 val->u.uint = read_offset (buf, is_dwarf64);
1188 return 1;
1189 case DW_FORM_ref1:
1191 val->u.uint = read_byte (buf);
1192 return 1;
1193 case DW_FORM_ref2:
1195 val->u.uint = read_uint16 (buf);
1196 return 1;
1197 case DW_FORM_ref4:
1199 val->u.uint = read_uint32 (buf);
1200 return 1;
1201 case DW_FORM_ref8:
1203 val->u.uint = read_uint64 (buf);
1204 return 1;
1205 case DW_FORM_ref_udata:
1207 val->u.uint = read_uleb128 (buf);
1208 return 1;
1209 case DW_FORM_indirect:
1210 {
1211 uint64_t form;
1212
1213 form = read_uleb128 (buf);
1214 if (form == DW_FORM_implicit_const)
1215 {
1216 dwarf_buf_error (buf,
1217 "DW_FORM_indirect to DW_FORM_implicit_const",
1218 0);
1219 return 0;
1220 }
1221 return read_attribute ((enum dwarf_form) form, 0, buf, is_dwarf64,
1222 version, addrsize, dwarf_sections, altlink,
1223 val);
1224 }
1225 case DW_FORM_sec_offset:
1227 val->u.uint = read_offset (buf, is_dwarf64);
1228 return 1;
1229 case DW_FORM_exprloc:
1230 val->encoding = ATTR_VAL_EXPR;
1231 return advance (buf, read_uleb128 (buf));
1233 val->encoding = ATTR_VAL_UINT;
1234 val->u.uint = 1;
1235 return 1;
1236 case DW_FORM_ref_sig8:
1238 val->u.uint = read_uint64 (buf);
1239 return 1;
1240 case DW_FORM_strx: case DW_FORM_strx1: case DW_FORM_strx2:
1241 case DW_FORM_strx3: case DW_FORM_strx4:
1242 {
1243 uint64_t offset;
1244
1245 switch (form)
1246 {
1247 case DW_FORM_strx:
1248 offset = read_uleb128 (buf);
1249 break;
1250 case DW_FORM_strx1:
1251 offset = read_byte (buf);
1252 break;
1253 case DW_FORM_strx2:
1254 offset = read_uint16 (buf);
1255 break;
1256 case DW_FORM_strx3:
1257 offset = read_uint24 (buf);
1258 break;
1259 case DW_FORM_strx4:
1260 offset = read_uint32 (buf);
1261 break;
1262 default:
1263 /* This case can't happen. */
1264 return 0;
1265 }
1267 val->u.uint = offset;
1268 return 1;
1269 }
1271 case DW_FORM_addrx3: case DW_FORM_addrx4:
1272 {
1273 uint64_t offset;
1274
1275 switch (form)
1276 {
1277 case DW_FORM_addrx:
1278 offset = read_uleb128 (buf);
1279 break;
1280 case DW_FORM_addrx1:
1281 offset = read_byte (buf);
1282 break;
1283 case DW_FORM_addrx2:
1284 offset = read_uint16 (buf);
1285 break;
1286 case DW_FORM_addrx3:
1287 offset = read_uint24 (buf);
1288 break;
1289 case DW_FORM_addrx4:
1290 offset = read_uint32 (buf);
1291 break;
1292 default:
1293 /* This case can't happen. */
1294 return 0;
1295 }
1297 val->u.uint = offset;
1298 return 1;
1299 }
1300 case DW_FORM_ref_sup4:
1302 val->u.uint = read_uint32 (buf);
1303 return 1;
1304 case DW_FORM_ref_sup8:
1306 val->u.uint = read_uint64 (buf);
1307 return 1;
1309 val->encoding = ATTR_VAL_UINT;
1310 val->u.uint = implicit_val;
1311 return 1;
1312 case DW_FORM_loclistx:
1313 /* We don't distinguish this from DW_FORM_sec_offset. It
1314 * shouldn't matter since we don't care about loclists. */
1316 val->u.uint = read_uleb128 (buf);
1317 return 1;
1318 case DW_FORM_rnglistx:
1320 val->u.uint = read_uleb128 (buf);
1321 return 1;
1324 val->u.uint = read_uleb128 (buf);
1325 return 1;
1328 val->u.uint = read_uleb128 (buf);
1329 return 1;
1331 val->u.uint = read_offset (buf, is_dwarf64);
1332 if (altlink == NULL)
1333 {
1334 val->encoding = ATTR_VAL_NONE;
1335 return 1;
1336 }
1338 return 1;
1340 {
1341 uint64_t offset;
1342
1343 offset = read_offset (buf, is_dwarf64);
1344 if (altlink == NULL)
1345 {
1346 val->encoding = ATTR_VAL_NONE;
1347 return 1;
1348 }
1349 if (offset >= altlink->dwarf_sections.size[DEBUG_STR])
1350 {
1351 dwarf_buf_error (buf, "DW_FORM_strp_sup out of range", 0);
1352 return 0;
1353 }
1355 val->u.string =
1356 (const char *) altlink->dwarf_sections.data[DEBUG_STR] + offset;
1357 return 1;
1358 }
1359 default:
1360 dwarf_buf_error (buf, "unrecognized DWARF form", -1);
1361 return 0;
1362 }
1363}
1364
1365/* If we can determine the value of a string attribute, set *STRING to
1366 point to the string. Return 1 on success, 0 on error. If we don't
1367 know the value, we consider that a success, and we don't change
1368 *STRING. An error is only reported for some sort of out of range
1369 offset. */
1370
1371static int
1372resolve_string (const struct dwarf_sections *dwarf_sections, int is_dwarf64,
1373 int is_bigendian, uint64_t str_offsets_base,
1374 const struct attr_val *val,
1376 const char **string)
1377{
1378 switch (val->encoding)
1379 {
1380 case ATTR_VAL_STRING:
1381 *string = val->u.string;
1382 return 1;
1383
1385 {
1386 uint64_t offset;
1387 struct dwarf_buf offset_buf;
1388
1389 offset = val->u.uint * (is_dwarf64 ? 8 : 4) + str_offsets_base;
1390 if (offset + (is_dwarf64 ? 8 : 4)
1392 {
1393 error_callback (data, "DW_FORM_strx value out of range", 0);
1394 return 0;
1395 }
1396
1397 offset_buf.name = ".debug_str_offsets";
1399 offset_buf.buf = dwarf_sections->data[DEBUG_STR_OFFSETS] + offset;
1400 offset_buf.left = dwarf_sections->size[DEBUG_STR_OFFSETS] - offset;
1401 offset_buf.is_bigendian = is_bigendian;
1402 offset_buf.error_callback = error_callback;
1403 offset_buf.data = data;
1404 offset_buf.reported_underflow = 0;
1405
1406 offset = read_offset (&offset_buf, is_dwarf64);
1407 if (offset >= dwarf_sections->size[DEBUG_STR])
1408 {
1409 dwarf_buf_error (&offset_buf,
1410 "DW_FORM_strx offset out of range",
1411 0);
1412 return 0;
1413 }
1414 *string = (const char *) dwarf_sections->data[DEBUG_STR] + offset;
1415 return 1;
1416 }
1417
1418 default:
1419 return 1;
1420 }
1421}
1422
1423/* Set *ADDRESS to the real address for a ATTR_VAL_ADDRESS_INDEX.
1424 Return 1 on success, 0 on error. */
1425
1426static int
1428 uint64_t addr_base, int addrsize, int is_bigendian,
1429 uint64_t addr_index,
1431 uintptr_t *address)
1432{
1433 uint64_t offset;
1434 struct dwarf_buf addr_buf;
1435
1436 offset = addr_index * addrsize + addr_base;
1437 if (offset + addrsize > dwarf_sections->size[DEBUG_ADDR])
1438 {
1439 error_callback (data, "DW_FORM_addrx value out of range", 0);
1440 return 0;
1441 }
1442
1443 addr_buf.name = ".debug_addr";
1444 addr_buf.start = dwarf_sections->data[DEBUG_ADDR];
1445 addr_buf.buf = dwarf_sections->data[DEBUG_ADDR] + offset;
1446 addr_buf.left = dwarf_sections->size[DEBUG_ADDR] - offset;
1447 addr_buf.is_bigendian = is_bigendian;
1448 addr_buf.error_callback = error_callback;
1449 addr_buf.data = data;
1450 addr_buf.reported_underflow = 0;
1451
1452 *address = (uintptr_t) read_address (&addr_buf, addrsize);
1453 return 1;
1454}
1455
1456/* Compare a unit offset against a unit for bsearch. */
1457
1458static int
1459units_search (const void *vkey, const void *ventry)
1460{
1461 const size_t *key = (const size_t *) vkey;
1462 const struct unit *entry = *((const struct unit *const *) ventry);
1463 size_t offset;
1464
1465 offset = *key;
1466 if (offset < entry->low_offset)
1467 return -1;
1468 else if (offset >= entry->high_offset)
1469 return 1;
1470 else
1471 return 0;
1472}
1473
1474/* Find a unit in PU containing OFFSET. */
1475
1476static struct unit *
1477find_unit (struct unit **pu, size_t units_count, size_t offset)
1478{
1479 struct unit **u;
1480 u = bsearch (&offset, pu, units_count, sizeof (struct unit *), units_search);
1481 return u == NULL ? NULL : *u;
1482}
1483
1484/* Compare function_addrs for qsort. When ranges are nested, make the
1485 smallest one sort last. */
1486
1487static int
1488function_addrs_compare (const void *v1, const void *v2)
1489{
1490 const struct function_addrs *a1 = (const struct function_addrs *) v1;
1491 const struct function_addrs *a2 = (const struct function_addrs *) v2;
1492
1493 if (a1->low < a2->low)
1494 return -1;
1495 if (a1->low > a2->low)
1496 return 1;
1497 if (a1->high < a2->high)
1498 return 1;
1499 if (a1->high > a2->high)
1500 return -1;
1501 return strcmp (a1->function->name, a2->function->name);
1502}
1503
1504/* Compare a PC against a function_addrs for bsearch. We always
1505 allocate an entra entry at the end of the vector, so that this
1506 routine can safely look at the next entry. Note that if there are
1507 multiple ranges containing PC, which one will be returned is
1508 unpredictable. We compensate for that in dwarf_fileline. */
1509
1510static int
1511function_addrs_search (const void *vkey, const void *ventry)
1512{
1513 const uintptr_t *key = (const uintptr_t *) vkey;
1514 const struct function_addrs *entry = (const struct function_addrs *) ventry;
1515 uintptr_t pc;
1516
1517 pc = *key;
1518 if (pc < entry->low)
1519 return -1;
1520 else if (pc > (entry + 1)->low)
1521 return 1;
1522 else
1523 return 0;
1524}
1525
1526/* Add a new compilation unit address range to a vector. This is
1527 called via add_ranges. Returns 1 on success, 0 on failure. */
1528
1529static int
1531 uintptr_t lowpc, uintptr_t highpc,
1533 void *pvec)
1534{
1535 struct unit *u = (struct unit *) rdata;
1536 struct unit_addrs_vector *vec = (struct unit_addrs_vector *) pvec;
1537 struct unit_addrs *p;
1538
1539 /* Try to merge with the last entry. */
1540 if (vec->count > 0)
1541 {
1542 p = (struct unit_addrs *) vec->vec.base + (vec->count - 1);
1543 if ((lowpc == p->high || lowpc == p->high + 1)
1544 && u == p->u)
1545 {
1546 if (highpc > p->high)
1547 p->high = highpc;
1548 return 1;
1549 }
1550 }
1551
1552 p = ((struct unit_addrs *)
1553 backtrace_vector_grow (state, sizeof (struct unit_addrs),
1554 error_callback, data, &vec->vec));
1555 if (p == NULL)
1556 return 0;
1557
1558 p->low = lowpc;
1559 p->high = highpc;
1560 p->u = u;
1561
1562 ++vec->count;
1563
1564 return 1;
1565}
1566
1567/* Compare unit_addrs for qsort. When ranges are nested, make the
1568 smallest one sort last. */
1569
1570static int
1571unit_addrs_compare (const void *v1, const void *v2)
1572{
1573 const struct unit_addrs *a1 = (const struct unit_addrs *) v1;
1574 const struct unit_addrs *a2 = (const struct unit_addrs *) v2;
1575
1576 if (a1->low < a2->low)
1577 return -1;
1578 if (a1->low > a2->low)
1579 return 1;
1580 if (a1->high < a2->high)
1581 return 1;
1582 if (a1->high > a2->high)
1583 return -1;
1584 if (a1->u->lineoff < a2->u->lineoff)
1585 return -1;
1586 if (a1->u->lineoff > a2->u->lineoff)
1587 return 1;
1588 return 0;
1589}
1590
1591/* Compare a PC against a unit_addrs for bsearch. We always allocate
1592 an entry entry at the end of the vector, so that this routine can
1593 safely look at the next entry. Note that if there are multiple
1594 ranges containing PC, which one will be returned is unpredictable.
1595 We compensate for that in dwarf_fileline. */
1596
1597static int
1598unit_addrs_search (const void *vkey, const void *ventry)
1599{
1600 const uintptr_t *key = (const uintptr_t *) vkey;
1601 const struct unit_addrs *entry = (const struct unit_addrs *) ventry;
1602 uintptr_t pc;
1603
1604 pc = *key;
1605 if (pc < entry->low)
1606 return -1;
1607 else if (pc > (entry + 1)->low)
1608 return 1;
1609 else
1610 return 0;
1611}
1612
1613/* Fill in overlapping ranges as needed. This is a subroutine of
1614 resolve_unit_addrs_overlap. */
1615
1616static int
1618 size_t *pfrom, size_t *pto,
1619 struct unit_addrs *enclosing,
1620 struct unit_addrs_vector *old_vec,
1622 void *data,
1623 struct unit_addrs_vector *new_vec)
1624{
1625 struct unit_addrs *old_addrs;
1626 size_t old_count;
1627 struct unit_addrs *new_addrs;
1628 size_t from;
1629 size_t to;
1630
1631 old_addrs = (struct unit_addrs *) old_vec->vec.base;
1632 old_count = old_vec->count;
1633 new_addrs = (struct unit_addrs *) new_vec->vec.base;
1634
1635 for (from = *pfrom, to = *pto; from < old_count; from++, to++)
1636 {
1637 /* If we are in the scope of a larger range that can no longer
1638 cover any further ranges, return back to the caller. */
1639
1640 if (enclosing != NULL
1641 && enclosing->high <= old_addrs[from].low)
1642 {
1643 *pfrom = from;
1644 *pto = to;
1645 return 1;
1646 }
1647
1648 new_addrs[to] = old_addrs[from];
1649
1650 /* If we are in scope of a larger range, fill in any gaps
1651 between this entry and the next one.
1652
1653 There is an extra entry at the end of the vector, so it's
1654 always OK to refer to from + 1. */
1655
1656 if (enclosing != NULL
1657 && enclosing->high > old_addrs[from].high
1658 && old_addrs[from].high < old_addrs[from + 1].low)
1659 {
1660 void *grew;
1661 size_t new_high;
1662
1663 grew = backtrace_vector_grow (state, sizeof (struct unit_addrs),
1664 error_callback, data, &new_vec->vec);
1665 if (grew == NULL)
1666 return 0;
1667 new_addrs = (struct unit_addrs *) new_vec->vec.base;
1668 to++;
1669 new_addrs[to].low = old_addrs[from].high;
1670 new_high = old_addrs[from + 1].low;
1671 if (enclosing->high < new_high)
1672 new_high = enclosing->high;
1673 new_addrs[to].high = new_high;
1674 new_addrs[to].u = enclosing->u;
1675 }
1676
1677 /* If this range has a larger scope than the next one, use it to
1678 fill in any gaps. */
1679
1680 if (old_addrs[from].high > old_addrs[from + 1].high)
1681 {
1682 *pfrom = from + 1;
1683 *pto = to + 1;
1684 if (!resolve_unit_addrs_overlap_walk (state, pfrom, pto,
1685 &old_addrs[from], old_vec,
1686 error_callback, data, new_vec))
1687 return 0;
1688 from = *pfrom;
1689 to = *pto;
1690
1691 /* Undo the increment the loop is about to do. */
1692 from--;
1693 to--;
1694 }
1695 }
1696
1697 if (enclosing == NULL)
1698 {
1699 struct unit_addrs *pa;
1700
1701 /* Add trailing entry. */
1702
1703 pa = ((struct unit_addrs *)
1704 backtrace_vector_grow (state, sizeof (struct unit_addrs),
1705 error_callback, data, &new_vec->vec));
1706 if (pa == NULL)
1707 return 0;
1708 pa->low = 0;
1709 --pa->low;
1710 pa->high = pa->low;
1711 pa->u = NULL;
1712
1713 new_vec->count = to;
1714 }
1715
1716 return 1;
1717}
1718
1719/* It is possible for the unit_addrs list to contain overlaps, as in
1720
1721 10: low == 10, high == 20, unit 1
1722 11: low == 12, high == 15, unit 2
1723 12: low == 20, high == 30, unit 1
1724
1725 In such a case, for pc == 17, a search using units_addr_search will
1726 return entry 11. However, pc == 17 doesn't fit in that range. We
1727 actually want range 10.
1728
1729 It seems that in general we might have an arbitrary number of
1730 ranges in between 10 and 12.
1731
1732 To handle this we look for cases where range R1 is followed by
1733 range R2 such that R2 is a strict subset of R1. In such cases we
1734 insert a new range R3 following R2 that fills in the remainder of
1735 the address space covered by R1. That lets a relatively simple
1736 search find the correct range.
1737
1738 These overlaps can occur because of the range merging we do in
1739 add_unit_addr. When the linker de-duplicates functions, it can
1740 leave behind an address range that refers to the address range of
1741 the retained duplicate. If the retained duplicate address range is
1742 merged with others, then after sorting we can see overlapping
1743 address ranges.
1744
1745 See https://github.com/ianlancetaylor/libbacktrace/issues/137. */
1746
1747static int
1750 void *data, struct unit_addrs_vector *addrs_vec)
1751{
1752 struct unit_addrs *addrs;
1753 size_t count;
1754 int found;
1755 struct unit_addrs *entry;
1756 size_t i;
1757 struct unit_addrs_vector new_vec;
1758 void *grew;
1759 size_t from;
1760 size_t to;
1761
1762 addrs = (struct unit_addrs *) addrs_vec->vec.base;
1763 count = addrs_vec->count;
1764
1765 if (count == 0)
1766 return 1;
1767
1768 /* Optimistically assume that overlaps are rare. */
1769 found = 0;
1770 entry = addrs;
1771 for (i = 0; i < count - 1; i++)
1772 {
1773 if (entry->low < (entry + 1)->low
1774 && entry->high > (entry + 1)->high)
1775 {
1776 found = 1;
1777 break;
1778 }
1779 entry++;
1780 }
1781 if (!found)
1782 return 1;
1783
1784 memset (&new_vec, 0, sizeof new_vec);
1786 count * sizeof (struct unit_addrs),
1787 error_callback, data, &new_vec.vec);
1788 if (grew == NULL)
1789 return 0;
1790
1791 from = 0;
1792 to = 0;
1793 resolve_unit_addrs_overlap_walk (state, &from, &to, NULL, addrs_vec,
1794 error_callback, data, &new_vec);
1796 *addrs_vec = new_vec;
1797
1798 return 1;
1799}
1800
1801/* Sort the line vector by PC. We want a stable sort here to maintain
1802 the order of lines for the same PC values. Since the sequence is
1803 being sorted in place, their addresses cannot be relied on to
1804 maintain stability. That is the purpose of the index member. */
1805
1806static int
1807line_compare (const void *v1, const void *v2)
1808{
1809 const struct line *ln1 = (const struct line *) v1;
1810 const struct line *ln2 = (const struct line *) v2;
1811
1812 if (ln1->pc < ln2->pc)
1813 return -1;
1814 else if (ln1->pc > ln2->pc)
1815 return 1;
1816 else if (ln1->idx < ln2->idx)
1817 return -1;
1818 else if (ln1->idx > ln2->idx)
1819 return 1;
1820 else
1821 return 0;
1822}
1823
1824/* Find a PC in a line vector. We always allocate an extra entry at
1825 the end of the lines vector, so that this routine can safely look
1826 at the next entry. Note that when there are multiple mappings for
1827 the same PC value, this will return the last one. */
1828
1829static int
1830line_search (const void *vkey, const void *ventry)
1831{
1832 const uintptr_t *key = (const uintptr_t *) vkey;
1833 const struct line *entry = (const struct line *) ventry;
1834 uintptr_t pc;
1835
1836 pc = *key;
1837 if (pc < entry->pc)
1838 return -1;
1839 else if (pc >= (entry + 1)->pc)
1840 return 1;
1841 else
1842 return 0;
1843}
1844
1845/* Sort the abbrevs by the abbrev code. This function is passed to
1846 both qsort and bsearch. */
1847
1848static int
1849abbrev_compare (const void *v1, const void *v2)
1850{
1851 const struct abbrev *a1 = (const struct abbrev *) v1;
1852 const struct abbrev *a2 = (const struct abbrev *) v2;
1853
1854 if (a1->code < a2->code)
1855 return -1;
1856 else if (a1->code > a2->code)
1857 return 1;
1858 else
1859 {
1860 /* This really shouldn't happen. It means there are two
1861 different abbrevs with the same code, and that means we don't
1862 know which one lookup_abbrev should return. */
1863 return 0;
1864 }
1865}
1866
1867/* Read the abbreviation table for a compilation unit. Returns 1 on
1868 success, 0 on failure. */
1869
1870static int
1871read_abbrevs (struct backtrace_state *state, uint64_t abbrev_offset,
1872 const unsigned char *dwarf_abbrev, size_t dwarf_abbrev_size,
1873 int is_bigendian, backtrace_error_callback error_callback,
1874 void *data, struct abbrevs *abbrevs)
1875{
1876 struct dwarf_buf abbrev_buf;
1877 struct dwarf_buf count_buf;
1878 size_t num_abbrevs;
1879
1880 abbrevs->num_abbrevs = 0;
1881 abbrevs->abbrevs = NULL;
1882
1883 if (abbrev_offset >= dwarf_abbrev_size)
1884 {
1885 error_callback (data, "abbrev offset out of range", 0);
1886 return 0;
1887 }
1888
1889 abbrev_buf.name = ".debug_abbrev";
1890 abbrev_buf.start = dwarf_abbrev;
1891 abbrev_buf.buf = dwarf_abbrev + abbrev_offset;
1892 abbrev_buf.left = dwarf_abbrev_size - abbrev_offset;
1893 abbrev_buf.is_bigendian = is_bigendian;
1894 abbrev_buf.error_callback = error_callback;
1895 abbrev_buf.data = data;
1896 abbrev_buf.reported_underflow = 0;
1897
1898 /* Count the number of abbrevs in this list. */
1899
1900 count_buf = abbrev_buf;
1901 num_abbrevs = 0;
1902 while (read_uleb128 (&count_buf) != 0)
1903 {
1904 if (count_buf.reported_underflow)
1905 return 0;
1906 ++num_abbrevs;
1907 // Skip tag.
1908 read_uleb128 (&count_buf);
1909 // Skip has_children.
1910 read_byte (&count_buf);
1911 // Skip attributes.
1912 while (read_uleb128 (&count_buf) != 0)
1913 {
1914 uint64_t form;
1915
1916 form = read_uleb128 (&count_buf);
1917 if ((enum dwarf_form) form == DW_FORM_implicit_const)
1918 read_sleb128 (&count_buf);
1919 }
1920 // Skip form of last attribute.
1921 read_uleb128 (&count_buf);
1922 }
1923
1924 if (count_buf.reported_underflow)
1925 return 0;
1926
1927 if (num_abbrevs == 0)
1928 return 1;
1929
1930 abbrevs->abbrevs = ((struct abbrev *)
1932 num_abbrevs * sizeof (struct abbrev),
1934 if (abbrevs->abbrevs == NULL)
1935 return 0;
1936 abbrevs->num_abbrevs = num_abbrevs;
1937 memset (abbrevs->abbrevs, 0, num_abbrevs * sizeof (struct abbrev));
1938
1939 num_abbrevs = 0;
1940 while (1)
1941 {
1942 uint64_t code;
1943 struct abbrev a;
1944 size_t num_attrs;
1945 struct attr *attrs;
1946
1947 if (abbrev_buf.reported_underflow)
1948 goto fail;
1949
1950 code = read_uleb128 (&abbrev_buf);
1951 if (code == 0)
1952 break;
1953
1954 a.code = code;
1955 a.tag = (enum dwarf_tag) read_uleb128 (&abbrev_buf);
1956 a.has_children = read_byte (&abbrev_buf);
1957
1958 count_buf = abbrev_buf;
1959 num_attrs = 0;
1960 while (read_uleb128 (&count_buf) != 0)
1961 {
1962 uint64_t form;
1963
1964 ++num_attrs;
1965 form = read_uleb128 (&count_buf);
1967 read_sleb128 (&count_buf);
1968 }
1969
1970 if (num_attrs == 0)
1971 {
1972 attrs = NULL;
1973 read_uleb128 (&abbrev_buf);
1974 read_uleb128 (&abbrev_buf);
1975 }
1976 else
1977 {
1978 attrs = ((struct attr *)
1979 backtrace_alloc (state, num_attrs * sizeof *attrs,
1981 if (attrs == NULL)
1982 goto fail;
1983 num_attrs = 0;
1984 while (1)
1985 {
1986 uint64_t name;
1987 uint64_t form;
1988
1989 name = read_uleb128 (&abbrev_buf);
1990 form = read_uleb128 (&abbrev_buf);
1991 if (name == 0)
1992 break;
1993 attrs[num_attrs].name = (enum dwarf_attribute) name;
1994 attrs[num_attrs].form = (enum dwarf_form) form;
1996 attrs[num_attrs].val = read_sleb128 (&abbrev_buf);
1997 else
1998 attrs[num_attrs].val = 0;
1999 ++num_attrs;
2000 }
2001 }
2002
2003 a.num_attrs = num_attrs;
2004 a.attrs = attrs;
2005
2006 abbrevs->abbrevs[num_abbrevs] = a;
2007 ++num_abbrevs;
2008 }
2009
2011 sizeof (struct abbrev), abbrev_compare);
2012
2013 return 1;
2014
2015 fail:
2017 return 0;
2018}
2019
2020/* Return the abbrev information for an abbrev code. */
2021
2022static const struct abbrev *
2025{
2026 struct abbrev key;
2027 void *p;
2028
2029 /* With GCC, where abbrevs are simply numbered in order, we should
2030 be able to just look up the entry. */
2031 if (code - 1 < abbrevs->num_abbrevs
2032 && abbrevs->abbrevs[code - 1].code == code)
2033 return &abbrevs->abbrevs[code - 1];
2034
2035 /* Otherwise we have to search. */
2036 memset (&key, 0, sizeof key);
2037 key.code = code;
2038 p = bsearch (&key, abbrevs->abbrevs, abbrevs->num_abbrevs,
2039 sizeof (struct abbrev), abbrev_compare);
2040 if (p == NULL)
2041 {
2042 error_callback (data, "invalid abbreviation code", 0);
2043 return NULL;
2044 }
2045 return (const struct abbrev *) p;
2046}
2047
2048/* This struct is used to gather address range information while
2049 reading attributes. We use this while building a mapping from
2050 address ranges to compilation units and then again while mapping
2051 from address ranges to function entries. Normally either
2052 lowpc/highpc is set or ranges is set. */
2053
2054struct pcrange {
2055 uintptr_t lowpc; /* The low PC value. */
2056 int have_lowpc; /* Whether a low PC value was found. */
2057 int lowpc_is_addr_index; /* Whether lowpc is in .debug_addr. */
2058 uintptr_t highpc; /* The high PC value. */
2059 int have_highpc; /* Whether a high PC value was found. */
2060 int highpc_is_relative; /* Whether highpc is relative to lowpc. */
2061 int highpc_is_addr_index; /* Whether highpc is in .debug_addr. */
2062 uint64_t ranges; /* Offset in ranges section. */
2063 int have_ranges; /* Whether ranges is valid. */
2064 int ranges_is_index; /* Whether ranges is DW_FORM_rnglistx. */
2065};
2066
2067/* Update PCRANGE from an attribute value. */
2068
2069static void
2070update_pcrange (const struct attr* attr, const struct attr_val* val,
2071 struct pcrange *pcrange)
2072{
2073 switch (attr->name)
2074 {
2075 case DW_AT_low_pc:
2076 if (val->encoding == ATTR_VAL_ADDRESS)
2077 {
2078 pcrange->lowpc = (uintptr_t) val->u.uint;
2079 pcrange->have_lowpc = 1;
2080 }
2081 else if (val->encoding == ATTR_VAL_ADDRESS_INDEX)
2082 {
2083 pcrange->lowpc = (uintptr_t) val->u.uint;
2084 pcrange->have_lowpc = 1;
2086 }
2087 break;
2088
2089 case DW_AT_high_pc:
2090 if (val->encoding == ATTR_VAL_ADDRESS)
2091 {
2092 pcrange->highpc = (uintptr_t) val->u.uint;
2093 pcrange->have_highpc = 1;
2094 }
2095 else if (val->encoding == ATTR_VAL_UINT)
2096 {
2097 pcrange->highpc = (uintptr_t) val->u.uint;
2098 pcrange->have_highpc = 1;
2100 }
2101 else if (val->encoding == ATTR_VAL_ADDRESS_INDEX)
2102 {
2103 pcrange->highpc = (uintptr_t) val->u.uint;
2104 pcrange->have_highpc = 1;
2106 }
2107 break;
2108
2109 case DW_AT_ranges:
2110 if (val->encoding == ATTR_VAL_UINT
2111 || val->encoding == ATTR_VAL_REF_SECTION)
2112 {
2113 pcrange->ranges = val->u.uint;
2114 pcrange->have_ranges = 1;
2115 }
2116 else if (val->encoding == ATTR_VAL_RNGLISTS_INDEX)
2117 {
2118 pcrange->ranges = val->u.uint;
2119 pcrange->have_ranges = 1;
2121 }
2122 break;
2123
2124 default:
2125 break;
2126 }
2127}
2128
2129/* Call ADD_RANGE for a low/high PC pair. Returns 1 on success, 0 on
2130 error. */
2131
2132static int
2134 const struct dwarf_sections *dwarf_sections,
2135 struct libbacktrace_base_address base_address,
2136 int is_bigendian, struct unit *u,
2137 const struct pcrange *pcrange,
2138 int (*add_range) (struct backtrace_state *state,
2139 void *rdata, uintptr_t lowpc,
2140 uintptr_t highpc,
2142 void *data, void *vec),
2143 void *rdata,
2145 void *vec)
2146{
2147 uintptr_t lowpc;
2148 uintptr_t highpc;
2149
2150 lowpc = pcrange->lowpc;
2152 {
2154 is_bigendian, lowpc, error_callback, data,
2155 &lowpc))
2156 return 0;
2157 }
2158
2159 highpc = pcrange->highpc;
2161 {
2163 is_bigendian, highpc, error_callback, data,
2164 &highpc))
2165 return 0;
2166 }
2168 highpc += lowpc;
2169
2170 /* Add in the base address of the module when recording PC values,
2171 so that we can look up the PC directly. */
2172 lowpc = libbacktrace_add_base (lowpc, base_address);
2173 highpc = libbacktrace_add_base (highpc, base_address);
2174
2175 return add_range (state, rdata, lowpc, highpc, error_callback, data, vec);
2176}
2177
2178/* Call ADD_RANGE for each range read from .debug_ranges, as used in
2179 DWARF versions 2 through 4. */
2180
2181static int
2183 struct backtrace_state *state,
2184 const struct dwarf_sections *dwarf_sections,
2185 struct libbacktrace_base_address base_address, int is_bigendian,
2186 struct unit *u, uintptr_t base,
2187 const struct pcrange *pcrange,
2188 int (*add_range) (struct backtrace_state *state, void *rdata,
2189 uintptr_t lowpc, uintptr_t highpc,
2191 void *vec),
2192 void *rdata,
2194 void *vec)
2195{
2196 struct dwarf_buf ranges_buf;
2197
2199 {
2200 error_callback (data, "ranges offset out of range", 0);
2201 return 0;
2202 }
2203
2204 ranges_buf.name = ".debug_ranges";
2205 ranges_buf.start = dwarf_sections->data[DEBUG_RANGES];
2208 ranges_buf.is_bigendian = is_bigendian;
2209 ranges_buf.error_callback = error_callback;
2210 ranges_buf.data = data;
2211 ranges_buf.reported_underflow = 0;
2212
2213 while (1)
2214 {
2215 uint64_t low;
2216 uint64_t high;
2217
2218 if (ranges_buf.reported_underflow)
2219 return 0;
2220
2221 low = read_address (&ranges_buf, u->addrsize);
2222 high = read_address (&ranges_buf, u->addrsize);
2223
2224 if (low == 0 && high == 0)
2225 break;
2226
2227 if (is_highest_address (low, u->addrsize))
2228 base = (uintptr_t) high;
2229 else
2230 {
2231 uintptr_t rl, rh;
2232
2233 rl = libbacktrace_add_base ((uintptr_t) low + base, base_address);
2234 rh = libbacktrace_add_base ((uintptr_t) high + base, base_address);
2235 if (!add_range (state, rdata, rl, rh, error_callback, data, vec))
2236 return 0;
2237 }
2238 }
2239
2240 if (ranges_buf.reported_underflow)
2241 return 0;
2242
2243 return 1;
2244}
2245
2246/* Call ADD_RANGE for each range read from .debug_rnglists, as used in
2247 DWARF version 5. */
2248
2249static int
2251 struct backtrace_state *state,
2252 const struct dwarf_sections *dwarf_sections,
2253 struct libbacktrace_base_address base_address, int is_bigendian,
2254 struct unit *u, uintptr_t base,
2255 const struct pcrange *pcrange,
2256 int (*add_range) (struct backtrace_state *state, void *rdata,
2257 uintptr_t lowpc, uintptr_t highpc,
2259 void *vec),
2260 void *rdata,
2262 void *vec)
2263{
2264 uint64_t offset;
2265 struct dwarf_buf rnglists_buf;
2266
2268 offset = pcrange->ranges;
2269 else
2270 offset = u->rnglists_base + pcrange->ranges * (u->is_dwarf64 ? 8 : 4);
2271 if (offset >= dwarf_sections->size[DEBUG_RNGLISTS])
2272 {
2273 error_callback (data, "rnglists offset out of range", 0);
2274 return 0;
2275 }
2276
2277 rnglists_buf.name = ".debug_rnglists";
2278 rnglists_buf.start = dwarf_sections->data[DEBUG_RNGLISTS];
2279 rnglists_buf.buf = dwarf_sections->data[DEBUG_RNGLISTS] + offset;
2280 rnglists_buf.left = dwarf_sections->size[DEBUG_RNGLISTS] - offset;
2281 rnglists_buf.is_bigendian = is_bigendian;
2282 rnglists_buf.error_callback = error_callback;
2283 rnglists_buf.data = data;
2284 rnglists_buf.reported_underflow = 0;
2285
2287 {
2288 offset = read_offset (&rnglists_buf, u->is_dwarf64);
2289 offset += u->rnglists_base;
2290 if (offset >= dwarf_sections->size[DEBUG_RNGLISTS])
2291 {
2292 error_callback (data, "rnglists index offset out of range", 0);
2293 return 0;
2294 }
2295 rnglists_buf.buf = dwarf_sections->data[DEBUG_RNGLISTS] + offset;
2296 rnglists_buf.left = dwarf_sections->size[DEBUG_RNGLISTS] - offset;
2297 }
2298
2299 while (1)
2300 {
2301 unsigned char rle;
2302
2303 rle = read_byte (&rnglists_buf);
2304 if (rle == DW_RLE_end_of_list)
2305 break;
2306 switch (rle)
2307 {
2309 {
2310 uint64_t index;
2311
2312 index = read_uleb128 (&rnglists_buf);
2314 u->addrsize, is_bigendian, index,
2316 return 0;
2317 }
2318 break;
2319
2320 case DW_RLE_startx_endx:
2321 {
2322 uint64_t index;
2323 uintptr_t low;
2324 uintptr_t high;
2325
2326 index = read_uleb128 (&rnglists_buf);
2328 u->addrsize, is_bigendian, index,
2329 error_callback, data, &low))
2330 return 0;
2331 index = read_uleb128 (&rnglists_buf);
2333 u->addrsize, is_bigendian, index,
2334 error_callback, data, &high))
2335 return 0;
2336 if (!add_range (state, rdata,
2337 libbacktrace_add_base (low, base_address),
2338 libbacktrace_add_base (high, base_address),
2339 error_callback, data, vec))
2340 return 0;
2341 }
2342 break;
2343
2345 {
2346 uint64_t index;
2347 uintptr_t low;
2348 uintptr_t length;
2349
2350 index = read_uleb128 (&rnglists_buf);
2352 u->addrsize, is_bigendian, index,
2353 error_callback, data, &low))
2354 return 0;
2355 length = read_uleb128 (&rnglists_buf);
2356 low = libbacktrace_add_base (low, base_address);
2357 if (!add_range (state, rdata, low, low + length,
2358 error_callback, data, vec))
2359 return 0;
2360 }
2361 break;
2362
2363 case DW_RLE_offset_pair:
2364 {
2365 uint64_t low;
2366 uint64_t high;
2367
2368 low = read_uleb128 (&rnglists_buf);
2369 high = read_uleb128 (&rnglists_buf);
2370 if (!add_range (state, rdata,
2371 libbacktrace_add_base (low + base, base_address),
2372 libbacktrace_add_base (high + base, base_address),
2373 error_callback, data, vec))
2374 return 0;
2375 }
2376 break;
2377
2379 base = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
2380 break;
2381
2382 case DW_RLE_start_end:
2383 {
2384 uintptr_t low;
2385 uintptr_t high;
2386
2387 low = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
2388 high = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
2389 if (!add_range (state, rdata,
2390 libbacktrace_add_base (low, base_address),
2391 libbacktrace_add_base (high, base_address),
2392 error_callback, data, vec))
2393 return 0;
2394 }
2395 break;
2396
2398 {
2399 uintptr_t low;
2400 uintptr_t length;
2401
2402 low = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
2403 length = (uintptr_t) read_uleb128 (&rnglists_buf);
2404 low = libbacktrace_add_base (low, base_address);
2405 if (!add_range (state, rdata, low, low + length,
2406 error_callback, data, vec))
2407 return 0;
2408 }
2409 break;
2410
2411 default:
2412 dwarf_buf_error (&rnglists_buf, "unrecognized DW_RLE value", -1);
2413 return 0;
2414 }
2415 }
2416
2417 if (rnglists_buf.reported_underflow)
2418 return 0;
2419
2420 return 1;
2421}
2422
2423/* Call ADD_RANGE for each lowpc/highpc pair in PCRANGE. RDATA is
2424 passed to ADD_RANGE, and is either a struct unit * or a struct
2425 function *. VEC is the vector we are adding ranges to, and is
2426 either a struct unit_addrs_vector * or a struct function_vector *.
2427 Returns 1 on success, 0 on error. */
2428
2429static int
2431 const struct dwarf_sections *dwarf_sections,
2432 struct libbacktrace_base_address base_address, int is_bigendian,
2433 struct unit *u, uintptr_t base, const struct pcrange *pcrange,
2434 int (*add_range) (struct backtrace_state *state, void *rdata,
2435 uintptr_t lowpc, uintptr_t highpc,
2437 void *data, void *vec),
2438 void *rdata,
2440 void *vec)
2441{
2443 return add_low_high_range (state, dwarf_sections, base_address,
2444 is_bigendian, u, pcrange, add_range, rdata,
2445 error_callback, data, vec);
2446
2447 if (!pcrange->have_ranges)
2448 {
2449 /* Did not find any address ranges to add. */
2450 return 1;
2451 }
2452
2453 if (u->version < 5)
2454 return add_ranges_from_ranges (state, dwarf_sections, base_address,
2455 is_bigendian, u, base, pcrange, add_range,
2456 rdata, error_callback, data, vec);
2457 else
2458 return add_ranges_from_rnglists (state, dwarf_sections, base_address,
2459 is_bigendian, u, base, pcrange, add_range,
2460 rdata, error_callback, data, vec);
2461}
2462
2463/* Find the address range covered by a compilation unit, reading from
2464 UNIT_BUF and adding values to U. Returns 1 if all data could be
2465 read, 0 if there is some error. */
2466
2467static int
2469 struct libbacktrace_base_address base_address,
2470 struct dwarf_buf *unit_buf,
2471 const struct dwarf_sections *dwarf_sections,
2472 int is_bigendian, struct dwarf_data *altlink,
2474 struct unit *u, struct unit_addrs_vector *addrs,
2475 enum dwarf_tag *unit_tag)
2476{
2477 while (unit_buf->left > 0)
2478 {
2479 uint64_t code;
2480 const struct abbrev *abbrev;
2481 struct pcrange pcrange;
2482 struct attr_val name_val;
2483 int have_name_val;
2484 struct attr_val comp_dir_val;
2485 int have_comp_dir_val;
2486 size_t i;
2487
2488 code = read_uleb128 (unit_buf);
2489 if (code == 0)
2490 return 1;
2491
2492 abbrev = lookup_abbrev (&u->abbrevs, code, error_callback, data);
2493 if (abbrev == NULL)
2494 return 0;
2495
2496 if (unit_tag != NULL)
2497 *unit_tag = abbrev->tag;
2498
2499 memset (&pcrange, 0, sizeof pcrange);
2500 memset (&name_val, 0, sizeof name_val);
2501 have_name_val = 0;
2502 memset (&comp_dir_val, 0, sizeof comp_dir_val);
2503 have_comp_dir_val = 0;
2504 for (i = 0; i < abbrev->num_attrs; ++i)
2505 {
2506 struct attr_val val;
2507
2509 unit_buf, u->is_dwarf64, u->version,
2510 u->addrsize, dwarf_sections, altlink, &val))
2511 return 0;
2512
2513 switch (abbrev->attrs[i].name)
2514 {
2515 case DW_AT_low_pc: case DW_AT_high_pc: case DW_AT_ranges:
2516 update_pcrange (&abbrev->attrs[i], &val, &pcrange);
2517 break;
2518
2519 case DW_AT_stmt_list:
2522 && (val.encoding == ATTR_VAL_UINT
2523 || val.encoding == ATTR_VAL_REF_SECTION))
2524 u->lineoff = val.u.uint;
2525 break;
2526
2527 case DW_AT_name:
2530 {
2531 name_val = val;
2532 have_name_val = 1;
2533 }
2534 break;
2535
2536 case DW_AT_comp_dir:
2539 {
2540 comp_dir_val = val;
2541 have_comp_dir_val = 1;
2542 }
2543 break;
2544
2549 u->str_offsets_base = val.u.uint;
2550 break;
2551
2552 case DW_AT_addr_base:
2556 u->addr_base = val.u.uint;
2557 break;
2558
2563 u->rnglists_base = val.u.uint;
2564 break;
2565
2566 default:
2567 break;
2568 }
2569 }
2570
2571 // Resolve strings after we're sure that we have seen
2572 // DW_AT_str_offsets_base.
2573 if (have_name_val)
2574 {
2575 if (!resolve_string (dwarf_sections, u->is_dwarf64, is_bigendian,
2576 u->str_offsets_base, &name_val,
2577 error_callback, data, &u->filename))
2578 return 0;
2579 }
2580 if (have_comp_dir_val)
2581 {
2582 if (!resolve_string (dwarf_sections, u->is_dwarf64, is_bigendian,
2583 u->str_offsets_base, &comp_dir_val,
2584 error_callback, data, &u->comp_dir))
2585 return 0;
2586 }
2587
2591 {
2592 if (!add_ranges (state, dwarf_sections, base_address,
2593 is_bigendian, u, pcrange.lowpc, &pcrange,
2594 add_unit_addr, (void *) u, error_callback, data,
2595 (void *) addrs))
2596 return 0;
2597
2598 /* If we found the PC range in the DW_TAG_compile_unit or
2599 DW_TAG_skeleton_unit, we can stop now. */
2604 return 1;
2605 }
2606
2607 if (abbrev->has_children)
2608 {
2609 if (!find_address_ranges (state, base_address, unit_buf,
2610 dwarf_sections, is_bigendian, altlink,
2611 error_callback, data, u, addrs, NULL))
2612 return 0;
2613 }
2614 }
2615
2616 return 1;
2617}
2618
2619/* Build a mapping from address ranges to the compilation units where
2620 the line number information for that range can be found. Returns 1
2621 on success, 0 on failure. */
2622
2623static int
2625 struct libbacktrace_base_address base_address,
2626 const struct dwarf_sections *dwarf_sections,
2627 int is_bigendian, struct dwarf_data *altlink,
2629 struct unit_addrs_vector *addrs,
2630 struct unit_vector *unit_vec)
2631{
2632 struct dwarf_buf info;
2633 struct backtrace_vector units;
2634 size_t units_count;
2635 size_t i;
2636 struct unit **pu;
2637 size_t unit_offset = 0;
2638 struct unit_addrs *pa;
2639
2640 memset (&addrs->vec, 0, sizeof addrs->vec);
2641 memset (&unit_vec->vec, 0, sizeof unit_vec->vec);
2642 addrs->count = 0;
2643 unit_vec->count = 0;
2644
2645 /* Read through the .debug_info section. FIXME: Should we use the
2646 .debug_aranges section? gdb and addr2line don't use it, but I'm
2647 not sure why. */
2648
2649 info.name = ".debug_info";
2651 info.buf = info.start;
2653 info.is_bigendian = is_bigendian;
2654 info.error_callback = error_callback;
2655 info.data = data;
2656 info.reported_underflow = 0;
2657
2658 memset (&units, 0, sizeof units);
2659 units_count = 0;
2660
2661 while (info.left > 0)
2662 {
2663 const unsigned char *unit_data_start;
2664 uint64_t len;
2665 int is_dwarf64;
2666 struct dwarf_buf unit_buf;
2667 int version;
2668 int unit_type;
2669 uint64_t abbrev_offset;
2670 int addrsize;
2671 struct unit *u;
2672 enum dwarf_tag unit_tag;
2673
2674 if (info.reported_underflow)
2675 goto fail;
2676
2677 unit_data_start = info.buf;
2678
2680 unit_buf = info;
2681 unit_buf.left = len;
2682
2683 if (!advance (&info, len))
2684 goto fail;
2685
2686 version = read_uint16 (&unit_buf);
2687 if (version < 2 || version > 5)
2688 {
2689 dwarf_buf_error (&unit_buf, "unrecognized DWARF version", -1);
2690 goto fail;
2691 }
2692
2693 if (version < 5)
2694 unit_type = 0;
2695 else
2696 {
2697 unit_type = read_byte (&unit_buf);
2698 if (unit_type == DW_UT_type || unit_type == DW_UT_split_type)
2699 {
2700 /* This unit doesn't have anything we need. */
2701 continue;
2702 }
2703 }
2704
2705 pu = ((struct unit **)
2706 backtrace_vector_grow (state, sizeof (struct unit *),
2707 error_callback, data, &units));
2708 if (pu == NULL)
2709 goto fail;
2710
2711 u = ((struct unit *)
2712 backtrace_alloc (state, sizeof *u, error_callback, data));
2713 if (u == NULL)
2714 goto fail;
2715
2716 *pu = u;
2717 ++units_count;
2718
2719 if (version < 5)
2720 addrsize = 0; /* Set below. */
2721 else
2722 addrsize = read_byte (&unit_buf);
2723
2724 memset (&u->abbrevs, 0, sizeof u->abbrevs);
2725 abbrev_offset = read_offset (&unit_buf, is_dwarf64);
2726 if (!read_abbrevs (state, abbrev_offset,
2729 is_bigendian, error_callback, data, &u->abbrevs))
2730 goto fail;
2731
2732 if (version < 5)
2733 addrsize = read_byte (&unit_buf);
2734
2735 switch (unit_type)
2736 {
2737 case 0:
2738 break;
2739 case DW_UT_compile: case DW_UT_partial:
2740 break;
2742 read_uint64 (&unit_buf); /* dwo_id */
2743 break;
2744 default:
2745 break;
2746 }
2747
2748 u->low_offset = unit_offset;
2749 unit_offset += len + (is_dwarf64 ? 12 : 4);
2750 u->high_offset = unit_offset;
2751 u->unit_data = unit_buf.buf;
2752 u->unit_data_len = unit_buf.left;
2753 u->unit_data_offset = unit_buf.buf - unit_data_start;
2754 u->version = version;
2756 u->addrsize = addrsize;
2757 u->filename = NULL;
2758 u->comp_dir = NULL;
2759 u->abs_filename = NULL;
2760 u->lineoff = 0;
2761 u->str_offsets_base = 0;
2762 u->addr_base = 0;
2763 u->rnglists_base = 0;
2764
2765 /* The actual line number mappings will be read as needed. */
2766 u->lines = NULL;
2767 u->lines_count = 0;
2768 u->function_addrs = NULL;
2769 u->function_addrs_count = 0;
2770
2771 if (!find_address_ranges (state, base_address, &unit_buf, dwarf_sections,
2772 is_bigendian, altlink, error_callback, data,
2773 u, addrs, &unit_tag))
2774 goto fail;
2775
2776 if (unit_buf.reported_underflow)
2777 goto fail;
2778 }
2779 if (info.reported_underflow)
2780 goto fail;
2781
2782 /* Add a trailing addrs entry, but don't include it in addrs->count. */
2783 pa = ((struct unit_addrs *)
2784 backtrace_vector_grow (state, sizeof (struct unit_addrs),
2785 error_callback, data, &addrs->vec));
2786 if (pa == NULL)
2787 goto fail;
2788 pa->low = 0;
2789 --pa->low;
2790 pa->high = pa->low;
2791 pa->u = NULL;
2792
2793 unit_vec->vec = units;
2794 unit_vec->count = units_count;
2795 return 1;
2796
2797 fail:
2798 if (units_count > 0)
2799 {
2800 pu = (struct unit **) units.base;
2801 for (i = 0; i < units_count; i++)
2802 {
2804 backtrace_free (state, pu[i], sizeof **pu, error_callback, data);
2805 }
2807 }
2808 if (addrs->count > 0)
2809 {
2811 addrs->count = 0;
2812 }
2813 return 0;
2814}
2815
2816/* Add a new mapping to the vector of line mappings that we are
2817 building. Returns 1 on success, 0 on failure. */
2818
2819static int
2821 uintptr_t pc, const char *filename, int lineno,
2823 struct line_vector *vec)
2824{
2825 struct line *ln;
2826
2827 /* If we are adding the same mapping, ignore it. This can happen
2828 when using discriminators. */
2829 if (vec->count > 0)
2830 {
2831 ln = (struct line *) vec->vec.base + (vec->count - 1);
2832 if (pc == ln->pc && filename == ln->filename && lineno == ln->lineno)
2833 return 1;
2834 }
2835
2836 ln = ((struct line *)
2838 data, &vec->vec));
2839 if (ln == NULL)
2840 return 0;
2841
2842 /* Add in the base address here, so that we can look up the PC
2843 directly. */
2844 ln->pc = libbacktrace_add_base (pc, ddata->base_address);
2845
2846 ln->filename = filename;
2847 ln->lineno = lineno;
2848 ln->idx = vec->count;
2849
2850 ++vec->count;
2851
2852 return 1;
2853}
2854
2855/* Free the line header information. */
2856
2857static void
2860{
2861 if (hdr->dirs_count != 0)
2862 backtrace_free (state, hdr->dirs, hdr->dirs_count * sizeof (const char *),
2865 hdr->filenames_count * sizeof (char *),
2867}
2868
2869/* Read the directories and file names for a line header for version
2870 2, setting fields in HDR. Return 1 on success, 0 on failure. */
2871
2872static int
2874 struct dwarf_buf *hdr_buf, struct line_header *hdr)
2875{
2876 const unsigned char *p;
2877 const unsigned char *pend;
2878 size_t i;
2879
2880 /* Count the number of directory entries. */
2881 hdr->dirs_count = 0;
2882 p = hdr_buf->buf;
2883 pend = p + hdr_buf->left;
2884 while (p < pend && *p != '\0')
2885 {
2886 p += strnlen((const char *) p, pend - p) + 1;
2887 ++hdr->dirs_count;
2888 }
2889
2890 /* The index of the first entry in the list of directories is 1. Index 0 is
2891 used for the current directory of the compilation. To simplify index
2892 handling, we set entry 0 to the compilation unit directory. */
2893 ++hdr->dirs_count;
2894 hdr->dirs = ((const char **)
2896 hdr->dirs_count * sizeof (const char *),
2897 hdr_buf->error_callback,
2898 hdr_buf->data));
2899 if (hdr->dirs == NULL)
2900 return 0;
2901
2902 hdr->dirs[0] = u->comp_dir;
2903 i = 1;
2904 while (*hdr_buf->buf != '\0')
2905 {
2906 if (hdr_buf->reported_underflow)
2907 return 0;
2908
2909 hdr->dirs[i] = read_string (hdr_buf);
2910 if (hdr->dirs[i] == NULL)
2911 return 0;
2912 ++i;
2913 }
2914 if (!advance (hdr_buf, 1))
2915 return 0;
2916
2917 /* Count the number of file entries. */
2918 hdr->filenames_count = 0;
2919 p = hdr_buf->buf;
2920 pend = p + hdr_buf->left;
2921 while (p < pend && *p != '\0')
2922 {
2923 p += strnlen ((const char *) p, pend - p) + 1;
2924 p += leb128_len (p);
2925 p += leb128_len (p);
2926 p += leb128_len (p);
2927 ++hdr->filenames_count;
2928 }
2929
2930 /* The index of the first entry in the list of file names is 1. Index 0 is
2931 used for the DW_AT_name of the compilation unit. To simplify index
2932 handling, we set entry 0 to the compilation unit file name. */
2933 ++hdr->filenames_count;
2934 hdr->filenames = ((const char **)
2936 hdr->filenames_count * sizeof (char *),
2937 hdr_buf->error_callback,
2938 hdr_buf->data));
2939 if (hdr->filenames == NULL)
2940 return 0;
2941 hdr->filenames[0] = u->filename;
2942 i = 1;
2943 while (*hdr_buf->buf != '\0')
2944 {
2945 const char *filename;
2946 uint64_t dir_index;
2947
2948 if (hdr_buf->reported_underflow)
2949 return 0;
2950
2951 filename = read_string (hdr_buf);
2952 if (filename == NULL)
2953 return 0;
2954 dir_index = read_uleb128 (hdr_buf);
2956 || (dir_index < hdr->dirs_count && hdr->dirs[dir_index] == NULL))
2957 hdr->filenames[i] = filename;
2958 else
2959 {
2960 const char *dir;
2961 size_t dir_len;
2962 size_t filename_len;
2963 char *s;
2964
2965 if (dir_index < hdr->dirs_count)
2966 dir = hdr->dirs[dir_index];
2967 else
2968 {
2969 dwarf_buf_error (hdr_buf,
2970 ("invalid directory index in "
2971 "line number program header"),
2972 0);
2973 return 0;
2974 }
2975 dir_len = strlen (dir);
2976 filename_len = strlen (filename);
2977 s = ((char *) backtrace_alloc (state, dir_len + filename_len + 2,
2978 hdr_buf->error_callback,
2979 hdr_buf->data));
2980 if (s == NULL)
2981 return 0;
2982 memcpy (s, dir, dir_len);
2983 /* FIXME: If we are on a DOS-based file system, and the
2984 directory or the file name use backslashes, then we
2985 should use a backslash here. */
2986 s[dir_len] = '/';
2987 memcpy (s + dir_len + 1, filename, filename_len + 1);
2988 hdr->filenames[i] = s;
2989 }
2990
2991 /* Ignore the modification time and size. */
2992 read_uleb128 (hdr_buf);
2993 read_uleb128 (hdr_buf);
2994
2995 ++i;
2996 }
2997
2998 return 1;
2999}
3000
3001/* Read a single version 5 LNCT entry for a directory or file name in a
3002 line header. Sets *STRING to the resulting name, ignoring other
3003 data. Return 1 on success, 0 on failure. */
3004
3005static int
3007 struct unit *u, struct dwarf_buf *hdr_buf,
3008 const struct line_header *hdr, size_t formats_count,
3009 const struct line_header_format *formats, const char **string)
3010{
3011 size_t i;
3012 const char *dir;
3013 const char *path;
3014
3015 dir = NULL;
3016 path = NULL;
3017 for (i = 0; i < formats_count; i++)
3018 {
3019 struct attr_val val;
3020
3021 if (!read_attribute (formats[i].form, 0, hdr_buf, u->is_dwarf64,
3022 u->version, hdr->addrsize, &ddata->dwarf_sections,
3023 ddata->altlink, &val))
3024 return 0;
3025 switch (formats[i].lnct)
3026 {
3027 case DW_LNCT_path:
3028 if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64,
3029 ddata->is_bigendian, u->str_offsets_base,
3030 &val, hdr_buf->error_callback, hdr_buf->data,
3031 &path))
3032 return 0;
3033 break;
3035 if (val.encoding == ATTR_VAL_UINT)
3036 {
3037 if (val.u.uint >= hdr->dirs_count)
3038 {
3039 dwarf_buf_error (hdr_buf,
3040 ("invalid directory index in "
3041 "line number program header"),
3042 0);
3043 return 0;
3044 }
3045 dir = hdr->dirs[val.u.uint];
3046 }
3047 break;
3048 default:
3049 /* We don't care about timestamps or sizes or hashes. */
3050 break;
3051 }
3052 }
3053
3054 if (path == NULL)
3055 {
3056 dwarf_buf_error (hdr_buf,
3057 "missing file name in line number program header",
3058 0);
3059 return 0;
3060 }
3061
3062 if (dir == NULL)
3063 *string = path;
3064 else
3065 {
3066 size_t dir_len;
3067 size_t path_len;
3068 char *s;
3069
3070 dir_len = strlen (dir);
3071 path_len = strlen (path);
3072 s = (char *) backtrace_alloc (state, dir_len + path_len + 2,
3073 hdr_buf->error_callback, hdr_buf->data);
3074 if (s == NULL)
3075 return 0;
3076 memcpy (s, dir, dir_len);
3077 /* FIXME: If we are on a DOS-based file system, and the
3078 directory or the path name use backslashes, then we should
3079 use a backslash here. */
3080 s[dir_len] = '/';
3081 memcpy (s + dir_len + 1, path, path_len + 1);
3082 *string = s;
3083 }
3084
3085 return 1;
3086}
3087
3088/* Read a set of DWARF 5 line header format entries, setting *PCOUNT
3089 and *PPATHS. Return 1 on success, 0 on failure. */
3090
3091static int
3093 struct dwarf_data *ddata,
3094 struct unit *u,
3095 struct dwarf_buf *hdr_buf,
3096 struct line_header *hdr,
3097 size_t *pcount,
3098 const char ***ppaths)
3099{
3100 size_t formats_count;
3101 struct line_header_format *formats;
3102 size_t paths_count;
3103 const char **paths;
3104 size_t i;
3105 int ret;
3106
3107 formats_count = read_byte (hdr_buf);
3108 if (formats_count == 0)
3109 formats = NULL;
3110 else
3111 {
3112 formats = ((struct line_header_format *)
3114 (formats_count
3115 * sizeof (struct line_header_format)),
3116 hdr_buf->error_callback,
3117 hdr_buf->data));
3118 if (formats == NULL)
3119 return 0;
3120
3121 for (i = 0; i < formats_count; i++)
3122 {
3123 formats[i].lnct = (int) read_uleb128(hdr_buf);
3124 formats[i].form = (enum dwarf_form) read_uleb128 (hdr_buf);
3125 }
3126 }
3127
3128 paths_count = read_uleb128 (hdr_buf);
3129 if (paths_count == 0)
3130 {
3131 *pcount = 0;
3132 *ppaths = NULL;
3133 ret = 1;
3134 goto exit;
3135 }
3136
3137 paths = ((const char **)
3138 backtrace_alloc (state, paths_count * sizeof (const char *),
3139 hdr_buf->error_callback, hdr_buf->data));
3140 if (paths == NULL)
3141 {
3142 ret = 0;
3143 goto exit;
3144 }
3145 for (i = 0; i < paths_count; i++)
3146 {
3147 if (!read_lnct (state, ddata, u, hdr_buf, hdr, formats_count,
3148 formats, &paths[i]))
3149 {
3150 backtrace_free (state, paths,
3151 paths_count * sizeof (const char *),
3152 hdr_buf->error_callback, hdr_buf->data);
3153 ret = 0;
3154 goto exit;
3155 }
3156 }
3157
3158 *pcount = paths_count;
3159 *ppaths = paths;
3160
3161 ret = 1;
3162
3163 exit:
3164 if (formats != NULL)
3165 backtrace_free (state, formats,
3166 formats_count * sizeof (struct line_header_format),
3167 hdr_buf->error_callback, hdr_buf->data);
3168
3169 return ret;
3170}
3171
3172/* Read the line header. Return 1 on success, 0 on failure. */
3173
3174static int
3176 struct unit *u, int is_dwarf64, struct dwarf_buf *line_buf,
3177 struct line_header *hdr)
3178{
3179 uint64_t hdrlen;
3180 struct dwarf_buf hdr_buf;
3181
3182 hdr->version = read_uint16 (line_buf);
3183 if (hdr->version < 2 || hdr->version > 5)
3184 {
3185 dwarf_buf_error (line_buf, "unsupported line number version", -1);
3186 return 0;
3187 }
3188
3189 if (hdr->version < 5)
3190 hdr->addrsize = u->addrsize;
3191 else
3192 {
3193 hdr->addrsize = read_byte (line_buf);
3194 /* We could support a non-zero segment_selector_size but I doubt
3195 we'll ever see it. */
3196 if (read_byte (line_buf) != 0)
3197 {
3198 dwarf_buf_error (line_buf,
3199 "non-zero segment_selector_size not supported",
3200 -1);
3201 return 0;
3202 }
3203 }
3204
3205 hdrlen = read_offset (line_buf, is_dwarf64);
3206
3207 hdr_buf = *line_buf;
3208 hdr_buf.left = hdrlen;
3209
3210 if (!advance (line_buf, hdrlen))
3211 return 0;
3212
3213 hdr->min_insn_len = read_byte (&hdr_buf);
3214 if (hdr->version < 4)
3215 hdr->max_ops_per_insn = 1;
3216 else
3217 hdr->max_ops_per_insn = read_byte (&hdr_buf);
3218
3219 /* We don't care about default_is_stmt. */
3220 read_byte (&hdr_buf);
3221
3222 hdr->line_base = read_sbyte (&hdr_buf);
3223 hdr->line_range = read_byte (&hdr_buf);
3224
3225 hdr->opcode_base = read_byte (&hdr_buf);
3226 hdr->opcode_lengths = hdr_buf.buf;
3227 if (!advance (&hdr_buf, hdr->opcode_base - 1))
3228 return 0;
3229
3230 if (hdr->version < 5)
3231 {
3232 if (!read_v2_paths (state, u, &hdr_buf, hdr))
3233 return 0;
3234 }
3235 else
3236 {
3237 if (!read_line_header_format_entries (state, ddata, u, &hdr_buf, hdr,
3238 &hdr->dirs_count,
3239 &hdr->dirs))
3240 return 0;
3241 if (!read_line_header_format_entries (state, ddata, u, &hdr_buf, hdr,
3242 &hdr->filenames_count,
3243 &hdr->filenames))
3244 return 0;
3245 }
3246
3247 if (hdr_buf.reported_underflow)
3248 return 0;
3249
3250 return 1;
3251}
3252
3253/* Read the line program, adding line mappings to VEC. Return 1 on
3254 success, 0 on failure. */
3255
3256static int
3258 const struct line_header *hdr, struct dwarf_buf *line_buf,
3259 struct line_vector *vec)
3260{
3261 uint64_t address;
3262 unsigned int op_index;
3263 const char *reset_filename;
3264 const char *filename;
3265 int lineno;
3266
3267 address = 0;
3268 op_index = 0;
3269 if (hdr->filenames_count > 1)
3270 reset_filename = hdr->filenames[1];
3271 else
3272 reset_filename = "";
3273 filename = reset_filename;
3274 lineno = 1;
3275 while (line_buf->left > 0)
3276 {
3277 unsigned int op;
3278
3279 op = read_byte (line_buf);
3280 if (op >= hdr->opcode_base)
3281 {
3282 unsigned int advance;
3283
3284 /* Special opcode. */
3285 op -= hdr->opcode_base;
3286 advance = op / hdr->line_range;
3287 address += (hdr->min_insn_len * (op_index + advance)
3288 / hdr->max_ops_per_insn);
3289 op_index = (op_index + advance) % hdr->max_ops_per_insn;
3290 lineno += hdr->line_base + (int) (op % hdr->line_range);
3291 add_line (state, ddata, address, filename, lineno,
3292 line_buf->error_callback, line_buf->data, vec);
3293 }
3294 else if (op == DW_LNS_extended_op)
3295 {
3296 uint64_t len;
3297
3298 len = read_uleb128 (line_buf);
3299 op = read_byte (line_buf);
3300 switch (op)
3301 {
3303 /* FIXME: Should we mark the high PC here? It seems
3304 that we already have that information from the
3305 compilation unit. */
3306 address = 0;
3307 op_index = 0;
3308 filename = reset_filename;
3309 lineno = 1;
3310 break;
3311 case DW_LNE_set_address:
3312 address = read_address (line_buf, hdr->addrsize);
3313 break;
3314 case DW_LNE_define_file:
3315 {
3316 const char *f;
3317 unsigned int dir_index;
3318
3319 f = read_string (line_buf);
3320 if (f == NULL)
3321 return 0;
3322 dir_index = read_uleb128 (line_buf);
3323 /* Ignore that time and length. */
3324 read_uleb128 (line_buf);
3325 read_uleb128 (line_buf);
3326 if (IS_ABSOLUTE_PATH (f))
3327 filename = f;
3328 else
3329 {
3330 const char *dir;
3331 size_t dir_len;
3332 size_t f_len;
3333 char *p;
3334
3335 if (dir_index < hdr->dirs_count)
3336 dir = hdr->dirs[dir_index];
3337 else
3338 {
3339 dwarf_buf_error (line_buf,
3340 ("invalid directory index "
3341 "in line number program"),
3342 0);
3343 return 0;
3344 }
3345 dir_len = strlen (dir);
3346 f_len = strlen (f);
3347 p = ((char *)
3348 backtrace_alloc (state, dir_len + f_len + 2,
3349 line_buf->error_callback,
3350 line_buf->data));
3351 if (p == NULL)
3352 return 0;
3353 memcpy (p, dir, dir_len);
3354 /* FIXME: If we are on a DOS-based file system,
3355 and the directory or the file name use
3356 backslashes, then we should use a backslash
3357 here. */
3358 p[dir_len] = '/';
3359 memcpy (p + dir_len + 1, f, f_len + 1);
3360 filename = p;
3361 }
3362 }
3363 break;
3365 /* We don't care about discriminators. */
3366 read_uleb128 (line_buf);
3367 break;
3368 default:
3369 if (!advance (line_buf, len - 1))
3370 return 0;
3371 break;
3372 }
3373 }
3374 else
3375 {
3376 switch (op)
3377 {
3378 case DW_LNS_copy:
3379 add_line (state, ddata, address, filename, lineno,
3380 line_buf->error_callback, line_buf->data, vec);
3381 break;
3382 case DW_LNS_advance_pc:
3383 {
3384 uint64_t advance;
3385
3386 advance = read_uleb128 (line_buf);
3387 address += (hdr->min_insn_len * (op_index + advance)
3388 / hdr->max_ops_per_insn);
3389 op_index = (op_index + advance) % hdr->max_ops_per_insn;
3390 }
3391 break;
3393 lineno += (int) read_sleb128 (line_buf);
3394 break;
3395 case DW_LNS_set_file:
3396 {
3397 uint64_t fileno;
3398
3399 fileno = read_uleb128 (line_buf);
3400 if (fileno >= hdr->filenames_count)
3401 {
3402 dwarf_buf_error (line_buf,
3403 ("invalid file number in "
3404 "line number program"),
3405 0);
3406 return 0;
3407 }
3408 filename = hdr->filenames[fileno];
3409 }
3410 break;
3411 case DW_LNS_set_column:
3412 read_uleb128 (line_buf);
3413 break;
3414 case DW_LNS_negate_stmt:
3415 break;
3417 break;
3419 {
3420 unsigned int advance;
3421
3422 op = 255 - hdr->opcode_base;
3423 advance = op / hdr->line_range;
3424 address += (hdr->min_insn_len * (op_index + advance)
3425 / hdr->max_ops_per_insn);
3426 op_index = (op_index + advance) % hdr->max_ops_per_insn;
3427 }
3428 break;
3430 address += read_uint16 (line_buf);
3431 op_index = 0;
3432 break;
3434 break;
3436 break;
3437 case DW_LNS_set_isa:
3438 read_uleb128 (line_buf);
3439 break;
3440 default:
3441 {
3442 unsigned int i;
3443
3444 for (i = hdr->opcode_lengths[op - 1]; i > 0; --i)
3445 read_uleb128 (line_buf);
3446 }
3447 break;
3448 }
3449 }
3450 }
3451
3452 return 1;
3453}
3454
3455/* Read the line number information for a compilation unit. Returns 1
3456 on success, 0 on failure. */
3457
3458static int
3461 struct unit *u, struct line_header *hdr, struct line **lines,
3462 size_t *lines_count)
3463{
3464 struct line_vector vec;
3465 struct dwarf_buf line_buf;
3466 uint64_t len;
3467 int is_dwarf64;
3468 struct line *ln;
3469
3470 memset (&vec.vec, 0, sizeof vec.vec);
3471 vec.count = 0;
3472
3473 memset (hdr, 0, sizeof *hdr);
3474
3475 if (u->lineoff != (off_t) (size_t) u->lineoff
3476 || (size_t) u->lineoff >= ddata->dwarf_sections.size[DEBUG_LINE])
3477 {
3478 error_callback (data, "unit line offset out of range", 0);
3479 goto fail;
3480 }
3481
3482 line_buf.name = ".debug_line";
3483 line_buf.start = ddata->dwarf_sections.data[DEBUG_LINE];
3484 line_buf.buf = ddata->dwarf_sections.data[DEBUG_LINE] + u->lineoff;
3485 line_buf.left = ddata->dwarf_sections.size[DEBUG_LINE] - u->lineoff;
3486 line_buf.is_bigendian = ddata->is_bigendian;
3487 line_buf.error_callback = error_callback;
3488 line_buf.data = data;
3489 line_buf.reported_underflow = 0;
3490
3491 len = read_initial_length (&line_buf, &is_dwarf64);
3492 line_buf.left = len;
3493
3494 if (!read_line_header (state, ddata, u, is_dwarf64, &line_buf, hdr))
3495 goto fail;
3496
3497 if (!read_line_program (state, ddata, hdr, &line_buf, &vec))
3498 goto fail;
3499
3500 if (line_buf.reported_underflow)
3501 goto fail;
3502
3503 if (vec.count == 0)
3504 {
3505 /* This is not a failure in the sense of generating an error,
3506 but it is a failure in that sense that we have no useful
3507 information. */
3508 goto fail;
3509 }
3510
3511 /* Allocate one extra entry at the end. */
3512 ln = ((struct line *)
3514 data, &vec.vec));
3515 if (ln == NULL)
3516 goto fail;
3517 ln->pc = (uintptr_t) -1;
3518 ln->filename = NULL;
3519 ln->lineno = 0;
3520 ln->idx = 0;
3521
3523 goto fail;
3524
3525 ln = (struct line *) vec.vec.base;
3526 backtrace_qsort (ln, vec.count, sizeof (struct line), line_compare);
3527
3528 *lines = ln;
3529 *lines_count = vec.count;
3530
3531 return 1;
3532
3533 fail:
3536 *lines = (struct line *) (uintptr_t) -1;
3537 *lines_count = 0;
3538 return 0;
3539}
3540
3541static const char *read_referenced_name (struct dwarf_data *, struct unit *,
3542 uint64_t, backtrace_error_callback,
3543 void *);
3544
3545/* Read the name of a function from a DIE referenced by ATTR with VAL. */
3546
3547static const char *
3549 struct attr *attr, struct attr_val *val,
3551 void *data)
3552{
3553 switch (attr->name)
3554 {
3557 break;
3558 default:
3559 return NULL;
3560 }
3561
3562 if (attr->form == DW_FORM_ref_sig8)
3563 return NULL;
3564
3565 if (val->encoding == ATTR_VAL_REF_INFO)
3566 {
3567 struct unit *unit
3568 = find_unit (ddata->units, ddata->units_count,
3569 val->u.uint);
3570 if (unit == NULL)
3571 return NULL;
3572
3573 uint64_t offset = val->u.uint - unit->low_offset;
3574 return read_referenced_name (ddata, unit, offset, error_callback, data);
3575 }
3576
3577 if (val->encoding == ATTR_VAL_UINT
3578 || val->encoding == ATTR_VAL_REF_UNIT)
3579 return read_referenced_name (ddata, u, val->u.uint, error_callback, data);
3580
3581 if (val->encoding == ATTR_VAL_REF_ALT_INFO)
3582 {
3583 struct unit *alt_unit
3584 = find_unit (ddata->altlink->units, ddata->altlink->units_count,
3585 val->u.uint);
3586 if (alt_unit == NULL)
3587 return NULL;
3588
3589 uint64_t offset = val->u.uint - alt_unit->low_offset;
3590 return read_referenced_name (ddata->altlink, alt_unit, offset,
3592 }
3593
3594 return NULL;
3595}
3596
3597/* Read the name of a function from a DIE referenced by a
3598 DW_AT_abstract_origin or DW_AT_specification tag. OFFSET is within
3599 the same compilation unit. */
3600
3601static const char *
3602read_referenced_name (struct dwarf_data *ddata, struct unit *u,
3604 void *data)
3605{
3606 struct dwarf_buf unit_buf;
3607 uint64_t code;
3608 const struct abbrev *abbrev;
3609 const char *ret;
3610 size_t i;
3611
3612 /* OFFSET is from the start of the data for this compilation unit.
3613 U->unit_data is the data, but it starts U->unit_data_offset bytes
3614 from the beginning. */
3615
3616 if (offset < u->unit_data_offset
3617 || offset - u->unit_data_offset >= u->unit_data_len)
3618 {
3620 "abstract origin or specification out of range",
3621 0);
3622 return NULL;
3623 }
3624
3625 offset -= u->unit_data_offset;
3626
3627 unit_buf.name = ".debug_info";
3628 unit_buf.start = ddata->dwarf_sections.data[DEBUG_INFO];
3629 unit_buf.buf = u->unit_data + offset;
3630 unit_buf.left = u->unit_data_len - offset;
3631 unit_buf.is_bigendian = ddata->is_bigendian;
3632 unit_buf.error_callback = error_callback;
3633 unit_buf.data = data;
3634 unit_buf.reported_underflow = 0;
3635
3636 code = read_uleb128 (&unit_buf);
3637 if (code == 0)
3638 {
3639 dwarf_buf_error (&unit_buf,
3640 "invalid abstract origin or specification",
3641 0);
3642 return NULL;
3643 }
3644
3646 if (abbrev == NULL)
3647 return NULL;
3648
3649 ret = NULL;
3650 for (i = 0; i < abbrev->num_attrs; ++i)
3651 {
3652 struct attr_val val;
3653
3655 &unit_buf, u->is_dwarf64, u->version, u->addrsize,
3656 &ddata->dwarf_sections, ddata->altlink, &val))
3657 return NULL;
3658
3659 switch (abbrev->attrs[i].name)
3660 {
3661 case DW_AT_name:
3662 /* Third name preference: don't override. A name we found in some
3663 other way, will normally be more useful -- e.g., this name is
3664 normally not mangled. */
3665 if (ret != NULL)
3666 break;
3667 if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64,
3668 ddata->is_bigendian, u->str_offsets_base,
3669 &val, error_callback, data, &ret))
3670 return NULL;
3671 break;
3672
3673 case DW_AT_linkage_name:
3675 /* First name preference: override all. */
3676 {
3677 const char *s;
3678
3679 s = NULL;
3680 if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64,
3681 ddata->is_bigendian, u->str_offsets_base,
3682 &val, error_callback, data, &s))
3683 return NULL;
3684 if (s != NULL)
3685 return s;
3686 }
3687 break;
3688
3690 /* Second name preference: override DW_AT_name, don't override
3691 DW_AT_linkage_name. */
3692 {
3693 const char *name;
3694
3696 &val, error_callback, data);
3697 if (name != NULL)
3698 ret = name;
3699 }
3700 break;
3701
3702 default:
3703 break;
3704 }
3705 }
3706
3707 return ret;
3708}
3709
3710/* Add a range to a unit that maps to a function. This is called via
3711 add_ranges. Returns 1 on success, 0 on error. */
3712
3713static int
3715 uintptr_t lowpc, uintptr_t highpc,
3717 void *pvec)
3718{
3719 struct function *function = (struct function *) rdata;
3720 struct function_vector *vec = (struct function_vector *) pvec;
3721 struct function_addrs *p;
3722
3723 if (vec->count > 0)
3724 {
3725 p = (struct function_addrs *) vec->vec.base + (vec->count - 1);
3726 if ((lowpc == p->high || lowpc == p->high + 1)
3727 && function == p->function)
3728 {
3729 if (highpc > p->high)
3730 p->high = highpc;
3731 return 1;
3732 }
3733 }
3734
3735 p = ((struct function_addrs *)
3736 backtrace_vector_grow (state, sizeof (struct function_addrs),
3737 error_callback, data, &vec->vec));
3738 if (p == NULL)
3739 return 0;
3740
3741 p->low = lowpc;
3742 p->high = highpc;
3743 p->function = function;
3744
3745 ++vec->count;
3746
3747 return 1;
3748}
3749
3750/* Read one entry plus all its children. Add function addresses to
3751 VEC. Returns 1 on success, 0 on error. */
3752
3753static int
3755 struct unit *u, uintptr_t base, struct dwarf_buf *unit_buf,
3756 const struct line_header *lhdr,
3758 struct function_vector *vec_function,
3759 struct function_vector *vec_inlined)
3760{
3761 while (unit_buf->left > 0)
3762 {
3763 uint64_t code;
3764 const struct abbrev *abbrev;
3765 int is_function;
3766 struct function *function;
3767 struct function_vector *vec;
3768 size_t i;
3769 struct pcrange pcrange;
3770 int have_linkage_name;
3771
3772 code = read_uleb128 (unit_buf);
3773 if (code == 0)
3774 return 1;
3775
3777 if (abbrev == NULL)
3778 return 0;
3779
3780 is_function = (abbrev->tag == DW_TAG_subprogram
3783
3785 vec = vec_inlined;
3786 else
3787 vec = vec_function;
3788
3789 function = NULL;
3790 if (is_function)
3791 {
3792 function = ((struct function *)
3793 backtrace_alloc (state, sizeof *function,
3795 if (function == NULL)
3796 return 0;
3797 memset (function, 0, sizeof *function);
3798 }
3799
3800 memset (&pcrange, 0, sizeof pcrange);
3801 have_linkage_name = 0;
3802 for (i = 0; i < abbrev->num_attrs; ++i)
3803 {
3804 struct attr_val val;
3805
3807 unit_buf, u->is_dwarf64, u->version,
3808 u->addrsize, &ddata->dwarf_sections,
3809 ddata->altlink, &val))
3810 return 0;
3811
3812 /* The compile unit sets the base address for any address
3813 ranges in the function entries. */
3816 && abbrev->attrs[i].name == DW_AT_low_pc)
3817 {
3818 if (val.encoding == ATTR_VAL_ADDRESS)
3819 base = (uintptr_t) val.u.uint;
3820 else if (val.encoding == ATTR_VAL_ADDRESS_INDEX)
3821 {
3822 if (!resolve_addr_index (&ddata->dwarf_sections,
3823 u->addr_base, u->addrsize,
3824 ddata->is_bigendian, val.u.uint,
3826 return 0;
3827 }
3828 }
3829
3830 if (is_function)
3831 {
3832 switch (abbrev->attrs[i].name)
3833 {
3834 case DW_AT_call_file:
3835 if (val.encoding == ATTR_VAL_UINT)
3836 {
3837 if (val.u.uint >= lhdr->filenames_count)
3838 {
3839 dwarf_buf_error (unit_buf,
3840 ("invalid file number in "
3841 "DW_AT_call_file attribute"),
3842 0);
3843 return 0;
3844 }
3845 function->caller_filename = lhdr->filenames[val.u.uint];
3846 }
3847 break;
3848
3849 case DW_AT_call_line:
3850 if (val.encoding == ATTR_VAL_UINT)
3851 function->caller_lineno = val.u.uint;
3852 break;
3853
3856 /* Second name preference: override DW_AT_name, don't override
3857 DW_AT_linkage_name. */
3858 if (have_linkage_name)
3859 break;
3860 {
3861 const char *name;
3862
3863 name
3865 &abbrev->attrs[i], &val,
3867 if (name != NULL)
3868 function->name = name;
3869 }
3870 break;
3871
3872 case DW_AT_name:
3873 /* Third name preference: don't override. */
3874 if (function->name != NULL)
3875 break;
3876 if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64,
3877 ddata->is_bigendian,
3878 u->str_offsets_base, &val,
3880 return 0;
3881 break;
3882
3883 case DW_AT_linkage_name:
3885 /* First name preference: override all. */
3886 {
3887 const char *s;
3888
3889 s = NULL;
3890 if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64,
3891 ddata->is_bigendian,
3892 u->str_offsets_base, &val,
3893 error_callback, data, &s))
3894 return 0;
3895 if (s != NULL)
3896 {
3897 function->name = s;
3898 have_linkage_name = 1;
3899 }
3900 }
3901 break;
3902
3903 case DW_AT_low_pc: case DW_AT_high_pc: case DW_AT_ranges:
3904 update_pcrange (&abbrev->attrs[i], &val, &pcrange);
3905 break;
3906
3907 default:
3908 break;
3909 }
3910 }
3911 }
3912
3913 /* If we couldn't find a name for the function, we have no use
3914 for it. */
3915 if (is_function && function->name == NULL)
3916 {
3919 is_function = 0;
3920 }
3921
3922 if (is_function)
3923 {
3926 {
3927 if (!add_ranges (state, &ddata->dwarf_sections,
3928 ddata->base_address, ddata->is_bigendian,
3930 (void *) function, error_callback, data,
3931 (void *) vec))
3932 return 0;
3933 }
3934 else
3935 {
3938 is_function = 0;
3939 }
3940 }
3941
3942 if (abbrev->has_children)
3943 {
3944 if (!is_function)
3945 {
3946 if (!read_function_entry (state, ddata, u, base, unit_buf, lhdr,
3947 error_callback, data, vec_function,
3948 vec_inlined))
3949 return 0;
3950 }
3951 else
3952 {
3953 struct function_vector fvec;
3954
3955 /* Gather any information for inlined functions in
3956 FVEC. */
3957
3958 memset (&fvec, 0, sizeof fvec);
3959
3960 if (!read_function_entry (state, ddata, u, base, unit_buf, lhdr,
3961 error_callback, data, vec_function,
3962 &fvec))
3963 return 0;
3964
3965 if (fvec.count > 0)
3966 {
3967 struct function_addrs *p;
3968 struct function_addrs *faddrs;
3969
3970 /* Allocate a trailing entry, but don't include it
3971 in fvec.count. */
3972 p = ((struct function_addrs *)
3974 sizeof (struct function_addrs),
3976 &fvec.vec));
3977 if (p == NULL)
3978 return 0;
3979 p->low = 0;
3980 --p->low;
3981 p->high = p->low;
3982 p->function = NULL;
3983
3984 if (!backtrace_vector_release (state, &fvec.vec,
3986 return 0;
3987
3988 faddrs = (struct function_addrs *) fvec.vec.base;
3989 backtrace_qsort (faddrs, fvec.count,
3990 sizeof (struct function_addrs),
3992
3993 function->function_addrs = faddrs;
3995 }
3996 }
3997 }
3998 }
3999
4000 return 1;
4001}
4002
4003/* Read function name information for a compilation unit. We look
4004 through the whole unit looking for function tags. */
4005
4006static void
4008 const struct line_header *lhdr,
4010 struct unit *u, struct function_vector *fvec,
4011 struct function_addrs **ret_addrs,
4012 size_t *ret_addrs_count)
4013{
4014 struct function_vector lvec;
4015 struct function_vector *pfvec;
4016 struct dwarf_buf unit_buf;
4017 struct function_addrs *p;
4018 struct function_addrs *addrs;
4019 size_t addrs_count;
4020
4021 /* Use FVEC if it is not NULL. Otherwise use our own vector. */
4022 if (fvec != NULL)
4023 pfvec = fvec;
4024 else
4025 {
4026 memset (&lvec, 0, sizeof lvec);
4027 pfvec = &lvec;
4028 }
4029
4030 unit_buf.name = ".debug_info";
4031 unit_buf.start = ddata->dwarf_sections.data[DEBUG_INFO];
4032 unit_buf.buf = u->unit_data;
4033 unit_buf.left = u->unit_data_len;
4034 unit_buf.is_bigendian = ddata->is_bigendian;
4035 unit_buf.error_callback = error_callback;
4036 unit_buf.data = data;
4037 unit_buf.reported_underflow = 0;
4038
4039 while (unit_buf.left > 0)
4040 {
4041 if (!read_function_entry (state, ddata, u, 0, &unit_buf, lhdr,
4042 error_callback, data, pfvec, pfvec))
4043 return;
4044 }
4045
4046 if (pfvec->count == 0)
4047 return;
4048
4049 /* Allocate a trailing entry, but don't include it in
4050 pfvec->count. */
4051 p = ((struct function_addrs *)
4052 backtrace_vector_grow (state, sizeof (struct function_addrs),
4053 error_callback, data, &pfvec->vec));
4054 if (p == NULL)
4055 return;
4056 p->low = 0;
4057 --p->low;
4058 p->high = p->low;
4059 p->function = NULL;
4060
4061 addrs_count = pfvec->count;
4062
4063 if (fvec == NULL)
4064 {
4066 return;
4067 addrs = (struct function_addrs *) pfvec->vec.base;
4068 }
4069 else
4070 {
4071 /* Finish this list of addresses, but leave the remaining space in
4072 the vector available for the next function unit. */
4073 addrs = ((struct function_addrs *)
4076 if (addrs == NULL)
4077 return;
4078 fvec->count = 0;
4079 }
4080
4081 backtrace_qsort (addrs, addrs_count, sizeof (struct function_addrs),
4083
4084 *ret_addrs = addrs;
4085 *ret_addrs_count = addrs_count;
4086}
4087
4088/* See if PC is inlined in FUNCTION. If it is, print out the inlined
4089 information, and update FILENAME and LINENO for the caller.
4090 Returns whatever CALLBACK returns, or 0 to keep going. */
4091
4092static int
4094 backtrace_full_callback callback, void *data,
4095 const char **filename, int *lineno)
4096{
4097 struct function_addrs *p;
4098 struct function_addrs *match;
4099 struct function *inlined;
4100 int ret;
4101
4103 return 0;
4104
4105 /* Our search isn't safe if pc == -1, as that is the sentinel
4106 value. */
4107 if (pc + 1 == 0)
4108 return 0;
4109
4110 p = ((struct function_addrs *)
4111 bsearch (&pc, function->function_addrs,
4113 sizeof (struct function_addrs),
4115 if (p == NULL)
4116 return 0;
4117
4118 /* Here pc >= p->low && pc < (p + 1)->low. The function_addrs are
4119 sorted by low, so if pc > p->low we are at the end of a range of
4120 function_addrs with the same low value. If pc == p->low walk
4121 forward to the end of the range with that low value. Then walk
4122 backward and use the first range that includes pc. */
4123 while (pc == (p + 1)->low)
4124 ++p;
4125 match = NULL;
4126 while (1)
4127 {
4128 if (pc < p->high)
4129 {
4130 match = p;
4131 break;
4132 }
4133 if (p == function->function_addrs)
4134 break;
4135 if ((p - 1)->low < p->low)
4136 break;
4137 --p;
4138 }
4139 if (match == NULL)
4140 return 0;
4141
4142 /* We found an inlined call. */
4143
4144 inlined = match->function;
4145
4146 /* Report any calls inlined into this one. */
4147 ret = report_inlined_functions (pc, inlined, callback, data,
4148 filename, lineno);
4149 if (ret != 0)
4150 return ret;
4151
4152 /* Report this inlined call. */
4153 ret = callback (data, pc, *filename, *lineno, inlined->name);
4154 if (ret != 0)
4155 return ret;
4156
4157 /* Our caller will report the caller of the inlined function; tell
4158 it the appropriate filename and line number. */
4159 *filename = inlined->caller_filename;
4160 *lineno = inlined->caller_lineno;
4161
4162 return 0;
4163}
4164
4165/* Look for a PC in the DWARF mapping for one module. On success,
4166 call CALLBACK and return whatever it returns. On error, call
4167 ERROR_CALLBACK and return 0. Sets *FOUND to 1 if the PC is found,
4168 0 if not. */
4169
4170static int
4172 uintptr_t pc, backtrace_full_callback callback,
4174 int *found)
4175{
4176 struct unit_addrs *entry;
4177 int found_entry;
4178 struct unit *u;
4179 int new_data;
4180 struct line *lines;
4181 struct line *ln;
4182 struct function_addrs *p;
4183 struct function_addrs *fmatch;
4184 struct function *function;
4185 const char *filename;
4186 int lineno;
4187 int ret;
4188
4189 *found = 1;
4190
4191 /* Find an address range that includes PC. Our search isn't safe if
4192 PC == -1, as we use that as a sentinel value, so skip the search
4193 in that case. */
4194 entry = (ddata->addrs_count == 0 || pc + 1 == 0
4195 ? NULL
4196 : bsearch (&pc, ddata->addrs, ddata->addrs_count,
4197 sizeof (struct unit_addrs), unit_addrs_search));
4198
4199 if (entry == NULL)
4200 {
4201 *found = 0;
4202 return 0;
4203 }
4204
4205 /* Here pc >= entry->low && pc < (entry + 1)->low. The unit_addrs
4206 are sorted by low, so if pc > p->low we are at the end of a range
4207 of unit_addrs with the same low value. If pc == p->low walk
4208 forward to the end of the range with that low value. Then walk
4209 backward and use the first range that includes pc. */
4210 while (pc == (entry + 1)->low)
4211 ++entry;
4212 found_entry = 0;
4213 while (1)
4214 {
4215 if (pc < entry->high)
4216 {
4217 found_entry = 1;
4218 break;
4219 }
4220 if (entry == ddata->addrs)
4221 break;
4222 if ((entry - 1)->low < entry->low)
4223 break;
4224 --entry;
4225 }
4226 if (!found_entry)
4227 {
4228 *found = 0;
4229 return 0;
4230 }
4231
4232 /* We need the lines, lines_count, function_addrs,
4233 function_addrs_count fields of u. If they are not set, we need
4234 to set them. When running in threaded mode, we need to allow for
4235 the possibility that some other thread is setting them
4236 simultaneously. */
4237
4238 u = entry->u;
4239 lines = u->lines;
4240
4241 /* Skip units with no useful line number information by walking
4242 backward. Useless line number information is marked by setting
4243 lines == -1. */
4244 while (entry > ddata->addrs
4245 && pc >= (entry - 1)->low
4246 && pc < (entry - 1)->high)
4247 {
4248 if (state->threaded)
4249 lines = (struct line *) backtrace_atomic_load_pointer (&u->lines);
4250
4251 if (lines != (struct line *) (uintptr_t) -1)
4252 break;
4253
4254 --entry;
4255
4256 u = entry->u;
4257 lines = u->lines;
4258 }
4259
4260 if (state->threaded)
4262
4263 new_data = 0;
4264 if (lines == NULL)
4265 {
4267 size_t function_addrs_count;
4268 struct line_header lhdr;
4269 size_t count;
4270
4271 /* We have never read the line information for this unit. Read
4272 it now. */
4273
4274 function_addrs = NULL;
4275 function_addrs_count = 0;
4276 if (read_line_info (state, ddata, error_callback, data, entry->u, &lhdr,
4277 &lines, &count))
4278 {
4279 struct function_vector *pfvec;
4280
4281 /* If not threaded, reuse DDATA->FVEC for better memory
4282 consumption. */
4283 if (state->threaded)
4284 pfvec = NULL;
4285 else
4286 pfvec = &ddata->fvec;
4288 entry->u, pfvec, &function_addrs,
4289 &function_addrs_count);
4291 new_data = 1;
4292 }
4293
4294 /* Atomically store the information we just read into the unit.
4295 If another thread is simultaneously writing, it presumably
4296 read the same information, and we don't care which one we
4297 wind up with; we just leak the other one. We do have to
4298 write the lines field last, so that the acquire-loads above
4299 ensure that the other fields are set. */
4300
4301 if (!state->threaded)
4302 {
4303 u->lines_count = count;
4305 u->function_addrs_count = function_addrs_count;
4306 u->lines = lines;
4307 }
4308 else
4309 {
4313 function_addrs_count);
4315 }
4316 }
4317
4318 /* Now all fields of U have been initialized. */
4319
4320 if (lines == (struct line *) (uintptr_t) -1)
4321 {
4322 /* If reading the line number information failed in some way,
4323 try again to see if there is a better compilation unit for
4324 this PC. */
4325 if (new_data)
4326 return dwarf_lookup_pc (state, ddata, pc, callback, error_callback,
4327 data, found);
4328 return callback (data, pc, NULL, 0, NULL);
4329 }
4330
4331 /* Search for PC within this unit. */
4332
4333 ln = (struct line *) bsearch (&pc, lines, entry->u->lines_count,
4334 sizeof (struct line), line_search);
4335 if (ln == NULL)
4336 {
4337 /* The PC is between the low_pc and high_pc attributes of the
4338 compilation unit, but no entry in the line table covers it.
4339 This implies that the start of the compilation unit has no
4340 line number information. */
4341
4342 if (entry->u->abs_filename == NULL)
4343 {
4344 const char *filename;
4345
4346 filename = entry->u->filename;
4347 if (filename != NULL
4349 && entry->u->comp_dir != NULL)
4350 {
4351 size_t filename_len;
4352 const char *dir;
4353 size_t dir_len;
4354 char *s;
4355
4356 filename_len = strlen (filename);
4357 dir = entry->u->comp_dir;
4358 dir_len = strlen (dir);
4359 s = (char *) backtrace_alloc (state, dir_len + filename_len + 2,
4361 if (s == NULL)
4362 {
4363 *found = 0;
4364 return 0;
4365 }
4366 memcpy (s, dir, dir_len);
4367 /* FIXME: Should use backslash if DOS file system. */
4368 s[dir_len] = '/';
4369 memcpy (s + dir_len + 1, filename, filename_len + 1);
4370 filename = s;
4371 }
4372 entry->u->abs_filename = filename;
4373 }
4374
4375 return callback (data, pc, entry->u->abs_filename, 0, NULL);
4376 }
4377
4378 /* Search for function name within this unit. */
4379
4380 if (entry->u->function_addrs_count == 0)
4381 return callback (data, pc, ln->filename, ln->lineno, NULL);
4382
4383 p = ((struct function_addrs *)
4384 bsearch (&pc, entry->u->function_addrs,
4385 entry->u->function_addrs_count,
4386 sizeof (struct function_addrs),
4388 if (p == NULL)
4389 return callback (data, pc, ln->filename, ln->lineno, NULL);
4390
4391 /* Here pc >= p->low && pc < (p + 1)->low. The function_addrs are
4392 sorted by low, so if pc > p->low we are at the end of a range of
4393 function_addrs with the same low value. If pc == p->low walk
4394 forward to the end of the range with that low value. Then walk
4395 backward and use the first range that includes pc. */
4396 while (pc == (p + 1)->low)
4397 ++p;
4398 fmatch = NULL;
4399 while (1)
4400 {
4401 if (pc < p->high)
4402 {
4403 fmatch = p;
4404 break;
4405 }
4406 if (p == entry->u->function_addrs)
4407 break;
4408 if ((p - 1)->low < p->low)
4409 break;
4410 --p;
4411 }
4412 if (fmatch == NULL)
4413 return callback (data, pc, ln->filename, ln->lineno, NULL);
4414
4415 function = fmatch->function;
4416
4417 filename = ln->filename;
4418 lineno = ln->lineno;
4419
4420 ret = report_inlined_functions (pc, function, callback, data,
4421 &filename, &lineno);
4422 if (ret != 0)
4423 return ret;
4424
4425 return callback (data, pc, filename, lineno, function->name);
4426}
4427
4428
4429/* Return the file/line information for a PC using the DWARF mapping
4430 we built earlier. */
4431
4432static int
4433dwarf_fileline (struct backtrace_state *state, uintptr_t pc,
4434 backtrace_full_callback callback,
4436{
4437 struct dwarf_data *ddata;
4438 int found;
4439 int ret;
4440
4441 if (!state->threaded)
4442 {
4443 for (ddata = (struct dwarf_data *) state->fileline_data;
4444 ddata != NULL;
4445 ddata = ddata->next)
4446 {
4447 ret = dwarf_lookup_pc (state, ddata, pc, callback, error_callback,
4448 data, &found);
4449 if (ret != 0 || found)
4450 return ret;
4451 }
4452 }
4453 else
4454 {
4455 struct dwarf_data **pp;
4456
4457 pp = (struct dwarf_data **) (void *) &state->fileline_data;
4458 while (1)
4459 {
4460 ddata = backtrace_atomic_load_pointer (pp);
4461 if (ddata == NULL)
4462 break;
4463
4464 ret = dwarf_lookup_pc (state, ddata, pc, callback, error_callback,
4465 data, &found);
4466 if (ret != 0 || found)
4467 return ret;
4468
4469 pp = &ddata->next;
4470 }
4471 }
4472
4473 /* FIXME: See if any libraries have been dlopen'ed. */
4474
4475 return callback (data, pc, NULL, 0, NULL);
4476}
4477
4478/* Initialize our data structures from the DWARF debug info for a
4479 file. Return NULL on failure. */
4480
4481static struct dwarf_data *
4484 const struct dwarf_sections *dwarf_sections,
4485 int is_bigendian,
4486 struct dwarf_data *altlink,
4488 void *data)
4489{
4490 struct unit_addrs_vector addrs_vec;
4491 struct unit_vector units_vec;
4492 struct dwarf_data *fdata;
4493
4495 altlink, error_callback, data, &addrs_vec,
4496 &units_vec))
4497 return NULL;
4498
4500 return NULL;
4502 return NULL;
4503
4504 backtrace_qsort ((struct unit_addrs *) addrs_vec.vec.base, addrs_vec.count,
4505 sizeof (struct unit_addrs), unit_addrs_compare);
4507 return NULL;
4508
4509 /* No qsort for units required, already sorted. */
4510
4511 fdata = ((struct dwarf_data *)
4512 backtrace_alloc (state, sizeof (struct dwarf_data),
4514 if (fdata == NULL)
4515 return NULL;
4516
4517 fdata->next = NULL;
4518 fdata->altlink = altlink;
4519 fdata->base_address = base_address;
4520 fdata->addrs = (struct unit_addrs *) addrs_vec.vec.base;
4521 fdata->addrs_count = addrs_vec.count;
4522 fdata->units = (struct unit **) units_vec.vec.base;
4523 fdata->units_count = units_vec.count;
4525 fdata->is_bigendian = is_bigendian;
4526 memset (&fdata->fvec, 0, sizeof fdata->fvec);
4527
4528 return fdata;
4529}
4530
4531/* Build our data structures from the DWARF sections for a module.
4532 Set FILELINE_FN and STATE->FILELINE_DATA. Return 1 on success, 0
4533 on failure. */
4534
4535int
4537 struct libbacktrace_base_address base_address,
4538 const struct dwarf_sections *dwarf_sections,
4539 int is_bigendian,
4540 struct dwarf_data *fileline_altlink,
4542 void *data, fileline *fileline_fn,
4543 struct dwarf_data **fileline_entry)
4544{
4545 struct dwarf_data *fdata;
4546
4548 fileline_altlink, error_callback, data);
4549 if (fdata == NULL)
4550 return 0;
4551
4552 if (fileline_entry != NULL)
4553 *fileline_entry = fdata;
4554
4555 if (!state->threaded)
4556 {
4557 struct dwarf_data **pp;
4558
4559 for (pp = (struct dwarf_data **) (void *) &state->fileline_data;
4560 *pp != NULL;
4561 pp = &(*pp)->next)
4562 ;
4563 *pp = fdata;
4564 }
4565 else
4566 {
4567 while (1)
4568 {
4569 struct dwarf_data **pp;
4570
4571 pp = (struct dwarf_data **) (void *) &state->fileline_data;
4572
4573 while (1)
4574 {
4575 struct dwarf_data *p;
4576
4578
4579 if (p == NULL)
4580 break;
4581
4582 pp = &p->next;
4583 }
4584
4585 if (__sync_bool_compare_and_swap (pp, NULL, fdata))
4586 break;
4587 }
4588 }
4589
4590 *fileline_fn = dwarf_fileline;
4591
4592 return 1;
4593}
log_entry msg
Definition acutest.h:794
void * backtrace_vector_grow(struct backtrace_state *state ATTRIBUTE_UNUSED, size_t size, backtrace_error_callback error_callback, void *data, struct backtrace_vector *vec)
Definition alloc.c:80
int backtrace_vector_release(struct backtrace_state *state ATTRIBUTE_UNUSED, struct backtrace_vector *vec, backtrace_error_callback error_callback, void *data)
Definition alloc.c:143
void * backtrace_alloc(struct backtrace_state *state ATTRIBUTE_UNUSED, size_t size, backtrace_error_callback error_callback, void *data)
Definition alloc.c:51
void backtrace_free(struct backtrace_state *state ATTRIBUTE_UNUSED, void *p, size_t size ATTRIBUTE_UNUSED, backtrace_error_callback error_callback ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED)
Definition alloc.c:69
void * backtrace_vector_finish(struct backtrace_state *state, struct backtrace_vector *vec, backtrace_error_callback error_callback, void *data)
Definition alloc.c:121
void(* backtrace_error_callback)(void *data, const char *msg, int errnum)
Definition backtrace.h:66
int(* backtrace_full_callback)(void *data, uintptr_t pc, const char *filename, int lineno, const char *function)
Definition backtrace.h:100
static void error_callback(void *data, const char *msg, int errnum)
Definition print.c:53
struct backtrace_vector vec
Definition dwarf.c:583
static int resolve_unit_addrs_overlap(struct backtrace_state *state, backtrace_error_callback error_callback, void *data, struct unit_addrs_vector *addrs_vec)
Definition dwarf.c:1748
size_t unit_data_len
Definition dwarf.c:635
enum dwarf_form form
Definition dwarf.c:554
int highpc_is_addr_index
Definition dwarf.c:2061
uintptr_t pc
Definition dwarf.c:565
static int resolve_string(const struct dwarf_sections *dwarf_sections, int is_dwarf64, int is_bigendian, uint64_t str_offsets_base, const struct attr_val *val, backtrace_error_callback error_callback, void *data, const char **string)
Definition dwarf.c:1372
static int add_function_range(struct backtrace_state *state, void *rdata, uintptr_t lowpc, uintptr_t highpc, backtrace_error_callback error_callback, void *data, void *pvec)
Definition dwarf.c:3714
const unsigned char * opcode_lengths
Definition dwarf.c:538
static int is_highest_address(uint64_t address, int addrsize)
Definition dwarf.c:938
static int read_v2_paths(struct backtrace_state *state, struct unit *u, struct dwarf_buf *hdr_buf, struct line_header *hdr)
Definition dwarf.c:2873
int64_t val
Definition dwarf.c:430
const unsigned char * start
Definition dwarf.c:406
size_t num_abbrevs
Definition dwarf.c:459
static uint64_t read_uleb128(struct dwarf_buf *buf)
Definition dwarf.c:958
static int require(struct dwarf_buf *buf, size_t count)
Definition dwarf.c:760
int have_highpc
Definition dwarf.c:2059
static int read_line_header_format_entries(struct backtrace_state *state, struct dwarf_data *ddata, struct unit *u, struct dwarf_buf *hdr_buf, struct line_header *hdr, size_t *pcount, const char ***ppaths)
Definition dwarf.c:3092
enum dwarf_tag tag
Definition dwarf.c:440
static size_t leb128_len(const unsigned char *p)
Definition dwarf.c:1031
union attr_val::@8 u
dwarf_line_number_op
Definition dwarf.c:325
@ DW_LNS_copy
Definition dwarf.c:327
@ DW_LNS_extended_op
Definition dwarf.c:326
@ DW_LNS_set_isa
Definition dwarf.c:338
@ DW_LNS_set_epilogue_begin
Definition dwarf.c:337
@ DW_LNS_set_basic_block
Definition dwarf.c:333
@ DW_LNS_const_add_pc
Definition dwarf.c:334
@ DW_LNS_fixed_advance_pc
Definition dwarf.c:335
@ DW_LNS_set_file
Definition dwarf.c:330
@ DW_LNS_advance_pc
Definition dwarf.c:328
@ DW_LNS_negate_stmt
Definition dwarf.c:332
@ DW_LNS_set_column
Definition dwarf.c:331
@ DW_LNS_advance_line
Definition dwarf.c:329
@ DW_LNS_set_prologue_end
Definition dwarf.c:336
struct unit * u
Definition dwarf.c:696
enum dwarf_form form
Definition dwarf.c:428
static struct unit * find_unit(struct unit **pu, size_t units_count, size_t offset)
Definition dwarf.c:1477
static const char * read_referenced_name(struct dwarf_data *, struct unit *, uint64_t, backtrace_error_callback, void *)
Definition dwarf.c:3602
uint64_t ranges
Definition dwarf.c:2062
unsigned int opcode_base
Definition dwarf.c:536
static int report_inlined_functions(uintptr_t pc, struct function *function, backtrace_full_callback callback, void *data, const char **filename, int *lineno)
Definition dwarf.c:4093
struct backtrace_vector vec
Definition dwarf.c:622
static int read_function_entry(struct backtrace_state *state, struct dwarf_data *ddata, struct unit *u, uintptr_t base, struct dwarf_buf *unit_buf, const struct line_header *lhdr, backtrace_error_callback error_callback, void *data, struct function_vector *vec_function, struct function_vector *vec_inlined)
Definition dwarf.c:3754
static size_t xstrnlen(const char *s, size_t maxlen)
Definition dwarf.c:385
size_t num_attrs
Definition dwarf.c:444
struct abbrev * abbrevs
Definition dwarf.c:461
static void update_pcrange(const struct attr *attr, const struct attr_val *val, struct pcrange *pcrange)
Definition dwarf.c:2070
backtrace_error_callback error_callback
Definition dwarf.c:414
uintptr_t high
Definition dwarf.c:694
static void free_line_header(struct backtrace_state *state, struct line_header *hdr, backtrace_error_callback error_callback, void *data)
Definition dwarf.c:2858
struct dwarf_sections dwarf_sections
Definition dwarf.c:736
static void read_function_info(struct backtrace_state *state, struct dwarf_data *ddata, const struct line_header *lhdr, backtrace_error_callback error_callback, void *data, struct unit *u, struct function_vector *fvec, struct function_addrs **ret_addrs, size_t *ret_addrs_count)
Definition dwarf.c:4007
struct attr * attrs
Definition dwarf.c:446
static int read_line_header(struct backtrace_state *state, struct dwarf_data *ddata, struct unit *u, int is_dwarf64, struct dwarf_buf *line_buf, struct line_header *hdr)
Definition dwarf.c:3175
size_t count
Definition dwarf.c:714
static int abbrev_compare(const void *v1, const void *v2)
Definition dwarf.c:1849
int backtrace_dwarf_add(struct backtrace_state *state, struct libbacktrace_base_address base_address, const struct dwarf_sections *dwarf_sections, int is_bigendian, struct dwarf_data *fileline_altlink, backtrace_error_callback error_callback, void *data, fileline *fileline_fn, struct dwarf_data **fileline_entry)
Definition dwarf.c:4536
int idx
Definition dwarf.c:574
static int function_addrs_search(const void *vkey, const void *ventry)
Definition dwarf.c:1511
const char ** filenames
Definition dwarf.c:546
uint64_t code
Definition dwarf.c:438
static int add_ranges_from_rnglists(struct backtrace_state *state, const struct dwarf_sections *dwarf_sections, struct libbacktrace_base_address base_address, int is_bigendian, struct unit *u, uintptr_t base, const struct pcrange *pcrange, int(*add_range)(struct backtrace_state *state, void *rdata, uintptr_t lowpc, uintptr_t highpc, backtrace_error_callback error_callback, void *data, void *vec), void *rdata, backtrace_error_callback error_callback, void *data, void *vec)
Definition dwarf.c:2250
static int build_address_map(struct backtrace_state *state, struct libbacktrace_base_address base_address, const struct dwarf_sections *dwarf_sections, int is_bigendian, struct dwarf_data *altlink, backtrace_error_callback error_callback, void *data, struct unit_addrs_vector *addrs, struct unit_vector *unit_vec)
Definition dwarf.c:2624
uintptr_t highpc
Definition dwarf.c:2058
int reported_underflow
Definition dwarf.c:418
int ranges_is_index
Definition dwarf.c:2064
static uint16_t read_uint16(struct dwarf_buf *buf)
Definition dwarf.c:833
int have_ranges
Definition dwarf.c:2063
int highpc_is_relative
Definition dwarf.c:2060
dwarf_form
Definition dwarf.c:55
@ DW_FORM_data2
Definition dwarf.c:59
@ DW_FORM_ref8
Definition dwarf.c:74
@ DW_FORM_indirect
Definition dwarf.c:76
@ DW_FORM_ref_addr
Definition dwarf.c:70
@ DW_FORM_data8
Definition dwarf.c:61
@ DW_FORM_string
Definition dwarf.c:62
@ DW_FORM_addrx3
Definition dwarf.c:97
@ DW_FORM_block1
Definition dwarf.c:64
@ DW_FORM_addrx2
Definition dwarf.c:96
@ DW_FORM_udata
Definition dwarf.c:69
@ DW_FORM_strx3
Definition dwarf.c:93
@ DW_FORM_addrx
Definition dwarf.c:82
@ DW_FORM_ref_sig8
Definition dwarf.c:80
@ DW_FORM_addr
Definition dwarf.c:56
@ DW_FORM_ref1
Definition dwarf.c:71
@ DW_FORM_addrx1
Definition dwarf.c:95
@ DW_FORM_block4
Definition dwarf.c:58
@ DW_FORM_rnglistx
Definition dwarf.c:89
@ DW_FORM_data16
Definition dwarf.c:85
@ DW_FORM_ref_sup4
Definition dwarf.c:83
@ DW_FORM_strx1
Definition dwarf.c:91
@ DW_FORM_data4
Definition dwarf.c:60
@ DW_FORM_ref_udata
Definition dwarf.c:75
@ DW_FORM_loclistx
Definition dwarf.c:88
@ DW_FORM_ref_sup8
Definition dwarf.c:90
@ DW_FORM_strx2
Definition dwarf.c:92
@ DW_FORM_strp_sup
Definition dwarf.c:84
@ DW_FORM_GNU_addr_index
Definition dwarf.c:99
@ DW_FORM_GNU_ref_alt
Definition dwarf.c:101
@ DW_FORM_exprloc
Definition dwarf.c:78
@ DW_FORM_addrx4
Definition dwarf.c:98
@ DW_FORM_flag_present
Definition dwarf.c:79
@ DW_FORM_implicit_const
Definition dwarf.c:87
@ DW_FORM_line_strp
Definition dwarf.c:86
@ DW_FORM_GNU_strp_alt
Definition dwarf.c:102
@ DW_FORM_sec_offset
Definition dwarf.c:77
@ DW_FORM_strp
Definition dwarf.c:68
@ DW_FORM_ref2
Definition dwarf.c:72
@ DW_FORM_block
Definition dwarf.c:63
@ DW_FORM_strx
Definition dwarf.c:81
@ DW_FORM_data1
Definition dwarf.c:65
@ DW_FORM_ref4
Definition dwarf.c:73
@ DW_FORM_sdata
Definition dwarf.c:67
@ DW_FORM_block2
Definition dwarf.c:57
@ DW_FORM_GNU_str_index
Definition dwarf.c:100
@ DW_FORM_strx4
Definition dwarf.c:94
@ DW_FORM_flag
Definition dwarf.c:66
uintptr_t high
Definition dwarf.c:612
int version
Definition dwarf.c:646
struct abbrevs abbrevs
Definition dwarf.c:666
static int find_address_ranges(struct backtrace_state *state, struct libbacktrace_base_address base_address, struct dwarf_buf *unit_buf, const struct dwarf_sections *dwarf_sections, int is_bigendian, struct dwarf_data *altlink, backtrace_error_callback error_callback, void *data, struct unit *u, struct unit_addrs_vector *addrs, enum dwarf_tag *unit_tag)
Definition dwarf.c:2468
const char * caller_filename
Definition dwarf.c:596
int is_dwarf64
Definition dwarf.c:648
#define strnlen
Definition dwarf.c:395
static int add_ranges_from_ranges(struct backtrace_state *state, const struct dwarf_sections *dwarf_sections, struct libbacktrace_base_address base_address, int is_bigendian, struct unit *u, uintptr_t base, const struct pcrange *pcrange, int(*add_range)(struct backtrace_state *state, void *rdata, uintptr_t lowpc, uintptr_t highpc, backtrace_error_callback error_callback, void *data, void *vec), void *rdata, backtrace_error_callback error_callback, void *data, void *vec)
Definition dwarf.c:2182
int is_bigendian
Definition dwarf.c:738
int addrsize
Definition dwarf.c:650
enum attr_val_encoding encoding
Definition dwarf.c:506
const char * filename
Definition dwarf.c:660
size_t count
Definition dwarf.c:624
const char * abs_filename
Definition dwarf.c:664
size_t function_addrs_count
Definition dwarf.c:681
static const char * read_referenced_name_from_attr(struct dwarf_data *ddata, struct unit *u, struct attr *attr, struct attr_val *val, backtrace_error_callback error_callback, void *data)
Definition dwarf.c:3548
struct unit ** units
Definition dwarf.c:732
static int read_abbrevs(struct backtrace_state *state, uint64_t abbrev_offset, const unsigned char *dwarf_abbrev, size_t dwarf_abbrev_size, int is_bigendian, backtrace_error_callback error_callback, void *data, struct abbrevs *abbrevs)
Definition dwarf.c:1871
static int dwarf_fileline(struct backtrace_state *state, uintptr_t pc, backtrace_full_callback callback, backtrace_error_callback error_callback, void *data)
Definition dwarf.c:4433
uint64_t rnglists_base
Definition dwarf.c:658
size_t count
Definition dwarf.c:585
const unsigned char * unit_data
Definition dwarf.c:633
const char * name
Definition dwarf.c:404
static int unit_addrs_search(const void *vkey, const void *ventry)
Definition dwarf.c:1598
uintptr_t lowpc
Definition dwarf.c:2055
int lineno
Definition dwarf.c:570
static int unit_addrs_compare(const void *v1, const void *v2)
Definition dwarf.c:1571
size_t addrs_count
Definition dwarf.c:730
struct function_vector fvec
Definition dwarf.c:741
struct function_addrs * function_addrs
Definition dwarf.c:680
int has_children
Definition dwarf.c:442
size_t lines_count
Definition dwarf.c:678
struct unit_addrs * addrs
Definition dwarf.c:728
const unsigned char * buf
Definition dwarf.c:408
const char ** dirs
Definition dwarf.c:542
uint64_t addr_base
Definition dwarf.c:656
static void dwarf_buf_error(struct dwarf_buf *buf, const char *msg, int errnum)
Definition dwarf.c:747
dwarf_extended_line_number_op
Definition dwarf.c:341
@ DW_LNE_set_address
Definition dwarf.c:343
@ DW_LNE_end_sequence
Definition dwarf.c:342
@ DW_LNE_set_discriminator
Definition dwarf.c:345
@ DW_LNE_define_file
Definition dwarf.c:344
static int64_t read_sleb128(struct dwarf_buf *buf)
Definition dwarf.c:993
int line_base
Definition dwarf.c:532
static int read_lnct(struct backtrace_state *state, struct dwarf_data *ddata, struct unit *u, struct dwarf_buf *hdr_buf, const struct line_header *hdr, size_t formats_count, const struct line_header_format *formats, const char **string)
Definition dwarf.c:3006
static int add_unit_addr(struct backtrace_state *state, void *rdata, uintptr_t lowpc, uintptr_t highpc, backtrace_error_callback error_callback, void *data, void *pvec)
Definition dwarf.c:1530
unsigned int max_ops_per_insn
Definition dwarf.c:530
int version
Definition dwarf.c:524
static uint64_t read_address(struct dwarf_buf *buf, int addrsize)
Definition dwarf.c:916
const char * filename
Definition dwarf.c:568
size_t dirs_count
Definition dwarf.c:540
static uint64_t read_offset(struct dwarf_buf *buf, int is_dwarf64)
Definition dwarf.c:904
static int resolve_unit_addrs_overlap_walk(struct backtrace_state *state, size_t *pfrom, size_t *pto, struct unit_addrs *enclosing, struct unit_addrs_vector *old_vec, backtrace_error_callback error_callback, void *data, struct unit_addrs_vector *new_vec)
Definition dwarf.c:1617
void * data
Definition dwarf.c:416
int addrsize
Definition dwarf.c:526
static struct dwarf_data * build_dwarf_data(struct backtrace_state *state, struct libbacktrace_base_address base_address, const struct dwarf_sections *dwarf_sections, int is_bigendian, struct dwarf_data *altlink, backtrace_error_callback error_callback, void *data)
Definition dwarf.c:4482
static int function_addrs_compare(const void *v1, const void *v2)
Definition dwarf.c:1488
static int line_compare(const void *v1, const void *v2)
Definition dwarf.c:1807
enum dwarf_attribute name
Definition dwarf.c:426
size_t left
Definition dwarf.c:410
struct dwarf_data * next
Definition dwarf.c:722
static int dwarf_lookup_pc(struct backtrace_state *state, struct dwarf_data *ddata, uintptr_t pc, backtrace_full_callback callback, backtrace_error_callback error_callback, void *data, int *found)
Definition dwarf.c:4171
int is_bigendian
Definition dwarf.c:412
attr_val_encoding
Definition dwarf.c:467
@ ATTR_VAL_UINT
Definition dwarf.c:476
@ ATTR_VAL_REF_INFO
Definition dwarf.c:486
@ ATTR_VAL_ADDRESS
Definition dwarf.c:471
@ ATTR_VAL_STRING
Definition dwarf.c:480
@ ATTR_VAL_REF_TYPE
Definition dwarf.c:492
@ ATTR_VAL_EXPR
Definition dwarf.c:498
@ ATTR_VAL_REF_ALT_INFO
Definition dwarf.c:488
@ ATTR_VAL_REF_UNIT
Definition dwarf.c:484
@ ATTR_VAL_STRING_INDEX
Definition dwarf.c:482
@ ATTR_VAL_REF_SECTION
Definition dwarf.c:490
@ ATTR_VAL_ADDRESS_INDEX
Definition dwarf.c:474
@ ATTR_VAL_BLOCK
Definition dwarf.c:496
@ ATTR_VAL_NONE
Definition dwarf.c:469
@ ATTR_VAL_RNGLISTS_INDEX
Definition dwarf.c:494
@ ATTR_VAL_SINT
Definition dwarf.c:478
static const char * read_string(struct dwarf_buf *buf)
Definition dwarf.c:790
struct dwarf_data * altlink
Definition dwarf.c:724
dwarf_line_number_content_type
Definition dwarf.c:348
@ DW_LNCT_path
Definition dwarf.c:349
@ DW_LNCT_hi_user
Definition dwarf.c:355
@ DW_LNCT_MD5
Definition dwarf.c:353
@ DW_LNCT_timestamp
Definition dwarf.c:351
@ DW_LNCT_lo_user
Definition dwarf.c:354
@ DW_LNCT_directory_index
Definition dwarf.c:350
@ DW_LNCT_size
Definition dwarf.c:352
unsigned int line_range
Definition dwarf.c:534
static unsigned char read_byte(struct dwarf_buf *buf)
Definition dwarf.c:809
dwarf_tag
Definition dwarf.c:47
@ DW_TAG_subprogram
Definition dwarf.c:51
@ DW_TAG_skeleton_unit
Definition dwarf.c:52
@ DW_TAG_entry_point
Definition dwarf.c:48
@ DW_TAG_compile_unit
Definition dwarf.c:49
@ DW_TAG_inlined_subroutine
Definition dwarf.c:50
uint64_t str_offsets_base
Definition dwarf.c:654
struct function_addrs * function_addrs
Definition dwarf.c:601
uintptr_t low
Definition dwarf.c:693
int have_lowpc
Definition dwarf.c:2056
size_t filenames_count
Definition dwarf.c:544
static void free_abbrevs(struct backtrace_state *state, struct abbrevs *abbrevs, backtrace_error_callback error_callback, void *data)
Definition dwarf.c:1066
static const struct abbrev * lookup_abbrev(struct abbrevs *abbrevs, uint64_t code, backtrace_error_callback error_callback, void *data)
Definition dwarf.c:2023
const char * comp_dir
Definition dwarf.c:662
dwarf_unit_type
Definition dwarf.c:369
@ DW_UT_compile
Definition dwarf.c:370
@ DW_UT_partial
Definition dwarf.c:372
@ DW_UT_split_compile
Definition dwarf.c:374
@ DW_UT_skeleton
Definition dwarf.c:373
@ DW_UT_hi_user
Definition dwarf.c:377
@ DW_UT_lo_user
Definition dwarf.c:376
@ DW_UT_type
Definition dwarf.c:371
@ DW_UT_split_type
Definition dwarf.c:375
struct libbacktrace_base_address base_address
Definition dwarf.c:726
static uint64_t read_initial_length(struct dwarf_buf *buf, int *is_dwarf64)
Definition dwarf.c:1047
static int read_line_program(struct backtrace_state *state, struct dwarf_data *ddata, const struct line_header *hdr, struct dwarf_buf *line_buf, struct line_vector *vec)
Definition dwarf.c:3257
struct backtrace_vector vec
Definition dwarf.c:713
static uint32_t read_uint24(struct dwarf_buf *buf)
Definition dwarf.c:848
static int add_ranges(struct backtrace_state *state, const struct dwarf_sections *dwarf_sections, struct libbacktrace_base_address base_address, int is_bigendian, struct unit *u, uintptr_t base, const struct pcrange *pcrange, int(*add_range)(struct backtrace_state *state, void *rdata, uintptr_t lowpc, uintptr_t highpc, backtrace_error_callback error_callback, void *data, void *vec), void *rdata, backtrace_error_callback error_callback, void *data, void *vec)
Definition dwarf.c:2430
struct function * function
Definition dwarf.c:614
static int line_search(const void *vkey, const void *ventry)
Definition dwarf.c:1830
dwarf_range_list_entry
Definition dwarf.c:358
@ DW_RLE_offset_pair
Definition dwarf.c:363
@ DW_RLE_base_address
Definition dwarf.c:364
@ DW_RLE_end_of_list
Definition dwarf.c:359
@ DW_RLE_base_addressx
Definition dwarf.c:360
@ DW_RLE_start_end
Definition dwarf.c:365
@ DW_RLE_start_length
Definition dwarf.c:366
@ DW_RLE_startx_endx
Definition dwarf.c:361
@ DW_RLE_startx_length
Definition dwarf.c:362
const char * name
Definition dwarf.c:593
static uint64_t read_uint64(struct dwarf_buf *buf)
Definition dwarf.c:882
static int read_attribute(enum dwarf_form form, uint64_t implicit_val, struct dwarf_buf *buf, int is_dwarf64, int version, int addrsize, const struct dwarf_sections *dwarf_sections, struct dwarf_data *altlink, struct attr_val *val)
Definition dwarf.c:1088
static int read_line_info(struct backtrace_state *state, struct dwarf_data *ddata, backtrace_error_callback error_callback, void *data, struct unit *u, struct line_header *hdr, struct line **lines, size_t *lines_count)
Definition dwarf.c:3459
struct backtrace_vector vec
Definition dwarf.c:704
int lowpc_is_addr_index
Definition dwarf.c:2057
static int advance(struct dwarf_buf *buf, size_t count)
Definition dwarf.c:778
int caller_lineno
Definition dwarf.c:599
size_t unit_data_offset
Definition dwarf.c:638
size_t function_addrs_count
Definition dwarf.c:602
static int resolve_addr_index(const struct dwarf_sections *dwarf_sections, uint64_t addr_base, int addrsize, int is_bigendian, uint64_t addr_index, backtrace_error_callback error_callback, void *data, uintptr_t *address)
Definition dwarf.c:1427
size_t units_count
Definition dwarf.c:734
struct line * lines
Definition dwarf.c:676
static int add_line(struct backtrace_state *state, struct dwarf_data *ddata, uintptr_t pc, const char *filename, int lineno, backtrace_error_callback error_callback, void *data, struct line_vector *vec)
Definition dwarf.c:2820
static signed char read_sbyte(struct dwarf_buf *buf)
Definition dwarf.c:821
size_t low_offset
Definition dwarf.c:641
static int add_low_high_range(struct backtrace_state *state, const struct dwarf_sections *dwarf_sections, struct libbacktrace_base_address base_address, int is_bigendian, struct unit *u, const struct pcrange *pcrange, int(*add_range)(struct backtrace_state *state, void *rdata, uintptr_t lowpc, uintptr_t highpc, backtrace_error_callback error_callback, void *data, void *vec), void *rdata, backtrace_error_callback error_callback, void *data, void *vec)
Definition dwarf.c:2133
static uint32_t read_uint32(struct dwarf_buf *buf)
Definition dwarf.c:865
uintptr_t low
Definition dwarf.c:611
dwarf_attribute
Definition dwarf.c:105
@ DW_AT_string_length_byte_size
Definition dwarf.c:202
@ DW_AT_GNU_template_name
Definition dwarf.c:280
@ DW_AT_HP_cold_region_low_pc
Definition dwarf.c:254
@ DW_AT_allocated
Definition dwarf.c:168
@ DW_AT_body_begin
Definition dwarf.c:269
@ DW_AT_loclists_base
Definition dwarf.c:229
@ DW_AT_GNU_pt_guarded_by
Definition dwarf.c:273
@ DW_AT_APPLE_property_name
Definition dwarf.c:317
@ DW_AT_prototyped
Definition dwarf.c:134
@ DW_AT_PGI_lstride
Definition dwarf.c:309
@ DW_AT_string_length_bit_size
Definition dwarf.c:201
@ DW_AT_signature
Definition dwarf.c:195
@ DW_AT_type
Definition dwarf.c:163
@ DW_AT_object_pointer
Definition dwarf.c:190
@ DW_AT_segment
Definition dwarf.c:160
@ DW_AT_APPLE_optimized
Definition dwarf.c:310
@ DW_AT_GNU_pt_guarded
Definition dwarf.c:275
@ DW_AT_HP_unmodifiable
Definition dwarf.c:244
@ DW_AT_GNU_odr_signature
Definition dwarf.c:279
@ DW_AT_HP_prologue
Definition dwarf.c:245
@ DW_AT_call_target_clobbered
Definition dwarf.c:221
@ DW_AT_body_end
Definition dwarf.c:270
@ DW_AT_GNU_bias
Definition dwarf.c:305
@ DW_AT_GNU_exclusive_locks_required
Definition dwarf.c:277
@ DW_AT_byte_stride
Definition dwarf.c:171
@ DW_AT_bit_size
Definition dwarf.c:113
@ DW_AT_const_value
Definition dwarf.c:127
@ DW_AT_GNU_dwo_id
Definition dwarf.c:292
@ DW_AT_call_value
Definition dwarf.c:215
@ DW_AT_GNU_addr_base
Definition dwarf.c:294
@ DW_AT_MIPS_loop_begin
Definition dwarf.c:233
@ DW_AT_GNU_call_site_target_clobbered
Definition dwarf.c:284
@ DW_AT_linkage_name
Definition dwarf.c:200
@ DW_AT_extension
Definition dwarf.c:174
@ DW_AT_rnglists_base
Definition dwarf.c:206
@ DW_AT_GNU_all_source_call_sites
Definition dwarf.c:288
@ DW_AT_enum_class
Definition dwarf.c:199
@ DW_AT_PGI_soffset
Definition dwarf.c:308
@ DW_AT_decimal_sign
Definition dwarf.c:184
@ DW_AT_description
Definition dwarf.c:180
@ DW_AT_HP_unit_name
Definition dwarf.c:259
@ DW_AT_GNU_call_site_data_value
Definition dwarf.c:282
@ DW_AT_endianity
Definition dwarf.c:191
@ DW_AT_sibling
Definition dwarf.c:106
@ DW_AT_MIPS_tail_loop_begin
Definition dwarf.c:234
@ DW_AT_high_pc
Definition dwarf.c:117
@ DW_AT_inline
Definition dwarf.c:130
@ DW_AT_MIPS_stride
Definition dwarf.c:239
@ DW_AT_call_column
Definition dwarf.c:177
@ DW_AT_call_all_tail_calls
Definition dwarf.c:213
@ DW_AT_addr_base
Definition dwarf.c:205
@ DW_AT_PGI_lbase
Definition dwarf.c:307
@ DW_AT_MIPS_has_inlines
Definition dwarf.c:242
@ DW_AT_GNU_pubnames
Definition dwarf.c:295
@ DW_AT_HP_opt_flags
Definition dwarf.c:253
@ DW_AT_call_return_pc
Definition dwarf.c:214
@ DW_AT_entry_pc
Definition dwarf.c:172
@ DW_AT_GNU_call_site_target
Definition dwarf.c:283
@ DW_AT_trampoline
Definition dwarf.c:176
@ DW_AT_low_pc
Definition dwarf.c:116
@ DW_AT_GNU_all_tail_call_sites
Definition dwarf.c:286
@ DW_AT_GNU_shared_locks_required
Definition dwarf.c:278
@ DW_AT_GNU_denominator
Definition dwarf.c:304
@ DW_AT_mutable
Definition dwarf.c:187
@ DW_AT_count
Definition dwarf.c:145
@ DW_AT_APPLE_major_runtime_vers
Definition dwarf.c:314
@ DW_AT_data_bit_offset
Definition dwarf.c:197
@ DW_AT_bit_stride
Definition dwarf.c:137
@ DW_AT_APPLE_block
Definition dwarf.c:313
@ DW_AT_containing_type
Definition dwarf.c:128
@ DW_AT_ordering
Definition dwarf.c:109
@ DW_AT_decl_file
Definition dwarf.c:148
@ DW_AT_HP_definition_points
Definition dwarf.c:262
@ DW_AT_byte_size
Definition dwarf.c:111
@ DW_AT_member
Definition dwarf.c:119
@ DW_AT_call_all_calls
Definition dwarf.c:211
@ DW_AT_abstract_origin
Definition dwarf.c:139
@ DW_AT_associated
Definition dwarf.c:169
@ DW_AT_call_parameter
Definition dwarf.c:217
@ DW_AT_explicit
Definition dwarf.c:189
@ DW_AT_GNU_vector
Definition dwarf.c:271
@ DW_AT_producer
Definition dwarf.c:133
@ DW_AT_element_list
Definition dwarf.c:114
@ DW_AT_GNU_tail_call
Definition dwarf.c:285
@ DW_AT_GNU_dwo_name
Definition dwarf.c:291
@ DW_AT_HP_opt_level
Definition dwarf.c:251
@ DW_AT_str_offsets_base
Definition dwarf.c:204
@ DW_AT_bit_offset
Definition dwarf.c:112
@ DW_AT_base_types
Definition dwarf.c:143
@ DW_AT_name
Definition dwarf.c:108
@ DW_AT_HP_actuals_stmt_list
Definition dwarf.c:247
@ DW_AT_discr_value
Definition dwarf.c:121
@ DW_AT_export_symbols
Definition dwarf.c:226
@ DW_AT_call_file
Definition dwarf.c:178
@ DW_AT_defaulted
Definition dwarf.c:228
@ DW_AT_sf_names
Definition dwarf.c:265
@ DW_AT_encoding
Definition dwarf.c:152
@ DW_AT_noreturn
Definition dwarf.c:224
@ DW_AT_GNU_all_call_sites
Definition dwarf.c:287
@ DW_AT_APPLE_objc_complete_type
Definition dwarf.c:321
@ DW_AT_comp_dir
Definition dwarf.c:126
@ DW_AT_HP_raw_data_ptr
Definition dwarf.c:249
@ DW_AT_upc_threads_scaled
Definition dwarf.c:306
@ DW_AT_elemental
Definition dwarf.c:192
@ DW_AT_use_location
Definition dwarf.c:164
@ DW_AT_call_line
Definition dwarf.c:179
@ DW_AT_virtuality
Definition dwarf.c:166
@ DW_AT_visibility
Definition dwarf.c:122
@ DW_AT_calling_convention
Definition dwarf.c:144
@ DW_AT_MIPS_fde
Definition dwarf.c:232
@ DW_AT_HP_default_location
Definition dwarf.c:263
@ DW_AT_const_expr
Definition dwarf.c:198
@ DW_AT_dwo_name
Definition dwarf.c:207
@ DW_AT_default_value
Definition dwarf.c:129
@ DW_AT_HP_prof_flags
Definition dwarf.c:258
@ DW_AT_call_tail_call
Definition dwarf.c:219
@ DW_AT_GNU_entry_view
Definition dwarf.c:299
@ DW_AT_HP_is_result_param
Definition dwarf.c:264
@ DW_AT_data_member_location
Definition dwarf.c:146
@ DW_AT_HP_pass_by_reference
Definition dwarf.c:250
@ DW_AT_language
Definition dwarf.c:118
@ DW_AT_MIPS_loop_unroll_factor
Definition dwarf.c:236
@ DW_AT_friend
Definition dwarf.c:155
@ DW_AT_frame_base
Definition dwarf.c:154
@ DW_AT_HP_epilogue
Definition dwarf.c:246
@ DW_AT_HP_widened_byte_size
Definition dwarf.c:261
@ DW_AT_GNU_locks_excluded
Definition dwarf.c:276
@ DW_AT_HP_block_index
Definition dwarf.c:243
@ DW_AT_HP_linkage_name
Definition dwarf.c:257
@ DW_AT_digit_count
Definition dwarf.c:185
@ DW_AT_GNU_locviews
Definition dwarf.c:298
@ DW_AT_MIPS_epilog_begin
Definition dwarf.c:235
@ DW_AT_macros
Definition dwarf.c:210
@ DW_AT_APPLE_property_setter
Definition dwarf.c:319
@ DW_AT_accessibility
Definition dwarf.c:140
@ DW_AT_GNU_guarded
Definition dwarf.c:274
@ DW_AT_APPLE_property
Definition dwarf.c:322
@ DW_AT_GNU_pubtypes
Definition dwarf.c:296
@ DW_AT_HP_all_variables_modifiable
Definition dwarf.c:256
@ DW_AT_small
Definition dwarf.c:183
@ DW_AT_GNU_guarded_by
Definition dwarf.c:272
@ DW_AT_APPLE_flags
Definition dwarf.c:311
@ DW_AT_string_length
Definition dwarf.c:124
@ DW_AT_lo_user
Definition dwarf.c:230
@ DW_AT_GNU_call_site_value
Definition dwarf.c:281
@ DW_AT_GNU_deleted
Definition dwarf.c:290
@ DW_AT_HP_prof_version_id
Definition dwarf.c:252
@ DW_AT_call_pc
Definition dwarf.c:218
@ DW_AT_main_subprogram
Definition dwarf.c:196
@ DW_AT_use_UTF8
Definition dwarf.c:173
@ DW_AT_static_link
Definition dwarf.c:162
@ DW_AT_GNU_ranges_base
Definition dwarf.c:293
@ DW_AT_GNAT_descriptive_type
Definition dwarf.c:302
@ DW_AT_APPLE_property_getter
Definition dwarf.c:318
@ DW_AT_rvalue_reference
Definition dwarf.c:209
@ DW_AT_pure
Definition dwarf.c:193
@ DW_AT_start_scope
Definition dwarf.c:136
@ DW_AT_MIPS_abstract_name
Definition dwarf.c:240
@ DW_AT_location
Definition dwarf.c:107
@ DW_AT_return_addr
Definition dwarf.c:135
@ DW_AT_APPLE_omit_frame_ptr
Definition dwarf.c:316
@ DW_AT_rank
Definition dwarf.c:203
@ DW_AT_mac_info
Definition dwarf.c:267
@ DW_AT_declaration
Definition dwarf.c:150
@ DW_AT_external
Definition dwarf.c:153
@ DW_AT_GNU_discriminator
Definition dwarf.c:297
@ DW_AT_import
Definition dwarf.c:123
@ DW_AT_decl_column
Definition dwarf.c:147
@ DW_AT_src_info
Definition dwarf.c:266
@ DW_AT_identifier_case
Definition dwarf.c:156
@ DW_AT_call_all_source_calls
Definition dwarf.c:212
@ DW_AT_ranges
Definition dwarf.c:175
@ DW_AT_src_coords
Definition dwarf.c:268
@ DW_AT_HP_unit_size
Definition dwarf.c:260
@ DW_AT_APPLE_property_attribute
Definition dwarf.c:320
@ DW_AT_address_class
Definition dwarf.c:141
@ DW_AT_GNU_macros
Definition dwarf.c:289
@ DW_AT_call_target
Definition dwarf.c:220
@ DW_AT_specification
Definition dwarf.c:161
@ DW_AT_MIPS_linkage_name
Definition dwarf.c:238
@ DW_AT_HP_cold_region_high_pc
Definition dwarf.c:255
@ DW_AT_threads_scaled
Definition dwarf.c:188
@ DW_AT_discr
Definition dwarf.c:120
@ DW_AT_GNU_numerator
Definition dwarf.c:303
@ DW_AT_deleted
Definition dwarf.c:227
@ DW_AT_use_GNAT_descriptive_type
Definition dwarf.c:301
@ DW_AT_call_data_value
Definition dwarf.c:223
@ DW_AT_MIPS_software_pipeline_depth
Definition dwarf.c:237
@ DW_AT_namelist_items
Definition dwarf.c:158
@ DW_AT_lower_bound
Definition dwarf.c:132
@ DW_AT_reference
Definition dwarf.c:208
@ DW_AT_alignment
Definition dwarf.c:225
@ DW_AT_decimal_scale
Definition dwarf.c:182
@ DW_AT_priority
Definition dwarf.c:159
@ DW_AT_vtable_elem_location
Definition dwarf.c:167
@ DW_AT_HP_proc_per_section
Definition dwarf.c:248
@ DW_AT_stmt_list
Definition dwarf.c:115
@ DW_AT_call_data_location
Definition dwarf.c:222
@ DW_AT_subscr_data
Definition dwarf.c:110
@ DW_AT_common_reference
Definition dwarf.c:125
@ DW_AT_hi_user
Definition dwarf.c:231
@ DW_AT_recursive
Definition dwarf.c:194
@ DW_AT_call_origin
Definition dwarf.c:216
@ DW_AT_picture_string
Definition dwarf.c:186
@ DW_AT_artificial
Definition dwarf.c:142
@ DW_AT_upper_bound
Definition dwarf.c:138
@ DW_AT_discr_list
Definition dwarf.c:151
@ DW_AT_decl_line
Definition dwarf.c:149
@ DW_AT_binary_scale
Definition dwarf.c:181
@ DW_AT_is_optional
Definition dwarf.c:131
@ DW_AT_VMS_rtnbeg_pd_address
Definition dwarf.c:300
@ DW_AT_data_location
Definition dwarf.c:170
@ DW_AT_variable_parameter
Definition dwarf.c:165
@ DW_AT_macro_info
Definition dwarf.c:157
@ DW_AT_MIPS_clone_origin
Definition dwarf.c:241
@ DW_AT_APPLE_isa
Definition dwarf.c:312
@ DW_AT_APPLE_runtime_class
Definition dwarf.c:315
size_t high_offset
Definition dwarf.c:644
unsigned int min_insn_len
Definition dwarf.c:528
static int units_search(const void *vkey, const void *ventry)
Definition dwarf.c:1459
off_t lineoff
Definition dwarf.c:652
Definition dwarf.c:424
Definition dwarf.c:563
Definition dwarf.c:631
#define IS_ABSOLUTE_PATH(f)
Definition filenames.h:51
void backtrace_qsort(void *base, size_t count, size_t size, int(*compar)(const void *, const void *))
Definition sort.c:61
#define backtrace_atomic_store_size_t(p, v)
Definition internal.h:118
#define backtrace_atomic_load_pointer(p)
Definition internal.h:115
int(* fileline)(struct backtrace_state *state, uintptr_t pc, backtrace_full_callback callback, backtrace_error_callback error_callback, void *data)
Definition internal.h:127
#define libbacktrace_add_base(pc, base)
Definition internal.h:361
const unsigned char * data[DEBUG_MAX]
Definition internal.h:323
@ DEBUG_RANGES
Definition internal.h:309
@ DEBUG_LINE_STR
Definition internal.h:313
@ DEBUG_LINE
Definition internal.h:307
@ DEBUG_STR_OFFSETS
Definition internal.h:312
@ DEBUG_INFO
Definition internal.h:306
@ DEBUG_ABBREV
Definition internal.h:308
@ DEBUG_ADDR
Definition internal.h:311
@ DEBUG_STR
Definition internal.h:310
@ DEBUG_RNGLISTS
Definition internal.h:314
static void backtrace_vector_free(struct backtrace_state *state, struct backtrace_vector *vec, backtrace_error_callback error_callback, void *data)
Definition internal.h:276
size_t size[DEBUG_MAX]
Definition internal.h:324
#define backtrace_atomic_store_pointer(p, v)
Definition internal.h:117
#define __sync_bool_compare_and_swap(A, B, C)
Definition internal.h:77
unsigned short uint16_t
unsigned int uint32_t
long long int off_t
static char const * name
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition snprintf.c:689
void * state
Definition testlib.c:46
const char * base(const char *p)
Definition testlib.c:55
Definition testlib.h:54
static unsigned count
Definition unittest.c:47
Functions to help with cleanup.
static fr_slen_t data
Definition value.h:1340