#define elf_check_arch(x) ((x) == EM_PPC)
#define ELF_USES_RELOCA
+#elif defined(HOST_PPC64)
+
+#define ELF_CLASS ELFCLASS64
+#define ELF_ARCH EM_PPC64
+#define elf_check_arch(x) ((x) == EM_PPC64)
+#define ELF_USES_RELOCA
+
#elif defined(HOST_S390)
#define ELF_CLASS ELFCLASS32
return data;
}
-int strstart(const char *str, const char *val, const char **ptr)
+static int strstart(const char *str, const char *val, const char **ptr)
{
const char *p, *q;
p = str;
return 1;
}
-void pstrcpy(char *buf, int buf_size, const char *str)
+static void pstrcpy(char *buf, int buf_size, const char *str)
{
int c;
char *q = buf;
*q = '\0';
}
-void swab16s(uint16_t *p)
+static void swab16s(uint16_t *p)
{
*p = bswap16(*p);
}
-void swab32s(uint32_t *p)
+static void swab32s(uint32_t *p)
{
*p = bswap32(*p);
}
-void swab32ss(int32_t *p)
+static void swab32ss(int32_t *p)
{
*p = bswap32(*p);
}
-void swab64s(uint64_t *p)
+static void swab64s(uint64_t *p)
{
*p = bswap64(*p);
}
-void swab64ss(int64_t *p)
+static void swab64ss(int64_t *p)
{
*p = bswap64(*p);
}
-uint16_t get16(uint16_t *p)
+static uint16_t get16(uint16_t *p)
{
uint16_t val;
val = *p;
return val;
}
-uint32_t get32(uint32_t *p)
+static uint32_t get32(uint32_t *p)
{
uint32_t val;
val = *p;
return val;
}
-void put16(uint16_t *p, uint16_t val)
+static void put16(uint16_t *p, uint16_t val)
{
if (do_swap)
val = bswap16(val);
*p = val;
}
-void put32(uint32_t *p, uint32_t val)
+static void put32(uint32_t *p, uint32_t val)
{
if (do_swap)
val = bswap32(val);
struct elfhdr ehdr;
char *strtab;
-int elf_must_swap(struct elfhdr *h)
+static int elf_must_swap(struct elfhdr *h)
{
union {
uint32_t i;
(swaptest.b[0] == 0);
}
-void elf_swap_ehdr(struct elfhdr *h)
+static void elf_swap_ehdr(struct elfhdr *h)
{
swab16s(&h->e_type); /* Object file type */
swab16s(&h-> e_machine); /* Architecture */
swab16s(&h-> e_shstrndx); /* Section header string table index */
}
-void elf_swap_shdr(struct elf_shdr *h)
+static void elf_swap_shdr(struct elf_shdr *h)
{
swab32s(&h-> sh_name); /* Section name (string tbl index) */
swab32s(&h-> sh_type); /* Section type */
swabls(&h-> sh_entsize); /* Entry size if section holds table */
}
-void elf_swap_phdr(struct elf_phdr *h)
+static void elf_swap_phdr(struct elf_phdr *h)
{
swab32s(&h->p_type); /* Segment type */
swabls(&h->p_offset); /* Segment file offset */
swabls(&h->p_align); /* Segment alignment */
}
-void elf_swap_rel(ELF_RELOC *rel)
+static void elf_swap_rel(ELF_RELOC *rel)
{
swabls(&rel->r_offset);
swabls(&rel->r_info);
#endif
}
-struct elf_shdr *find_elf_section(struct elf_shdr *shdr, int shnum, const char *shstr,
- const char *name)
+static struct elf_shdr *find_elf_section(struct elf_shdr *shdr, int shnum,
+ const char *shstr, const char *name)
{
int i;
const char *shname;
return NULL;
}
-int find_reloc(int sh_index)
+static int find_reloc(int sh_index)
{
struct elf_shdr *sec;
int i;
}
/* load an elf object file */
-int load_object(const char *filename)
+static int load_object(const char *filename)
{
int fd;
struct elf_shdr *sec, *symtab_sec, *strtab_sec, *text_sec;
#endif /* CONFIG_FORMAT_MACH */
/* return true if the expression is a label reference */
-int get_reloc_expr(char *name, int name_size, const char *sym_name)
+static int get_reloc_expr(char *name, int name_size, const char *sym_name)
{
const char *p;
#define MAX_ARGS 3
/* generate op code */
-void gen_code(const char *name, host_ulong offset, host_ulong size,
- FILE *outfile, int gen_switch)
+static void gen_code(const char *name, host_ulong offset, host_ulong size,
+ FILE *outfile, int gen_switch)
{
int copy_size = 0;
uint8_t *p_start, *p_end;
}
#elif defined(HOST_ARM)
error("dyngen targets not supported on ARM");
+#elif defined(HOST_PPC64)
+ error("dyngen targets not supported on PPC64");
#else
#error unsupported CPU
#endif
char relname[256];
int type;
int addend;
+ int is_label;
int reloc_offset;
for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
if (rel->r_offset >= start_offset &&
- rel->r_offset < start_offset + copy_size) {
+ rel->r_offset < start_offset + copy_size) {
sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
reloc_offset = rel->r_offset - start_offset;
if (strstart(sym_name, "__op_jmp", &p)) {
get_reloc_expr(relname, sizeof(relname), sym_name);
type = ELF32_R_TYPE(rel->r_info);
+ is_label = get_reloc_expr(relname, sizeof(relname), sym_name);
addend = rel->r_addend;
- switch(type) {
- case R_PPC_ADDR32:
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
- reloc_offset, relname, addend);
- break;
- case R_PPC_ADDR16_LO:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d);\n",
- reloc_offset, relname, addend);
- break;
- case R_PPC_ADDR16_HI:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d) >> 16;\n",
- reloc_offset, relname, addend);
- break;
- case R_PPC_ADDR16_HA:
- fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d + 0x8000) >> 16;\n",
- reloc_offset, relname, addend);
- break;
- case R_PPC_REL24:
- /* warning: must be at 32 MB distancy */
- fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n",
- reloc_offset, reloc_offset, relname, reloc_offset, addend);
- break;
- default:
- error("unsupported powerpc relocation (%d)", type);
+ if (is_label) {
+ switch (type) {
+ case R_PPC_REL24:
+ fprintf (outfile, " tcg_out_reloc(s, gen_code_ptr + %d, %d, %s, %d);\n",
+ reloc_offset, type, relname, addend);
+ break;
+ default:
+ error ("unsupported ppc relocation (%d)", type);
+ }
+ }
+ else {
+ switch(type) {
+ case R_PPC_ADDR32:
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
+ reloc_offset, relname, addend);
+ break;
+ case R_PPC_ADDR16_LO:
+ fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d);\n",
+ reloc_offset, relname, addend);
+ break;
+ case R_PPC_ADDR16_HI:
+ fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d) >> 16;\n",
+ reloc_offset, relname, addend);
+ break;
+ case R_PPC_ADDR16_HA:
+ fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d + 0x8000) >> 16;\n",
+ reloc_offset, relname, addend);
+ break;
+ case R_PPC_REL24:
+ /* warning: must be at 32 MB distancy */
+ fprintf(outfile, "{\n"
+ " long disp = (%s - (long)(gen_code_ptr + %d) + %d);\n"
+ " if ((disp << 6) >> 6 != disp) {;\n"
+ " fprintf(stderr, \"Branch target is too far away\\n\");"
+ " abort();\n"
+ " }\n"
+ "}\n",
+ relname, reloc_offset, addend);
+ fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n",
+ reloc_offset, reloc_offset, relname, reloc_offset, addend);
+ break;
+ default:
+ error("unsupported powerpc relocation (%d)", type);
+ }
}
}
}
}
#elif defined(HOST_ARM)
error("dyngen targets not supported on ARM");
+#elif defined(HOST_PPC64)
+ error("dyngen targets not supported on PPC64");
#else
#error unsupported CPU
#endif
}
}
-int gen_file(FILE *outfile, int out_type)
+static int gen_file(FILE *outfile, int out_type)
{
int i;
EXE_SYM *sym;
return 0;
}
-void usage(void)
+static void usage(void)
{
printf("dyngen (c) 2003 Fabrice Bellard\n"
"usage: dyngen [-o outfile] [-c] objfile\n"