From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pf1-x435.google.com (mail-pf1-x435.google.com [IPv6:2607:f8b0:4864:20::435]) by sourceware.org (Postfix) with ESMTPS id 2F3FC3858288 for ; Thu, 16 Jun 2022 00:25:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2F3FC3858288 Received: by mail-pf1-x435.google.com with SMTP id w21so93504pfc.0 for ; Wed, 15 Jun 2022 17:25:33 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition; bh=PyIgxT1o/PvpEEl+O6DsO8v9RAkFPLpG/gdW6d0bk5o=; b=1/CEI+OIziZvzbyAJKeSZLl2gdkfzVLOF5aljC1xVbC1KKvYXdbGf4HfXKeqx5QMRD eXdKcyxQMsmQLO159cxXeFsPuPpQi/gZsPvwiUbBYbtjLNGENwzDn/ysyLYZk7vsqTbf B3MoKXLzeFCiAP0eAB4BpW2Btz4fW5xG8YCcmcptxt7FipszxavRCB+WQBVvDPvMPVbq E+S75RSceiiCxDZggEbrV8y66ZEI5aug+RTujNo3xiINW+3lVp3ADoId7xlfO/+WBXxl hkb+8aXuIVLuDL5nV9SbXIPkBx4/H6BV78xEcfSJAJGJ4A/mxmdy4zEzsKKvpFyKR2zx 03cg== X-Gm-Message-State: AJIora8sM/6+wHRxuZFHqqHG0Od5VyyUcf8IeLYu6FDp3ERcJ14xrVGX FDMdxhz1V3N1TFhmSePGSMr8nVwU2a0= X-Google-Smtp-Source: AGRyM1uspfoScZ0nVaOk4Who4LkJANaQgj8kX+ks0v+o+VvNFnKl4Ac/YtRTaSgq7Rp4gqPEjxVSmw== X-Received: by 2002:a63:e34b:0:b0:405:111a:a295 with SMTP id o11-20020a63e34b000000b00405111aa295mr2127606pgj.48.1655339131643; Wed, 15 Jun 2022 17:25:31 -0700 (PDT) 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 jf13-20020a170903268d00b00163cdf1a200sm237205plb.38.2022.06.15.17.25.29 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 15 Jun 2022 17:25:30 -0700 (PDT) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id 7979A11403D9; Thu, 16 Jun 2022 09:55:27 +0930 (ACST) Date: Thu, 16 Jun 2022 09:55:27 +0930 From: Alan Modra To: binutils@sourceware.org Subject: PR29250, readelf erases CIE initial register state Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-3037.1 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, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 16 Jun 2022 00:25:35 -0000 PR 29250 binutils/ * dwarf.c (display_debug_frames): Set col_type[reg] on sizing pass over FDE to cie->col_type[reg] if CIE specifies reg. Handle DW_CFA_restore and DW_CFA_restore_extended on second pass using the same logic. Remove unnecessary casts. Don't call frame_need_space on second pass over FDE. gas/ * testsuite/gas/i386/ehinterp.d, * testsuite/gas/i386/ehinterp.s: New test. * testsuite/gas/i386/i386.exp: Run it. diff --git a/binutils/dwarf.c b/binutils/dwarf.c index c16f5a891b7..f11eeaa24ce 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -9306,18 +9306,17 @@ display_debug_frames (struct dwarf_section *section, /* Warning: if you add any more cases to this switch, be sure to add them to the corresponding switch below. */ + reg = -1u; switch (op) { case DW_CFA_advance_loc: break; case DW_CFA_offset: SKIP_ULEB (start, block_end); - if (frame_need_space (fc, opa) >= 0) - fc->col_type[opa] = DW_CFA_undefined; + reg = opa; break; case DW_CFA_restore: - if (frame_need_space (fc, opa) >= 0) - fc->col_type[opa] = DW_CFA_undefined; + reg = opa; break; case DW_CFA_set_loc: if ((size_t) (block_end - start) < encoded_ptr_size) @@ -9347,29 +9346,19 @@ display_debug_frames (struct dwarf_section *section, case DW_CFA_val_offset: READ_ULEB (reg, start, block_end); SKIP_ULEB (start, block_end); - if (frame_need_space (fc, reg) >= 0) - fc->col_type[reg] = DW_CFA_undefined; break; case DW_CFA_restore_extended: READ_ULEB (reg, start, block_end); - if (frame_need_space (fc, reg) >= 0) - fc->col_type[reg] = DW_CFA_undefined; break; case DW_CFA_undefined: READ_ULEB (reg, start, block_end); - if (frame_need_space (fc, reg) >= 0) - fc->col_type[reg] = DW_CFA_undefined; break; case DW_CFA_same_value: READ_ULEB (reg, start, block_end); - if (frame_need_space (fc, reg) >= 0) - fc->col_type[reg] = DW_CFA_undefined; break; case DW_CFA_register: READ_ULEB (reg, start, block_end); SKIP_ULEB (start, block_end); - if (frame_need_space (fc, reg) >= 0) - fc->col_type[reg] = DW_CFA_undefined; break; case DW_CFA_def_cfa: SKIP_ULEB (start, block_end); @@ -9396,15 +9385,11 @@ display_debug_frames (struct dwarf_section *section, start = block_end; else start += temp; - if (frame_need_space (fc, reg) >= 0) - fc->col_type[reg] = DW_CFA_undefined; break; case DW_CFA_offset_extended_sf: case DW_CFA_val_offset_sf: READ_ULEB (reg, start, block_end); SKIP_SLEB (start, block_end); - if (frame_need_space (fc, reg) >= 0) - fc->col_type[reg] = DW_CFA_undefined; break; case DW_CFA_def_cfa_sf: SKIP_ULEB (start, block_end); @@ -9425,12 +9410,21 @@ display_debug_frames (struct dwarf_section *section, case DW_CFA_GNU_negative_offset_extended: READ_ULEB (reg, start, block_end); SKIP_ULEB (start, block_end); - if (frame_need_space (fc, reg) >= 0) - fc->col_type[reg] = DW_CFA_undefined; break; default: break; } + if (reg != -1u && frame_need_space (fc, reg) >= 0) + { + /* Don't leave any reg as DW_CFA_unreferenced so + that frame_display_row prints name of regs in + header, and all referenced regs in each line. */ + if (reg >= cie->ncols + || cie->col_type[reg] == DW_CFA_unreferenced) + fc->col_type[reg] = DW_CFA_undefined; + else + fc->col_type[reg] = cie->col_type[reg]; + } } start = tmp; } @@ -9480,7 +9474,7 @@ display_debug_frames (struct dwarf_section *section, case DW_CFA_offset: READ_ULEB (roffs, start, block_end); - if (opa >= (unsigned int) fc->ncols) + 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", @@ -9494,7 +9488,7 @@ display_debug_frames (struct dwarf_section *section, break; case DW_CFA_restore: - if (opa >= (unsigned int) fc->ncols) + if (opa >= fc->ncols) reg_prefix = bad_reg; if (! do_debug_frames_interp || *reg_prefix != '\0') printf (" DW_CFA_restore: %s%s\n", @@ -9502,9 +9496,8 @@ display_debug_frames (struct dwarf_section *section, if (*reg_prefix != '\0') break; - if (opa >= (unsigned int) cie->ncols - || (do_debug_frames_interp - && cie->col_type[opa] == DW_CFA_unreferenced)) + if (opa >= cie->ncols + || cie->col_type[opa] == DW_CFA_unreferenced) { fc->col_type[opa] = DW_CFA_undefined; fc->col_offset[opa] = 0; @@ -9569,7 +9562,7 @@ display_debug_frames (struct dwarf_section *section, case DW_CFA_offset_extended: READ_ULEB (reg, start, block_end); READ_ULEB (roffs, start, block_end); - if (reg >= (unsigned int) fc->ncols) + 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", @@ -9585,7 +9578,7 @@ display_debug_frames (struct dwarf_section *section, case DW_CFA_val_offset: READ_ULEB (reg, start, block_end); READ_ULEB (roffs, start, block_end); - if (reg >= (unsigned int) fc->ncols) + 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", @@ -9600,7 +9593,7 @@ display_debug_frames (struct dwarf_section *section, case DW_CFA_restore_extended: READ_ULEB (reg, start, block_end); - if (reg >= (unsigned int) fc->ncols) + if (reg >= fc->ncols) reg_prefix = bad_reg; if (! do_debug_frames_interp || *reg_prefix != '\0') printf (" DW_CFA_restore_extended: %s%s\n", @@ -9608,7 +9601,8 @@ display_debug_frames (struct dwarf_section *section, if (*reg_prefix != '\0') break; - if (reg >= (unsigned int) cie->ncols) + if (reg >= cie->ncols + || cie->col_type[reg] == DW_CFA_unreferenced) { fc->col_type[reg] = DW_CFA_undefined; fc->col_offset[reg] = 0; @@ -9622,7 +9616,7 @@ display_debug_frames (struct dwarf_section *section, case DW_CFA_undefined: READ_ULEB (reg, start, block_end); - if (reg >= (unsigned int) fc->ncols) + if (reg >= fc->ncols) reg_prefix = bad_reg; if (! do_debug_frames_interp || *reg_prefix != '\0') printf (" DW_CFA_undefined: %s%s\n", @@ -9636,7 +9630,7 @@ display_debug_frames (struct dwarf_section *section, case DW_CFA_same_value: READ_ULEB (reg, start, block_end); - if (reg >= (unsigned int) fc->ncols) + if (reg >= fc->ncols) reg_prefix = bad_reg; if (! do_debug_frames_interp || *reg_prefix != '\0') printf (" DW_CFA_same_value: %s%s\n", @@ -9651,7 +9645,7 @@ display_debug_frames (struct dwarf_section *section, case DW_CFA_register: READ_ULEB (reg, start, block_end); READ_ULEB (roffs, start, block_end); - if (reg >= (unsigned int) fc->ncols) + if (reg >= fc->ncols) reg_prefix = bad_reg; if (! do_debug_frames_interp || *reg_prefix != '\0') { @@ -9761,7 +9755,7 @@ display_debug_frames (struct dwarf_section *section, case DW_CFA_expression: READ_ULEB (reg, start, block_end); READ_ULEB (ul, start, block_end); - if (reg >= (unsigned int) fc->ncols) + if (reg >= fc->ncols) reg_prefix = bad_reg; /* PR 17512: file: 069-133014-0.006. */ /* PR 17512: file: 98c02eb4. */ @@ -9786,7 +9780,7 @@ display_debug_frames (struct dwarf_section *section, case DW_CFA_val_expression: READ_ULEB (reg, start, block_end); READ_ULEB (ul, start, block_end); - if (reg >= (unsigned int) fc->ncols) + if (reg >= fc->ncols) reg_prefix = bad_reg; if (ul > (size_t) (block_end - start)) { @@ -9809,7 +9803,7 @@ display_debug_frames (struct dwarf_section *section, case DW_CFA_offset_extended_sf: READ_ULEB (reg, start, block_end); READ_SLEB (l, start, block_end); - if (frame_need_space (fc, reg) < 0) + 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%+ld\n", @@ -9825,7 +9819,7 @@ display_debug_frames (struct dwarf_section *section, case DW_CFA_val_offset_sf: READ_ULEB (reg, start, block_end); READ_SLEB (l, start, block_end); - if (frame_need_space (fc, reg) < 0) + 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%+ld\n", @@ -9885,7 +9879,7 @@ display_debug_frames (struct dwarf_section *section, READ_ULEB (reg, start, block_end); READ_SLEB (l, start, block_end); l = - l; - if (frame_need_space (fc, reg) < 0) + 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%+ld\n", diff --git a/gas/testsuite/gas/i386/ehinterp.d b/gas/testsuite/gas/i386/ehinterp.d new file mode 100644 index 00000000000..5b6ac858709 --- /dev/null +++ b/gas/testsuite/gas/i386/ehinterp.d @@ -0,0 +1,20 @@ +#readelf: --debug-dump=frames-interp + +Contents of the \.eh_frame section: + +0+ 0+14 0+ CIE "zR" cf=1 df=-8 ra=16 + +LOC +CFA +ra * +0+ rsp\+8 +c-8 * + +0+18 0+10 0+1c FDE cie=0+ pc=0+..0+6 + +LOC +CFA +ra * +0+ rsp\+8 +c-8 * +0+4 rsp\+8 +u * + +0+2c 0+20 0+30 FDE cie=0+ pc=0+6..0+24 + +LOC +CFA +rbp +ra * +0+6 rsp\+8 +u +c-8 * +0+b rsp\+16 +c-16 +c-8 * +0+e rbp\+16 +c-16 +c-8 * +0+23 rsp\+8 +c-16 +c-8 * + diff --git a/gas/testsuite/gas/i386/ehinterp.s b/gas/testsuite/gas/i386/ehinterp.s new file mode 100644 index 00000000000..634cef1aab3 --- /dev/null +++ b/gas/testsuite/gas/i386/ehinterp.s @@ -0,0 +1,35 @@ + .file "hello.c" + .text + .section .rodata +.LC0: + .string "Hello" + .text + .globl dummy + .type dummy, @function +dummy: + .cfi_startproc + endbr64 + .cfi_undefined rip + jmp . + .cfi_endproc + .size dummy, .-dummy + + .globl main + .type main, @function +main: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + leaq .LC0(%rip), %rax + movq %rax, %rdi + call puts@PLT + movl $0, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc + .size main, .-main diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index 99a11ebde78..a4fc5b4096b 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -1339,7 +1339,7 @@ if [gas_64_check] then { if {[istarget "*-*-linux*"]} then { run_dump_test "x86-64-align-branch-3" } - + run_dump_test ehinterp } run_dump_test pr27198 -- Alan Modra Australia Development Lab, IBM