summaryrefslogtreecommitdiff
path: root/arch/x32/reloc.h
diff options
context:
space:
mode:
authorrofl0r <retnyg@gmx.net>2014-01-07 22:43:34 +0100
committerrofl0r <retnyg@gmx.net>2014-02-23 11:07:18 +0100
commit323272db175204b951f119dae4bd99ef05e20f13 (patch)
tree70329156d5189294b1e9e7f9c7c326924ad62e35 /arch/x32/reloc.h
parent0f169cbb79c39a5b15f7a27d9283cdeb6e122b8f (diff)
downloadmusl-323272db175204b951f119dae4bd99ef05e20f13.tar.gz
import vanilla x86_64 code as x32
Diffstat (limited to 'arch/x32/reloc.h')
-rw-r--r--arch/x32/reloc.h46
1 files changed, 46 insertions, 0 deletions
diff --git a/arch/x32/reloc.h b/arch/x32/reloc.h
new file mode 100644
index 00000000..28cf7cc1
--- /dev/null
+++ b/arch/x32/reloc.h
@@ -0,0 +1,46 @@
+#include <stdint.h>
+#include <string.h>
+#include <elf.h>
+
+#define LDSO_ARCH "x86_64"
+
+#define IS_COPY(x) ((x)==R_X86_64_COPY)
+#define IS_PLT(x) ((x)==R_X86_64_JUMP_SLOT)
+
+static inline void do_single_reloc(
+ struct dso *self, unsigned char *base_addr,
+ size_t *reloc_addr, int type, size_t addend,
+ Sym *sym, size_t sym_size,
+ struct symdef def, size_t sym_val)
+{
+ switch(type) {
+ case R_X86_64_GLOB_DAT:
+ case R_X86_64_JUMP_SLOT:
+ case R_X86_64_64:
+ *reloc_addr = sym_val + addend;
+ break;
+ case R_X86_64_32:
+ *(uint32_t *)reloc_addr = sym_val + addend;
+ break;
+ case R_X86_64_PC32:
+ *reloc_addr = sym_val + addend - (size_t)reloc_addr + (size_t)base_addr;
+ break;
+ case R_X86_64_RELATIVE:
+ *reloc_addr = (size_t)base_addr + addend;
+ break;
+ case R_X86_64_COPY:
+ memcpy(reloc_addr, (void *)sym_val, sym_size);
+ break;
+ case R_X86_64_DTPMOD64:
+ *reloc_addr = def.dso ? def.dso->tls_id : self->tls_id;
+ break;
+ case R_X86_64_DTPOFF64:
+ *reloc_addr = def.sym->st_value + addend;
+ break;
+ case R_X86_64_TPOFF64:
+ *reloc_addr = (def.sym
+ ? def.sym->st_value - def.dso->tls_offset
+ : 0 - self->tls_offset) + addend;
+ break;
+ }
+}