summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlrich Drepper <[email protected]>2005-08-13 17:50:47 +0000
committerUlrich Drepper <[email protected]>2005-08-13 17:50:47 +0000
commitc5c33a6a2ce5ea400ac5d06b3c2f15808f68b803 (patch)
tree766e4fa596159c98baa73efde0730ea49f266d8e
parentad11217601d90e4bb79e4305541e7ecd9ec13182 (diff)
Minor cleanups of last changes to elflint and libebl to support
clean ppc/ppc64 handling.
-rw-r--r--config/elfutils.spec.in6
-rw-r--r--libebl/ChangeLog17
-rw-r--r--libebl/ebl_check_special_symbol.c5
-rw-r--r--libebl/eblbsspltp.c5
-rw-r--r--libebl/eblopenbackend.c8
-rw-r--r--libebl/libebl.h4
-rw-r--r--libebl/libeblP.h7
-rw-r--r--libebl/libebl_ppc.h4
-rw-r--r--libebl/libebl_ppc64.h4
-rw-r--r--libebl/ppc64_symbol.c13
-rw-r--r--libebl/ppc_symbol.c73
-rw-r--r--src/ChangeLog6
-rw-r--r--src/elflint.c69
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