summaryrefslogtreecommitdiffstats
path: root/contrib/elftoolchain/libdwarf
diff options
context:
space:
mode:
authoremaste <emaste@FreeBSD.org>2015-02-12 02:08:44 +0000
committeremaste <emaste@FreeBSD.org>2015-02-12 02:08:44 +0000
commit2b789577d72ca58b39cc94f51ca9a6d89b0b6b45 (patch)
tree9bfa2ade0df06ecd68a11b3b8d357478900a5e92 /contrib/elftoolchain/libdwarf
parent4bd760cd4d715b070e9075747ac4d2b624b94458 (diff)
downloadFreeBSD-src-2b789577d72ca58b39cc94f51ca9a6d89b0b6b45.zip
FreeBSD-src-2b789577d72ca58b39cc94f51ca9a6d89b0b6b45.tar.gz
libdwarf: Handle .rel relocations
Some architectures use .rel relocations (for debug data), so they must be handled. This was discovered from ctfconvert on ARM object files. The lack of relocation handling caused all string lookups to return the string at offset 0 in .debug_str, typically "FreeBSD clang version ..." Reviewed by: gnn, imp, rpaulo (earlier version) Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D1819
Diffstat (limited to 'contrib/elftoolchain/libdwarf')
-rw-r--r--contrib/elftoolchain/libdwarf/_libdwarf.h2
-rw-r--r--contrib/elftoolchain/libdwarf/dwarf_reloc.c4
-rw-r--r--contrib/elftoolchain/libdwarf/dwarf_set_reloc_application.34
-rw-r--r--contrib/elftoolchain/libdwarf/libdwarf.c2
-rw-r--r--contrib/elftoolchain/libdwarf/libdwarf_elf_init.c71
5 files changed, 50 insertions, 33 deletions
diff --git a/contrib/elftoolchain/libdwarf/_libdwarf.h b/contrib/elftoolchain/libdwarf/_libdwarf.h
index d2e74c1..a7669e2 100644
--- a/contrib/elftoolchain/libdwarf/_libdwarf.h
+++ b/contrib/elftoolchain/libdwarf/_libdwarf.h
@@ -49,7 +49,7 @@
struct _libdwarf_globals {
Dwarf_Handler errhand;
Dwarf_Ptr errarg;
- int applyrela;
+ int applyreloc;
};
extern struct _libdwarf_globals _libdwarf;
diff --git a/contrib/elftoolchain/libdwarf/dwarf_reloc.c b/contrib/elftoolchain/libdwarf/dwarf_reloc.c
index 5e96db3..c912f27 100644
--- a/contrib/elftoolchain/libdwarf/dwarf_reloc.c
+++ b/contrib/elftoolchain/libdwarf/dwarf_reloc.c
@@ -33,8 +33,8 @@ dwarf_set_reloc_application(int apply)
{
int oldapply;
- oldapply = _libdwarf.applyrela;
- _libdwarf.applyrela = apply;
+ oldapply = _libdwarf.applyreloc;
+ _libdwarf.applyreloc = apply;
return (oldapply);
}
diff --git a/contrib/elftoolchain/libdwarf/dwarf_set_reloc_application.3 b/contrib/elftoolchain/libdwarf/dwarf_set_reloc_application.3
index d53c746..e62b262 100644
--- a/contrib/elftoolchain/libdwarf/dwarf_set_reloc_application.3
+++ b/contrib/elftoolchain/libdwarf/dwarf_set_reloc_application.3
@@ -24,7 +24,7 @@
.\"
.\" $Id: dwarf_set_reloc_application.3 2075 2011-10-27 03:47:28Z jkoshy $
.\"
-.Dd June 26, 2011
+.Dd February 11, 2015
.Os
.Dt DWARF_SET_RELOC_APPLICATION 3
.Sh NAME
@@ -47,6 +47,8 @@ handled by the DWARF(3) library.
If the argument
.Ar apply
holds a non-zero value, the library will process all the relevant
+.Dq ".rel"
+and
.Dq ".rela"
relocation sections and will apply the relocation records found to
their corresponding DWARF sections.
diff --git a/contrib/elftoolchain/libdwarf/libdwarf.c b/contrib/elftoolchain/libdwarf/libdwarf.c
index 5f48762..961fe2c 100644
--- a/contrib/elftoolchain/libdwarf/libdwarf.c
+++ b/contrib/elftoolchain/libdwarf/libdwarf.c
@@ -31,5 +31,5 @@ ELFTC_VCSID("$Id: libdwarf.c 2070 2011-10-27 03:05:32Z jkoshy $");
struct _libdwarf_globals _libdwarf = {
.errhand = NULL,
.errarg = NULL,
- .applyrela = 1
+ .applyreloc = 1
};
diff --git a/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c b/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c
index 2ed48eb..731a20d 100644
--- a/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c
+++ b/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c
@@ -50,36 +50,46 @@ static const char *debug_name[] = {
};
static void
-_dwarf_elf_apply_reloc(Dwarf_Debug dbg, void *buf, Elf_Data *rel_data,
- Elf_Data *symtab_data, int endian)
+_dwarf_elf_write_reloc(Dwarf_Debug dbg, Elf_Data *symtab_data, int endian,
+ void *buf, uint64_t offset, GElf_Xword r_info, GElf_Sxword r_addend)
{
- Dwarf_Unsigned type;
- GElf_Rela rela;
GElf_Sym sym;
- size_t symndx;
- uint64_t offset;
- int size, j;
+ int size;
+
+ if (gelf_getsym(symtab_data, GELF_R_SYM(r_info), &sym) == NULL)
+ return;
+ if ((size = _dwarf_get_reloc_size(dbg, GELF_R_TYPE(r_info))) == 0)
+ return; /* Unknown or non-absolute relocation. */
+ if (endian == ELFDATA2MSB)
+ _dwarf_write_msb(buf, &offset, sym.st_value + r_addend, size);
+ else
+ _dwarf_write_lsb(buf, &offset, sym.st_value + r_addend, size);
+}
+
+static void
+_dwarf_elf_apply_rel_reloc(Dwarf_Debug dbg, void *buf, Elf_Data *rel_data,
+ Elf_Data *symtab_data, int endian)
+{
+ GElf_Rel rel;
+ int j;
j = 0;
- while (gelf_getrela(rel_data, j++, &rela) != NULL) {
- symndx = GELF_R_SYM(rela.r_info);
- type = GELF_R_TYPE(rela.r_info);
+ while (gelf_getrel(rel_data, j++, &rel) != NULL)
+ _dwarf_elf_write_reloc(dbg, symtab_data, endian, buf,
+ rel.r_offset, rel.r_info, 0);
+}
- if (gelf_getsym(symtab_data, symndx, &sym) == NULL)
- continue;
+static void
+_dwarf_elf_apply_rela_reloc(Dwarf_Debug dbg, void *buf, Elf_Data *rel_data,
+ Elf_Data *symtab_data, int endian)
+{
+ GElf_Rela rela;
+ int j;
- offset = rela.r_offset;
- size = _dwarf_get_reloc_size(dbg, type);
- if (size == 0)
- continue; /* Unknown or non-absolute relocation. */
-
- if (endian == ELFDATA2MSB)
- _dwarf_write_msb(buf, &offset,
- sym.st_value + rela.r_addend, size);
- else
- _dwarf_write_lsb(buf, &offset,
- sym.st_value + rela.r_addend, size);
- }
+ j = 0;
+ while (gelf_getrela(rel_data, j++, &rela) != NULL)
+ _dwarf_elf_write_reloc(dbg, symtab_data, endian, buf,
+ rela.r_offset, rela.r_info, rela.r_addend);
}
static int
@@ -108,7 +118,8 @@ _dwarf_elf_relocate(Dwarf_Debug dbg, Elf *elf, Dwarf_Elf_Data *ed, size_t shndx,
return (DW_DLE_ELF);
}
- if (sh.sh_type != SHT_RELA || sh.sh_size == 0)
+ if ((sh.sh_type != SHT_REL && sh.sh_type != SHT_RELA) ||
+ sh.sh_size == 0)
continue;
if (sh.sh_info == shndx && sh.sh_link == symtab) {
@@ -129,8 +140,12 @@ _dwarf_elf_relocate(Dwarf_Debug dbg, Elf *elf, Dwarf_Elf_Data *ed, size_t shndx,
}
memcpy(ed->ed_alloc, ed->ed_data->d_buf,
ed->ed_data->d_size);
- _dwarf_elf_apply_reloc(dbg, ed->ed_alloc, rel,
- symtab_data, eh.e_ident[EI_DATA]);
+ if (sh.sh_type == SHT_REL)
+ _dwarf_elf_apply_rel_reloc(dbg, ed->ed_alloc,
+ rel, symtab_data, eh.e_ident[EI_DATA]);
+ else
+ _dwarf_elf_apply_rela_reloc(dbg, ed->ed_alloc,
+ rel, symtab_data, eh.e_ident[EI_DATA]);
return (DW_DLE_NONE);
}
@@ -286,7 +301,7 @@ _dwarf_elf_init(Dwarf_Debug dbg, Elf *elf, Dwarf_Error *error)
}
}
- if (_libdwarf.applyrela) {
+ if (_libdwarf.applyreloc) {
if (_dwarf_elf_relocate(dbg, elf,
&e->eo_data[j], elf_ndxscn(scn), symtab_ndx,
symtab_data, error) != DW_DLE_NONE)
OpenPOWER on IntegriCloud