aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorPetr Machata <pmachata@redhat.com>2012-03-24 02:06:48 +0100
committerPetr Machata <pmachata@redhat.com>2012-04-19 01:18:47 +0200
commit644d669f96c0fe261fe938cecda41938e804c7d9 (patch)
tree495db755f69b6e8b1acf5b26f0dbefd5017e4c7b /sysdeps
parentffd5aab0bddbbb7c650c2f5c12a48e0298f82516 (diff)
downloadltrace-644d669f96c0fe261fe938cecda41938e804c7d9.tar.gz
Drop recently introduced arch_elf_dynamic_tag
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/linux-gnu/mipsel/arch.h2
-rw-r--r--sysdeps/linux-gnu/mipsel/plt.c43
-rw-r--r--sysdeps/linux-gnu/ppc/arch.h3
-rw-r--r--sysdeps/linux-gnu/ppc/plt.c42
4 files changed, 66 insertions, 24 deletions
diff --git a/sysdeps/linux-gnu/mipsel/arch.h b/sysdeps/linux-gnu/mipsel/arch.h
index e2fdbf8..a447edb 100644
--- a/sysdeps/linux-gnu/mipsel/arch.h
+++ b/sysdeps/linux-gnu/mipsel/arch.h
@@ -8,8 +8,8 @@
#define PLTs_INIT_BY_HERE "_start"
#define E_ENTRY_NAME "_start"
+#define ARCH_HAVE_LTELF_DATA
#ifdef DEFINING_LTELF
-# define ARCH_HAVE_LTELF_DATA
struct arch_ltelf_data {
size_t pltgot_addr;
size_t mips_local_gotno;
diff --git a/sysdeps/linux-gnu/mipsel/plt.c b/sysdeps/linux-gnu/mipsel/plt.c
index 77807b1..5eec221 100644
--- a/sysdeps/linux-gnu/mipsel/plt.c
+++ b/sysdeps/linux-gnu/mipsel/plt.c
@@ -1,6 +1,7 @@
#include "debug.h"
#include <gelf.h>
#include <sys/ptrace.h>
+#include <error.h>
#include "proc.h"
#include "common.h"
@@ -87,23 +88,39 @@ sym2addr(Process *proc, struct library_symbol *sym) {
*/
int
-arch_elf_dynamic_tag(struct ltelf *lte, GElf_Dyn dyn)
+arch_elf_init(struct ltelf *lte)
{
- if(dyn.d_tag == DT_PLTGOT) {
- lte->arch.pltgot_addr = dyn.d_un.d_ptr;
- }
- if(dyn.d_tag == DT_MIPS_LOCAL_GOTNO){
- lte->arch.mips_local_gotno = dyn.d_un.d_val;
+ Elf_Scn *scn;
+ GElf_Shdr shdr;
+ if (elf_get_section_type(lte, SHT_DYNAMIC, &scn, &shdr) < 0
+ || scn == NULL) {
+ fail:
+ error(0, 0, "Couldn't get SHT_DYNAMIC: %s",
+ elf_errmsg(-1));
+ return -1;
}
- if(dyn.d_tag == DT_MIPS_GOTSYM){
- lte->arch.mips_gotsym = dyn.d_un.d_val;
+
+ Elf_Data *data = elf_loaddata(scn, &shdr);
+ if (data == NULL)
+ goto fail;
+
+ size_t j;
+ for (j = 0; j < shdr.sh_size / shdr.sh_entsize; ++j) {
+ GElf_Dyn dyn;
+ if (gelf_getdyn(data, j, &dyn) == NULL)
+ goto fail;
+
+ if(dyn.d_tag == DT_PLTGOT) {
+ lte->arch.pltgot_addr = dyn.d_un.d_ptr;
+ }
+ if(dyn.d_tag == DT_MIPS_LOCAL_GOTNO){
+ lte->arch.mips_local_gotno = dyn.d_un.d_val;
+ }
+ if(dyn.d_tag == DT_MIPS_GOTSYM){
+ lte->arch.mips_gotsym = dyn.d_un.d_val;
+ }
}
- return 0;
-}
-int
-arch_elf_init(struct ltelf *lte)
-{
return 0;
}
diff --git a/sysdeps/linux-gnu/ppc/arch.h b/sysdeps/linux-gnu/ppc/arch.h
index 609a6b9..6fd4714 100644
--- a/sysdeps/linux-gnu/ppc/arch.h
+++ b/sysdeps/linux-gnu/ppc/arch.h
@@ -24,10 +24,9 @@
#error "Length of the breakpoint value not equal to the length of a nop instruction"
#endif
+#define ARCH_HAVE_LTELF_DATA
#ifdef DEFINING_LTELF
-# define ARCH_HAVE_LTELF_DATA
struct arch_ltelf_data {
- GElf_Addr ppcgot;
GElf_Addr plt_stub_vma;
int secure_plt;
};
diff --git a/sysdeps/linux-gnu/ppc/plt.c b/sysdeps/linux-gnu/ppc/plt.c
index a0701eb..6075d7d 100644
--- a/sysdeps/linux-gnu/ppc/plt.c
+++ b/sysdeps/linux-gnu/ppc/plt.c
@@ -167,14 +167,36 @@ get_glink_vma(struct ltelf *lte, GElf_Addr ppcgot, Elf_Data *plt_data)
return 0;
}
-int
-arch_elf_dynamic_tag(struct ltelf *lte, GElf_Dyn dyn)
+static int
+load_ppcgot(struct ltelf *lte, GElf_Addr *ppcgotp)
{
- if (dyn.d_tag == DT_PPC_GOT) {
- lte->arch.ppcgot = dyn.d_un.d_val;
- debug(1, "ppcgot %#" PRIx64, lte->arch.ppcgot);
+ Elf_Scn *scn;
+ GElf_Shdr shdr;
+ if (elf_get_section_type(lte, SHT_DYNAMIC, &scn, &shdr) < 0
+ || scn == NULL) {
+ fail:
+ error(0, 0, "Couldn't get SHT_DYNAMIC: %s",
+ elf_errmsg(-1));
+ return -1;
}
- return 0;
+
+ Elf_Data *data = elf_loaddata(scn, &shdr);
+ if (data == NULL)
+ goto fail;
+
+ size_t j;
+ for (j = 0; j < shdr.sh_size / shdr.sh_entsize; ++j) {
+ GElf_Dyn dyn;
+ if (gelf_getdyn(data, j, &dyn) == NULL)
+ goto fail;
+
+ if(dyn.d_tag == DT_PPC_GOT) {
+ *ppcgotp = dyn.d_un.d_ptr;
+ return 0;
+ }
+ }
+
+ return -1;
}
int
@@ -182,8 +204,12 @@ arch_elf_init(struct ltelf *lte)
{
lte->arch.secure_plt = !(lte->lte_flags & LTE_PLT_EXECUTABLE);
if (lte->ehdr.e_machine == EM_PPC && lte->arch.secure_plt) {
- GElf_Addr glink_vma
- = get_glink_vma(lte, lte->arch.ppcgot, lte->plt_data);
+ GElf_Addr ppcgot;
+ if (load_ppcgot(lte, &ppcgot) < 0) {
+ fprintf(stderr, "Couldn't find DT_PPC_GOT.\n");
+ return -1;
+ }
+ GElf_Addr glink_vma = get_glink_vma(lte, ppcgot, lte->plt_data);
assert (lte->relplt_size % 12 == 0);
size_t count = lte->relplt_size / 12; // size of RELA entry