From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 112560 invoked by alias); 6 Feb 2018 11:51:19 -0000 Mailing-List: contact elfutils-devel-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Post: List-Help: List-Subscribe: Sender: elfutils-devel-owner@sourceware.org Received: (qmail 112435 invoked by uid 89); 6 Feb 2018 11:50:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Checked: by ClamAV 0.99.2 on sourceware.org X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=HTo:U*elfutils-devel, H*Ad:U*elfutils-devel, H*MI:localdomain X-Spam-Status: No, score=-26.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on sourceware.org X-Spam-Level: X-HELO: mail-lf0-f46.google.com Received: from mail-lf0-f46.google.com (HELO mail-lf0-f46.google.com) (209.85.215.46) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 06 Feb 2018 11:50:52 +0000 Received: by mail-lf0-f46.google.com with SMTP id x196so2288802lfd.12 for ; Tue, 06 Feb 2018 03:50:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:subject:message-id:mime-version:content-disposition :user-agent; bh=CM/yEGoMeqET744dzC8DACJ6LtO268dUeeGB8Ki0+xc=; b=urE0E2/6fD6aBku+cxVPYSyX4cDF7dW+nO1Dh8Z5DqWZhiEhvTcCfknA9X2RAXmTVg Dr9NQOWAK3vmChaOEHpPhziFO6O+jossnLN+Y3/7aakzNmUhavvCc3HIBuF74bqJgmzd 1Fi70MCulZPoqYVZiL1U527lk3uxe2Otbs2L+AOfinrQgEJWC5jEnM/6maN2fkziixYv px5+BvTjIiWD43ZxkvTCyRYAUatEs2Nh/4TIDvSVB3BNbXMXjh4u2KV0T4v7pqbVFI19 Jm9kaM9ab2naTkoZYytdIG3RVcBWCYSfOc0tToHGmaeIBsMZk7gwJlVxeM7e/xFt7C80 htCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition:user-agent; bh=CM/yEGoMeqET744dzC8DACJ6LtO268dUeeGB8Ki0+xc=; b=dRlPvm8+2QGH1rkYtKX79hS11NPXSpSehaFQzWCgsuDd5GNxbzj6MVG/M8oBnrMZ7V /hqFJIpmqkXkQ5MTicDx0+PjZaqlzRQplnlt8bc4AG64QoGOH0ulrGt0CMLiXwjfq82C dhXTCwOp4+RQgD0zDjQBPOiAe8hN4RXgTDAIJzEaOsQA6Z4mpXSujRCYCNpF+liz9ODx BvZtcfD0BS7cIker4p5M4ZUIlmsSPC1kFAcvl+MBtv0OIRQatN7xuuDeEiQHtjDr99ir CJmj/N5XBp7fFsoybCp78PhpIV9g7L5ghPmoKkfeeZxdtvIT3ExumbtkzcYRy85SFkEW qehg== X-Gm-Message-State: APf1xPCME8tpAg+LQ3N47vMSYPQUKzA9H9/t+xJtHYfP4sgs3/hu5Toa M/E0gZSEUemVwhsjLADYO8A6Cg== X-Google-Smtp-Source: AH8x227UhM/s6S57H+OpVdmmFThd7kVcOqCoV4dp8dBbxqZtcaK9HZaWUgipBdheNadSmOFTduoyMg== X-Received: by 10.25.201.81 with SMTP id z78mr1415872lff.74.1517917849827; Tue, 06 Feb 2018 03:50:49 -0800 (PST) Received: from celery.localdomain ([109.94.180.5]) by smtp.gmail.com with ESMTPSA id p12sm2281357ljb.95.2018.02.06.03.50.48 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 06 Feb 2018 03:50:49 -0800 (PST) Date: Tue, 06 Feb 2018 11:51:00 -0000 From: Alexey Tourbin To: elfutils-devel@sourceware.org Subject: [PATCH] dwz.c: special-case SHT_NOBITS sections Message-ID: <20180206115046.GA3233@celery.localdomain> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.8.3 (2017-05-23) X-IsSubscribed: yes X-SW-Source: 2018-q1/txt/msg00019.txt.bz2 When eu-strip is used to create separate .debug files, and is invoked with the --strip-debug option instead of --strip-all, the .symtab section is kept in a.out, but eu-strip also creates an empty .symtab section in a.out.debug with type NOBITS, but with the original size. Section Headers: [Nr] Name Type Address Off Size ES Flg Lk Inf Al - [33] .symtab SYMTAB 0000000000000000 002b10 0006a8 18 34 55 8 - [34] .strtab STRTAB 0000000000000000 0031b8 0001d1 00 0 0 1 + [33] .symtab NOBITS 0000000000000000 002110 0006a8 18 34 55 8 + [34] .strtab NOBITS 0000000000000000 002110 0001d1 00 0 0 1 This makes dwz fail with the following message: dwz: Section offsets in a.out.debug not monotonically increasing This is because dwz does not take into account the possibility of SHT_NOBITS sections, and always increments sh_offset by sh_size. So one way to fix this would be to disable writing of empty sections in eu-strip. However, this seems to be the expected behavior, which also matches the behavior of the strip program from binutils (regarding its "--only-keep-debug" option, the manpage reads: "the section headers of the stripped sections are preserved, including their sizes, but the contents of the section are discarded.") Thus the next best thing is to actually teach dwz about NOBITS sections (this is a subtle reference to the fact that dwz doesn't have a mailing list or a dedicated sourceware.org/bugzilla component, so dealing with dwz might be a bit harder in this respect.) After the patch was first drafted, I came across a similar patch by Richard Guenther . He goes much further in that he tries to handle truly unordered sections by qsorting them first. Richard explains such binaries can be created by the kernel linker script. As I only need to use dwz with userland programs - moreover, I want to ensure that those programs meet certain criteria - I decided to proceed with this much simpler patch of my own that does not permit truly unordered sections. More specifically, I only need to apply dwz to separate .debug files, and I expect it to keep their sections in the same order as in the original executable or shared object. There are other differences: in Richard's patch, NOBITS sections are simply ignored, and their offsets are not updated, - in other words, they are left technically unordered in the output. Here's a simple test case reproducible on Fedora 27 x86-64. The patch covers a larger set of cases by also handling allocatable NOBITS sections as well as non-allocatable. echo 'int main(){}' >test.c gcc -g -O2 test.c eu-strip --strip-debug -f a.out.debug dwz a.out.debug --- dwz.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/dwz.c b/dwz.c index b3b779d..01bc553 100644 --- a/dwz.c +++ b/dwz.c @@ -10141,7 +10141,8 @@ write_dso (DSO *dso, const char *file, struct stat *st) for (j = 1; j < dso->ehdr.e_shnum; ++j) if (dso->shdr[j].sh_offset < min_shoff && !last_shoff) continue; - else if ((dso->shdr[j].sh_flags & SHF_ALLOC) != 0) + else if ((dso->shdr[j].sh_flags & SHF_ALLOC) != 0 + && dso->shdr[j].sh_type != SHT_NOBITS) { error (0, 0, "Allocatable section in %s after non-allocatable " "ones", dso->filename); @@ -10157,7 +10158,9 @@ write_dso (DSO *dso, const char *file, struct stat *st) { if (k == -1) k = j; - last_shoff = dso->shdr[j].sh_offset + dso->shdr[j].sh_size; + last_shoff = dso->shdr[j].sh_offset; + if (dso->shdr[j].sh_type != SHT_NOBITS) + last_shoff += dso->shdr[j].sh_size; } last_shoff = min_shoff; for (j = k; j <= dso->ehdr.e_shnum; ++j) @@ -10181,7 +10184,9 @@ write_dso (DSO *dso, const char *file, struct stat *st) dso->shdr[j].sh_offset = (last_shoff + dso->shdr[j].sh_addralign - 1) & ~(dso->shdr[j].sh_addralign - (GElf_Off) 1); - last_shoff = dso->shdr[j].sh_offset + dso->shdr[j].sh_size; + last_shoff = dso->shdr[j].sh_offset; + if (dso->shdr[j].sh_type != SHT_NOBITS) + last_shoff += dso->shdr[j].sh_size; if (addsec != -1 && j == addsec) last_shoff += addsize; } -- 2.10.4