diff options
author | Ulrich Drepper <[email protected]> | 2005-08-13 17:50:47 +0000 |
---|---|---|
committer | Ulrich Drepper <[email protected]> | 2005-08-13 17:50:47 +0000 |
commit | c5c33a6a2ce5ea400ac5d06b3c2f15808f68b803 (patch) | |
tree | 766e4fa596159c98baa73efde0730ea49f266d8e | |
parent | ad11217601d90e4bb79e4305541e7ecd9ec13182 (diff) |
Minor cleanups of last changes to elflint and libebl to support
clean ppc/ppc64 handling.
-rw-r--r-- | config/elfutils.spec.in | 6 | ||||
-rw-r--r-- | libebl/ChangeLog | 17 | ||||
-rw-r--r-- | libebl/ebl_check_special_symbol.c | 5 | ||||
-rw-r--r-- | libebl/eblbsspltp.c | 5 | ||||
-rw-r--r-- | libebl/eblopenbackend.c | 8 | ||||
-rw-r--r-- | libebl/libebl.h | 4 | ||||
-rw-r--r-- | libebl/libeblP.h | 7 | ||||
-rw-r--r-- | libebl/libebl_ppc.h | 4 | ||||
-rw-r--r-- | libebl/libebl_ppc64.h | 4 | ||||
-rw-r--r-- | libebl/ppc64_symbol.c | 13 | ||||
-rw-r--r-- | libebl/ppc_symbol.c | 73 | ||||
-rw-r--r-- | src/ChangeLog | 6 | ||||
-rw-r--r-- | src/elflint.c | 69 |
13 files changed, 125 insertions, 96 deletions
diff --git a/config/elfutils.spec.in b/config/elfutils.spec.in index 9cc91ade..f47fee48 100644 --- a/config/elfutils.spec.in +++ b/config/elfutils.spec.in @@ -183,6 +183,12 @@ rm -rf ${RPM_BUILD_ROOT} %{_libdir}/libelf.so %changelog +* Wed Aug 10 2005 Ulrich Drepper <@redhat.com> 0.113-1 +- elflint: relax a bit. Allow version definitions for defined symbols ag +ainstDSO versions also for symbols in nobits sections. Allow .rodata +sectionto have STRINGS and MERGE flag set. +- strip: add some more compatibility with binutils. + * Sat Aug 6 2005 Ulrich Drepper <@redhat.com> 0.113-1 - elflint: relax a bit. Allow version definitions for defined symbols ag ainstDSO versions also for symbols in nobits sections. Allow .rodata diff --git a/libebl/ChangeLog b/libebl/ChangeLog index 3e6c6937..eb4cdae6 100644 --- a/libebl/ChangeLog +++ b/libebl/ChangeLog @@ -1,3 +1,20 @@ +2005-08-13 Ulrich Drepper <[email protected]> + + * libebl.h: Add ehdr parameter to ebl_bss_plt_p and + ebl_check_special_symbol. + * libeblP.h (struct ebl): Adjust callback functions. + * eblopenbackend.c: Adjust dummy functions. + * ebl_check_special_symbol.c: Add parameter and pass it on. + * eblbsspltp.c: Likewise. + * ppc_symbol.c (find_dyn_got): With ehdr passed, simplify search for + the dynamic section entry. + (ppc_check_special_symbol): Add ehdr parameter. + (ppc_bss_plt_p): Likewise. + * libebl_ppc.h: Adjust prototypes. + * ppc64_symbol.c (ppc_check_special_symbol): Add ehdr parameter. + (ppc_bss_plt_p): Likewise. + * libebl_ppc64.h: Adjust prototypes. + 2005-08-12 Roland McGrath <[email protected]> * ppc_symbol.c (find_dyn_got): New function, broken out of ... diff --git a/libebl/ebl_check_special_symbol.c b/libebl/ebl_check_special_symbol.c index 8825ee3f..176e9a6c 100644 --- a/libebl/ebl_check_special_symbol.c +++ b/libebl/ebl_check_special_symbol.c @@ -20,8 +20,9 @@ bool -ebl_check_special_symbol (ebl, sym, name, destshdr) +ebl_check_special_symbol (ebl, ehdr, sym, name, destshdr) Ebl *ebl; + GElf_Ehdr *ehdr; const GElf_Sym *sym; const char *name; const GElf_Shdr *destshdr; @@ -29,5 +30,5 @@ ebl_check_special_symbol (ebl, sym, name, destshdr) if (ebl == NULL) return false; - return ebl->check_special_symbol (ebl->elf, sym, name, destshdr); + return ebl->check_special_symbol (ebl->elf, ehdr, sym, name, destshdr); } diff --git a/libebl/eblbsspltp.c b/libebl/eblbsspltp.c index 48e19df7..62a4bb01 100644 --- a/libebl/eblbsspltp.c +++ b/libebl/eblbsspltp.c @@ -20,8 +20,9 @@ bool -ebl_bss_plt_p (ebl) +ebl_bss_plt_p (ebl, ehdr) Ebl *ebl; + GElf_Ehdr *ehdr; { - return ebl == NULL ? false : ebl->bss_plt_p (ebl->elf); + return ebl == NULL ? false : ebl->bss_plt_p (ebl->elf, ehdr); } diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c index f3ae7ab1..aef289ca 100644 --- a/libebl/eblopenbackend.c +++ b/libebl/eblopenbackend.c @@ -153,11 +153,11 @@ static bool default_object_note (const char *name, uint32_t type, uint32_t descsz, const char *desc); static bool default_debugscn_p (const char *name); static bool default_copy_reloc_p (int reloc); -static bool default_check_special_symbol (Elf *elf, +static bool default_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, const GElf_Sym *sym, const char *name, const GElf_Shdr *destshdr); -static bool default_bss_plt_p (Elf *elf); +static bool default_bss_plt_p (Elf *elf, GElf_Ehdr *ehdr); static void @@ -563,6 +563,7 @@ default_copy_reloc_p (int reloc __attribute__ ((unused))) static bool default_check_special_symbol (Elf *elf __attribute__ ((unused)), + GElf_Ehdr *ehdr __attribute__ ((unused)), const GElf_Sym *sym __attribute__ ((unused)), const char *name __attribute__ ((unused)), const GElf_Shdr *destshdr __attribute__ ((unused))) @@ -571,7 +572,8 @@ default_check_special_symbol (Elf *elf __attribute__ ((unused)), } static bool -default_bss_plt_p (Elf *elf __attribute__ ((unused))) +default_bss_plt_p (Elf *elf __attribute__ ((unused)), + GElf_Ehdr *ehdr __attribute__ ((unused))) { return false; } diff --git a/libebl/libebl.h b/libebl/libebl.h index 46373441..8b51aef7 100644 --- a/libebl/libebl.h +++ b/libebl/libebl.h @@ -114,7 +114,7 @@ extern bool ebl_dynamic_tag_check (Ebl *ebl, int64_t tag); /* Check whether given symbol's st_value and st_size are OK despite failing normal checks. */ -extern bool ebl_check_special_symbol (Ebl *ebl, +extern bool ebl_check_special_symbol (Ebl *ebl, GElf_Ehdr *ehdr, const GElf_Sym *sym, const char *name, const GElf_Shdr *destshdr); @@ -154,7 +154,7 @@ extern bool ebl_section_strip_p (Ebl *ebl, const GElf_Ehdr *ehdr, bool remove_comment, bool only_remove_debug); /* Check if backend uses a bss PLT in this file. */ -extern bool ebl_bss_plt_p (Ebl *ebl); +extern bool ebl_bss_plt_p (Ebl *ebl, GElf_Ehdr *ehdr); /* ELF string table handling. */ diff --git a/libebl/libeblP.h b/libebl/libeblP.h index adf51913..e3696f96 100644 --- a/libebl/libeblP.h +++ b/libebl/libeblP.h @@ -106,12 +106,11 @@ struct ebl bool (*copy_reloc_p) (int); /* Check whether given symbol's value is ok despite normal checks. */ - bool (*check_special_symbol) (Elf *elf, - const GElf_Sym *sym, const char *name, - const GElf_Shdr *destshdr); + bool (*check_special_symbol) (Elf *, GElf_Ehdr *, const GElf_Sym *, + const char *, const GElf_Shdr *); /* Check if backend uses a bss PLT in this file. */ - bool (*bss_plt_p) (Elf *elf); + bool (*bss_plt_p) (Elf *, GElf_Ehdr *); /* Destructor for ELF backend handle. */ void (*destr) (struct ebl *); diff --git a/libebl/libebl_ppc.h b/libebl/libebl_ppc.h index 03df06db..67e64afc 100644 --- a/libebl/libebl_ppc.h +++ b/libebl/libebl_ppc.h @@ -52,12 +52,12 @@ extern bool ppc_copy_reloc_p (int reloc); /* Check whether given symbol's st_value and st_size are OK despite normal checks. */ -extern bool ppc_check_special_symbol (Elf *elf, +extern bool ppc_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, const GElf_Sym *sym, const char *name, const GElf_Shdr *destshdr); /* Check if backend uses a bss PLT in this file. */ -extern bool ppc_bss_plt_p (Elf *elf); +extern bool ppc_bss_plt_p (Elf *elf, GElf_Ehdr *ehdr); #endif /* libebl_ppc.h */ diff --git a/libebl/libebl_ppc64.h b/libebl/libebl_ppc64.h index d8d445ff..e03a1a7c 100644 --- a/libebl/libebl_ppc64.h +++ b/libebl/libebl_ppc64.h @@ -52,12 +52,12 @@ extern bool ppc64_copy_reloc_p (int reloc); /* Check whether given symbol's st_value and st_size are OK despite normal checks. */ -extern bool ppc64_check_special_symbol (Elf *elf, +extern bool ppc64_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, const GElf_Sym *sym, const char *name, const GElf_Shdr *destshdr); /* Check if backend uses a bss PLT in this file. */ -extern bool ppc64_bss_plt_p (Elf *elf); +extern bool ppc64_bss_plt_p (Elf *elf, GElf_Ehdr *ehdr); #endif /* libebl_ppc.h */ diff --git a/libebl/ppc64_symbol.c b/libebl/ppc64_symbol.c index 12188a98..7222ae40 100644 --- a/libebl/ppc64_symbol.c +++ b/libebl/ppc64_symbol.c @@ -228,6 +228,7 @@ ppc64_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)), return NULL; } + bool ppc64_dynamic_tag_check (int64_t tag) { @@ -248,24 +249,22 @@ ppc64_copy_reloc_p (int reloc) /* Check whether given symbol's st_value and st_size are OK despite failing normal checks. */ bool -ppc64_check_special_symbol (Elf *elf, +ppc64_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, const GElf_Sym *sym __attribute__ ((unused)), const char *name __attribute__ ((unused)), const GElf_Shdr *destshdr) { - GElf_Ehdr ehdr_mem; - GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); - if (ehdr == NULL) - return false; const char *sname = elf_strptr (elf, ehdr->e_shstrndx, destshdr->sh_name); if (sname == NULL) return false; - return !strcmp (sname, ".opd"); + return strcmp (sname, ".opd") == 0; } + /* Check if backend uses a bss PLT in this file. */ bool -ppc64_bss_plt_p (Elf *elf __attribute__ ((unused))) +ppc64_bss_plt_p (Elf *elf __attribute__ ((unused)), + GElf_Ehdr *ehdr __attribute__ ((unused))) { return true; } diff --git a/libebl/ppc_symbol.c b/libebl/ppc_symbol.c index d642a710..d83da9ec 100644 --- a/libebl/ppc_symbol.c +++ b/libebl/ppc_symbol.c @@ -203,82 +203,81 @@ ppc_copy_reloc_p (int reloc) return reloc == R_PPC_COPY; } + /* Look for DT_PPC_GOT. */ static bool -find_dyn_got (Elf *elf, GElf_Addr *addr) +find_dyn_got (Elf *elf, GElf_Ehdr *ehdr, GElf_Addr *addr) { - Elf_Scn *scn = NULL; - while ((scn = elf_nextscn (elf, scn)) != NULL) + for (int i = 0; i < ehdr->e_phnum; ++i) { + GElf_Phdr phdr_mem; + GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem); + if (phdr == NULL || phdr->p_type != PT_DYNAMIC) + continue; + + Elf_Scn *scn = gelf_offscn (elf, phdr->p_offset); GElf_Shdr shdr_mem; GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); - if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC) - { - Elf_Data *data = elf_getdata (scn, NULL); - if (data == NULL) - break; - for (unsigned int i = 0; i < shdr->sh_size / shdr->sh_entsize; ++i) - { - GElf_Dyn dyn_mem; - GElf_Dyn *dyn = gelf_getdyn (data, i, &dyn_mem); - if (dyn == NULL) - break; - if (dyn->d_tag == DT_PPC_GOT) - { - *addr = dyn->d_un.d_ptr; - return true; - } - } - } + Elf_Data *data = elf_getdata (scn, NULL); + if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC && data != NULL) + for (unsigned int j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j) + { + GElf_Dyn dyn_mem; + GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem); + if (dyn != NULL && dyn->d_tag == DT_PPC_GOT) + { + *addr = dyn->d_un.d_ptr; + return true; + } + } + + /* There is only one PT_DYNAMIC entry. */ + break; } return false; } + /* Check whether given symbol's st_value and st_size are OK despite failing normal checks. */ bool -ppc_check_special_symbol (Elf *elf, - const GElf_Sym *sym, - const char *name, - const GElf_Shdr *destshdr) +ppc_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, const GElf_Sym *sym, + const char *name, const GElf_Shdr *destshdr) { if (name == NULL) return false; - if (!strcmp (name, "_GLOBAL_OFFSET_TABLE_")) + if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) { GElf_Addr gotaddr; - if (find_dyn_got (elf, &gotaddr)) + if (find_dyn_got (elf, ehdr, &gotaddr)) return sym->st_value == gotaddr; return sym->st_value == destshdr->sh_addr + 4; } - GElf_Ehdr ehdr_mem; - GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); - if (ehdr == NULL) - return false; const char *sname = elf_strptr (elf, ehdr->e_shstrndx, destshdr->sh_name); if (sname == NULL) return false; - if (!strcmp (name, "_SDA_BASE_")) - return (!strcmp (sname, ".sdata") + if (strcmp (name, "_SDA_BASE_") == 0) + return (strcmp (sname, ".sdata") == 0 && sym->st_value == destshdr->sh_addr + 0x8000 && sym->st_size == 0); - if (!strcmp (name, "_SDA2_BASE_")) - return (!strcmp (sname, ".sdata2") + if (strcmp (name, "_SDA2_BASE_") == 0) + return (strcmp (sname, ".sdata2") == 0 && sym->st_value == destshdr->sh_addr + 0x8000 && sym->st_size == 0); return false; } + /* Check if backend uses a bss PLT in this file. */ bool -ppc_bss_plt_p (Elf *elf) +ppc_bss_plt_p (Elf *elf, GElf_Ehdr *ehdr) { GElf_Addr addr; - return ! find_dyn_got (elf, &addr); + return ! find_dyn_got (elf, ehdr, &addr); } diff --git a/src/ChangeLog b/src/ChangeLog index e3535884..ce6887ba 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2005-08-13 Ulrich Drepper <[email protected]> + + * elflint.c (check_symtab): Simplify last change a bit. Pass ehdr + to ebl_check_special_symbol. + (check_sections): Pass ehdr to ebl_bss_plt_p. + 2005-08-12 Roland McGrath <[email protected]> * elflint.c (check_symtab): Check that _GLOBAL_OFFSET_TABLE_ st_shndx diff --git a/src/elflint.c b/src/elflint.c index 73a4061a..59e6eaf9 100644 --- a/src/elflint.c +++ b/src/elflint.c @@ -713,20 +713,21 @@ section [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"), { if (GELF_ST_TYPE (sym->st_info) != STT_TLS) { - bool special = ebl_check_special_symbol (ebl, sym, name, - destshdr); - if ((sym->st_value - destshdr->sh_addr) > destshdr->sh_size - && !special) - ERROR (gettext ("\ + if (! ebl_check_special_symbol (ebl, ehdr, sym, name, + destshdr)) + { + if ((sym->st_value - destshdr->sh_addr) + > destshdr->sh_size) + ERROR (gettext ("\ section [%2d] '%s': symbol %zu: st_value out of bounds\n"), - idx, section_name (ebl, idx), cnt); - else if ((sym->st_value - destshdr->sh_addr + sym->st_size) - > destshdr->sh_size - && !special) - ERROR (gettext ("\ + idx, section_name (ebl, idx), cnt); + else if ((sym->st_value - destshdr->sh_addr + + sym->st_size) > destshdr->sh_size) + ERROR (gettext ("\ section [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"), - idx, section_name (ebl, idx), cnt, - (int) xndx, section_name (ebl, xndx)); + idx, section_name (ebl, idx), cnt, + (int) xndx, section_name (ebl, xndx)); + } } else { @@ -834,10 +835,8 @@ section [%2d] '%s': symbol %zu: non-local section symbol\n"), if (destshdr == NULL && xndx == SHN_ABS) { /* In a DSO, we have to find the GOT section by name. */ - - Elf_Scn *gscn = NULL; - Elf_Scn *gotscn = NULL; + Elf_Scn *gscn = NULL; while ((gscn = elf_nextscn (ebl->elf, gscn)) != NULL) { destshdr = gelf_getshdr (gscn, &destshdr_mem); @@ -847,9 +846,9 @@ section [%2d] '%s': symbol %zu: non-local section symbol\n"), destshdr->sh_name); if (sname != NULL) { - if (!strcmp (sname, ".got.plt")) + if (strcmp (sname, ".got.plt") == 0) break; - if (!strcmp (sname, ".got")) + if (strcmp (sname, ".got") == 0) /* Do not stop looking. There might be a .got.plt section. */ gotscn = gscn; @@ -878,26 +877,26 @@ section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to '%s' section\n"), if (destshdr != NULL) { /* Found it. */ - - bool special = ebl_check_special_symbol (ebl, sym, name, - destshdr); - - if (sym->st_value != destshdr->sh_addr && !special) - /* This test is more strict than the psABIs which - usually allow the symbol to be in the middle of - the .got section, allowing negative offsets. */ - ERROR (gettext ("\ + if (!ebl_check_special_symbol (ebl, ehdr, sym, name, + destshdr)) + { + if (sym->st_value != destshdr->sh_addr) + /* This test is more strict than the psABIs which + usually allow the symbol to be in the middle of + the .got section, allowing negative offsets. */ + ERROR (gettext ("\ section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#" PRIx64 " does not match %s section address %#" PRIx64 "\n"), - idx, section_name (ebl, idx), - (uint64_t) sym->st_value, - sname, (uint64_t) destshdr->sh_addr); + idx, section_name (ebl, idx), + (uint64_t) sym->st_value, + sname, (uint64_t) destshdr->sh_addr); - if (!gnuld && sym->st_size != destshdr->sh_size && !special) - ERROR (gettext ("\ + if (!gnuld && sym->st_size != destshdr->sh_size) + ERROR (gettext ("\ section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %" PRIu64 " does not match %s section size %" PRIu64 "\n"), - idx, section_name (ebl, idx), - (uint64_t) sym->st_size, - sname, (uint64_t) destshdr->sh_size); + idx, section_name (ebl, idx), + (uint64_t) sym->st_size, + sname, (uint64_t) destshdr->sh_size); + } } else ERROR (gettext ("\ @@ -2589,7 +2588,7 @@ cannot get section header for section [%2zu] '%s': %s\n"), GElf_Word good_type = special_sections[s].type; if (special_sections[s].namelen == sizeof ".plt" && !memcmp (special_sections[s].name, ".plt", sizeof ".plt") - && ebl_bss_plt_p (ebl)) + && ebl_bss_plt_p (ebl, ehdr)) good_type = SHT_NOBITS; if (shdr->sh_type != good_type |