8000 Support GCC's DWARF 5 [Bug #17585] (#4240) · github/ruby@9e5105c · GitHub
[go: up one dir, main page]

Skip to content

Commit 9e5105c

Browse files
mamextkoba (Tee KOBAYASHI)
andauthored
Support GCC's DWARF 5 [Bug #17585] (ruby#4240)
Co-Authored-By: xtkoba (Tee KOBAYASHI) <xtkoba+ruby@gmail.com>
1 parent 82b6f89 commit 9e5105c

File tree

1 file changed

+97
-22
lines changed

1 file changed

+97
-22
lines changed

addr2line.c

Lines changed: 97 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,12 @@ typedef struct obj_info {
159159
struct dwarf_section debug_info;
160160
struct dwarf_section debug_line;
161161
struct dwarf_section debug_ranges;
162+
struct dwarf_section debug_rnglists;
162163
struct dwarf_section debug_str;
163164
struct obj_info *next;
164165
} obj_info_t;
165166

166-
#define DWARF_SECTION_COUNT 5
167+
#define DWARF_SECTION_COUNT 6
167168

168169
static struct dwarf_section *
169170
obj_dwarf_section_at(obj_info_t *obj, int n)
@@ -173,6 +174,7 @@ obj_dwarf_section_at(obj_info_t *obj, int n)
173174
&obj->debug_info,
174175
&obj->debug_line,
175176
&obj->debug_ranges,
177+
&obj->debug_rnglists,
176178
&obj->debug_str
177179
};
178180
if (n < 0 || DWARF_SECTION_COUNT <= n) {
@@ -411,7 +413,7 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
411413
FILL_LINE();
412414
break;
413415
case DW_LNS_advance_pc:
414-
a = uleb128((char **)&p);
416+
a = uleb128((char **)&p) * header.minimum_instruction_length;
415417
addr += a;
416418
break;
417419
case DW_LNS_advance_line: {
@@ -451,7 +453,7 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
451453
/* isa = (unsigned int)*/(void)uleb128((char **)&p);
452454
break;
453455
case 0:
454-
a = *(unsigned char *)p++;
456+
a = uleb128((char **)&p);
455457
op = *p++;
456458
switch (op) {
457459
case DW_LNE_end_sequence:
@@ -808,6 +810,18 @@ enum
808810
DW_FORM_addrx4 = 0x2c
809811
};
810812

813+
/* Range list entry encodings */
814+
enum {
815+
DW_RLE_end_of_list = 0x00,
816+
DW_RLE_base_addressx = 0x01,
817+
DW_RLE_startx_endx = 0x02,
818+
DW_RLE_startx_length = 0x03,
819+
DW_RLE_offset_pair = 0x04,
820+
DW_RLE_base_address = 0x05,
821+
DW_RLE_start_end = 0x06,
822+
DW_RLE_start_length = 0x07
823+
};
824+
811825
enum {
812826
VAL_none = 0,
813827
VAL_cstr = 1,
@@ -961,6 +975,23 @@ debug_info_reader_init(DebugInfoReader *reader, obj_info_t *obj)
961975
reader->current_low_pc = 0;
962976
}
963977

978+
static void
979+
di_skip_die_attributes(char **p)
980+
{
981+
for (;;) {
982+
uint64_t at = uleb128(p);
983+
uint64_t form = uleb128(p);
984+
if (!at && !form) break;
985+
switch (form) {
986+
default:
987+
break;
988+
case DW_FORM_implicit_const:
989+
sleb128(p);
990+
break;
991+
}
992+
}
993+
}
994+
964995
static void
965996
di_read_debug_abbrev_cu(DebugInfoReader *reader)
966997
{
@@ -975,12 +1006,7 @@ di_read_debug_abbrev_cu(DebugInfoReader *reader)
9751006
prev = abbrev_number;
9761007
uleb128(&p); /* tag */
9771008
p++; /* has_children */
978-
/* skip content */
979-
for (;;) {
980-
uint64_t at = uleb128(&p);
981-
uint64_t form = uleb128(&p);
982-
if (!at && !form) break;
983-
}
1009+
di_skip_die_attributes(&p);
9841010
}
9851011
}
9861012

@@ -1244,25 +1270,15 @@ di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number)
12441270
/* skip 255th record */
12451271
uleb128(&p); /* tag */
12461272
p++; /* has_children */
1247-
/* skip content */
1248-
for (;;) {
1249-
uint64_t at = uleb128(&p);
1250-
uint64_t form = uleb128(&p);
1251-
if (!at && !form) break;
1252-
}
1273+
di_skip_die_attributes(&p);
12531274
for (uint64_t n = uleb128(&p); abbrev_number != n; n = uleb128(&p)) {
12541275
if (n == 0) {
12551276
fprintf(stderr,"%d: Abbrev Number %"PRId64" not found\n",__LINE__, abbrev_number);
12561277
exit(1);
12571278
}
12581279
uleb128(&p); /* tag */
12591280
p++; /* has_children */
1260-
/* skip content */
1261-
for (;;) {
1262-
uint64_t at = uleb128(&p);
1263-
uint64_t form = uleb128(&p);
1264-
if (!at && !form) break;
1265-
}
1281+
di_skip_die_attributes(&p);
12661282
}
12671283
return p;
12681284
}
@@ -1390,6 +1406,21 @@ ranges_set(ranges_t *ptr, DebugInfoValue *v)
13901406
}
13911407
}
13921408

