From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by sourceware.org (Postfix) with ESMTP id 1592A3850426 for ; Fri, 8 Jan 2021 08:05:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 1592A3850426 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-168-NV8Y4qPxPk-N1828C2Bfjw-1; Fri, 08 Jan 2021 03:05:00 -0500 X-MC-Unique: NV8Y4qPxPk-N1828C2Bfjw-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 9015610054FF for ; Fri, 8 Jan 2021 08:04:59 +0000 (UTC) Received: from hostfoo.redhat.com (ovpn-112-148.ams2.redhat.com [10.36.112.148]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5E44D19442 for ; Fri, 8 Jan 2021 08:04:57 +0000 (UTC) From: tbaeder@redhat.com To: elfutils-devel@sourceware.org Subject: [PATCH 2/4] strip: Pull relocate() info file scope Date: Fri, 8 Jan 2021 09:04:47 +0100 Message-Id: <20210108080449.2201310-3-tbaeder@redhat.com> In-Reply-To: <20210108080449.2201310-1-tbaeder@redhat.com> References: <20210108080449.2201310-1-tbaeder@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-14.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 08 Jan 2021 08:05:08 -0000 From: Timm Bäder Pull relocate() info file scope and get rid of a nested function this way. Refactor remove_debug_relocations() to minimize the parameters we need to pass to relocate(). Signed-off-by: Timm Bäder --- src/strip.c | 347 ++++++++++++++++++++++++++++------------------------ 1 file changed, 184 insertions(+), 163 deletions(-) diff --git a/src/strip.c b/src/strip.c index c971b6c2..71913fac 100644 --- a/src/strip.c +++ b/src/strip.c @@ -442,6 +442,127 @@ update_shdrstrndx (Elf *elf, size_t shdrstrndx) return 0; } + +/* Apply one relocation. Returns true when trivial + relocation actually done. */ +static bool +relocate (Elf *elf, GElf_Addr offset, const GElf_Sxword addend, + Elf_Data *tdata, unsigned int ei_data, const char *fname, + bool is_rela, GElf_Sym *sym, int addsub, Elf_Type type) +{ + /* These are the types we can relocate. */ +#define TYPES DO_TYPE (BYTE, Byte); DO_TYPE (HALF, Half); \ + DO_TYPE (WORD, Word); DO_TYPE (SWORD, Sword); \ + DO_TYPE (XWORD, Xword); DO_TYPE (SXWORD, Sxword) + + size_t size; + +#define DO_TYPE(NAME, Name) GElf_##Name Name; + union { TYPES; } tmpbuf; +#undef DO_TYPE + + switch (type) + { +#define DO_TYPE(NAME, Name) \ + case ELF_T_##NAME: \ + size = sizeof (GElf_##Name); \ + tmpbuf.Name = 0; \ + break; + TYPES; +#undef DO_TYPE + default: + return false; + } + + if (offset > tdata->d_size + || tdata->d_size - offset < size) + { + cleanup_debug (); + error (EXIT_FAILURE, 0, _("bad relocation")); + } + + /* When the symbol value is zero then for SHT_REL + sections this is all that needs to be checked. + The addend is contained in the original data at + the offset already. So if the (section) symbol + address is zero and the given addend is zero + just remove the relocation, it isn't needed + anymore. */ + if (addend == 0 && sym->st_value == 0) + return true; + + Elf_Data tmpdata = + { + .d_type = type, + .d_buf = &tmpbuf, + .d_size = size, + .d_version = EV_CURRENT, + }; + Elf_Data rdata = + { + .d_type = type, + .d_buf = tdata->d_buf + offset, + .d_size = size, + .d_version = EV_CURRENT, + }; + + GElf_Addr value = sym->st_value; + if (is_rela) + { + /* For SHT_RELA sections we just take the + given addend and add it to the value. */ + value += addend; + /* For ADD/SUB relocations we need to fetch the + current section contents. */ + if (addsub != 0) + { + Elf_Data *d = gelf_xlatetom (elf, &tmpdata, + &rdata, + ei_data); + if (d == NULL) + INTERNAL_ERROR (fname); + assert (d == &tmpdata); + } + } + else + { + /* For SHT_REL sections we have to peek at + what is already in the section at the given + offset to get the addend. */ + Elf_Data *d = gelf_xlatetom (elf, &tmpdata, + &rdata, + ei_data); + if (d == NULL) + INTERNAL_ERROR (fname); + assert (d == &tmpdata); + } + + switch (type) + { +#define DO_TYPE(NAME, Name) \ + case ELF_T_##NAME: \ + if (addsub < 0) \ + tmpbuf.Name -= (GElf_##Name) value; \ + else \ + tmpbuf.Name += (GElf_##Name) value; \ + break; + TYPES; +#undef DO_TYPE + default: + abort (); + } + + /* Now finally put in the new value. */ + Elf_Data *s = gelf_xlatetof (elf, &rdata, + &tmpdata, + ei_data); + if (s == NULL) + INTERNAL_ERROR (fname); + assert (s == &rdata); + + return true; +} + /* Remove any relocations between debug sections in ET_REL for the debug file when requested. These relocations are always zero based between the unallocated sections. */ @@ -517,180 +638,80 @@ remove_debug_relocations (Ebl *ebl, Elf *elf, GElf_Ehdr *ehdr, if (symdata == NULL) INTERNAL_ERROR (fname); - /* Apply one relocation. Returns true when trivial - relocation actually done. */ - bool relocate (GElf_Addr offset, const GElf_Sxword addend, - bool is_rela, int rtype, int symndx) - { - /* R_*_NONE relocs can always just be removed. */ - if (rtype == 0) - return true; + if (shdr->sh_entsize == 0) + INTERNAL_ERROR (fname); - /* We only do simple absolute relocations. */ - int addsub = 0; - Elf_Type type = ebl_reloc_simple_type (ebl, rtype, &addsub); - if (type == ELF_T_NUM) - return false; + size_t nrels = shdr->sh_size / shdr->sh_entsize; + size_t next = 0; + const bool is_rela = (shdr->sh_type == SHT_RELA); + const unsigned int ei_data = ehdr->e_ident[EI_DATA]; - /* These are the types we can relocate. */ -#define TYPES DO_TYPE (BYTE, Byte); DO_TYPE (HALF, Half); \ - DO_TYPE (WORD, Word); DO_TYPE (SWORD, Sword); \ - DO_TYPE (XWORD, Xword); DO_TYPE (SXWORD, Sxword) - - /* And only for relocations against other debug sections. */ - GElf_Sym sym_mem; - Elf32_Word xndx; - GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata, - symndx, &sym_mem, - &xndx); - Elf32_Word sec = (sym->st_shndx == SHN_XINDEX - ? xndx : sym->st_shndx); - - if (ebl_debugscn_p (ebl, secndx_name (elf, sec))) - { - size_t size; + for (size_t relidx = 0; relidx < nrels; ++relidx) + { + int rtype, symndx, offset, addend; + union { GElf_Rela rela; GElf_Rel rel; } mem; + void *rel_p; /* Pointer to either rela or rel above */ -#define DO_TYPE(NAME, Name) GElf_##Name Name; - union { TYPES; } tmpbuf; -#undef DO_TYPE + if (is_rela) + { + GElf_Rela *r = gelf_getrela (reldata, relidx, &mem.rela); + offset = r->r_offset; + addend = r->r_addend; + rtype = GELF_R_TYPE (r->r_info); + symndx = GELF_R_SYM (r->r_info); + rel_p = r; + } + else + { + GElf_Rel *r = gelf_getrel (reldata, relidx, &mem.rel); + offset = r->r_offset; + addend = 0; + rtype = GELF_R_TYPE (r->r_info); + symndx = GELF_R_SYM (r->r_info); + rel_p = r; + } - switch (type) - { -#define DO_TYPE(NAME, Name) \ - case ELF_T_##NAME: \ - size = sizeof (GElf_##Name); \ - tmpbuf.Name = 0; \ - break; - TYPES; -#undef DO_TYPE - default: - return false; - } + /* R_*_NONE relocs can always just be removed. */ + if (rtype == 0) + continue; - if (offset > tdata->d_size - || tdata->d_size - offset < size) - { - cleanup_debug (); - error (EXIT_FAILURE, 0, _("bad relocation")); - } + /* We only do simple absolute relocations. */ + int addsub = 0; + Elf_Type type = ebl_reloc_simple_type (ebl, rtype, &addsub); + if (type == ELF_T_NUM) + goto relocate_failed; - /* When the symbol value is zero then for SHT_REL - sections this is all that needs to be checked. - The addend is contained in the original data at - the offset already. So if the (section) symbol - address is zero and the given addend is zero - just remove the relocation, it isn't needed - anymore. */ - if (addend == 0 && sym->st_value == 0) - return true; - - Elf_Data tmpdata = - { - .d_type = type, - .d_buf = &tmpbuf, - .d_size = size, - .d_version = EV_CURRENT, - }; - Elf_Data rdata = - { - .d_type = type, - .d_buf = tdata->d_buf + offset, - .d_size = size, - .d_version = EV_CURRENT, - }; - - GElf_Addr value = sym->st_value; - if (is_rela) - { - /* For SHT_RELA sections we just take the - given addend and add it to the value. */ - value += addend; - /* For ADD/SUB relocations we need to fetch the - current section contents. */ - if (addsub != 0) - { - Elf_Data *d = gelf_xlatetom (elf, &tmpdata, - &rdata, - ehdr->e_ident[EI_DATA]); - if (d == NULL) - INTERNAL_ERROR (fname); - assert (d == &tmpdata); - } - } - else - { - /* For SHT_REL sections we have to peek at - what is already in the section at the given - offset to get the addend. */ - Elf_Data *d = gelf_xlatetom (elf, &tmpdata, - &rdata, - ehdr->e_ident[EI_DATA]); - if (d == NULL) - INTERNAL_ERROR (fname); - assert (d == &tmpdata); - } + /* And only for relocations against other debug sections. */ + GElf_Sym sym_mem; + Elf32_Word xndx; + GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata, + symndx, &sym_mem, + &xndx); + Elf32_Word sec = (sym->st_shndx == SHN_XINDEX + ? xndx : sym->st_shndx); - switch (type) - { -#define DO_TYPE(NAME, Name) \ - case ELF_T_##NAME: \ - if (addsub < 0) \ - tmpbuf.Name -= (GElf_##Name) value; \ - else \ - tmpbuf.Name += (GElf_##Name) value; \ - break; - TYPES; -#undef DO_TYPE - default: - abort (); - } + bool dbg_scn = ebl_debugscn_p (ebl, secndx_name (elf, sec)); - /* Now finally put in the new value. */ - Elf_Data *s = gelf_xlatetof (elf, &rdata, - &tmpdata, - ehdr->e_ident[EI_DATA]); - if (s == NULL) - INTERNAL_ERROR (fname); - assert (s == &rdata); + if (!dbg_scn) + goto relocate_failed; - return true; - } - return false; - } + if (! relocate (elf, offset, addend, + tdata, ei_data, fname, is_rela, + sym, addsub, type)) + goto relocate_failed; - if (shdr->sh_entsize == 0) - INTERNAL_ERROR (fname); + continue; /* Next */ - size_t nrels = shdr->sh_size / shdr->sh_entsize; - size_t next = 0; - if (shdr->sh_type == SHT_REL) - for (size_t relidx = 0; relidx < nrels; ++relidx) - { - GElf_Rel rel_mem; - GElf_Rel *r = gelf_getrel (reldata, relidx, &rel_mem); - if (! relocate (r->r_offset, 0, false, - GELF_R_TYPE (r->r_info), - GELF_R_SYM (r->r_info))) - { - if (relidx != next) - gelf_update_rel (reldata, next, r); - ++next; - } - } - else - for (size_t relidx = 0; relidx < nrels; ++relidx) - { - GElf_Rela rela_mem; - GElf_Rela *r = gelf_getrela (reldata, relidx, &rela_mem); - if (! relocate (r->r_offset, r->r_addend, true, - GELF_R_TYPE (r->r_info), - GELF_R_SYM (r->r_info))) - { - if (relidx != next) - gelf_update_rela (reldata, next, r); - ++next; - } - } +relocate_failed: + if (relidx != next) + { + if (is_rela) + gelf_update_rela (reldata, next, rel_p); + else + gelf_update_rel (reldata, next, rel_p); + } + ++next; + } nrels = next; shdr->sh_size = reldata->d_size = nrels * shdr->sh_entsize; -- 2.26.2