|
Lines 385-390
static void set_expr_rule(uleb128_t reg, enum item_location where,
|
Link Here
|
|---|
|
| 385 |
uleb128_t len = get_uleb128(expr, end); |
385 |
uleb128_t len = get_uleb128(expr, end); |
| 386 |
dbug_unwind(1, "reg=%lx, where=%d, expr=%lu@%p\n", |
386 |
dbug_unwind(1, "reg=%lx, where=%d, expr=%lu@%p\n", |
| 387 |
reg, where, len, *expr); |
387 |
reg, where, len, *expr); |
|
|
388 |
/* Sanity check that expr falls completely inside known data. */ |
| 388 |
if (end - *expr >= len && reg < ARRAY_SIZE(REG_STATE.regs)) { |
389 |
if (end - *expr >= len && reg < ARRAY_SIZE(REG_STATE.regs)) { |
| 389 |
REG_STATE.regs[reg].where = where; |
390 |
REG_STATE.regs[reg].where = where; |
| 390 |
REG_STATE.regs[reg].expr = start; |
391 |
REG_STATE.regs[reg].expr = start; |
|
Lines 524-553
static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc,
|
Link Here
|
|---|
|
| 524 |
case DW_CFA_def_cfa: |
525 |
case DW_CFA_def_cfa: |
| 525 |
value = get_uleb128(&ptr.p8, end); |
526 |
value = get_uleb128(&ptr.p8, end); |
| 526 |
dbug_unwind(1, "map DW_CFA_def_cfa value %ld to reg_info idx %ld\n", value, DWARF_REG_MAP(value)); |
527 |
dbug_unwind(1, "map DW_CFA_def_cfa value %ld to reg_info idx %ld\n", value, DWARF_REG_MAP(value)); |
|
|
528 |
REG_STATE.cfa_is_expr = 0; |
| 527 |
REG_STATE.cfa.reg = value; |
529 |
REG_STATE.cfa.reg = value; |
| 528 |
dbug_unwind(1, "DW_CFA_def_cfa reg=%ld\n", REG_STATE.cfa.reg); |
530 |
dbug_unwind(1, "DW_CFA_def_cfa reg=%ld\n", REG_STATE.cfa.reg); |
| 529 |
/*nobreak */ |
531 |
/*nobreak */ |
| 530 |
case DW_CFA_def_cfa_offset: |
532 |
case DW_CFA_def_cfa_offset: |
| 531 |
REG_STATE.cfa.offs = get_uleb128(&ptr.p8, end); |
533 |
if (REG_STATE.cfa_is_expr != 0) { |
| 532 |
dbug_unwind(1, "DW_CFA_def_cfa_offset offs=%lx\n", REG_STATE.cfa.offs); |
534 |
_stp_warn("Unexpected DW_CFA_def_cfa_offset\n"); |
|
|
535 |
} else { |
| 536 |
REG_STATE.cfa.offs = get_uleb128(&ptr.p8, end); |
| 537 |
dbug_unwind(1, "DW_CFA_def_cfa_offset offs=%lx\n", REG_STATE.cfa.offs); |
| 538 |
} |
| 533 |
break; |
539 |
break; |
| 534 |
case DW_CFA_def_cfa_sf: |
540 |
case DW_CFA_def_cfa_sf: |
| 535 |
value = get_uleb128(&ptr.p8, end); |
541 |
value = get_uleb128(&ptr.p8, end); |
| 536 |
dbug_unwind(1, "map DW_CFA_def_cfa_sf value %ld to reg_info idx %ld\n", value, DWARF_REG_MAP(value)); |
542 |
dbug_unwind(1, "map DW_CFA_def_cfa_sf value %ld to reg_info idx %ld\n", value, DWARF_REG_MAP(value)); |
|
|
543 |
REG_STATE.cfa_is_expr = 0; |
| 537 |
REG_STATE.cfa.reg = value; |
544 |
REG_STATE.cfa.reg = value; |
| 538 |
/*nobreak */ |
545 |
/*nobreak */ |
| 539 |
case DW_CFA_def_cfa_offset_sf: |
546 |
case DW_CFA_def_cfa_offset_sf: |
| 540 |
REG_STATE.cfa.offs = get_sleb128(&ptr.p8, end) * state->dataAlign; |
547 |
if (REG_STATE.cfa_is_expr != 0) { |
| 541 |
dbug_unwind(1, "DW_CFA_def_cfa_offset_sf offs=%lx\n", REG_STATE.cfa.offs); |
548 |
_stp_warn("Unexpected DW_CFA_def_cfa_offset_sf\n"); |
|
|
549 |
} else { |
| 550 |
REG_STATE.cfa.offs = get_sleb128(&ptr.p8, end) * state->dataAlign; |
| 551 |
dbug_unwind(1, "DW_CFA_def_cfa_offset_sf offs=%lx\n", REG_STATE.cfa.offs); |
| 552 |
} |
| 542 |
break; |
553 |
break; |
| 543 |
case DW_CFA_def_cfa_register: |
554 |
case DW_CFA_def_cfa_register: |
| 544 |
value = get_uleb128(&ptr.p8, end); |
555 |
if (REG_STATE.cfa_is_expr != 0) { |
| 545 |
dbug_unwind(1, "map DW_CFA_def_cfa_register value %ld to reg_info idx %ld\n", value, DWARF_REG_MAP(value)); |
556 |
_stp_warn("Unexpected DW_CFA_def_cfa_register\n"); |
| 546 |
REG_STATE.cfa.reg = value; |
557 |
} else { |
|
|
558 |
value = get_uleb128(&ptr.p8, end); |
| 559 |
dbug_unwind(1, "map DW_CFA_def_cfa_register value %ld to reg_info idx %ld\n", value, DWARF_REG_MAP(value)); |
| 560 |
REG_STATE.cfa.reg = value; |
| 561 |
} |
| 547 |
break; |
562 |
break; |
| 548 |
case DW_CFA_def_cfa_expression: { |
563 |
case DW_CFA_def_cfa_expression: { |
| 549 |
const u8 *cfa_expr = ptr.p8; |
564 |
const u8 *cfa_expr = ptr.p8; |
| 550 |
value = get_uleb128(&ptr.p8, end); |
565 |
value = get_uleb128(&ptr.p8, end); |
|
|
566 |
/* Sanity check that cfa_expr falls completely |
| 567 |
inside known data. */ |
| 551 |
if (ptr.p8 < end && end - ptr.p8 >= value) { |
568 |
if (ptr.p8 < end && end - ptr.p8 >= value) { |
| 552 |
REG_STATE.cfa_is_expr = 1; |
569 |
REG_STATE.cfa_is_expr = 1; |
| 553 |
REG_STATE.cfa_expr = cfa_expr; |
570 |
REG_STATE.cfa_expr = cfa_expr; |
|
Lines 801-806
static int compute_expr(const u8 *expr, struct unwind_frame_info *frame,
|
Link Here
|
|---|
|
| 801 |
{ |
818 |
{ |
| 802 |
/* |
819 |
/* |
| 803 |
* We previously validated the length, so we won't read off the end. |
820 |
* We previously validated the length, so we won't read off the end. |
|
|
821 |
* See sanity checks in set_expr() and for DW_CFA_def_cfa_expression. |
| 804 |
*/ |
822 |
*/ |
| 805 |
uleb128_t len = get_uleb128(&expr, (const u8 *) -1UL); |
823 |
uleb128_t len = get_uleb128(&expr, (const u8 *) -1UL); |
| 806 |
const u8 *const start = expr; |
824 |
const u8 *const start = expr; |