Initial JIT support for Darwin/x86. Seems there is still a problem though.

This commit is contained in:
gbeauche 2005-07-11 07:06:31 +00:00
parent d08df6e659
commit d8dc5827d3

View File

@ -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, &section_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)
{