View | Details | Raw Unified | Return to bug 13714 | Differences between
and this patch

Collapse All | Expand All

(-)a/runtime/unwind.c (-7 / +25 lines)
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;

Return to bug 13714