1409+
static uint64_t
1410+
read_dw_form_addr(DebugInfoReader *reader, char **ptr)
1411+
{
1412+
char *p = *ptr;
1413+
*ptr = p + reader->format;
1414+
if (reader->format == 4) {
1415+
return read_uint32(&p);
1416+
} else if (reader->format == 8) {
1417+
return read_uint64(&p);
1418+
} else {
1419+
fprintf(stderr,"unknown address_size:%d", reader->address_size);
1420+
abort();
1421+
}
1422+
}
1423+
13931424
static uintptr_t
13941425
ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr)
13951426
{
@@ -1403,8 +1434,50 @@ ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr)
14031434
}
14041435
else if (ptr->ranges_set) {
14051436
/* TODO: support base address selection entry */
1406-
char *p = reader->obj->debug_ranges.ptr + ptr->ranges;
1437+
char *p;
14071438
uint64_t base = ptr->low_pc_set ? ptr->low_pc : reader->current_low_pc;
1439+
if (reader->obj->debug_rnglists.ptr) {
1440+
p = reader->obj->debug_rnglists.ptr + ptr->ranges;
1441+
for (;;) {
1442+
uint8_t rle = read_uint8(&p);
1443+
uintptr_t base_address = 0;
1444+
uintptr_t from, to;
1445+
if (rle == DW_RLE_end_of_list) break;
1446+
switch (rle) {
1447+
case DW_RLE_base_addressx:
1448+
uleb128(&p);
1449+
break;
1450+
case DW_RLE_startx_endx:
1451+
uleb128(&p);
1452+
uleb128(&p);
1453+
break;
1454+
case DW_RLE_startx_length:
1455+
uleb128(&p);
1456+
uleb128(&p);
1457+
break;
1458+
case DW_RLE_offset_pair:
1459+
from = base_address + uleb128(&p);
1460+
to = base_address + uleb128(&p);
1461+
if (base + from <= addr && addr < base + to) {
1462+
return from;
1463+
}
1464+
break;
1465+
case DW_RLE_base_address:
1466+
base_address = read_dw_form_addr(reader, &p);
1467+
break;
1468+
case DW_RLE_start_end:
1469+
read_dw_form_addr(reader, &p);
1470+
read_dw_form_addr(reader, &p);
1471+
break;
1472+
case DW_RLE_start_length:
1473+
read_dw_form_addr(reader, &p);
1474+
uleb128(&p);
1475+
break;
1476+
}
1477+
}
1478+
return false;
1479+
}
1480+
p = reader->obj->debug_ranges.ptr + ptr->ranges;
14081481
for (;;) {
14091482
uintptr_t from = read_uintptr(&p);
14101483
uintptr_t to = read_uintptr(&p);
@@ -1748,6 +1821,7 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
17481821
".debug_info",
17491822
".debug_line",
17501823
".debug_ranges",
1824+
".debug_rnglists",
17511825
".debug_str"
17521826
};
17531827

@@ -2004,6 +2078,7 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
20042078
"__debug_info",
20052079
"__debug_line",
20062080
"__debug_ranges",
2081+
"__debug_rnglists",
20072082
"__debug_str"
20082083
};
20092084
struct LP(segment_command) *scmd = (struct LP(segment_command) *)lcmd;

0 commit comments

Comments
 (0)
0