mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-03-03 05:29:19 +00:00
Initial JIT support for Darwin/x86. Seems there is still a problem though.
This commit is contained in:
parent
d08df6e659
commit
d8dc5827d3
@ -305,6 +305,20 @@ typedef struct coff_rel {
|
||||
#include <mach-o/reloc.h>
|
||||
#include <mach-o/ppc/reloc.h>
|
||||
|
||||
#ifdef HOST_PPC
|
||||
|
||||
#define MACH_CPU_TYPE CPU_TYPE_POWERPC
|
||||
#define mach_check_cputype(x) ((x) == CPU_TYPE_POWERPC)
|
||||
|
||||
#elif defined(HOST_I386)
|
||||
|
||||
#define MACH_CPU_TYPE CPU_TYPE_I386
|
||||
#define mach_check_cputype(x) ((x) == CPU_TYPE_I386)
|
||||
|
||||
#else
|
||||
#error unsupported CPU - please update the code
|
||||
#endif
|
||||
|
||||
# define check_mach_header(x) (x.magic == MH_MAGIC)
|
||||
typedef int32_t host_long;
|
||||
typedef uint32_t host_ulong;
|
||||
@ -1248,8 +1262,27 @@ static const char * get_reloc_name(EXE_RELOC * rel, int * sslide)
|
||||
/* init the slide value */
|
||||
*sslide = 0;
|
||||
|
||||
if(R_SCATTERED & rel->r_address)
|
||||
return (char *)find_reloc_name_given_its_address(sca_rel->r_value);
|
||||
if (R_SCATTERED & rel->r_address) {
|
||||
char *name = (char *)find_reloc_name_given_its_address(sca_rel->r_value);
|
||||
|
||||
/* search it in the full symbol list, if not found */
|
||||
if (!name) {
|
||||
int i;
|
||||
for (i = 0; i < nb_syms; i++) {
|
||||
EXE_SYM *sym = &symtab[i];
|
||||
if (sym->st_value == sca_rel->r_value) {
|
||||
name = get_sym_name(sym);
|
||||
switch (sca_rel->r_type) {
|
||||
case GENERIC_RELOC_VANILLA:
|
||||
*sslide = *(uint32_t *)(text + sca_rel->r_address) - sca_rel->r_value;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
if(rel->r_extern)
|
||||
{
|
||||
@ -1281,13 +1314,20 @@ static const char * get_reloc_name(EXE_RELOC * rel, int * sslide)
|
||||
sectoffset = ( *(uint32_t *)(text + rel->r_address) & 0x03fffffc );
|
||||
if (sectoffset & 0x02000000) sectoffset |= 0xfc000000;
|
||||
break;
|
||||
case GENERIC_RELOC_VANILLA:
|
||||
sectoffset = *(uint32_t *)(text + rel->r_address);
|
||||
break;
|
||||
default:
|
||||
error("switch(rel->type) not found");
|
||||
error("switch(rel->type=%d) not found", rel->r_type);
|
||||
}
|
||||
|
||||
if(rel->r_pcrel)
|
||||
if(rel->r_pcrel) {
|
||||
sectoffset += rel->r_address;
|
||||
|
||||
#ifdef HOST_I386
|
||||
sectoffset += (1 << rel->r_length);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (rel->r_type == PPC_RELOC_BR24)
|
||||
name = (char *)find_reloc_name_in_sec_ptr((int)sectoffset, §ion_hdr[sectnum-1]);
|
||||
|
||||
@ -1340,7 +1380,7 @@ int load_object(const char *filename, FILE *outfile)
|
||||
error("bad Mach header");
|
||||
}
|
||||
|
||||
if (mach_hdr.cputype != CPU_TYPE_POWERPC)
|
||||
if (!mach_check_cputype(mach_hdr.cputype))
|
||||
error("Unsupported CPU");
|
||||
|
||||
if (mach_hdr.filetype != MH_OBJECT)
|
||||
@ -1594,16 +1634,25 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
if (op_execute) {
|
||||
uint8_t *p;
|
||||
copy_size = p_end - p_start;
|
||||
#ifdef CONFIG_FORMAT_MACH
|
||||
#if defined(HOST_PPC)
|
||||
for (p = p_start; p < p_end; p += 4) {
|
||||
if (get32((uint32_t *)p) == 0x18deadff)
|
||||
fprintf(outfile, "DEFINE_CST(op_exec_return_offset,0x%xL)\n\n", (p + 4) - p_start);
|
||||
}
|
||||
#endif
|
||||
#if defined(HOST_I386)
|
||||
static const uint8_t return_insn[] = {0x0f,0xa6,0xf0};
|
||||
for (p = p_start; p < p_end; p++) {
|
||||
if (memcmp(p, return_insn, sizeof(return_insn)) == 0)
|
||||
fprintf(outfile, "DEFINE_CST(op_exec_return_offset,0x%xL)\n\n", (p + sizeof(return_insn)) - p_start);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else
|
||||
#if defined(HOST_I386) || defined(HOST_AMD64)
|
||||
#ifdef CONFIG_FORMAT_COFF
|
||||
#if defined(CONFIG_FORMAT_COFF) || defined(CONFIG_FORMAT_MACH)
|
||||
{
|
||||
uint8_t *p;
|
||||
p = p_end - 1;
|
||||
@ -1903,6 +1952,86 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
/* patch relocations */
|
||||
#if defined(HOST_I386)
|
||||
{
|
||||
#ifdef CONFIG_FORMAT_MACH
|
||||
struct scattered_relocation_info *scarel;
|
||||
struct relocation_info * rel;
|
||||
char final_sym_name[256];
|
||||
const char *sym_name;
|
||||
const char *p;
|
||||
int slide, sslide;
|
||||
int i;
|
||||
|
||||
for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
|
||||
unsigned int offset, length, value = 0;
|
||||
unsigned int type, pcrel, isym = 0;
|
||||
unsigned int usesym = 0;
|
||||
|
||||
if (R_SCATTERED & rel->r_address) {
|
||||
scarel = (struct scattered_relocation_info*)rel;
|
||||
offset = (unsigned int)scarel->r_address;
|
||||
length = scarel->r_length;
|
||||
pcrel = scarel->r_pcrel;
|
||||
type = scarel->r_type;
|
||||
value = scarel->r_value;
|
||||
}
|
||||
else {
|
||||
value = isym = rel->r_symbolnum;
|
||||
usesym = (rel->r_extern);
|
||||
offset = rel->r_address;
|
||||
length = rel->r_length;
|
||||
pcrel = rel->r_pcrel;
|
||||
type = rel->r_type;
|
||||
}
|
||||
|
||||
slide = offset - start_offset;
|
||||
|
||||
if (!(offset >= start_offset && offset < start_offset + size))
|
||||
continue; /* not in our range */
|
||||
|
||||
sym_name = get_reloc_name(rel, &sslide);
|
||||
|
||||
if (usesym && symtab[isym].n_type & N_STAB)
|
||||
continue; /* don't handle STAB (debug sym) */
|
||||
|
||||
if (sym_name && strstart(sym_name, "__op_jmp", &p)) {
|
||||
int n;
|
||||
n = strtol(p, NULL, 10);
|
||||
fprintf(outfile, " jmp_addr[%d] = code_ptr() + %d;\n", n, slide);
|
||||
continue; /* Nothing more to do */
|
||||
}
|
||||
|
||||
if (!sym_name) {
|
||||
fprintf(outfile, "/* #warning relocation not handled in %s (value 0x%x, %s, offset 0x%x, length 0x%x, %s, type 0x%x) */\n",
|
||||
name, value, usesym ? "use sym" : "don't use sym", offset, length, pcrel ? "pcrel":"", type);
|
||||
continue; /* dunno how to handle without final_sym_name */
|
||||
}
|
||||
|
||||
if (strstart(sym_name, "__op_param", &p))
|
||||
snprintf(final_sym_name, sizeof(final_sym_name), "param%s", p);
|
||||
else if (strstart(sym_name, "__op_cpuparam", &p))
|
||||
snprintf(final_sym_name, sizeof(final_sym_name), "(long)(cpu())", p);
|
||||
else
|
||||
snprintf(final_sym_name, sizeof(final_sym_name), "(long)(&%s)", sym_name);
|
||||
|
||||
if (length != 2)
|
||||
error("unsupported %d-bit relocation", 8 * (1 << length));
|
||||
|
||||
switch (type) {
|
||||
case GENERIC_RELOC_VANILLA:
|
||||
if (pcrel) {
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = %s - (long)(code_ptr() + %d) - 4;\n",
|
||||
slide, final_sym_name, slide);
|
||||
}
|
||||
else {
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = (%s + %d);\n",
|
||||
slide, final_sym_name, sslide);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error("unsupported i386 relocation (%d)", type);
|
||||
}
|
||||
}
|
||||
#else
|
||||
char name[256];
|
||||
int type;
|
||||
int addend;
|
||||
@ -1976,6 +2105,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#elif defined(HOST_AMD64)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user