summaryrefslogtreecommitdiffstats
path: root/usr.sbin/kldxref/ef_amd64.c
diff options
context:
space:
mode:
authoriedowse <iedowse@FreeBSD.org>2004-08-28 19:31:10 +0000
committeriedowse <iedowse@FreeBSD.org>2004-08-28 19:31:10 +0000
commitd0d1e68e58c10e5172f1d8f13525f20e9cdc942f (patch)
treedf9e4ff7a3c76c8c08fd9ddaf5e27dba6ee28c29 /usr.sbin/kldxref/ef_amd64.c
parentc409ad7413ce9b5f3bfb661a5d87805c96d093b7 (diff)
downloadFreeBSD-src-d0d1e68e58c10e5172f1d8f13525f20e9cdc942f.zip
FreeBSD-src-d0d1e68e58c10e5172f1d8f13525f20e9cdc942f.tar.gz
Explicitly pass in the relocation base and data offset into ef_reloc()
rather than relying on a trick that happens to work for the current relocation schemes. Also add some comments and improve variable naming.
Diffstat (limited to 'usr.sbin/kldxref/ef_amd64.c')
-rw-r--r--usr.sbin/kldxref/ef_amd64.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/usr.sbin/kldxref/ef_amd64.c b/usr.sbin/kldxref/ef_amd64.c
index f0acba8..445640a 100644
--- a/usr.sbin/kldxref/ef_amd64.c
+++ b/usr.sbin/kldxref/ef_amd64.c
@@ -37,11 +37,13 @@
#include "ef.h"
/*
- * Apply relocations to the values we got from the file.
+ * Apply relocations to the values we got from the file. `relbase' is the
+ * target relocation address of the section, and `dataoff' is the target
+ * relocation address of the data in `dest'.
*/
int
-ef_reloc(struct elf_file *ef, const void *data, int type, Elf_Off offset,
- size_t len, void *dest)
+ef_reloc(struct elf_file *ef, const void *reldata, int reltype, Elf_Off relbase,
+ Elf_Off dataoff, size_t len, void *dest)
{
Elf64_Addr *where, val;
Elf32_Addr *where32, val32;
@@ -50,16 +52,17 @@ ef_reloc(struct elf_file *ef, const void *data, int type, Elf_Off offset,
const Elf_Rel *rel;
const Elf_Rela *rela;
- switch (type) {
+ switch (reltype) {
case EF_RELOC_REL:
- rel = (const Elf_Rel *)data;
- where = (Elf_Addr *)(dest + rel->r_offset - offset);
+ rel = (const Elf_Rel *)reldata;
+ where = (Elf_Addr *)(dest + relbase + rel->r_offset - dataoff);
+ addend = 0;
rtype = ELF_R_TYPE(rel->r_info);
symidx = ELF_R_SYM(rel->r_info);
break;
case EF_RELOC_RELA:
- rela = (const Elf_Rela *)data;
- where = (Elf_Addr *)(dest + rela->r_offset - offset);
+ rela = (const Elf_Rela *)reldata;
+ where = (Elf_Addr *)(dest + relbase + rela->r_offset - dataoff);
addend = rela->r_addend;
rtype = ELF_R_TYPE(rela->r_info);
symidx = ELF_R_SYM(rela->r_info);
@@ -71,7 +74,7 @@ ef_reloc(struct elf_file *ef, const void *data, int type, Elf_Off offset,
if ((char *)where < (char *)dest || (char *)where >= (char *)dest + len)
return (0);
- if (type == EF_RELOC_REL) {
+ if (reltype == EF_RELOC_REL) {
/* Addend is 32 bit on 32 bit relocs */
switch (rtype) {
case R_X86_64_PC32:
@@ -103,7 +106,7 @@ ef_reloc(struct elf_file *ef, const void *data, int type, Elf_Off offset,
*where = addr;
break;
case R_X86_64_RELATIVE: /* B + A */
- addr = (Elf_Addr)addend;
+ addr = (Elf_Addr)addend + relbase;
val = addr;
*where = val;
break;
OpenPOWER on IntegriCloud