mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-01-11 10:30:09 +00:00
[ Patch from Jean-Pierre <chombier@free.fr> ]
More changes to support mach-o x86_64.
This commit is contained in:
parent
f4705aa5e1
commit
ded367a176
@ -572,6 +572,7 @@ int text_shndx;
|
|||||||
int data_shndx;
|
int data_shndx;
|
||||||
uint8_t *text;
|
uint8_t *text;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
|
uint8_t *literal16;
|
||||||
EXE_RELOC *relocs;
|
EXE_RELOC *relocs;
|
||||||
int nb_relocs;
|
int nb_relocs;
|
||||||
|
|
||||||
@ -1156,6 +1157,7 @@ struct symtab_command *symtabcmd = 0;
|
|||||||
struct SECTION *section_hdr;
|
struct SECTION *section_hdr;
|
||||||
struct SECTION *text_sec_hdr;
|
struct SECTION *text_sec_hdr;
|
||||||
struct SECTION *data_sec_hdr;
|
struct SECTION *data_sec_hdr;
|
||||||
|
struct SECTION *literal16_sec_hdr;
|
||||||
uint8_t **sdata;
|
uint8_t **sdata;
|
||||||
|
|
||||||
/* relocs */
|
/* relocs */
|
||||||
@ -1277,8 +1279,8 @@ static const char * find_reloc_name_in_sec_ptr(int address, struct SECTION * sec
|
|||||||
error("size = 0");
|
error("size = 0");
|
||||||
|
|
||||||
}
|
}
|
||||||
else if( sec_hdr->flags & S_LAZY_SYMBOL_POINTERS ||
|
else if( (sec_hdr->flags & S_LAZY_SYMBOL_POINTERS) ||
|
||||||
sec_hdr->flags & S_NON_LAZY_SYMBOL_POINTERS)
|
(sec_hdr->flags & S_NON_LAZY_SYMBOL_POINTERS) )
|
||||||
size = sizeof(unsigned long);
|
size = sizeof(unsigned long);
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
@ -1355,6 +1357,10 @@ static const char * get_reloc_name(EXE_RELOC * rel, int * sslide)
|
|||||||
return get_sym_name(&symtab[rel->r_symbolnum]);
|
return get_sym_name(&symtab[rel->r_symbolnum]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HOST_X86_64
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
|
||||||
/* Intruction contains an offset to the symbols pointed to, in the rel->r_symbolnum section */
|
/* Intruction contains an offset to the symbols pointed to, in the rel->r_symbolnum section */
|
||||||
sectoffset = *(uint32_t *)(text + rel->r_address) & 0xffff;
|
sectoffset = *(uint32_t *)(text + rel->r_address) & 0xffff;
|
||||||
|
|
||||||
@ -1401,6 +1407,7 @@ static const char * get_reloc_name(EXE_RELOC * rel, int * sslide)
|
|||||||
name = (char *)find_sym_with_value_and_sec_number(sectoffset, sectnum, sslide);
|
name = (char *)find_sym_with_value_and_sec_number(sectoffset, sectnum, sslide);
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Used by dyngen common code */
|
/* Used by dyngen common code */
|
||||||
@ -1510,10 +1517,12 @@ int load_object(const char *filename, FILE *outfile)
|
|||||||
/* .data section */
|
/* .data section */
|
||||||
data_sec_hdr = find_mach_sec_hdr(section_hdr, segment->nsects, SEG_DATA, SECT_DATA);
|
data_sec_hdr = find_mach_sec_hdr(section_hdr, segment->nsects, SEG_DATA, SECT_DATA);
|
||||||
i = find_mach_sec_index(section_hdr, segment->nsects, SEG_DATA, SECT_DATA);
|
i = find_mach_sec_index(section_hdr, segment->nsects, SEG_DATA, SECT_DATA);
|
||||||
if (i == -1)
|
data = (i == -1) ? NULL : sdata[i];
|
||||||
data = NULL;
|
|
||||||
else
|
/* const section TODO: __cstring __literal4 __literal8 */
|
||||||
data = sdata[i];
|
literal16_sec_hdr = find_mach_sec_hdr(section_hdr, segment->nsects, SEG_TEXT, "__literal16");
|
||||||
|
i = find_mach_sec_index(section_hdr, segment->nsects, SEG_TEXT, "__literal16");
|
||||||
|
literal16 = (i == -1) ? NULL : sdata[i];
|
||||||
|
|
||||||
/* .text section */
|
/* .text section */
|
||||||
text_sec_hdr = find_mach_sec_hdr(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);
|
text_sec_hdr = find_mach_sec_hdr(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);
|
||||||
@ -1584,7 +1593,14 @@ int load_object(const char *filename, FILE *outfile)
|
|||||||
void get_reloc_expr(char *name, int name_size, const char *sym_name)
|
void get_reloc_expr(char *name, int name_size, const char *sym_name)
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
|
char *demangled;
|
||||||
|
char demangled_buf[256];
|
||||||
|
size_t nd = sizeof(demangled_buf);
|
||||||
|
int status;
|
||||||
|
|
||||||
|
demangled = cxx_demangle(sym_name, demangled_buf, &nd, &status);
|
||||||
|
if (!status && demangled)
|
||||||
|
sym_name = demangled;
|
||||||
if (strstart(sym_name, "__op_param", &p) ||
|
if (strstart(sym_name, "__op_param", &p) ||
|
||||||
strstart(sym_name, "__op_PARAM", &p)) {
|
strstart(sym_name, "__op_PARAM", &p)) {
|
||||||
snprintf(name, name_size, "param%s", p);
|
snprintf(name, name_size, "param%s", p);
|
||||||
@ -1713,6 +1729,10 @@ void gen_code(const char *name, const char *demangled_name,
|
|||||||
const char *sym_name, *p;
|
const char *sym_name, *p;
|
||||||
EXE_RELOC *rel;
|
EXE_RELOC *rel;
|
||||||
int op_execute = 0;
|
int op_execute = 0;
|
||||||
|
char demangled_buf[256];
|
||||||
|
size_t nd;
|
||||||
|
char *demangled;
|
||||||
|
int status;
|
||||||
|
|
||||||
if (strncmp(name, "op_execute", 10) == 0)
|
if (strncmp(name, "op_execute", 10) == 0)
|
||||||
op_execute = 1;
|
op_execute = 1;
|
||||||
@ -1933,6 +1953,10 @@ void gen_code(const char *name, const char *demangled_name,
|
|||||||
sym_name = get_rel_sym_name(rel);
|
sym_name = get_rel_sym_name(rel);
|
||||||
if(!sym_name)
|
if(!sym_name)
|
||||||
continue;
|
continue;
|
||||||
|
nd = sizeof(demangled_buf);
|
||||||
|
demangled = cxx_demangle(sym_name, demangled_buf, &nd, &status);
|
||||||
|
if (!status && demangled)
|
||||||
|
sym_name = demangled;
|
||||||
if (strstart(sym_name, "__op_PARAM", &p)) {
|
if (strstart(sym_name, "__op_PARAM", &p)) {
|
||||||
n = strtoul(p, NULL, 10);
|
n = strtoul(p, NULL, 10);
|
||||||
if (n > MAX_ARGS)
|
if (n > MAX_ARGS)
|
||||||
@ -1979,6 +2003,10 @@ void gen_code(const char *name, const char *demangled_name,
|
|||||||
sym_name = get_rel_sym_name(rel);
|
sym_name = get_rel_sym_name(rel);
|
||||||
if(!sym_name)
|
if(!sym_name)
|
||||||
continue;
|
continue;
|
||||||
|
nd = sizeof(demangled_buf);
|
||||||
|
demangled = cxx_demangle(sym_name, demangled_buf, &nd, &status);
|
||||||
|
if (!status && demangled)
|
||||||
|
sym_name = demangled;
|
||||||
if (*sym_name &&
|
if (*sym_name &&
|
||||||
!strstart(sym_name, "__op_PARAM", NULL) &&
|
!strstart(sym_name, "__op_PARAM", NULL) &&
|
||||||
!strstart(sym_name, "__op_jmp", NULL) &&
|
!strstart(sym_name, "__op_jmp", NULL) &&
|
||||||
@ -2218,8 +2246,9 @@ void patch_relocations(FILE *outfile, const char *name, host_ulong size, host_ul
|
|||||||
const char *p;
|
const char *p;
|
||||||
int slide, sslide;
|
int slide, sslide;
|
||||||
int i, bytecount, bitlength;
|
int i, bytecount, bitlength;
|
||||||
|
int local16;
|
||||||
|
|
||||||
for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
|
for (i = 0, rel = relocs, local16 = 0; i < nb_relocs; i++, rel++) {
|
||||||
unsigned int isym, usesym, offset, length, pcrel, type;
|
unsigned int isym, usesym, offset, length, pcrel, type;
|
||||||
|
|
||||||
isym = rel->r_symbolnum;
|
isym = rel->r_symbolnum;
|
||||||
@ -2238,14 +2267,36 @@ void patch_relocations(FILE *outfile, const char *name, host_ulong size, host_ul
|
|||||||
if (length > 3)
|
if (length > 3)
|
||||||
error("unsupported %d-bit relocation", 8 * (1 << length));
|
error("unsupported %d-bit relocation", 8 * (1 << length));
|
||||||
|
|
||||||
sym_name = get_reloc_name(rel, &sslide);
|
bytecount = (1 << length);
|
||||||
if (!sym_name) {
|
bitlength = 8 * bytecount;
|
||||||
fprintf(outfile, "/* #warning relocation not handled in %s (value 0x%x, %s, offset 0x%x, length 0x%x, %s, type 0x%x) */\n",
|
slide = offset - start_offset;
|
||||||
name, isym, usesym ? "use sym" : "don't use sym", offset, length, pcrel ? "pcrel":"", type);
|
|
||||||
continue; /* dunno how to handle without final_sym_name */
|
if (!usesym) {
|
||||||
|
// local reloc
|
||||||
|
sslide = get32((uint32_t *)(text + offset)) + rel->r_address + 4;
|
||||||
|
if ( literal16_sec_hdr
|
||||||
|
&& sslide >= literal16_sec_hdr->addr
|
||||||
|
&& sslide + 16 <= literal16_sec_hdr->addr + literal16_sec_hdr->size ) {
|
||||||
|
sprintf(final_sym_name, "literal16_%d", ++local);
|
||||||
|
print_data(outfile, final_sym_name, literal16 + sslide - literal16_sec_hdr->addr, 16);
|
||||||
|
fprintf(outfile, " static uint8 *data_p_%d = NULL;\n", local);
|
||||||
|
fprintf(outfile, " if (data_p_%d == NULL)\n", local);
|
||||||
|
fprintf(outfile, " data_p_%d = copy_data(%s, %d);\n", local, final_sym_name, 16);
|
||||||
|
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = (int32_t)((long)data_p_%d - (long)(code_ptr() + %d + %d));\n",
|
||||||
|
slide, local, slide, bytecount);
|
||||||
|
} else {
|
||||||
|
fprintf(outfile, "/* #warning relocation not handled in %s (section %d, offset 0x%x, length 0x%x, %s, type 0x%x) */\n",
|
||||||
|
name, isym, offset, length, pcrel ? "pcrel":"", type);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sym_name = get_reloc_name(rel, &sslide);
|
||||||
|
if (!sym_name) {
|
||||||
|
error("external symbol not found in %s (section %d, offset 0x%x, length 0x%x, %s, type 0x%x\n",
|
||||||
|
name, isym, offset, length, pcrel ? "pcrel":"", type);
|
||||||
}
|
}
|
||||||
|
|
||||||
slide = offset - start_offset;
|
|
||||||
if (strstart(sym_name, "__op_jmp", &p)) {
|
if (strstart(sym_name, "__op_jmp", &p)) {
|
||||||
int n;
|
int n;
|
||||||
n = strtol(p, NULL, 10);
|
n = strtol(p, NULL, 10);
|
||||||
@ -2254,9 +2305,6 @@ void patch_relocations(FILE *outfile, const char *name, host_ulong size, host_ul
|
|||||||
continue; /* Nothing more to do */
|
continue; /* Nothing more to do */
|
||||||
}
|
}
|
||||||
|
|
||||||
bytecount = (1 << length);
|
|
||||||
bitlength = 8 * bytecount;
|
|
||||||
|
|
||||||
get_reloc_expr(final_sym_name, sizeof(final_sym_name), sym_name);
|
get_reloc_expr(final_sym_name, sizeof(final_sym_name), sym_name);
|
||||||
|
|
||||||
if (pcrel || strstart(sym_name,"__op_gen_label",&p)) {
|
if (pcrel || strstart(sym_name,"__op_gen_label",&p)) {
|
||||||
@ -2854,6 +2902,7 @@ int gen_file(FILE *outfile, int out_type)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* demangle C++ symbols */
|
/* demangle C++ symbols */
|
||||||
|
nd = 256;
|
||||||
demangled_name = cxx_demangle(name, demangled_name, &nd, &status);
|
demangled_name = cxx_demangle(name, demangled_name, &nd, &status);
|
||||||
if (status == 0 && strstart(demangled_name, OP_PREFIX, NULL)) {
|
if (status == 0 && strstart(demangled_name, OP_PREFIX, NULL)) {
|
||||||
/* get real function name */
|
/* get real function name */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user