Project

General

Profile

Bug #17585 ยป ruby-dwarf5-avoid_crash-r1.patch

xtkoba (Tee KOBAYASHI), 02/25/2021 09:15 PM

View differences:

addr2line.c
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 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 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 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 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,
......
962 976
}
963 977

  
964 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

  
995
static void
965 996
di_read_debug_abbrev_cu(DebugInfoReader *reader)
966 997
{
967 998
    uint64_t prev = 0;
......
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 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);
......
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 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 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 1821
                    ".debug_info",
1749 1822
                    ".debug_line",
1750 1823
                    ".debug_ranges",
1824
                    ".debug_rnglists",
1751 1825
                    ".debug_str"
1752 1826
                };
1753 1827

  
......
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;