@@ -159,11 +159,12 @@ typedef struct obj_info {
159
159
struct dwarf_section debug_info ;
160
160
struct dwarf_section debug_line ;
161
161
struct dwarf_section debug_ranges ;
162
+ struct dwarf_section debug_rnglists ;
162
163
struct dwarf_section debug_str ;
163
164
struct obj_info * next ;
164
165
} obj_info_t ;
165
166
166
- #define DWARF_SECTION_COUNT 5
167
+ #define DWARF_SECTION_COUNT 6
167
168
168
169
static struct dwarf_section *
169
170
obj_dwarf_section_at (obj_info_t * obj , int n )
@@ -173,6 +174,7 @@ obj_dwarf_section_at(obj_info_t *obj, int n)
173
174
& obj -> debug_info ,
174
175
& obj -> debug_line ,
175
176
& obj -> debug_ranges ,
177
+ & obj -> debug_rnglists ,
176
178
& obj -> debug_str
177
179
};
178
180
if (n < 0 || DWARF_SECTION_COUNT <= n ) {
@@ -411,7 +413,7 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
411
413
FILL_LINE ();
412
414
break ;
413
415
case DW_LNS_advance_pc :
414
- a = uleb128 ((char * * )& p );
416
+ a = uleb128 ((char * * )& p ) * header . minimum_instruction_length ;
415
417
addr += a ;
416
418
break ;
417
419
case DW_LNS_advance_line : {
@@ -451,7 +453,7 @@ parse_debug_line_cu(int num_traces, void **traces, char **debug_line,
451
453
/* isa = (unsigned int)*/ (void )uleb128 ((char * * )& p );
452
454
break ;
453
455
case 0 :
454
- a = * ( unsigned char * ) p ++ ;
456
+ a = uleb128 (( char * * ) & p ) ;
455
457
op = * p ++ ;
456
458
switch (op ) {
457
459
case DW_LNE_end_sequence :
@@ -808,6 +810,18 @@ enum
808
810
DW_FORM_addrx4 = 0x2c
809
811
};
810
812
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
+
811
825
enum {
812
826
VAL_none = 0 ,
813
827
VAL_cstr = 1 ,
@@ -961,6 +975,23 @@ debug_info_reader_init(DebugInfoReader *reader, obj_info_t *obj)
961
975
reader -> current_low_pc = 0 ;
962
976
}
963
977
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
+
964
995
static void
965
996
di_read_debug_abbrev_cu (DebugInfoReader * reader )
966
997
{
@@ -975,12 +1006,7 @@ di_read_debug_abbrev_cu(DebugInfoReader *reader)
975
1006
prev = abbrev_number ;
976
1007
uleb128 (& p ); /* tag */
977
1008
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 );
984
1010
}
985
1011
}
986
1012
@@ -1244,25 +1270,15 @@ di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number)
1244
1270
/* skip 255th record */
1245
1271
uleb128 (& p ); /* tag */
1246
1272
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 );
1253
1274
for (uint64_t n = uleb128 (& p ); abbrev_number != n ; n = uleb128 (& p )) {
1254
1275
if (n == 0 ) {
1255
1276
fprintf (stderr ,"%d: Abbrev Number %" PRId64 " not found\n" ,__LINE__ , abbrev_number );
1256
1277
exit (1 );
1257
1278
}
1258
1279
uleb128 (& p ); /* tag */
1259
1280
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 );
1266
1282
}
1267
1283
return p ;
1268
1284
}
@@ -1390,6 +1406,21 @@ ranges_set(ranges_t *ptr, DebugInfoValue *v)
1390
1406
}
1391
1407
}
1392
1408
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
+
1393
1424
static uintptr_t
1394
1425
ranges_include (DebugInfoReader * reader , ranges_t * ptr , uint64_t addr )
1395
1426
{
@@ -1403,8 +1434,50 @@ ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr)
1403
1434
}
1404
1435
else if (ptr -> ranges_set ) {
1405
1436
/* TODO: support base address selection entry */
1406
- char * p = reader -> obj -> debug_ranges . ptr + ptr -> ranges ;
1437
+ char * p ;
1407
1438
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 ;
1408
1481
for (;;) {
1409
1482
uintptr_t from = read_uintptr (& p );
1410
1483
uintptr_t to = read_uintptr (& p );
@@ -1748,6 +1821,7 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
1748
1821
".debug_info" ,
1749
1822
".debug_line" ,
1750
1823
".debug_ranges" ,
1824
+ ".debug_rnglists" ,
1751
1825
".debug_str"
1752
1826
};
1753
1827
@@ -2004,6 +2078,7 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
2004
2078
"__debug_info" ,
2005
2079
"__debug_line" ,
2006
2080
"__debug_ranges" ,
2081
+ "__debug_rnglists" ,
2007
2082
"__debug_str"
2008
2083
};
2009
2084
struct LP (segment_command ) * scmd = (struct LP (segment_command ) * )lcmd ;
0 commit comments