diff options
-rw-r--r-- | Makefile.target | 4 | ||||
-rw-r--r-- | cpu-exec.c | 3 | ||||
-rw-r--r-- | dyngen.c | 22 |
3 files changed, 24 insertions, 5 deletions
diff --git a/Makefile.target b/Makefile.target index 9bb12c2f59..aa99f39cd1 100644 --- a/Makefile.target +++ b/Makefile.target @@ -181,7 +181,7 @@ BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld endif ifeq ($(ARCH),mips) -OP_CFLAGS+=-G 0 -fomit-frame-pointer -fno-delayed-branch +OP_CFLAGS+=-mabi=32 -G0 -fno-PIC -mno-abicalls -fomit-frame-pointer -fno-delayed-branch -Wa,-O0 ifeq ($(WORDS_BIGENDIAN),yes) BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld else @@ -190,7 +190,7 @@ endif endif ifeq ($(ARCH),mips64) -OP_CFLAGS+=-G 0 -fomit-frame-pointer -fno-delayed-branch +OP_CFLAGS+=-mabi=n32 -G0 -fno-PIC -mno-abicalls -fomit-frame-pointer -fno-delayed-branch -Wa,-O0 ifeq ($(WORDS_BIGENDIAN),yes) BASE_LDFLAGS+=-Wl,-T,$(SRC_PATH)/$(ARCH).ld else diff --git a/cpu-exec.c b/cpu-exec.c index cd74412a76..fedabef601 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -1545,9 +1545,10 @@ int cpu_signal_handler(int host_signum, void *pinfo, #elif defined(__mips__) -int cpu_signal_handler(int host_signum, struct siginfo *info, +int cpu_signal_handler(int host_signum, void *pinfo, void *puc) { + siginfo_t *info = pinfo; struct ucontext *uc = puc; greg_t pc = uc->uc_mcontext.pc; int is_write; @@ -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); |