From patchwork Thu Mar 8 22:25:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jozef Lawrynowicz X-Patchwork-Id: 26245 Received: (qmail 3842 invoked by alias); 8 Mar 2018 22:26:05 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 3832 invoked by uid 89); 8 Mar 2018 22:26:04 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_NUMSUBJECT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=HX-Received:10.28.1.208, H*RU:2a00, Hx-spam-relays-external:2a00 X-HELO: mail-wm0-f48.google.com Received: from mail-wm0-f48.google.com (HELO mail-wm0-f48.google.com) (74.125.82.48) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 08 Mar 2018 22:26:02 +0000 Received: by mail-wm0-f48.google.com with SMTP id 139so643995wmn.2 for ; Thu, 08 Mar 2018 14:26:01 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:to:from:subject:message-id:date:user-agent :mime-version:content-language; bh=1rl7btGevEbeJwsZagvsdm4pwVCU/JsvQFsgk2oPQec=; b=g0cK6OkKFji+Np0RNnyYe4Y5SRULrh1smbAYvHmsT+LFZT9ZkHBCsL92jP5LxIFo+S vmf5BjEzkkUS8P03/wkFga0Km5CSqythlMmnMnLlg34/AJNzd32FPIGHbp2PrRaV1h9O qHgp7vK/zyl5h/8y5yPZc1pjIGj6krCptmAi0+/Hy3ZhwFl9gGJcGKZDDkhuR8j9QpJx AAFnreKVwjEUpGcOXMJN74lDInWEB0iLofR2NRpjxucphshnZ0dieu4oU/r9l63uIEo3 13KRQvRZvr6PpkUL0/gt8OSP6if/l4AklXiBmoua6m7IKooQxoZ66IRaLgYf34/AdJ+4 diOg== X-Gm-Message-State: AElRT7EEAONOTSa1Mm9E4JGoJkItGa0hPmwTfOVbnysTnDk6BQzQUegf v2yikNqEYdPzW30ZcvWAqafI6CFWjGM= X-Google-Smtp-Source: AG47ELsSpt89XguwoN1PhK3VVQcidryOjAes48LP58a+2MpZNmqj9ADk6xVnFAnPhkzBlQLuejR57Q== X-Received: by 10.28.1.208 with SMTP id 199mr296084wmb.26.1520547959897; Thu, 08 Mar 2018 14:25:59 -0800 (PST) Received: from ?IPv6:2a00:23c5:e02:ea00:35f7:fa4a:c17a:172c? ([2a00:23c5:e02:ea00:35f7:fa4a:c17a:172c]) by smtp.gmail.com with ESMTPSA id v75sm47442834wrb.76.2018.03.08.14.25.59 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 08 Mar 2018 14:25:59 -0800 (PST) To: gdb-patches@sourceware.org From: Jozef Lawrynowicz Subject: [PATCH] Fix seg fault with --write PR gdb/20948 Message-ID: <845cbec4-aa1d-005e-b7f3-d010ecd8cf74@mittosystems.com> Date: Thu, 8 Mar 2018 22:25:58 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 GDB segfaults when invoking it with the --write option, then quitting. First reported in PR gdb/20948. An assertion fails because elf_shstrtab is uninitialized, and elf_shstrtab is only initialized if abfd_output_has_begun is FALSE. bfd/format.c:bfd_check_format_matches as called from gdb/exec.c:exec_file_attach always sets output_has_begun to TRUE if the bfd was opened for update, so the attached patch sets output_has_begun back to FALSE in exec_file_attach when we return from bfd_check_format_matches. This leads to a further assertion failure in bfd/elf.c:assign_file_positions_for_non_load_sections: BFD_ASSERT (hdr->sh_offset == hdr->bfd_section->filepos); filepos for non-load sections has been set already, but sh_offset is 0 as it needs to be set by _bfd_elf_assign_file_position_for_section, which is called in a further conditional block. So this first conditional has been extended to evaluate to FALSE if sh_offset == 0 but filepos != 0. The attached patche includes tests which verify that the --write behaviour works as expected i.e. that modifications to the loaded executable persist once the GDB session is ended. For Unix and msp430-elf targets, completed testing for binutils, gas, ld, gdb, sim (for msp430) without regressions. If the patch is acceptable, I would appreciate if someone could commit it for me as I don't have write access. From 5a9c30cac1edbdd8675025dc3faffa6e6544487d Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Wed, 7 Mar 2018 16:57:15 +0000 Subject: [PATCH] Fix GDB segfault with --write 2018-03-08 Jozef Lawrynowicz Fix PR gdb/20948 bfd/ * elf.c (assign_file_positions_for_non_load_sections): Allow hdr->sh_offset to be set by function if hdr->bfd_section->filepos != 0. gdb/ * exec.c (exec_file_attach): Set output_has_begun to FALSE for the bfd if write_files is TRUE. gdb/testsuite/gdb.base/ * write_mem.exp: New test. * write_mem.c: New test source file. --- bfd/elf.c | 9 ++++++++- gdb/exec.c | 4 ++++ gdb/testsuite/gdb.base/write_mem.c | 5 +++++ gdb/testsuite/gdb.base/write_mem.exp | 31 +++++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 gdb/testsuite/gdb.base/write_mem.c create mode 100644 gdb/testsuite/gdb.base/write_mem.exp diff --git a/bfd/elf.c b/bfd/elf.c index 8ea5a81..b731e90 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -5736,7 +5736,14 @@ assign_file_positions_for_non_load_sections (bfd *abfd, hdr = *hdrpp; if (hdr->bfd_section != NULL - && (hdr->bfd_section->filepos != 0 + && (((hdr->sh_flags & SHF_ALLOC) != 0 + && hdr->bfd_section->filepos != 0) + /* If we haven't been called by the ELF linker, non load sections + may have filepos>0 but sh_offset==0, so allow this function + to set sh_offset. */ + || ((hdr->sh_flags & SHF_ALLOC) == 0 + && hdr->bfd_section->filepos != 0 + && hdr->sh_offset != 0) || (hdr->sh_type == SHT_NOBITS && hdr->contents == NULL))) BFD_ASSERT (hdr->sh_offset == hdr->bfd_section->filepos); diff --git a/gdb/exec.c b/gdb/exec.c index 6b910e8..c6662e0 100644 --- a/gdb/exec.c +++ b/gdb/exec.c @@ -351,6 +351,10 @@ exec_file_attach (const char *filename, int from_tty) gdb_bfd_errmsg (bfd_get_error (), matching)); } + /* bfd_check_format_matches assumes output_has_begun in all cases. */ + if (write_files) + exec_bfd->output_has_begun = FALSE; + if (build_section_table (exec_bfd, §ions, §ions_end)) { /* Make sure to close exec_bfd, or else "run" might try to use diff --git a/gdb/testsuite/gdb.base/write_mem.c b/gdb/testsuite/gdb.base/write_mem.c new file mode 100644 index 0000000..b72eacd --- /dev/null +++ b/gdb/testsuite/gdb.base/write_mem.c @@ -0,0 +1,5 @@ +int main (void) +{ + while (1); + return 0; +} diff --git a/gdb/testsuite/gdb.base/write_mem.exp b/gdb/testsuite/gdb.base/write_mem.exp new file mode 100644 index 0000000..558c61d --- /dev/null +++ b/gdb/testsuite/gdb.base/write_mem.exp @@ -0,0 +1,31 @@ +global GDBFLAGS + +standard_testfile + +global srcdir +global subdir + +if {[build_executable $testfile.exp $testfile \ + $srcfile [list debug nowarnings] ] == -1} { + untested $testfile.exp + return -1 +} + +clean_restart + +# Expect a failure before --write has been added to the command line +test_print_reject "set {int}&main = 0x4242" + +set old_gdbflags $GDBFLAGS +set GDBFLAGS "$old_gdbflags --write $binfile" +clean_restart + +# Setting memory should now work correctly +gdb_test_no_output "set {int}&main = 0x4242" + +# Check that memory write persists after quitting GDB +gdb_exit +gdb_start +gdb_test "x /xh main" "
:.*4242" + +set GDBFLAGS $old_gdbflags -- 2.7.4