Author: emaste
Date: Sat Oct 13 21:26:07 2018
New Revision: 339350
URL: https://svnweb.freebsd.org/changeset/base/339350

Log:
  elfcopy: delete filter_reloc, it is broken and unnecessary
  
  elfcopy contained logic to filter individual relocations in STRIP_ALL
  mode.  However, this is not valid; relocations emitted by the linker are
  required, unless they apply to an entire section being removed (which is
  handled by other logic in elfcopy).
  
  Note that filter_reloc was also buggy: for RELA relocation sections it
  operated on uninitialized rel.r_info resulting in invalid operation.
  
  The logic most likely needs to be inverted: instead of removing
  relocations because their associated symbols are being removed, we must
  keep symbols referenced by relocations.  That said, in practice we do
  not encounter this code path today: objects being stripped are either
  dynamically linked binaries which retain .dynsym, or static binaries
  with no relocations.
  
  Just remove filter_reloc.  This fixes certain cases including statically
  linked binaries containing ifuncs.  Stripping binaries with relocations
  referencing removed symbols was already broken, and after this change
  may still be broken in a different way.
  
  PR:           232176
  Reviewed by:  kaiw, kib, markj
  Approved by:  re (rgrimes)
  MFC after:    1 month
  Sponsored by: The FreeBSD Foundation
  Differential Revision:        https://reviews.freebsd.org/D17519

Modified:
  head/contrib/elftoolchain/elfcopy/sections.c

Modified: head/contrib/elftoolchain/elfcopy/sections.c
==============================================================================
--- head/contrib/elftoolchain/elfcopy/sections.c        Sat Oct 13 21:18:31 
2018        (r339349)
+++ head/contrib/elftoolchain/elfcopy/sections.c        Sat Oct 13 21:26:07 
2018        (r339350)
@@ -39,7 +39,6 @@ ELFTC_VCSID("$Id: sections.c 3443 2016-04-15 18:57:54Z
 static void    add_gnu_debuglink(struct elfcopy *ecp);
 static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc);
 static void    check_section_rename(struct elfcopy *ecp, struct section *s);
-static void    filter_reloc(struct elfcopy *ecp, struct section *s);
 static int     get_section_flags(struct elfcopy *ecp, const char *name);
 static void    insert_sections(struct elfcopy *ecp);
 static void    insert_to_strtab(struct section *t, const char *s);
