#include <unistd.h>
#include <fcntl.h>
-#include "config.h"
+#include "config-host.h"
/* elf format definitions. We use these macros to test the CPU to
allow cross compilation (this tool must be ran on the build
#define elf_check_arch(x) ((x) == EM_ARM)
#define ELF_USES_RELOC
+#elif defined(HOST_M68K)
+
+#define ELF_CLASS ELFCLASS32
+#define ELF_ARCH EM_68K
+#define elf_check_arch(x) ((x) == EM_68K)
+#define ELF_USES_RELOCA
+
#else
#error unsupported CPU - please update the code
#endif
#define SHT_RELOC SHT_REL
#endif
-#define NO_THUNK_TYPE_SIZE
-#include "thunk.h"
+#include "bswap.h"
enum {
OUT_GEN_OP,
relocs, nb_relocs);
break;
#endif
+ case EM_68K:
+ {
+ uint8_t *p;
+ p = (void *)(p_end - 2);
+ if (p == p_start)
+ error("empty code for %s", name);
+ // remove NOP's, probably added for alignment
+ while ((get16((uint16_t *)p) == 0x4e71) &&
+ (p>p_start))
+ p -= 2;
+ if (get16((uint16_t *)p) != 0x4e75)
+ error("rts expected at the end of %s", name);
+ copy_size = p - p_start;
+ }
+ break;
default:
error("unknown ELF architecture");
}
{
ElfW(Sym) *sym;
const char *sym_name, *p;
- target_ulong val;
+ unsigned long val;
int n;
for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
if (!ptr)
error("__op_labelN in invalid section");
offset = sym->st_value;
- val = *(target_ulong *)(ptr + offset);
+ val = *(unsigned long *)(ptr + offset);
#ifdef ELF_USES_RELOCA
{
int reloc_shndx, nb_relocs1, j;
if (val >= start_offset && val < start_offset + copy_size) {
n = strtol(p, NULL, 10);
- fprintf(outfile, " label_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n", n, val - start_offset);
+ fprintf(outfile, " label_offsets[%d] = %ld + (gen_code_ptr - gen_code_buf);\n", n, val - start_offset);
}
}
}
}
}
}
+#elif defined(HOST_M68K)
+ {
+ char name[256];
+ int type;
+ int addend;
+ Elf32_Sym *sym;
+ for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
+ if (rel->r_offset >= start_offset &&
+ rel->r_offset < start_offset + copy_size) {
+ sym = &(symtab[ELFW(R_SYM)(rel->r_info)]);
+ sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
+ if (strstart(sym_name, "__op_param", &p)) {
+ snprintf(name, sizeof(name), "param%s", p);
+ } else {
+ snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
+ }
+ type = ELF32_R_TYPE(rel->r_info);
+ addend = get32((uint32_t *)(text + rel->r_offset)) + rel->r_addend;
+ switch(type) {
+ case R_68K_32:
+ fprintf(outfile, " /* R_68K_32 RELOC, offset %x */\n", rel->r_offset) ;
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %#x;\n",
+ rel->r_offset - start_offset, name, addend );
+ break;
+ case R_68K_PC32:
+ fprintf(outfile, " /* R_68K_PC32 RELOC, offset %x */\n", rel->r_offset);
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %#x) + %#x;\n",
+ rel->r_offset - start_offset, name, rel->r_offset - start_offset, /*sym->st_value+*/ addend);
+ break;
+ default:
+ error("unsupported m68k relocation (%d)", type);
+ }
+ }
+ }
+ }
#else
#error unsupported CPU
#endif
}
if (out_type == OUT_INDEX_OP) {
- fprintf(outfile, "DEF(nop1, 0, 0)\n");
- fprintf(outfile, "DEF(nop2, 0, 0)\n");
- fprintf(outfile, "DEF(nop3, 0, 0)\n");
- fprintf(outfile, "DEF(nop, 0, 0)\n");
fprintf(outfile, "DEF(end, 0, 0)\n");
+ fprintf(outfile, "DEF(nop, 0, 0)\n");
+ fprintf(outfile, "DEF(nop1, 1, 0)\n");
+ fprintf(outfile, "DEF(nop2, 2, 0)\n");
+ fprintf(outfile, "DEF(nop3, 3, 0)\n");
for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
const char *name, *p;
name = strtab + sym->st_name;
" the_end:\n"
);
-/* generate epilogue */
- switch(ELF_ARCH) {
- case EM_386:
- fprintf(outfile, "*gen_code_ptr++ = 0xc3; /* ret */\n");
- break;
- case EM_PPC:
- fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x4e800020; /* blr */\n");
- break;
- case EM_S390:
- fprintf(outfile, "*((uint16_t *)gen_code_ptr)++ = 0x07fe; /* br %%r14 */\n");
- break;
- case EM_ALPHA:
- fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x6bfa8001; /* ret */\n");
- break;
- case EM_IA_64:
- fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x00840008; /* br.ret.sptk.many b0;; */\n");
- break;
- case EM_SPARC:
- case EM_SPARC32PLUS:
- fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x81c62008; /* jmpl %%i0 + 8, %%g0 */\n");
- fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x01000000; /* nop */\n");
- break;
- case EM_SPARCV9:
- fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x81c7e008; /* ret */\n");
- fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x81e80000; /* restore */\n");
- break;
- case EM_ARM:
- fprintf(outfile, "gen_code_ptr = arm_flush_ldr(gen_code_ptr, arm_ldr_table, arm_ldr_ptr, arm_data_table, arm_data_ptr, 0);\n");
- break;
- default:
- error("unknown ELF architecture");
- }
+/* generate some code patching */
+#ifdef HOST_ARM
+fprintf(outfile, "gen_code_ptr = arm_flush_ldr(gen_code_ptr, arm_ldr_table, arm_ldr_ptr, arm_data_table, arm_data_ptr, 0);\n");
+#endif
/* flush instruction cache */
fprintf(outfile, "flush_icache_range((unsigned long)gen_code_buf, (unsigned long)gen_code_ptr);\n");