summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland McGrath <[email protected]>2005-08-13 03:26:06 +0000
committerRoland McGrath <[email protected]>2005-08-13 03:26:06 +0000
commitf8873cb86317d18399593eb95947e0c543bc9d72 (patch)
treea9b1d7a658bd30ef6e4ce3fc6f90cc6e985b6d44
parent653d3763e986da9f1c8a92ff9103d85c534754cd (diff)
libebl/
2005-08-12 Roland McGrath <[email protected]> * ppc_symbol.c (find_dyn_got): New function, broken out of ... (ppc_bss_plt_p): ... here. Call that. (ppc_check_special_symbol): Use find_dyn_got to fetch value to check against _GLOBAL_OFFSET_TABLE_.
-rw-r--r--libebl/ChangeLog5
-rw-r--r--libebl/ppc64_symbol.c3
-rw-r--r--libebl/ppc_symbol.c63
3 files changed, 46 insertions, 25 deletions
diff --git a/libebl/ChangeLog b/libebl/ChangeLog
index 68ec2217..3e6c6937 100644
--- a/libebl/ChangeLog
+++ b/libebl/ChangeLog
@@ -1,5 +1,10 @@
2005-08-12 Roland McGrath <[email protected]>
+ * ppc_symbol.c (find_dyn_got): New function, broken out of ...
+ (ppc_bss_plt_p): ... here. Call that.
+ (ppc_check_special_symbol): Use find_dyn_got to fetch value to check
+ against _GLOBAL_OFFSET_TABLE_.
+
* libeblP.h (struct ebl): Add bss_plt_p hook.
* eblopenbackend.c (default_bss_plt_p): New function.
(fill_defaults): Use it.
diff --git a/libebl/ppc64_symbol.c b/libebl/ppc64_symbol.c
index ef0f5f70..12188a98 100644
--- a/libebl/ppc64_symbol.c
+++ b/libebl/ppc64_symbol.c
@@ -245,7 +245,8 @@ ppc64_copy_reloc_p (int reloc)
}
-/* Check whether given symbol's st_size is ok despite normal check failing. */
+/* Check whether given symbol's st_value and st_size are OK despite failing
+ normal checks. */
bool
ppc64_check_special_symbol (Elf *elf,
const GElf_Sym *sym __attribute__ ((unused)),
diff --git a/libebl/ppc_symbol.c b/libebl/ppc_symbol.c
index 8afabba2..d642a710 100644
--- a/libebl/ppc_symbol.c
+++ b/libebl/ppc_symbol.c
@@ -203,7 +203,40 @@ ppc_copy_reloc_p (int reloc)
return reloc == R_PPC_COPY;
}
-/* Check whether given symbol's value is ok despite failing normal checks. */
+/* Look for DT_PPC_GOT. */
+static bool
+find_dyn_got (Elf *elf, GElf_Addr *addr)
+{
+ Elf_Scn *scn = NULL;
+ while ((scn = elf_nextscn (elf, scn)) != NULL)
+ {
+ 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;
+ }
+ }
+ }
+ }
+
+ 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,
@@ -215,6 +248,9 @@ ppc_check_special_symbol (Elf *elf,
if (!strcmp (name, "_GLOBAL_OFFSET_TABLE_"))
{
+ GElf_Addr gotaddr;
+ if (find_dyn_got (elf, &gotaddr))
+ return sym->st_value == gotaddr;
return sym->st_value == destshdr->sh_addr + 4;
}
@@ -243,27 +279,6 @@ ppc_check_special_symbol (Elf *elf,
bool
ppc_bss_plt_p (Elf *elf)
{
- Elf_Scn *scn = NULL;
- while ((scn = elf_nextscn (elf, scn)) != NULL)
- {
- 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)
- return false;
- }
- }
- }
-
- return true;
+ GElf_Addr addr;
+ return ! find_dyn_got (elf, &addr);
}