]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libebl/
authorRoland McGrath <roland@redhat.com>
Sat, 13 Aug 2005 03:26:06 +0000 (03:26 +0000)
committerRoland McGrath <roland@redhat.com>
Sat, 13 Aug 2005 03:26:06 +0000 (03:26 +0000)
2005-08-12  Roland McGrath  <roland@redhat.com>

* 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_.

libebl/ChangeLog
libebl/ppc64_symbol.c
libebl/ppc_symbol.c

index 68ec22178e0fa085bf992b4bc9c7921706d2ae5c..3e6c6937d1efb67f5004f0a82b15ef88daa50e91 100644 (file)
@@ -1,5 +1,10 @@
 2005-08-12  Roland McGrath  <roland@redhat.com>
 
+       * 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.
index ef0f5f70fc01bb0192b955a5ab75cf67aea4b0e6..12188a98f7f995916ba7ed2bc5e5f3a3242780fd 100644 (file)
@@ -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)),
index 8afabba2f3d567436ca038c7e4962263c6a899bd..d642a71046c9056283b36f7a68a57d4b7805b3e2 100644 (file)
@@ -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);
 }