diff options
Diffstat (limited to 'dyngen.c')
-rw-r--r-- | dyngen.c | 22 |
1 files changed, 20 insertions, 2 deletions
@@ -124,6 +124,14 @@ #define elf_check_arch(x) ((x) == EM_MIPS) #define ELF_USES_RELOC +#elif defined(HOST_MIPS64) + +/* Assume n32 ABI here, which is ELF32. */ +#define ELF_CLASS ELFCLASS32 +#define ELF_ARCH EM_MIPS +#define elf_check_arch(x) ((x) == EM_MIPS) +#define ELF_USES_RELOCA + #else #error unsupported CPU - please update the code #endif @@ -1648,7 +1656,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, error("rts expected at the end of %s", name); copy_size = p - p_start; } -#elif defined(HOST_MIPS) +#elif defined(HOST_MIPS) || defined(HOST_MIPS64) { #define INSN_RETURN 0x03e00008 #define INSN_NOP 0x00000000 @@ -2510,7 +2518,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, } } } -#elif defined(HOST_MIPS) +#elif defined(HOST_MIPS) || defined(HOST_MIPS64) { for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) { if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) { @@ -2528,6 +2536,16 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, addend = get32((uint32_t *)(text + rel->r_offset)); reloc_offset = rel->r_offset - start_offset; switch (type) { + case R_MIPS_26: + fprintf(outfile, " /* R_MIPS_26 RELOC, offset 0x%x, name %s */\n", + rel->r_offset, sym_name); + fprintf(outfile, + " *(uint32_t *)(gen_code_ptr + 0x%x) = " + "(0x%x & ~0x3fffff) " + "| ((0x%x + ((%s - (*(uint32_t *)(gen_code_ptr + 0x%x))) >> 2)) " + " & 0x3fffff);\n", + reloc_offset, addend, addend, name, reloc_offset); + break; case R_MIPS_HI16: fprintf(outfile, " /* R_MIPS_HI16 RELOC, offset 0x%x, name %s */\n", rel->r_offset, sym_name); |