From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-x62e.google.com (mail-pl1-x62e.google.com [IPv6:2607:f8b0:4864:20::62e]) by sourceware.org (Postfix) with ESMTPS id 12DA838378FD for ; Wed, 14 Dec 2022 03:35:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 12DA838378FD Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-pl1-x62e.google.com with SMTP id 17so2093500pll.0 for ; Tue, 13 Dec 2022 19:35:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-disposition:mime-version:message-id:subject:to:from:date :from:to:cc:subject:date:message-id:reply-to; bh=evLtp+tD3NZHMFqBcT7cYCuU4v008gX2L2Z14qqdhI4=; b=h1F5l6e0Ag1o/hFOY+O0qrn+YQ5cfTUK1AK4Gv8Gkr5KKcic3xyyiA/JT8NjH+/FkG mn+JBYBKiVkSGk3HTvTfr5sy4QTlRm9zJ/v8nNIkNlI5FLA2jDKwud6v7YY0dmrewVTq dL2vtIySRQMtOeV1gcNYwBMOCX4Tu8fNAwsr89xrVoL0inxyb06igbJztg0ys7VcSHZW EP1UZMBhOWHfXK+BnAHSJtwxDnSsFX7iukFbq8AjBPBRcWAf2PeoUQu6hcGmk4s3ncJS pkxhd0kzrXKtXxCNl0geria2NToiUxgk56ytP+L3VdwlQdhMxuanfgiTFS+hM9suRWbJ Vx7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-disposition:mime-version:message-id:subject:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=evLtp+tD3NZHMFqBcT7cYCuU4v008gX2L2Z14qqdhI4=; b=vLYhiScnkxuKM0FxL9ztNsZnAd5aiATZ0gjMdZ681tBQ+k5qk5Ek5amI41QHUm62Bc zRm+CBTynKYUaIaJwmN6825Gk4DQ1jT0mpUBQTqet+NlR1uHkt9BuoTi9As9FuBi1ZUD IQjJwIT0bJcn5KDMvEBlKdqMKM87hH1nxR4lz1FLjA9vJbrtqUOrJwGN2bCkQn09XGGW 9giMHcgTGTO5zsUkEC7YYdiwyzNIjQ4G6AWxFA8z3vADn6vZ/tUay1r5bK55cSS+YY4R QiiUzSGxhzBFY/BFUjBGUr9ObprJQ3Zhm1jBJxLKZi43fwkhA2Jv1gN2zsgBTfqzjTeV IDLg== X-Gm-Message-State: ANoB5pneqpY9twyrQUIG6K9E55S/P9gjZyYtk6QVtDOyiiYMZ0Jr836t cSCuDoWwh2Vp46oa35lq2zCukSWYiSo= X-Google-Smtp-Source: AA0mqf4yEc3wNpJBUF2+A1AKe65cUimt1bwA3ALedYbDbIG2kaBf5+m0qf70/MKzDjCTY8qqlbQlRA== X-Received: by 2002:a05:6a21:9187:b0:a7:8919:3312 with SMTP id tp7-20020a056a21918700b000a789193312mr26019940pzb.29.1670988945671; Tue, 13 Dec 2022 19:35:45 -0800 (PST) Received: from squeak.grove.modra.org (158.106.96.58.static.exetel.com.au. [58.96.106.158]) by smtp.gmail.com with ESMTPSA id u5-20020a170903124500b00189847cd4acsm601625plh.237.2022.12.13.19.35.44 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Dec 2022 19:35:45 -0800 (PST) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id D5AD21143017; Wed, 14 Dec 2022 14:05:42 +1030 (ACDT) Date: Wed, 14 Dec 2022 14:05:42 +1030 From: Alan Modra To: binutils@sourceware.org Subject: asan: signed integer overflow in display_debug_frames Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-3036.0 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: * dwarf.c (struct Frame_Chunk): Make col_offset an int64_t. Adjust all places allocating col_offset and col_type to use the size of the array element rather than the size of a type. (frame_display_row): Adjust printing of col_offset. (display_debug_frames): Factor out multiplication by code_factor and data_factor. Avoid signed overflow. Use 64-bit variables. diff --git a/binutils/dwarf.c b/binutils/dwarf.c index c39c695863a..33ee41cb6c9 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -8334,7 +8334,7 @@ typedef struct Frame_Chunk unsigned int ncols; /* DW_CFA_{undefined,same_value,offset,register,unreferenced} */ short int *col_type; - int *col_offset; + int64_t *col_offset; char *augmentation; unsigned int code_factor; int data_factor; @@ -8391,9 +8391,10 @@ frame_need_space (Frame_Chunk *fc, unsigned int reg) return -1; } - fc->col_type = (short int *) xcrealloc (fc->col_type, fc->ncols, - sizeof (short int)); - fc->col_offset = (int *) xcrealloc (fc->col_offset, fc->ncols, sizeof (int)); + fc->col_type = xcrealloc (fc->col_type, fc->ncols, + sizeof (*fc->col_type)); + fc->col_offset = xcrealloc (fc->col_offset, fc->ncols, + sizeof (*fc->col_offset)); /* PR 17512: file:002-10025-0.005. */ if (fc->col_type == NULL || fc->col_offset == NULL) { @@ -8806,10 +8807,10 @@ frame_display_row (Frame_Chunk *fc, int *need_col_headers, unsigned int *max_reg strcpy (tmp, "s"); break; case DW_CFA_offset: - sprintf (tmp, "c%+d", fc->col_offset[r]); + sprintf (tmp, "c%+" PRId64, fc->col_offset[r]); break; case DW_CFA_val_offset: - sprintf (tmp, "v%+d", fc->col_offset[r]); + sprintf (tmp, "v%+" PRId64, fc->col_offset[r]); break; case DW_CFA_register: sprintf (tmp, "%s", regname (fc->col_offset[r], 0)); @@ -8850,8 +8851,8 @@ read_cie (unsigned char *start, unsigned char *end, fc = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk)); memset (fc, 0, sizeof (Frame_Chunk)); - fc->col_type = (short int *) xmalloc (sizeof (short int)); - fc->col_offset = (int *) xmalloc (sizeof (int)); + fc->col_type = xmalloc (sizeof (*fc->col_type)); + fc->col_offset = xmalloc (sizeof (*fc->col_offset)); version = *start++; @@ -9225,8 +9226,8 @@ display_debug_frames (struct dwarf_section *section, if (!cie) { fc->ncols = 0; - fc->col_type = (short int *) xmalloc (sizeof (short int)); - fc->col_offset = (int *) xmalloc (sizeof (int)); + fc->col_type = xmalloc (sizeof (*fc->col_type)); + fc->col_offset = xmalloc (sizeof (*fc->col_offset)); if (frame_need_space (fc, max_regs > 0 ? max_regs - 1 : 0) < 0) { warn (_("Invalid max register\n")); @@ -9241,10 +9242,12 @@ display_debug_frames (struct dwarf_section *section, else { fc->ncols = cie->ncols; - fc->col_type = (short int *) xcmalloc (fc->ncols, sizeof (short int)); - fc->col_offset = (int *) xcmalloc (fc->ncols, sizeof (int)); - memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int)); - memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int)); + fc->col_type = xcmalloc (fc->ncols, sizeof (*fc->col_type)); + fc->col_offset = xcmalloc (fc->ncols, sizeof (*fc->col_offset)); + memcpy (fc->col_type, cie->col_type, + fc->ncols * sizeof (*fc->col_type)); + memcpy (fc->col_offset, cie->col_offset, + fc->ncols * sizeof (*fc->col_offset)); fc->augmentation = cie->augmentation; fc->ptr_size = cie->ptr_size; eh_addr_size = cie->ptr_size; @@ -9489,14 +9492,12 @@ display_debug_frames (struct dwarf_section *section, while (start < block_end) { unsigned op, opa; - unsigned long ul, roffs; /* Note: It is tempting to use an unsigned long for 'reg' but there are various functions, notably frame_space_needed() that assume that reg is an unsigned int. */ unsigned int reg; - int64_t l; + int64_t sofs; uint64_t ofs; - uint64_t vma; const char *reg_prefix = ""; op = *start++; @@ -9513,31 +9514,30 @@ display_debug_frames (struct dwarf_section *section, switch (op) { case DW_CFA_advance_loc: + opa *= fc->code_factor; if (do_debug_frames_interp) frame_display_row (fc, &need_col_headers, &max_regs); else { - printf (" DW_CFA_advance_loc: %d to ", - opa * fc->code_factor); - print_hex_ns (fc->pc_begin + opa * fc->code_factor, - fc->ptr_size); + printf (" DW_CFA_advance_loc: %d to ", opa); + print_hex_ns (fc->pc_begin + opa, fc->ptr_size); printf ("\n"); } - fc->pc_begin += opa * fc->code_factor; + fc->pc_begin += opa; break; case DW_CFA_offset: - READ_ULEB (roffs, start, block_end); + READ_ULEB (ofs, start, block_end); + ofs *= fc->data_factor; if (opa >= fc->ncols) reg_prefix = bad_reg; if (! do_debug_frames_interp || *reg_prefix != '\0') - printf (" DW_CFA_offset: %s%s at cfa%+ld\n", - reg_prefix, regname (opa, 0), - roffs * fc->data_factor); + printf (" DW_CFA_offset: %s%s at cfa%+" PRId64 "\n", + reg_prefix, regname (opa, 0), ofs); if (*reg_prefix == '\0') { fc->col_type[opa] = DW_CFA_offset; - fc->col_offset[opa] = roffs * fc->data_factor; + fc->col_offset[opa] = ofs; } break; @@ -9564,93 +9564,90 @@ display_debug_frames (struct dwarf_section *section, break; case DW_CFA_set_loc: - vma = get_encoded_value (&start, fc->fde_encoding, section, + ofs = get_encoded_value (&start, fc->fde_encoding, section, block_end); if (do_debug_frames_interp) frame_display_row (fc, &need_col_headers, &max_regs); else { printf (" DW_CFA_set_loc: "); - print_hex_ns (vma, fc->ptr_size); + print_hex_ns (ofs, fc->ptr_size); printf ("\n"); } - fc->pc_begin = vma; + fc->pc_begin = ofs; break; case DW_CFA_advance_loc1: SAFE_BYTE_GET_AND_INC (ofs, start, 1, block_end); + ofs *= fc->code_factor; if (do_debug_frames_interp) frame_display_row (fc, &need_col_headers, &max_regs); else { - printf (" DW_CFA_advance_loc1: %" PRId64 " to ", - ofs * fc->code_factor); - print_hex_ns (fc->pc_begin + ofs * fc->code_factor, - fc->ptr_size); + printf (" DW_CFA_advance_loc1: %" PRId64 " to ", ofs); + print_hex_ns (fc->pc_begin + ofs, fc->ptr_size); printf ("\n"); } - fc->pc_begin += ofs * fc->code_factor; + fc->pc_begin += ofs; break; case DW_CFA_advance_loc2: SAFE_BYTE_GET_AND_INC (ofs, start, 2, block_end); + ofs *= fc->code_factor; if (do_debug_frames_interp) frame_display_row (fc, &need_col_headers, &max_regs); else { - printf (" DW_CFA_advance_loc2: %" PRId64 " to ", - ofs * fc->code_factor); - print_hex_ns (fc->pc_begin + ofs * fc->code_factor, - fc->ptr_size); + printf (" DW_CFA_advance_loc2: %" PRId64 " to ", ofs); + print_hex_ns (fc->pc_begin + ofs, fc->ptr_size); printf ("\n"); } - fc->pc_begin += ofs * fc->code_factor; + fc->pc_begin += ofs; break; case DW_CFA_advance_loc4: SAFE_BYTE_GET_AND_INC (ofs, start, 4, block_end); + ofs *= fc->code_factor; if (do_debug_frames_interp) frame_display_row (fc, &need_col_headers, &max_regs); else { - printf (" DW_CFA_advance_loc4: %" PRId64 " to ", - ofs * fc->code_factor); - print_hex_ns (fc->pc_begin + ofs * fc->code_factor, - fc->ptr_size); + printf (" DW_CFA_advance_loc4: %" PRId64 " to ", ofs); + print_hex_ns (fc->pc_begin + ofs, fc->ptr_size); printf ("\n"); } - fc->pc_begin += ofs * fc->code_factor; + fc->pc_begin += ofs; break; case DW_CFA_offset_extended: READ_ULEB (reg, start, block_end); - READ_ULEB (roffs, start, block_end); + READ_ULEB (ofs, start, block_end); + ofs *= fc->data_factor; if (reg >= fc->ncols) reg_prefix = bad_reg; if (! do_debug_frames_interp || *reg_prefix != '\0') - printf (" DW_CFA_offset_extended: %s%s at cfa%+ld\n", - reg_prefix, regname (reg, 0), - roffs * fc->data_factor); + printf (" DW_CFA_offset_extended: %s%s at cfa%+" PRId64 "\n", + reg_prefix, regname (reg, 0), ofs); if (*reg_prefix == '\0') { fc->col_type[reg] = DW_CFA_offset; - fc->col_offset[reg] = roffs * fc->data_factor; + fc->col_offset[reg] = ofs; } break; case DW_CFA_val_offset: READ_ULEB (reg, start, block_end); - READ_ULEB (roffs, start, block_end); + READ_ULEB (ofs, start, block_end); + ofs *= fc->data_factor; if (reg >= fc->ncols) reg_prefix = bad_reg; if (! do_debug_frames_interp || *reg_prefix != '\0') - printf (" DW_CFA_val_offset: %s%s is cfa%+ld\n", - reg_prefix, regname (reg, 0), - roffs * fc->data_factor); + printf (" DW_CFA_val_offset: %s%s is cfa%+" PRId64 "\n", + reg_prefix, regname (reg, 0), ofs); if (*reg_prefix == '\0') { fc->col_type[reg] = DW_CFA_val_offset; - fc->col_offset[reg] = roffs * fc->data_factor; + fc->col_offset[reg] = ofs; } break; @@ -9707,19 +9704,19 @@ display_debug_frames (struct dwarf_section *section, case DW_CFA_register: READ_ULEB (reg, start, block_end); - READ_ULEB (roffs, start, block_end); + READ_ULEB (ofs, start, block_end); if (reg >= fc->ncols) reg_prefix = bad_reg; if (! do_debug_frames_interp || *reg_prefix != '\0') { printf (" DW_CFA_register: %s%s in ", reg_prefix, regname (reg, 0)); - puts (regname (roffs, 0)); + puts (regname (ofs, 0)); } if (*reg_prefix == '\0') { fc->col_type[reg] = DW_CFA_register; - fc->col_offset[reg] = roffs; + fc->col_offset[reg] = ofs; } break; @@ -9732,11 +9729,12 @@ display_debug_frames (struct dwarf_section *section, rs->ra = fc->ra; rs->cfa_exp = fc->cfa_exp; rs->ncols = fc->ncols; - rs->col_type = (short int *) xcmalloc (rs->ncols, - sizeof (* rs->col_type)); - rs->col_offset = (int *) xcmalloc (rs->ncols, sizeof (* rs->col_offset)); - memcpy (rs->col_type, fc->col_type, rs->ncols * sizeof (* fc->col_type)); - memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (* fc->col_offset)); + rs->col_type = xcmalloc (rs->ncols, sizeof (*rs->col_type)); + rs->col_offset = xcmalloc (rs->ncols, sizeof (*rs->col_offset)); + memcpy (rs->col_type, fc->col_type, + rs->ncols * sizeof (*fc->col_type)); + memcpy (rs->col_offset, fc->col_offset, + rs->ncols * sizeof (*fc->col_offset)); rs->next = remembered_state; remembered_state = rs; break; @@ -9758,9 +9756,10 @@ display_debug_frames (struct dwarf_section *section, fc->ncols = 0; break; } - memcpy (fc->col_type, rs->col_type, rs->ncols * sizeof (* rs->col_type)); + memcpy (fc->col_type, rs->col_type, + rs->ncols * sizeof (*rs->col_type)); memcpy (fc->col_offset, rs->col_offset, - rs->ncols * sizeof (* rs->col_offset)); + rs->ncols * sizeof (*rs->col_offset)); free (rs->col_type); free (rs->col_offset); free (rs); @@ -9798,33 +9797,35 @@ display_debug_frames (struct dwarf_section *section, break; case DW_CFA_def_cfa_expression: - READ_ULEB (ul, start, block_end); - if (ul > (size_t) (block_end - start)) + READ_ULEB (ofs, start, block_end); + if (ofs > (size_t) (block_end - start)) { - printf (_(" DW_CFA_def_cfa_expression: \n"), ul); + printf (_(" %s: \n"), + "DW_CFA_def_cfa_expression", ofs); break; } if (! do_debug_frames_interp) { printf (" DW_CFA_def_cfa_expression ("); decode_location_expression (start, eh_addr_size, 0, -1, - ul, 0, section); + ofs, 0, section); printf (")\n"); } fc->cfa_exp = 1; - start += ul; + start += ofs; break; case DW_CFA_expression: READ_ULEB (reg, start, block_end); - READ_ULEB (ul, start, block_end); + READ_ULEB (ofs, start, block_end); if (reg >= fc->ncols) reg_prefix = bad_reg; /* PR 17512: file: 069-133014-0.006. */ /* PR 17512: file: 98c02eb4. */ - if (ul > (size_t) (block_end - start)) + if (ofs > (size_t) (block_end - start)) { - printf (_(" DW_CFA_expression: \n"), ul); + printf (_(" %s: \n"), + "DW_CFA_expression", ofs); break; } if (! do_debug_frames_interp || *reg_prefix != '\0') @@ -9832,22 +9833,23 @@ display_debug_frames (struct dwarf_section *section, printf (" DW_CFA_expression: %s%s (", reg_prefix, regname (reg, 0)); decode_location_expression (start, eh_addr_size, 0, -1, - ul, 0, section); + ofs, 0, section); printf (")\n"); } if (*reg_prefix == '\0') fc->col_type[reg] = DW_CFA_expression; - start += ul; + start += ofs; break; case DW_CFA_val_expression: READ_ULEB (reg, start, block_end); - READ_ULEB (ul, start, block_end); + READ_ULEB (ofs, start, block_end); if (reg >= fc->ncols) reg_prefix = bad_reg; - if (ul > (size_t) (block_end - start)) + if (ofs > (size_t) (block_end - start)) { - printf (" DW_CFA_val_expression: \n", ul); + printf (" %s: \n", + "DW_CFA_val_expression", ofs); break; } if (! do_debug_frames_interp || *reg_prefix != '\0') @@ -9855,78 +9857,84 @@ display_debug_frames (struct dwarf_section *section, printf (" DW_CFA_val_expression: %s%s (", reg_prefix, regname (reg, 0)); decode_location_expression (start, eh_addr_size, 0, -1, - ul, 0, section); + ofs, 0, section); printf (")\n"); } if (*reg_prefix == '\0') fc->col_type[reg] = DW_CFA_val_expression; - start += ul; + start += ofs; break; case DW_CFA_offset_extended_sf: READ_ULEB (reg, start, block_end); - READ_SLEB (l, start, block_end); + READ_SLEB (sofs, start, block_end); + /* data_factor multiplicaton done here as unsigned to + avoid integer overflow warnings from asan on fuzzed + objects. */ + ofs = sofs; + ofs *= fc->data_factor; if (reg >= fc->ncols) reg_prefix = bad_reg; if (! do_debug_frames_interp || *reg_prefix != '\0') printf (" DW_CFA_offset_extended_sf: %s%s at cfa%+" PRId64 "\n", - reg_prefix, regname (reg, 0), - l * fc->data_factor); + reg_prefix, regname (reg, 0), ofs); if (*reg_prefix == '\0') { fc->col_type[reg] = DW_CFA_offset; - fc->col_offset[reg] = l * fc->data_factor; + fc->col_offset[reg] = ofs; } break; case DW_CFA_val_offset_sf: READ_ULEB (reg, start, block_end); - READ_SLEB (l, start, block_end); + READ_SLEB (sofs, start, block_end); + ofs = sofs; + ofs *= fc->data_factor; if (reg >= fc->ncols) reg_prefix = bad_reg; if (! do_debug_frames_interp || *reg_prefix != '\0') printf (" DW_CFA_val_offset_sf: %s%s is cfa%+" PRId64 "\n", - reg_prefix, regname (reg, 0), - l * fc->data_factor); + reg_prefix, regname (reg, 0), ofs); if (*reg_prefix == '\0') { fc->col_type[reg] = DW_CFA_val_offset; - fc->col_offset[reg] = l * fc->data_factor; + fc->col_offset[reg] = ofs; } break; case DW_CFA_def_cfa_sf: READ_ULEB (fc->cfa_reg, start, block_end); - READ_SLEB (l, start, block_end); - l *= fc->data_factor; - fc->cfa_offset = l; + READ_SLEB (sofs, start, block_end); + ofs = sofs; + ofs *= fc->data_factor; + fc->cfa_offset = ofs; fc->cfa_exp = 0; if (! do_debug_frames_interp) printf (" DW_CFA_def_cfa_sf: %s ofs %" PRId64 "\n", - regname (fc->cfa_reg, 0), l); + regname (fc->cfa_reg, 0), ofs); break; case DW_CFA_def_cfa_offset_sf: - READ_SLEB (l, start, block_end); - l *= fc->data_factor; - fc->cfa_offset = l; + READ_SLEB (sofs, start, block_end); + ofs = sofs; + ofs *= fc->data_factor; + fc->cfa_offset = ofs; if (! do_debug_frames_interp) - printf (" DW_CFA_def_cfa_offset_sf: %" PRId64 "\n", l); + printf (" DW_CFA_def_cfa_offset_sf: %" PRId64 "\n", ofs); break; case DW_CFA_MIPS_advance_loc8: SAFE_BYTE_GET_AND_INC (ofs, start, 8, block_end); + ofs *= fc->code_factor; if (do_debug_frames_interp) frame_display_row (fc, &need_col_headers, &max_regs); else { - printf (" DW_CFA_MIPS_advance_loc8: %" PRId64 " to ", - ofs * fc->code_factor); - print_hex_ns (fc->pc_begin + ofs * fc->code_factor, - fc->ptr_size); + printf (" DW_CFA_MIPS_advance_loc8: %" PRId64 " to ", ofs); + print_hex_ns (fc->pc_begin + ofs, fc->ptr_size); printf ("\n"); } - fc->pc_begin += ofs * fc->code_factor; + fc->pc_begin += ofs; break; case DW_CFA_GNU_window_save: @@ -9935,26 +9943,26 @@ display_debug_frames (struct dwarf_section *section, break; case DW_CFA_GNU_args_size: - READ_ULEB (ul, start, block_end); + READ_ULEB (ofs, start, block_end); if (! do_debug_frames_interp) - printf (" DW_CFA_GNU_args_size: %ld\n", ul); + printf (" DW_CFA_GNU_args_size: %" PRIu64 "\n", ofs); break; case DW_CFA_GNU_negative_offset_extended: READ_ULEB (reg, start, block_end); - READ_SLEB (l, start, block_end); - l = - l; + READ_SLEB (sofs, start, block_end); + ofs = sofs; + ofs = -ofs * fc->data_factor; if (reg >= fc->ncols) reg_prefix = bad_reg; if (! do_debug_frames_interp || *reg_prefix != '\0') printf (" DW_CFA_GNU_negative_offset_extended: %s%s " "at cfa%+" PRId64 "\n", - reg_prefix, regname (reg, 0), - l * fc->data_factor); + reg_prefix, regname (reg, 0), ofs); if (*reg_prefix == '\0') { fc->col_type[reg] = DW_CFA_offset; - fc->col_offset[reg] = l * fc->data_factor; + fc->col_offset[reg] = ofs; } break; -- Alan Modra Australia Development Lab, IBM