1213
1213
#endif /* CONFIG_FORMAT_MACH */
1215
void get_reloc_expr(char *name, int name_size, const char *sym_name)
1215
/* return true if the expression is a label reference */
1216
int get_reloc_expr(char *name, int name_size, const char *sym_name)
1219
1220
if (strstart(sym_name, "__op_param", &p)) {
1220
1221
snprintf(name, name_size, "param%s", p);
1221
1222
} else if (strstart(sym_name, "__op_gen_label", &p)) {
1222
snprintf(name, name_size, "gen_labels[param%s]", p);
1223
snprintf(name, name_size, "param%s", p);
1224
1226
#ifdef HOST_SPARC
1225
1227
if (sym_name[0] == '.')
1871
get_reloc_expr(relname, sizeof(relname), sym_name);
1874
is_label = get_reloc_expr(relname, sizeof(relname), sym_name);
1872
1875
addend = get32((uint32_t *)(text + rel->r_offset));
1873
1876
#ifdef CONFIG_FORMAT_ELF
1874
1877
type = ELF32_R_TYPE(rel->r_info);
1877
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
1878
reloc_offset, relname, addend);
1881
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
1882
reloc_offset, relname, reloc_offset, addend);
1885
error("unsupported i386 relocation (%d)", type);
1882
fprintf(outfile, " tcg_out_reloc(s, gen_code_ptr + %d, %d, %s, %d);\n",
1883
reloc_offset, type, relname, addend);
1886
error("unsupported i386 relocation (%d)", type);
1891
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
1892
reloc_offset, relname, addend);
1895
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
1896
reloc_offset, relname, reloc_offset, addend);
1899
error("unsupported i386 relocation (%d)", type);
1887
1902
#elif defined(CONFIG_FORMAT_COFF)
1901
1916
type = rel->r_type;
1904
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
1905
reloc_offset, relname, addend);
1908
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d -4;\n",
1909
reloc_offset, relname, reloc_offset, addend);
1912
error("unsupported i386 relocation (%d)", type);
1918
/* TCG uses elf relocation constants */
1920
#define R_386_PC32 2
1929
fprintf(outfile, " tcg_out_reloc(s, gen_code_ptr + %d, %d, %s, %d);\n",
1930
reloc_offset, type, relname, addend);
1933
error("unsupported i386 relocation (%d)", type);
1938
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
1939
reloc_offset, relname, addend);
1942
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d -4;\n",
1943
reloc_offset, relname, reloc_offset, addend);
1946
error("unsupported i386 relocation (%d)", type);
1915
1950
#error unsupport object format
1920
1955
#elif defined(HOST_X86_64)
1922
1957
char relname[256];
1925
1960
int reloc_offset;
1926
1961
for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
1927
1962
if (rel->r_offset >= start_offset &&
1928
1963
rel->r_offset < start_offset + copy_size) {
1929
1964
sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
1930
get_reloc_expr(relname, sizeof(relname), sym_name);
1965
is_label = get_reloc_expr(relname, sizeof(relname), sym_name);
1931
1966
type = ELF32_R_TYPE(rel->r_info);
1932
1967
addend = rel->r_addend;
1933
1968
reloc_offset = rel->r_offset - start_offset;
1936
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (uint32_t)%s + %d;\n",
1937
reloc_offset, relname, addend);
1940
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (int32_t)%s + %d;\n",
1941
reloc_offset, relname, addend);
1944
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
1945
reloc_offset, relname, reloc_offset, addend);
1948
error("unsupported X86_64 relocation (%d)", type);
1974
fprintf(outfile, " tcg_out_reloc(s, gen_code_ptr + %d, %d, %s, %d);\n",
1975
reloc_offset, type, relname, addend);
1978
error("unsupported X86_64 relocation (%d)", type);
1983
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (uint32_t)%s + %d;\n",
1984
reloc_offset, relname, addend);
1987
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (int32_t)%s + %d;\n",
1988
reloc_offset, relname, addend);
1991
fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
1992
reloc_offset, relname, reloc_offset, addend);
1995
error("unsupported X86_64 relocation (%d)", type);
2641
2689
if (out_type == OUT_INDEX_OP) {
2642
fprintf(outfile, "DEF(end, 0, 0)\n");
2643
fprintf(outfile, "DEF(nop, 0, 0)\n");
2644
fprintf(outfile, "DEF(nop1, 1, 0)\n");
2645
fprintf(outfile, "DEF(nop2, 2, 0)\n");
2646
fprintf(outfile, "DEF(nop3, 3, 0)\n");
2647
2690
for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
2648
2691
const char *name;
2649
2692
name = get_sym_name(sym);
2654
2697
} else if (out_type == OUT_GEN_OP) {
2655
2698
/* generate gen_xxx functions */
2656
fprintf(outfile, "#include \"dyngen-op.h\"\n");
2657
2699
for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
2658
2700
const char *name;
2659
2701
name = get_sym_name(sym);
2694
"int dyngen_code(uint8_t *gen_code_buf,\n"
2695
" uint16_t *label_offsets, uint16_t *jmp_offsets,\n"
2696
" const uint16_t *opc_buf, const uint32_t *opparam_buf, const long *gen_labels)\n"
2698
" uint8_t *gen_code_ptr;\n"
2699
" const uint16_t *opc_ptr;\n"
2700
" const uint32_t *opparam_ptr;\n");
2702
2736
#ifdef HOST_ARM
2703
2738
/* Arm is tricky because it uses constant pools for loading immediate values.
2704
2739
We assume (and require) each function is code followed by a constant pool.
2705
2740
All the ops are small so this should be ok. For each op we figure
2831
2853
gen_code(name, sym->st_value, sym->st_size, outfile, 1);
2836
" case INDEX_op_nop:\n"
2838
" case INDEX_op_nop1:\n"
2841
" case INDEX_op_nop2:\n"
2842
" opparam_ptr += 2;\n"
2844
" case INDEX_op_nop3:\n"
2845
" opparam_ptr += 3;\n"
2859
" extern char code_gen_buffer[];\n"
2860
" ia64_apply_fixes(&gen_code_ptr, ltoff_fixes, "
2861
"(uint64_t) code_gen_buffer + 2*(1<<20), plt_fixes,\n\t\t\t"
2862
"sizeof(plt_target)/sizeof(plt_target[0]),\n\t\t\t"
2863
"plt_target, plt_offset);\n }\n");
2866
/* generate some code patching */
2869
"if (arm_data_ptr != arm_data_table + ARM_LDR_TABLE_SIZE)\n"
2870
" gen_code_ptr = arm_flush_ldr(gen_code_ptr, arm_ldr_table, "
2871
"arm_ldr_ptr, arm_data_ptr, arm_data_table + ARM_LDR_TABLE_SIZE, 0);\n");
2873
/* flush instruction cache */
2874
fprintf(outfile, "flush_icache_range((unsigned long)gen_code_buf, (unsigned long)gen_code_ptr);\n");
2876
fprintf(outfile, "return gen_code_ptr - gen_code_buf;\n");
2877
fprintf(outfile, "}\n\n");