mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-11-26 10:49:21 +00:00
[ Patch from Jean-Pierre <chombier@free.fr> ]
Dyngen patch for Snow Leopard x86_64 compatibility. This work is mostly based on the unofficial and incomplete x86_64 mach-o patch of qemu.
This commit is contained in:
parent
5a266542af
commit
df4aef1fba
@ -61,7 +61,7 @@
|
||||
#elif defined(__sparc__)
|
||||
#define HOST_SPARC 1
|
||||
#elif defined(__x86_64__)
|
||||
#define HOST_AMD64 1
|
||||
#define HOST_X86_64 1
|
||||
#elif defined(__m68k__)
|
||||
#define HOST_M68K 1
|
||||
#elif defined(__mips__)
|
||||
@ -69,7 +69,7 @@
|
||||
#endif
|
||||
|
||||
/* Debug generated code */
|
||||
#if ENABLE_MON && (defined(HOST_I386) || defined(HOST_AMD64)) && 0
|
||||
#if ENABLE_MON && (defined(HOST_I386) || defined(HOST_X86_64)) && 0
|
||||
#define DYNGEN_PRETTY_PRINT 1
|
||||
|
||||
#include "disass/dis-asm.h"
|
||||
@ -124,7 +124,7 @@ static int dyngen_sprintf(struct SFILE *f, const char *format, ...)
|
||||
return n;
|
||||
}
|
||||
|
||||
#if defined(HOST_I386) || defined(HOST_AMD64)
|
||||
#if defined(HOST_I386) || defined(HOST_X86_64)
|
||||
static int pretty_print(char *buf, uintptr_t addr, uintptr_t base)
|
||||
{
|
||||
disassemble_info info;
|
||||
@ -132,7 +132,7 @@ static int pretty_print(char *buf, uintptr_t addr, uintptr_t base)
|
||||
sfile.buffer = buf;
|
||||
sfile.current = buf;
|
||||
INIT_DISASSEMBLE_INFO(info, (FILE *)&sfile, (fprintf_ftype)dyngen_sprintf);
|
||||
#if defined(HOST_AMD64)
|
||||
#if defined(HOST_X86_64)
|
||||
info.mach = bfd_mach_x86_64;
|
||||
#endif
|
||||
print_address_base = base;
|
||||
@ -163,7 +163,7 @@ static int pretty_print(char *buf, uintptr_t addr, uintptr_t base)
|
||||
#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
|
||||
#undef ELF_USES_RELOCA
|
||||
|
||||
#elif defined(HOST_AMD64)
|
||||
#elif defined(HOST_X86_64)
|
||||
|
||||
#define ELF_CLASS ELFCLASS64
|
||||
#define ELF_ARCH EM_X86_64
|
||||
@ -251,11 +251,9 @@ static int pretty_print(char *buf, uintptr_t addr, uintptr_t base)
|
||||
#endif
|
||||
|
||||
#if ELF_CLASS == ELFCLASS32
|
||||
typedef int32_t host_long;
|
||||
typedef uint32_t host_ulong;
|
||||
#define swabls(x) swab32s(x)
|
||||
#else
|
||||
typedef int64_t host_long;
|
||||
typedef uint64_t host_ulong;
|
||||
#define swabls(x) swab64s(x)
|
||||
#endif
|
||||
@ -283,7 +281,6 @@ typedef ElfW(Rela) elf_rela;
|
||||
|
||||
#include "a.out-defs.h"
|
||||
|
||||
typedef int32_t host_long;
|
||||
typedef uint32_t host_ulong;
|
||||
|
||||
#define FILENAMELEN 256
|
||||
@ -315,29 +312,45 @@ typedef struct coff_rel {
|
||||
#include <mach-o/reloc.h>
|
||||
#include <mach-o/ppc/reloc.h>
|
||||
|
||||
#ifdef HOST_PPC
|
||||
#if defined(HOST_PPC) || defined(HOST_I386)
|
||||
|
||||
#define MACH_CPU_TYPE CPU_TYPE_POWERPC
|
||||
#define mach_check_cputype(x) ((x) == CPU_TYPE_POWERPC)
|
||||
# if defined(HOST_I386)
|
||||
|
||||
#elif defined(HOST_I386)
|
||||
# define mach_check_cputype(x) ((x) == CPU_TYPE_I386)
|
||||
# else
|
||||
# define mach_check_cputype(x) ((x) == CPU_TYPE_POWERPC)
|
||||
# endif
|
||||
# define check_mach_header(x) (x.magic == MH_MAGIC)
|
||||
# define SEGMENT_COMMAND segment_command
|
||||
# define MACH_HEADER mach_header
|
||||
# define SECTION section
|
||||
# define NLIST nlist
|
||||
typedef uint32_t host_ulong;
|
||||
|
||||
#define MACH_CPU_TYPE CPU_TYPE_I386
|
||||
#define mach_check_cputype(x) ((x) == CPU_TYPE_I386)
|
||||
#elif defined(HOST_X86_64)
|
||||
|
||||
# include <mach-o/x86_64/reloc.h>
|
||||
# define mach_check_cputype(x) ((x) == CPU_TYPE_X86_64)
|
||||
# define check_mach_header(x) (x.magic == MH_MAGIC_64)
|
||||
# define SEGMENT_COMMAND segment_command_64
|
||||
# define MACH_HEADER mach_header_64
|
||||
# define SECTION section_64
|
||||
# define NLIST nlist_64
|
||||
typedef uint64_t host_ulong;
|
||||
|
||||
#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;
|
||||
|
||||
struct nlist_extended
|
||||
{
|
||||
union {
|
||||
#ifdef HOST_X86_64
|
||||
unsigned int n_strx;
|
||||
#else
|
||||
char *n_name;
|
||||
long n_strx;
|
||||
#endif
|
||||
} n_un;
|
||||
unsigned char n_type;
|
||||
unsigned char n_sect;
|
||||
@ -1131,17 +1144,17 @@ int load_object(const char *filename, FILE *outfile)
|
||||
#ifdef CONFIG_FORMAT_MACH
|
||||
|
||||
/* File Header */
|
||||
struct mach_header mach_hdr;
|
||||
struct MACH_HEADER mach_hdr;
|
||||
|
||||
/* commands */
|
||||
struct segment_command *segment = 0;
|
||||
struct SEGMENT_COMMAND *segment = 0;
|
||||
struct dysymtab_command *dysymtabcmd = 0;
|
||||
struct symtab_command *symtabcmd = 0;
|
||||
|
||||
/* section */
|
||||
struct section *section_hdr;
|
||||
struct section *text_sec_hdr;
|
||||
struct section *data_sec_hdr;
|
||||
struct SECTION *section_hdr;
|
||||
struct SECTION *text_sec_hdr;
|
||||
struct SECTION *data_sec_hdr;
|
||||
uint8_t **sdata;
|
||||
|
||||
/* relocs */
|
||||
@ -1149,7 +1162,7 @@ struct relocation_info *relocs;
|
||||
|
||||
/* symbols */
|
||||
EXE_SYM *symtab;
|
||||
struct nlist *symtab_std;
|
||||
struct NLIST *symtab_std;
|
||||
char *strtab;
|
||||
|
||||
/* indirect symbols */
|
||||
@ -1179,11 +1192,11 @@ static char *get_sym_name(EXE_SYM *sym)
|
||||
}
|
||||
|
||||
/* find a section index given its segname, sectname */
|
||||
static int find_mach_sec_index(struct section *section_hdr, int shnum, const char *segname,
|
||||
static int find_mach_sec_index(struct SECTION *section_hdr, int shnum, const char *segname,
|
||||
const char *sectname)
|
||||
{
|
||||
int i;
|
||||
struct section *sec = section_hdr;
|
||||
struct SECTION *sec = section_hdr;
|
||||
|
||||
for(i = 0; i < shnum; i++, sec++) {
|
||||
if (!sec->segname || !sec->sectname)
|
||||
@ -1195,7 +1208,7 @@ static int find_mach_sec_index(struct section *section_hdr, int shnum, const cha
|
||||
}
|
||||
|
||||
/* find a section header given its segname, sectname */
|
||||
struct section *find_mach_sec_hdr(struct section *section_hdr, int shnum, const char *segname,
|
||||
struct SECTION *find_mach_sec_hdr(struct SECTION *section_hdr, int shnum, const char *segname,
|
||||
const char *sectname)
|
||||
{
|
||||
int index = find_mach_sec_index(section_hdr, shnum, segname, sectname);
|
||||
@ -1248,7 +1261,7 @@ static const char * find_sym_with_value_and_sec_number( int value, int sectnum,
|
||||
* Find symbol name given a (virtual) address, and a section which is of type
|
||||
* S_NON_LAZY_SYMBOL_POINTERS or S_LAZY_SYMBOL_POINTERS or S_SYMBOL_STUBS
|
||||
*/
|
||||
static const char * find_reloc_name_in_sec_ptr(int address, struct section * sec_hdr)
|
||||
static const char * find_reloc_name_in_sec_ptr(int address, struct SECTION * sec_hdr)
|
||||
{
|
||||
unsigned int tocindex, symindex, size;
|
||||
const char *name = 0;
|
||||
@ -1296,9 +1309,18 @@ static const char * get_reloc_name(EXE_RELOC * rel, int * sslide)
|
||||
struct scattered_relocation_info * sca_rel = (struct scattered_relocation_info*)rel;
|
||||
int sectnum = rel->r_symbolnum;
|
||||
int sectoffset;
|
||||
int other_half=0;
|
||||
unsigned int other_half=0;
|
||||
|
||||
/* init the slide value */
|
||||
#ifdef HOST_X86_64 /* no scattered on x86_64 */
|
||||
switch(rel->r_length)
|
||||
{
|
||||
case 0: *sslide = *(uint8_t *)(text + rel->r_address); break;
|
||||
case 1: *sslide = *(uint16_t *)(text + rel->r_address); break;
|
||||
case 2: *sslide = *(uint32_t *)(text + rel->r_address); break;
|
||||
case 3: *sslide = *(uint64_t *)(text + rel->r_address); break;
|
||||
}
|
||||
#else
|
||||
*sslide = 0;
|
||||
|
||||
if (R_SCATTERED & rel->r_address) {
|
||||
@ -1322,6 +1344,7 @@ static const char * get_reloc_name(EXE_RELOC * rel, int * sslide)
|
||||
}
|
||||
return name;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(rel->r_extern)
|
||||
{
|
||||
@ -1343,6 +1366,8 @@ static const char * get_reloc_name(EXE_RELOC * rel, int * sslide)
|
||||
|
||||
switch(rel->r_type)
|
||||
{
|
||||
case PPC_RELOC_PAIR: // The second relocation entry of a pair. A PPC_RELOC_PAIR entry must follow each of the other relocation entry types, except for PPC_RELOC_VANILLA, PPC_RELOC_BR14, PPC_RELOC_BR24, and PPC_RELOC_PB_LA_PTR.
|
||||
break;
|
||||
case PPC_RELOC_LO16: fetch_next_pair_value(rel+1, &other_half); sectoffset |= (other_half << 16);
|
||||
break;
|
||||
case PPC_RELOC_HI16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (sectoffset << 16) | (uint16_t)(other_half & 0xffff);
|
||||
@ -1404,7 +1429,7 @@ int load_object(const char *filename, FILE *outfile)
|
||||
struct load_command lc;
|
||||
unsigned int i, j;
|
||||
EXE_SYM *sym;
|
||||
struct nlist *syment;
|
||||
struct NLIST *syment;
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
@ -1430,29 +1455,37 @@ int load_object(const char *filename, FILE *outfile)
|
||||
{
|
||||
if(read(fd, &lc, sizeof(struct load_command)) != sizeof(struct load_command))
|
||||
error("unable to read load_command");
|
||||
if(lc.cmd == LC_SEGMENT)
|
||||
{
|
||||
switch(lc.cmd) {
|
||||
#ifdef HOST_X86_64
|
||||
case LC_SEGMENT_64:
|
||||
#else
|
||||
case LC_SEGMENT:
|
||||
#endif
|
||||
offset_to_segment = j;
|
||||
lseek(fd, offset_to_segment, SEEK_SET);
|
||||
segment = malloc(sizeof(struct segment_command));
|
||||
if(read(fd, segment, sizeof(struct segment_command)) != sizeof(struct segment_command))
|
||||
segment = malloc(sizeof(struct SEGMENT_COMMAND));
|
||||
if(read(fd, segment, sizeof(struct SEGMENT_COMMAND)) != sizeof(struct SEGMENT_COMMAND))
|
||||
error("unable to read LC_SEGMENT");
|
||||
}
|
||||
if(lc.cmd == LC_DYSYMTAB)
|
||||
{
|
||||
break;
|
||||
|
||||
case LC_DYSYMTAB:
|
||||
offset_to_dysymtab = j;
|
||||
lseek(fd, offset_to_dysymtab, SEEK_SET);
|
||||
dysymtabcmd = malloc(sizeof(struct dysymtab_command));
|
||||
if(read(fd, dysymtabcmd, sizeof(struct dysymtab_command)) != sizeof(struct dysymtab_command))
|
||||
error("unable to read LC_DYSYMTAB");
|
||||
}
|
||||
if(lc.cmd == LC_SYMTAB)
|
||||
{
|
||||
break;
|
||||
|
||||
case LC_SYMTAB:
|
||||
offset_to_symtab = j;
|
||||
lseek(fd, offset_to_symtab, SEEK_SET);
|
||||
symtabcmd = malloc(sizeof(struct symtab_command));
|
||||
if(read(fd, symtabcmd, sizeof(struct symtab_command)) != sizeof(struct symtab_command))
|
||||
error("unable to read LC_SYMTAB");
|
||||
break;
|
||||
|
||||
default:
|
||||
error("LC: unknown command: %#x", lc.cmd);
|
||||
}
|
||||
j+=lc.cmdsize;
|
||||
|
||||
@ -1463,7 +1496,7 @@ int load_object(const char *filename, FILE *outfile)
|
||||
error("unable to find LC_SEGMENT");
|
||||
|
||||
/* read section headers */
|
||||
section_hdr = load_data(fd, offset_to_segment + sizeof(struct segment_command), segment->nsects * sizeof(struct section));
|
||||
section_hdr = load_data(fd, offset_to_segment + sizeof(struct SEGMENT_COMMAND), segment->nsects * sizeof(struct SECTION));
|
||||
|
||||
/* read all section data */
|
||||
sdata = (uint8_t **)malloc(sizeof(void *) * segment->nsects);
|
||||
@ -1473,15 +1506,15 @@ int load_object(const char *filename, FILE *outfile)
|
||||
for(i = 0; i < segment->nsects; i++)
|
||||
sdata[i] = load_data(fd, section_hdr[i].offset, section_hdr[i].size);
|
||||
|
||||
/* data section */
|
||||
/* .data section */
|
||||
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);
|
||||
if (i == -1 || !data_sec_hdr)
|
||||
if (i == -1)
|
||||
data = NULL;
|
||||
else
|
||||
data = sdata[i];
|
||||
|
||||
/* text section */
|
||||
/* .text section */
|
||||
text_sec_hdr = find_mach_sec_hdr(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);
|
||||
i = find_mach_sec_index(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);
|
||||
if (i == -1 || !text_sec_hdr)
|
||||
@ -1500,25 +1533,28 @@ int load_object(const char *filename, FILE *outfile)
|
||||
error("could not find __SYMTAB segment");
|
||||
nb_syms = symtabcmd->nsyms;
|
||||
|
||||
symtab_std = load_data(fd, symtabcmd->symoff, symtabcmd->nsyms * sizeof(struct nlist));
|
||||
symtab_std = load_data(fd, symtabcmd->symoff, symtabcmd->nsyms * sizeof(struct NLIST));
|
||||
strtab = load_data(fd, symtabcmd->stroff, symtabcmd->strsize);
|
||||
|
||||
symtab = malloc(sizeof(EXE_SYM) * nb_syms);
|
||||
|
||||
/* Now transform the symtab, to an extended version, with the sym size, and the C name */
|
||||
for(i = 0, sym = symtab, syment = symtab_std; i < nb_syms; i++, sym++, syment++) {
|
||||
struct nlist *sym_follow, *sym_next = 0;
|
||||
struct NLIST *sym_follow, *sym_next = 0;
|
||||
unsigned int j;
|
||||
memset(sym, 0, sizeof(*sym));
|
||||
|
||||
if ( syment->n_type & N_STAB ) /* Debug symbols are skipped */
|
||||
continue;
|
||||
|
||||
if ( strchr((char*)(strtab + syment->n_un.n_strx), '.') ) /* no Exception handlers */
|
||||
continue;
|
||||
|
||||
memcpy(sym, syment, sizeof(*syment));
|
||||
|
||||
/* Find the following symbol in order to get the current symbol size */
|
||||
for(j = 0, sym_follow = symtab_std; j < nb_syms; j++, sym_follow++) {
|
||||
if ( sym_follow->n_sect != 1 || sym_follow->n_type & N_STAB || !(sym_follow->n_value > sym->st_value))
|
||||
if ( sym_follow->n_sect != 1 || (sym_follow->n_type & N_STAB) || !(sym_follow->n_value > sym->st_value) )
|
||||
continue;
|
||||
if(!sym_next) {
|
||||
sym_next = sym_follow;
|
||||
@ -1544,6 +1580,27 @@ int load_object(const char *filename, FILE *outfile)
|
||||
|
||||
#endif /* CONFIG_FORMAT_MACH */
|
||||
|
||||
void get_reloc_expr(char *name, int name_size, const char *sym_name)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
if (strstart(sym_name, "__op_param", &p) ||
|
||||
strstart(sym_name, "__op_PARAM", &p)) {
|
||||
snprintf(name, name_size, "param%s", p);
|
||||
} else if (strstart(sym_name, "__op_gen_label", &p)) {
|
||||
snprintf(name, name_size, "gen_labels[param%s]", p);
|
||||
} else {
|
||||
#ifdef HOST_SPARC
|
||||
if (sym_name[0] == '.')
|
||||
snprintf(name, name_size,
|
||||
"(long)(&__dot_%s)",
|
||||
sym_name + 1);
|
||||
else
|
||||
#endif
|
||||
snprintf(name, name_size, "(long)(&%s)", sym_name);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HOST_ARM
|
||||
|
||||
int arm_emit_ldr_info(const char *name, unsigned long start_offset,
|
||||
@ -1603,11 +1660,7 @@ int arm_emit_ldr_info(const char *name, unsigned long start_offset,
|
||||
if (rel->r_offset == (pc_offset + start_offset)) {
|
||||
sym_name = get_rel_sym_name(rel);
|
||||
/* the compiler leave some unnecessary references to the code */
|
||||
if (strstart(sym_name, "__op_PARAM", &p)) {
|
||||
snprintf(relname, sizeof(relname), "param%s", p);
|
||||
} else {
|
||||
snprintf(relname, sizeof(relname), "(long)(&%s)", sym_name);
|
||||
}
|
||||
get_reloc_expr(relname, sizeof(relname), sym_name);
|
||||
type = ELF32_R_TYPE(rel->r_info);
|
||||
if (type != R_ARM_ABS32)
|
||||
error("%s: unsupported data relocation", name);
|
||||
@ -1680,8 +1733,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
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)
|
||||
#elif 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)
|
||||
@ -1691,7 +1743,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
#endif
|
||||
}
|
||||
else
|
||||
#if defined(HOST_I386) || defined(HOST_AMD64)
|
||||
#if defined(HOST_I386) || defined(HOST_X86_64)
|
||||
#if defined(CONFIG_FORMAT_COFF) || defined(CONFIG_FORMAT_MACH)
|
||||
{
|
||||
uint8_t *p;
|
||||
@ -1867,6 +1919,8 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
#error unsupported CPU
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* compute the number of arguments by looking at the relocations */
|
||||
for(i = 0;i < MAX_ARGS; i++)
|
||||
args_present[i] = 0;
|
||||
@ -2041,7 +2095,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
|
||||
sym_name = get_reloc_name(rel, &sslide);
|
||||
|
||||
if (usesym && symtab[isym].n_type & N_STAB)
|
||||
if (usesym && (symtab[isym].n_type & N_STAB))
|
||||
continue; /* don't handle STAB (debug sym) */
|
||||
|
||||
if (sym_name && strstart(sym_name, "__op_jmp", &p)) {
|
||||
@ -2057,10 +2111,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
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
|
||||
snprintf(final_sym_name, sizeof(final_sym_name), "(long)(&%s)", sym_name);
|
||||
get_reloc_expr(final_sym_name, sizeof(final_sym_name), sym_name);
|
||||
|
||||
if (length != 2)
|
||||
error("unsupported %d-bit relocation", 8 * (1 << length));
|
||||
@ -2081,7 +2132,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
}
|
||||
}
|
||||
#else
|
||||
char name[256];
|
||||
char final_sym_name[256];
|
||||
int type;
|
||||
int addend;
|
||||
for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
|
||||
@ -2100,22 +2151,18 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strstart(sym_name, "__op_PARAM", &p)) {
|
||||
snprintf(name, sizeof(name), "param%s", p);
|
||||
} else {
|
||||
snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
|
||||
}
|
||||
get_reloc_expr(final_sym_name, sizeof(final_sym_name), sym_name);
|
||||
addend = get32((uint32_t *)(text + rel->r_offset));
|
||||
#ifdef CONFIG_FORMAT_ELF
|
||||
type = ELF32_R_TYPE(rel->r_info);
|
||||
switch(type) {
|
||||
case R_386_32:
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = %s + %d;\n",
|
||||
rel->r_offset - start_offset, name, addend);
|
||||
rel->r_offset - start_offset, final_sym_name, addend);
|
||||
break;
|
||||
case R_386_PC32:
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = %s - (long)(code_ptr() + %d) + %d;\n",
|
||||
rel->r_offset - start_offset, name, rel->r_offset - start_offset, addend);
|
||||
rel->r_offset - start_offset, final_sym_name, rel->r_offset - start_offset, addend);
|
||||
break;
|
||||
default:
|
||||
error("unsupported i386 relocation (%d)", type);
|
||||
@ -2138,30 +2185,106 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
switch(type) {
|
||||
case DIR32:
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = %s + %d;\n",
|
||||
rel->r_offset - start_offset, name, addend);
|
||||
rel->r_offset - start_offset, final_sym_name, addend);
|
||||
break;
|
||||
case DISP32:
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = %s - (long)(code_ptr() + %d) + %d -4;\n",
|
||||
rel->r_offset - start_offset, name, rel->r_offset - start_offset, addend);
|
||||
rel->r_offset - start_offset, final_sym_name, rel->r_offset - start_offset, addend);
|
||||
break;
|
||||
default:
|
||||
error("unsupported i386 relocation (%d)", type);
|
||||
}
|
||||
#else
|
||||
#error unsupport object format
|
||||
#error unsupport object format for HOST_I386
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#elif defined(HOST_AMD64)
|
||||
#elif defined(HOST_X86_64)
|
||||
{
|
||||
char name[256];
|
||||
#if defined(CONFIG_FORMAT_MACH)
|
||||
struct relocation_info * rel;
|
||||
char final_sym_name[256];
|
||||
const char *sym_name;
|
||||
const char *p;
|
||||
int slide, sslide;
|
||||
int i, bytecount, bitlength;
|
||||
|
||||
for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
|
||||
unsigned int isym, usesym, offset, length, pcrel, type;
|
||||
|
||||
isym = rel->r_symbolnum;
|
||||
usesym = rel->r_extern;
|
||||
offset = rel->r_address;
|
||||
length = rel->r_length;
|
||||
pcrel = rel->r_pcrel;
|
||||
type = rel->r_type;
|
||||
|
||||
if (usesym && (symtab[isym].n_type & N_STAB))
|
||||
continue; /* don't handle STAB (debug sym) */
|
||||
|
||||
if (!(offset >= start_offset && offset < start_offset + size))
|
||||
continue; /* not in our range */
|
||||
|
||||
if (length > 3)
|
||||
error("unsupported %d-bit relocation", 8 * (1 << length));
|
||||
|
||||
sym_name = get_reloc_name(rel, &sslide);
|
||||
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, isym, usesym ? "use sym" : "don't use sym", offset, length, pcrel ? "pcrel":"", type);
|
||||
continue; /* dunno how to handle without final_sym_name */
|
||||
}
|
||||
|
||||
slide = offset - start_offset;
|
||||
if (strstart(sym_name, "__op_jmp", &p)) {
|
||||
int n;
|
||||
n = strtol(p, NULL, 10);
|
||||
fprintf(outfile, " jmp_addr[%d] = code_ptr() + %d;\n", n, slide);
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = 0;\n", slide);
|
||||
continue; /* Nothing more to do */
|
||||
}
|
||||
|
||||
bytecount = (1 << length);
|
||||
bitlength = 8 * bytecount;
|
||||
|
||||
get_reloc_expr(final_sym_name, sizeof(final_sym_name), sym_name);
|
||||
|
||||
if (pcrel || strstart(sym_name,"__op_gen_label",&p)) {
|
||||
switch (type) {
|
||||
case X86_64_RELOC_UNSIGNED: // for absolute addresses
|
||||
case X86_64_RELOC_SIGNED: // for signed 32-bit displacement
|
||||
case X86_64_RELOC_BRANCH: // a CALL/JMP instruction with 32-bit displacement
|
||||
fprintf(outfile, " *(uint%d_t *)(code_ptr() + %d) = (int%d_t)((long)%s - (long)(code_ptr() + %d + %d)) + %d;\n",
|
||||
bitlength, slide, bitlength, final_sym_name, slide, bytecount, sslide);
|
||||
break;
|
||||
default:
|
||||
error("unsupported x86_64 relocation (%d) in %s\n", type, sym_name);
|
||||
}
|
||||
} else {
|
||||
switch (type) {
|
||||
case X86_64_RELOC_UNSIGNED: // for absolute addresses
|
||||
fprintf(outfile, " *(uint%d_t *)(code_ptr() + %d) = (uint%d_t)%s + %d;\n",
|
||||
bitlength, slide, bitlength, final_sym_name, sslide);
|
||||
break;
|
||||
case X86_64_RELOC_SIGNED: // for signed 32-bit displacement
|
||||
fprintf(outfile, " *(uint%d_t *)(code_ptr() + %d) = (int%d_t)%s + %d;\n",
|
||||
bitlength, slide, bitlength, final_sym_name, sslide);
|
||||
break;
|
||||
default:
|
||||
error("unsupported x86_64 relocation (%d) in %s\n", type, sym_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif defined (CONFIG_FORMAT_ELF)
|
||||
char final_sym_name[256];
|
||||
int type;
|
||||
int addend;
|
||||
for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
|
||||
if (rel->r_offset >= start_offset &&
|
||||
rel->r_offset < start_offset + copy_size) {
|
||||
int slide;
|
||||
sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
|
||||
if (strstart(sym_name, "__op_jmp", &p)) {
|
||||
int n;
|
||||
@ -2175,46 +2298,43 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strstart(sym_name, "__op_PARAM", &p))
|
||||
snprintf(name, sizeof(name), "param%s", p);
|
||||
else if (strstart(sym_name, ".LC", NULL))
|
||||
snprintf(name, sizeof(name), "(long)(gen_const_%s())", gen_dot_prefix(sym_name));
|
||||
else
|
||||
snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
|
||||
slide = rel->r_offset - start_offset;
|
||||
get_reloc_expr(final_sym_name, sizeof(final_sym_name), sym_name);
|
||||
type = ELF32_R_TYPE(rel->r_info);
|
||||
addend = rel->r_addend;
|
||||
switch(type) {
|
||||
case R_X86_64_64:
|
||||
fprintf(outfile, " *(uintptr *)(code_ptr() + %d) = (uintptr)%s + %d;\n",
|
||||
rel->r_offset - start_offset, name, addend);
|
||||
fprintf(outfile, " *(uintptr *)(code_ptr() + %d) = (uintptr)%s + %d;\n", slide, final_sym_name, addend);
|
||||
break;
|
||||
case R_X86_64_32:
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = (uint32_t)%s + %d;\n",
|
||||
rel->r_offset - start_offset, name, addend);
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = (uint32_t)%s + %d;\n", slide, final_sym_name, addend);
|
||||
break;
|
||||
case R_X86_64_32S:
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = (int32_t)%s + %d;\n",
|
||||
rel->r_offset - start_offset, name, addend);
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = (int32_t)%s + %d;\n", slide, final_sym_name, addend);
|
||||
break;
|
||||
case R_X86_64_PC32:
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = %s - (long)(code_ptr() + %d) + %d;\n",
|
||||
rel->r_offset - start_offset, name, rel->r_offset - start_offset, addend);
|
||||
slide, final_sym_name, slide, addend);
|
||||
break;
|
||||
default:
|
||||
error("unsupported AMD64 relocation (%d)", type);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
#error unsupport object format for HOST_X86_64
|
||||
#endif
|
||||
}
|
||||
#elif defined(HOST_PPC)
|
||||
{
|
||||
#ifdef CONFIG_FORMAT_ELF
|
||||
char name[256];
|
||||
char final_sym_name[256];
|
||||
int type;
|
||||
int addend;
|
||||
for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
|
||||
if (rel->r_offset >= start_offset &&
|
||||
rel->r_offset < start_offset + copy_size) {
|
||||
int slide;
|
||||
sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
|
||||
if (strstart(sym_name, "__op_jmp", &p)) {
|
||||
int n;
|
||||
@ -2228,34 +2348,31 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strstart(sym_name, "__op_PARAM", &p)) {
|
||||
snprintf(name, sizeof(name), "param%s", p);
|
||||
} else {
|
||||
snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
|
||||
}
|
||||
slide = rel->r_offset - start_offset;
|
||||
get_reloc_expr(final_sym_name, sizeof(final_sym_name), sym_name);
|
||||
type = ELF32_R_TYPE(rel->r_info);
|
||||
addend = rel->r_addend;
|
||||
switch(type) {
|
||||
case R_PPC_ADDR32:
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = %s + %d;\n",
|
||||
rel->r_offset - start_offset, name, addend);
|
||||
slide, final_sym_name, addend);
|
||||
break;
|
||||
case R_PPC_ADDR16_LO:
|
||||
fprintf(outfile, " *(uint16_t *)(code_ptr() + %d) = (%s + %d);\n",
|
||||
rel->r_offset - start_offset, name, addend);
|
||||
slide, final_sym_name, addend);
|
||||
break;
|
||||
case R_PPC_ADDR16_HI:
|
||||
fprintf(outfile, " *(uint16_t *)(code_ptr() + %d) = (%s + %d) >> 16;\n",
|
||||
rel->r_offset - start_offset, name, addend);
|
||||
slide, final_sym_name, addend);
|
||||
break;
|
||||
case R_PPC_ADDR16_HA:
|
||||
fprintf(outfile, " *(uint16_t *)(code_ptr() + %d) = (%s + %d + 0x8000) >> 16;\n",
|
||||
rel->r_offset - start_offset, name, addend);
|
||||
slide, final_sym_name, addend);
|
||||
break;
|
||||
case R_PPC_REL24:
|
||||
/* warning: must be at 32 MB distancy */
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = (*(uint32_t *)(code_ptr() + %d) & ~0x03fffffc) | ((%s - (long)(code_ptr() + %d) + %d) & 0x03fffffc);\n",
|
||||
rel->r_offset - start_offset, rel->r_offset - start_offset, name, rel->r_offset - start_offset, addend);
|
||||
slide, slide, final_sym_name, slide, addend);
|
||||
break;
|
||||
default:
|
||||
error("unsupported powerpc relocation (%d)", type);
|
||||
@ -2299,7 +2416,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
|
||||
sym_name = get_reloc_name(rel, &sslide);
|
||||
|
||||
if(usesym && symtab[isym].n_type & N_STAB)
|
||||
if(usesym && (symtab[isym].n_type & N_STAB))
|
||||
continue; /* don't handle STAB (debug sym) */
|
||||
|
||||
if (sym_name && strstart(sym_name, "__op_jmp", &p)) {
|
||||
@ -2317,11 +2434,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
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 {
|
||||
snprintf(final_sym_name, sizeof(final_sym_name), "(long)(&%s)", sym_name);
|
||||
}
|
||||
get_reloc_expr(final_sym_name, sizeof(final_sym_name), sym_name);
|
||||
|
||||
switch(type) {
|
||||
case PPC_RELOC_BR24:
|
||||
@ -2329,7 +2442,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
fprintf(outfile, "{\n");
|
||||
fprintf(outfile, " uint32_t imm = *(uint32_t *)(code_ptr() + %d) & 0x3fffffc;\n", slide);
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = (*(uint32_t *)(code_ptr() + %d) & ~0x03fffffc) | ((imm + ((long)%s - (long)code_ptr()) + %d) & 0x03fffffc);\n",
|
||||
slide, slide, name, sslide );
|
||||
slide, slide, final_sym_name, sslide );
|
||||
fprintf(outfile, "}\n");
|
||||
} else {
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = (*(uint32_t *)(code_ptr() + %d) & ~0x03fffffc) | (((long)%s - (long)code_ptr() - %d) & 0x03fffffc);\n",
|
||||
@ -2358,32 +2471,30 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
}
|
||||
#elif defined(HOST_S390)
|
||||
{
|
||||
char name[256];
|
||||
char final_sym_name[256];
|
||||
int type;
|
||||
int addend;
|
||||
for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
|
||||
if (rel->r_offset >= start_offset &&
|
||||
rel->r_offset < start_offset + copy_size) {
|
||||
int slide;
|
||||
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);
|
||||
}
|
||||
get_reloc_expr(final_sym_name, sizeof(final_sym_name), sym_name);
|
||||
type = ELF32_R_TYPE(rel->r_info);
|
||||
slide = rel->r_offset - start_offset;
|
||||
addend = rel->r_addend;
|
||||
switch(type) {
|
||||
case R_390_32:
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = %s + %d;\n",
|
||||
rel->r_offset - start_offset, name, addend);
|
||||
slide, final_sym_name, addend);
|
||||
break;
|
||||
case R_390_16:
|
||||
fprintf(outfile, " *(uint16_t *)(code_ptr() + %d) = %s + %d;\n",
|
||||
rel->r_offset - start_offset, name, addend);
|
||||
slide, final_sym_name, addend);
|
||||
break;
|
||||
case R_390_8:
|
||||
fprintf(outfile, " *(uint8_t *)(code_ptr() + %d) = %s + %d;\n",
|
||||
rel->r_offset - start_offset, name, addend);
|
||||
slide, final_sym_name, addend);
|
||||
break;
|
||||
default:
|
||||
error("unsupported s390 relocation (%d)", type);
|
||||
@ -2392,7 +2503,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
}
|
||||
}
|
||||
#elif defined(HOST_ALPHA)
|
||||
{
|
||||
{
|
||||
for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
|
||||
if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) {
|
||||
int type;
|
||||
@ -2444,27 +2555,23 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif defined(HOST_IA64)
|
||||
{
|
||||
char name[256];
|
||||
char final_sym_name[256];
|
||||
int type;
|
||||
int addend;
|
||||
for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
|
||||
if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) {
|
||||
sym_name = strtab + symtab[ELF64_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);
|
||||
}
|
||||
get_reloc_expr(final_sym_name, sizeof(final_sym_name), sym_name);
|
||||
type = ELF64_R_TYPE(rel->r_info);
|
||||
addend = rel->r_addend;
|
||||
switch(type) {
|
||||
case R_IA64_LTOFF22:
|
||||
error("must implemnt R_IA64_LTOFF22 relocation");
|
||||
error("must implement R_IA64_LTOFF22 relocation");
|
||||
case R_IA64_PCREL21B:
|
||||
error("must implemnt R_IA64_PCREL21B relocation");
|
||||
error("must implement R_IA64_PCREL21B relocation");
|
||||
default:
|
||||
error("unsupported ia64 relocation (%d)", type);
|
||||
}
|
||||
@ -2473,7 +2580,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
}
|
||||
#elif defined(HOST_SPARC)
|
||||
{
|
||||
char name[256];
|
||||
char final_sym_name[256];
|
||||
int type;
|
||||
int addend;
|
||||
for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
|
||||
@ -2481,14 +2588,14 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
rel->r_offset < start_offset + copy_size) {
|
||||
sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
|
||||
if (strstart(sym_name, "__op_PARAM", &p)) {
|
||||
snprintf(name, sizeof(name), "param%s", p);
|
||||
snprintf(final_sym_name, sizeof(final_sym_name), "param%s", p);
|
||||
} else {
|
||||
if (sym_name[0] == '.')
|
||||
snprintf(name, sizeof(name),
|
||||
snprintf(final_sym_name, sizeof(final_sym_name),
|
||||
"(long)(&__dot_%s)",
|
||||
sym_name + 1);
|
||||
else
|
||||
snprintf(name, sizeof(name),
|
||||
snprintf(final_sym_name, sizeof(final_sym_name),
|
||||
"(long)(&%s)", sym_name);
|
||||
}
|
||||
type = ELF32_R_TYPE(rel->r_info);
|
||||
@ -2496,7 +2603,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
switch(type) {
|
||||
case R_SPARC_32:
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = %s + %d;\n",
|
||||
rel->r_offset - start_offset, name, addend);
|
||||
rel->r_offset - start_offset, final_sym_name, addend);
|
||||
break;
|
||||
case R_SPARC_HI22:
|
||||
fprintf(outfile,
|
||||
@ -2506,7 +2613,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
" | (((%s + %d) >> 10) & 0x3fffff);\n",
|
||||
rel->r_offset - start_offset,
|
||||
rel->r_offset - start_offset,
|
||||
name, addend);
|
||||
final_sym_name, addend);
|
||||
break;
|
||||
case R_SPARC_LO10:
|
||||
fprintf(outfile,
|
||||
@ -2516,7 +2623,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
" | ((%s + %d) & 0x3ff);\n",
|
||||
rel->r_offset - start_offset,
|
||||
rel->r_offset - start_offset,
|
||||
name, addend);
|
||||
final_sym_name, addend);
|
||||
break;
|
||||
case R_SPARC_WDISP30:
|
||||
fprintf(outfile,
|
||||
@ -2527,7 +2634,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
" & 0x3fffffff);\n",
|
||||
rel->r_offset - start_offset,
|
||||
rel->r_offset - start_offset,
|
||||
name, addend,
|
||||
final_sym_name, addend,
|
||||
rel->r_offset - start_offset);
|
||||
break;
|
||||
default:
|
||||
@ -2538,24 +2645,20 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
}
|
||||
#elif defined(HOST_SPARC64)
|
||||
{
|
||||
char name[256];
|
||||
char final_sym_name[256];
|
||||
int type;
|
||||
int addend;
|
||||
for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
|
||||
if (rel->r_offset >= start_offset &&
|
||||
rel->r_offset < start_offset + copy_size) {
|
||||
sym_name = strtab + symtab[ELF64_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);
|
||||
}
|
||||
get_reloc_expr(final_sym_name, sizeof(final_sym_name), sym_name);
|
||||
type = ELF64_R_TYPE(rel->r_info);
|
||||
addend = rel->r_addend;
|
||||
switch(type) {
|
||||
case R_SPARC_32:
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = %s + %d;\n",
|
||||
rel->r_offset - start_offset, name, addend);
|
||||
rel->r_offset - start_offset, final_sym_name, addend);
|
||||
break;
|
||||
case R_SPARC_HI22:
|
||||
fprintf(outfile,
|
||||
@ -2565,7 +2668,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
" | (((%s + %d) >> 10) & 0x3fffff);\n",
|
||||
rel->r_offset - start_offset,
|
||||
rel->r_offset - start_offset,
|
||||
name, addend);
|
||||
final_sym_name, addend);
|
||||
break;
|
||||
case R_SPARC_LO10:
|
||||
fprintf(outfile,
|
||||
@ -2575,7 +2678,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
" | ((%s + %d) & 0x3ff);\n",
|
||||
rel->r_offset - start_offset,
|
||||
rel->r_offset - start_offset,
|
||||
name, addend);
|
||||
final_sym_name, addend);
|
||||
break;
|
||||
case R_SPARC_WDISP30:
|
||||
fprintf(outfile,
|
||||
@ -2586,7 +2689,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
" & 0x3fffffff);\n",
|
||||
rel->r_offset - start_offset,
|
||||
rel->r_offset - start_offset,
|
||||
name, addend,
|
||||
final_sym_name, addend,
|
||||
rel->r_offset - start_offset);
|
||||
break;
|
||||
default:
|
||||
@ -2597,11 +2700,11 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
}
|
||||
#elif defined(HOST_ARM)
|
||||
{
|
||||
char name[256];
|
||||
char final_sym_name[256];
|
||||
int type;
|
||||
int addend;
|
||||
|
||||
arm_emit_ldr_info(name, start_offset, outfile, p_start, p_end,
|
||||
arm_emit_ldr_info(final_sym_name, start_offset, outfile, p_start, p_end,
|
||||
relocs, nb_relocs);
|
||||
|
||||
for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
|
||||
@ -2611,21 +2714,17 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
/* the compiler leave some unnecessary references to the code */
|
||||
if (sym_name[0] == '\0')
|
||||
continue;
|
||||
if (strstart(sym_name, "__op_PARAM", &p)) {
|
||||
snprintf(name, sizeof(name), "param%s", p);
|
||||
} else {
|
||||
snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
|
||||
}
|
||||
get_reloc_expr(final_sym_name, sizeof(final_sym_name), sym_name);
|
||||
type = ELF32_R_TYPE(rel->r_info);
|
||||
addend = get32((uint32_t *)(text + rel->r_offset));
|
||||
switch(type) {
|
||||
case R_ARM_ABS32:
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = %s + %d;\n",
|
||||
rel->r_offset - start_offset, name, addend);
|
||||
rel->r_offset - start_offset, final_sym_name, addend);
|
||||
break;
|
||||
case R_ARM_PC24:
|
||||
fprintf(outfile, " arm_reloc_pc24((uint32_t *)(code_ptr() + %d), 0x%x, %s);\n",
|
||||
rel->r_offset - start_offset, addend, name);
|
||||
rel->r_offset - start_offset, addend, final_sym_name);
|
||||
break;
|
||||
default:
|
||||
error("unsupported arm relocation (%d)", type);
|
||||
@ -2635,7 +2734,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
}
|
||||
#elif defined(HOST_M68K)
|
||||
{
|
||||
char name[256];
|
||||
char final_sym_name[256];
|
||||
int type;
|
||||
int addend;
|
||||
Elf32_Sym *sym;
|
||||
@ -2644,23 +2743,19 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
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);
|
||||
}
|
||||
get_reloc_expr(final_sym_name, sizeof(final_sym_name), 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 *)(code_ptr() + %d) = %s + %#x;\n",
|
||||
rel->r_offset - start_offset, name, addend );
|
||||
rel->r_offset - start_offset, final_sym_name, addend );
|
||||
break;
|
||||
case R_68K_PC32:
|
||||
fprintf(outfile, " /* R_68K_PC32 RELOC, offset %x */\n", rel->r_offset);
|
||||
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = %s - (long)(code_ptr() + %#x) + %#x;\n",
|
||||
rel->r_offset - start_offset, name, rel->r_offset - start_offset, /*sym->st_value+*/ addend);
|
||||
rel->r_offset - start_offset, final_sym_name, rel->r_offset - start_offset, /*sym->st_value+*/ addend);
|
||||
break;
|
||||
default:
|
||||
error("unsupported m68k relocation (%d)", type);
|
||||
@ -2670,7 +2765,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
}
|
||||
#elif defined(HOST_MIPS)
|
||||
{
|
||||
char name[256];
|
||||
char final_sym_name[256];
|
||||
int type;
|
||||
int addend;
|
||||
for (i = 0, rel = relocs; i < nb_relocs; i++, rel++) {
|
||||
@ -2689,11 +2784,7 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strstart(sym_name, "__op_PARAM", &p)) {
|
||||
snprintf(name, sizeof(name), "param%s", p);
|
||||
} else {
|
||||
snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
|
||||
}
|
||||
get_reloc_expr(final_sym_name, sizeof(final_sym_name), sym_name);
|
||||
type = ELFW(R_TYPE)(rel->r_info);
|
||||
addend = rel->r_addend;
|
||||
if (addend)
|
||||
@ -2702,12 +2793,12 @@ void gen_code(const char *name, const char *demangled_name,
|
||||
case R_MIPS_HI16:
|
||||
fprintf(outfile, " /* R_MIPS_HI16 reloc, offset %x */\n", rel->r_offset);
|
||||
fprintf(outfile, " *(uint16_t *)(code_ptr() + %d) = (uint16_t)((uint32_t)(%s)>>16);\n",
|
||||
rel->r_offset - start_offset + 2, name);
|
||||
rel->r_offset - start_offset + 2, final_sym_name);
|
||||
break;
|
||||
case R_MIPS_LO16:
|
||||
fprintf(outfile, " /* R_MIPS_LO16 reloc, offset %x */\n", rel->r_offset);
|
||||
fprintf(outfile, " *(uint16_t *)(code_ptr() + %d) = (uint16_t)((uint32_t)(%s)&0xffff);\n",
|
||||
rel->r_offset - start_offset + 2, name);
|
||||
rel->r_offset - start_offset + 2, final_sym_name);
|
||||
break;
|
||||
default:
|
||||
error("unsupported MIPS relocation (%d)", type);
|
||||
@ -2747,6 +2838,9 @@ int gen_file(FILE *outfile, int out_type)
|
||||
const char *name;
|
||||
name = get_sym_name(sym);
|
||||
if (strstart(name, OP_PREFIX "execute", NULL)) {
|
||||
/* skip Exception handlers */
|
||||
if (strchr(name, '.'))
|
||||
continue;
|
||||
strcpy(func_name, name);
|
||||
#if defined(CONFIG_FORMAT_ELF) || defined(CONFIG_FORMAT_COFF)
|
||||
if (sym->st_shndx != text_shndx)
|
||||
@ -2762,7 +2856,7 @@ int gen_file(FILE *outfile, int out_type)
|
||||
#endif
|
||||
if (data == NULL)
|
||||
error("no .data section found");
|
||||
fprintf(outfile, "DEFINE_CST(%s,0x%xL)\n\n", name, *((host_ulong *)(data + sym->st_value)));
|
||||
fprintf(outfile, "DEFINE_CST(%s,0x%xL)\n\n", name, *((host_ulong *)(data + sym->st_value - data_sec_hdr->addr)));
|
||||
}
|
||||
else if (strstart(name, OP_PREFIX "invoke", NULL)) {
|
||||
const char *prefix = "helper_";
|
||||
|
Loading…
Reference in New Issue
Block a user