summaryrefslogtreecommitdiffstats
path: root/kexec/arch/i386/kexec-elf-rel-x86.c
diff options
context:
space:
mode:
Diffstat (limited to 'kexec/arch/i386/kexec-elf-rel-x86.c')
-rw-r--r--kexec/arch/i386/kexec-elf-rel-x86.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/kexec/arch/i386/kexec-elf-rel-x86.c b/kexec/arch/i386/kexec-elf-rel-x86.c
new file mode 100644
index 0000000..55a214e
--- /dev/null
+++ b/kexec/arch/i386/kexec-elf-rel-x86.c
@@ -0,0 +1,36 @@
+#include <stdio.h>
+#include <elf.h>
+#include "../../kexec.h"
+#include "../../kexec-elf.h"
+
+int machine_verify_elf_rel(struct mem_ehdr *ehdr)
+{
+ if (ehdr->ei_data != ELFDATA2LSB) {
+ return 0;
+ }
+ if (ehdr->ei_class != ELFCLASS32) {
+ return 0;
+ }
+ if ((ehdr->e_machine != EM_386) && (ehdr->e_machine != EM_486))
+ {
+ return 0;
+ }
+ return 1;
+}
+
+void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
+ struct mem_sym *UNUSED(sym), unsigned long r_type, void *location,
+ unsigned long address, unsigned long value)
+{
+ switch(r_type) {
+ case R_386_32:
+ *((uint32_t *)location) += value;
+ break;
+ case R_386_PC32:
+ *((uint32_t *)location) += value - address;
+ break;
+ default:
+ die("Unknown rel relocation: %lu\n", r_type);
+ break;
+ }
+}