@@ -574,14 +573,6 @@ copy_content(struct elfcopy *ecp)
                        continue;
 
                /*
-                * If strip action is STRIP_ALL, relocation info need
-                * to be stripped. Skip filtering otherwisw.
-                */
-               if (ecp->strip == STRIP_ALL &&
-                   (s->type == SHT_REL || s->type == SHT_RELA))
-                       filter_reloc(ecp, s);
-
-               /*
                 * The section indices in the SHT_GROUP section needs
                 * to be updated since we might have stripped some
                 * sections and changed section numbering.
@@ -670,125 +661,6 @@ update_section_group(struct elfcopy *ecp, struct secti
                        s->sz -= 4;
        }
 
-       s->nocopy = 1;
-}
-
-/*
- * Filter relocation entries, only keep those entries whose
- * symbol is in the keep list.
- */
-static void
-filter_reloc(struct elfcopy *ecp, struct section *s)
-{
-       const char      *name;
-       GElf_Shdr        ish;
-       GElf_Rel         rel;
-       GElf_Rela        rela;
-       Elf32_Rel       *rel32;
-       Elf64_Rel       *rel64;
-       Elf32_Rela      *rela32;
-       Elf64_Rela      *rela64;
-       Elf_Data        *id;
-       uint64_t         cap, n, nrels;
-       int              elferr, i;
-
-       if (gelf_getshdr(s->is, &ish) == NULL)
-               errx(EXIT_FAILURE, "gelf_getehdr() failed: %s",
-                   elf_errmsg(-1));
-
-       /* We don't want to touch relocation info for dynamic symbols. */
-       if ((ecp->flags & SYMTAB_EXIST) == 0) {
-               if (ish.sh_link == 0 || ecp->secndx[ish.sh_link] == 0) {
-                       /*
-                        * This reloc section applies to the symbol table
-                        * that was stripped, so discard whole section.
-                        */
-                       s->nocopy = 1;
-                       s->sz = 0;
-               }
-               return;
-       } else {
-               /* Symbol table exist, check if index equals. */
-               if (ish.sh_link != elf_ndxscn(ecp->symtab->is))
-                       return;
-       }
-
-#define        COPYREL(REL, SZ) do {                                   \
-       if (nrels == 0) {                                       \
-               if ((REL##SZ = malloc(cap *                     \
-                   sizeof(*REL##SZ))) == NULL)                 \
-                       err(EXIT_FAILURE, "malloc failed");     \
-       }                                                       \
-       if (nrels >= cap) {                                     \
-               cap *= 2;                                       \
-               if ((REL##SZ = realloc(REL##SZ, cap *           \
-                   sizeof(*REL##SZ))) == NULL)                 \
-                       err(EXIT_FAILURE, "realloc failed");    \
-       }                                                       \
-       REL##SZ[nrels].r_offset = REL.r_offset;                 \
-       REL##SZ[nrels].r_info   = REL.r_info;                   \
-       if (s->type == SHT_RELA)                                \
-               rela##SZ[nrels].r_addend = rela.r_addend;       \
-       nrels++;                                                \
-} while (0)
-
-       nrels = 0;
-       cap = 4;                /* keep list is usually small. */
-       rel32 = NULL;
-       rel64 = NULL;
-       rela32 = NULL;
-       rela64 = NULL;
-       if ((id = elf_getdata(s->is, NULL)) == NULL)
-               errx(EXIT_FAILURE, "elf_getdata() failed: %s",
-                   elf_errmsg(-1));
-       n = ish.sh_size / ish.sh_entsize;
-       for(i = 0; (uint64_t)i < n; i++) {
-               if (s->type == SHT_REL) {
-                       if (gelf_getrel(id, i, &rel) != &rel)
-                               errx(EXIT_FAILURE, "gelf_getrel failed: %s",
-                                   elf_errmsg(-1));
-               } else {
-                       if (gelf_getrela(id, i, &rela) != &rela)
-                               errx(EXIT_FAILURE, "gelf_getrel failed: %s",
-                                   elf_errmsg(-1));
-               }
-               name = elf_strptr(ecp->ein, elf_ndxscn(ecp->strtab->is),
-                   GELF_R_SYM(rel.r_info));
-               if (name == NULL)
-                       errx(EXIT_FAILURE, "elf_strptr failed: %s",
-                           elf_errmsg(-1));
-               if (lookup_symop_list(ecp, name, SYMOP_KEEP) != NULL) {
-                       if (ecp->oec == ELFCLASS32) {
-                               if (s->type == SHT_REL)
-                                       COPYREL(rel, 32);
-                               else
-                                       COPYREL(rela, 32);
-                       } else {
-                               if (s->type == SHT_REL)
-                                       COPYREL(rel, 64);
-                               else
-                                       COPYREL(rela, 64);
-                       }
-               }
-       }
-       elferr = elf_errno();
-       if (elferr != 0)
-               errx(EXIT_FAILURE, "elf_getdata() failed: %s",
-                   elf_errmsg(elferr));
-
-       if (ecp->oec == ELFCLASS32) {
-               if (s->type == SHT_REL)
-                       s->buf = rel32;
-               else
-                       s->buf = rela32;
-       } else {
-               if (s->type == SHT_REL)
-                       s->buf = rel64;
-               else
-                       s->buf = rela64;
-       }
-       s->sz = gelf_fsize(ecp->eout, (s->type == SHT_REL ? ELF_T_REL :
-           ELF_T_RELA), nrels, EV_CURRENT);
        s->nocopy = 1;
 }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to