summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ltrace-elf.c32
-rw-r--r--ltrace-elf.h4
-rw-r--r--sysdeps/linux-gnu/ppc/plt.c45
3 files changed, 43 insertions, 38 deletions
diff --git a/ltrace-elf.c b/ltrace-elf.c
index 92b642b..6f86d56 100644
--- a/ltrace-elf.c
+++ b/ltrace-elf.c
@@ -531,6 +531,38 @@ elf_read_relocs(struct ltelf *lte, Elf_Scn *scn, GElf_Shdr *shdr,
return 0;
}
+int
+elf_load_dynamic_entry(struct ltelf *lte, int tag, GElf_Addr *valuep)
+{
+ Elf_Scn *scn;
+ GElf_Shdr shdr;
+ if (elf_get_section_type(lte, SHT_DYNAMIC, &scn, &shdr) < 0
+ || scn == NULL) {
+ fail:
+ fprintf(stderr, "Couldn't get SHT_DYNAMIC: %s\n",
+ elf_errmsg(-1));
+ return -1;
+ }
+
+ 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 == tag) {
+ *valuep = dyn.d_un.d_ptr;
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
static int
ltelf_read_elf(struct ltelf *lte, const char *filename)
{
diff --git a/ltrace-elf.h b/ltrace-elf.h
index ea14512..db4ffe9 100644
--- a/ltrace-elf.h
+++ b/ltrace-elf.h
@@ -139,6 +139,10 @@ struct elf_each_symbol_t {
int elf_read_relocs(struct ltelf *lte, Elf_Scn *scn, GElf_Shdr *shdr,
struct vect *rela_vec);
+/* Read a given DT_ TAG from LTE. Value is returned in *VALUEP.
+ * Returns 0 on success or a negative value on failure. */
+int elf_load_dynamic_entry(struct ltelf *lte, int tag, GElf_Addr *valuep);
+
/* Read, respectively, 1, 2, 4, or 8 bytes from Elf data at given
* OFFSET, and store it in *RETP. Returns 0 on success or a negative
* value if there's not enough data. */
diff --git a/sysdeps/linux-gnu/ppc/plt.c b/sysdeps/linux-gnu/ppc/plt.c
index 5e3ffe1..3ec1397 100644
--- a/sysdeps/linux-gnu/ppc/plt.c
+++ b/sysdeps/linux-gnu/ppc/plt.c
@@ -402,38 +402,6 @@ get_glink_vma(struct ltelf *lte, GElf_Addr ppcgot, Elf_Data *plt_data)
}
static int
-load_dynamic_entry(struct ltelf *lte, int tag, GElf_Addr *valuep)
-{
- Elf_Scn *scn;
- GElf_Shdr shdr;
- if (elf_get_section_type(lte, SHT_DYNAMIC, &scn, &shdr) < 0
- || scn == NULL) {
- fail:
- fprintf(stderr, "Couldn't get SHT_DYNAMIC: %s\n",
- elf_errmsg(-1));
- return -1;
- }
-
- 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 == tag) {
- *valuep = dyn.d_un.d_ptr;
- return 0;
- }
- }
-
- return -1;
-}
-
-static int
nonzero_data(Elf_Data *data)
{
/* We are not supposed to get here if there's no PLT. */
@@ -488,8 +456,8 @@ arch_elf_init(struct ltelf *lte, struct library *lib)
Elf_Scn *rela_sec;
GElf_Shdr rela_shdr;
if ((lte->ehdr.e_machine == EM_PPC64 || lte->arch.secure_plt)
- && load_dynamic_entry(lte, DT_RELA, &rela) == 0
- && load_dynamic_entry(lte, DT_RELASZ, &relasz) == 0
+ && elf_load_dynamic_entry(lte, DT_RELA, &rela) == 0
+ && elf_load_dynamic_entry(lte, DT_RELASZ, &relasz) == 0
&& elf_get_section_covering(lte, rela, &rela_sec, &rela_shdr) == 0
&& rela_sec != NULL) {
@@ -509,7 +477,7 @@ arch_elf_init(struct ltelf *lte, struct library *lib)
if (lte->ehdr.e_machine == EM_PPC && lte->arch.secure_plt) {
GElf_Addr ppcgot;
- if (load_dynamic_entry(lte, DT_PPC_GOT, &ppcgot) < 0) {
+ if (elf_load_dynamic_entry(lte, DT_PPC_GOT, &ppcgot) < 0) {
fprintf(stderr, "couldn't find DT_PPC_GOT\n");
return -1;
}
@@ -522,7 +490,8 @@ arch_elf_init(struct ltelf *lte, struct library *lib)
} else if (lte->ehdr.e_machine == EM_PPC64) {
GElf_Addr glink_vma;
- if (load_dynamic_entry(lte, DT_PPC64_GLINK, &glink_vma) < 0) {
+ if (elf_load_dynamic_entry(lte, DT_PPC64_GLINK,
+ &glink_vma) < 0) {
fprintf(stderr, "couldn't find DT_PPC64_GLINK\n");
return -1;
}
@@ -532,8 +501,8 @@ arch_elf_init(struct ltelf *lte, struct library *lib)
} else {
/* By exhaustion--PPC32 BSS. */
- if (load_dynamic_entry(lte, DT_PLTGOT,
- &lib->arch.pltgot_addr) < 0) {
+ if (elf_load_dynamic_entry(lte, DT_PLTGOT,
+ &lib->arch.pltgot_addr) < 0) {
fprintf(stderr, "couldn't find DT_PLTGOT\n");
return -1;
}