Commit 90426a4e2d1994026a3ca6fdc149f55730aa2b8a
1 parent
2662e13f
ppc dyngen fix (malc)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4585 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
39 additions
and
25 deletions
dyngen.c
| ... | ... | @@ -1910,10 +1910,11 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, |
| 1910 | 1910 | char relname[256]; |
| 1911 | 1911 | int type; |
| 1912 | 1912 | int addend; |
| 1913 | + int is_label; | |
| 1913 | 1914 | int reloc_offset; |
| 1914 | 1915 | for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { |
| 1915 | 1916 | if (rel->r_offset >= start_offset && |
| 1916 | - rel->r_offset < start_offset + copy_size) { | |
| 1917 | + rel->r_offset < start_offset + copy_size) { | |
| 1917 | 1918 | sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name; |
| 1918 | 1919 | reloc_offset = rel->r_offset - start_offset; |
| 1919 | 1920 | if (strstart(sym_name, "__op_jmp", &p)) { |
| ... | ... | @@ -1930,31 +1931,44 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, |
| 1930 | 1931 | |
| 1931 | 1932 | get_reloc_expr(relname, sizeof(relname), sym_name); |
| 1932 | 1933 | type = ELF32_R_TYPE(rel->r_info); |
| 1934 | + is_label = get_reloc_expr(relname, sizeof(relname), sym_name); | |
| 1933 | 1935 | addend = rel->r_addend; |
| 1934 | - switch(type) { | |
| 1935 | - case R_PPC_ADDR32: | |
| 1936 | - fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n", | |
| 1937 | - reloc_offset, relname, addend); | |
| 1938 | - break; | |
| 1939 | - case R_PPC_ADDR16_LO: | |
| 1940 | - fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d);\n", | |
| 1941 | - reloc_offset, relname, addend); | |
| 1942 | - break; | |
| 1943 | - case R_PPC_ADDR16_HI: | |
| 1944 | - fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d) >> 16;\n", | |
| 1945 | - reloc_offset, relname, addend); | |
| 1946 | - break; | |
| 1947 | - case R_PPC_ADDR16_HA: | |
| 1948 | - fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d + 0x8000) >> 16;\n", | |
| 1949 | - reloc_offset, relname, addend); | |
| 1950 | - break; | |
| 1951 | - case R_PPC_REL24: | |
| 1952 | - /* warning: must be at 32 MB distancy */ | |
| 1953 | - fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n", | |
| 1954 | - reloc_offset, reloc_offset, relname, reloc_offset, addend); | |
| 1955 | - break; | |
| 1956 | - default: | |
| 1957 | - error("unsupported powerpc relocation (%d)", type); | |
| 1936 | + if (is_label) { | |
| 1937 | + switch (type) { | |
| 1938 | + case R_PPC_REL24: | |
| 1939 | + fprintf (outfile, " tcg_out_reloc(s, gen_code_ptr + %d, %d, %s, %d);\n", | |
| 1940 | + reloc_offset, type, relname, addend); | |
| 1941 | + break; | |
| 1942 | + default: | |
| 1943 | + error ("unsupported ppc relocation (%d)", type); | |
| 1944 | + } | |
| 1945 | + } | |
| 1946 | + else { | |
| 1947 | + switch(type) { | |
| 1948 | + case R_PPC_ADDR32: | |
| 1949 | + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n", | |
| 1950 | + reloc_offset, relname, addend); | |
| 1951 | + break; | |
| 1952 | + case R_PPC_ADDR16_LO: | |
| 1953 | + fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d);\n", | |
| 1954 | + reloc_offset, relname, addend); | |
| 1955 | + break; | |
| 1956 | + case R_PPC_ADDR16_HI: | |
| 1957 | + fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d) >> 16;\n", | |
| 1958 | + reloc_offset, relname, addend); | |
| 1959 | + break; | |
| 1960 | + case R_PPC_ADDR16_HA: | |
| 1961 | + fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d + 0x8000) >> 16;\n", | |
| 1962 | + reloc_offset, relname, addend); | |
| 1963 | + break; | |
| 1964 | + case R_PPC_REL24: | |
| 1965 | + /* warning: must be at 32 MB distancy */ | |
| 1966 | + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n", | |
| 1967 | + reloc_offset, reloc_offset, relname, reloc_offset, addend); | |
| 1968 | + break; | |
| 1969 | + default: | |
| 1970 | + error("unsupported powerpc relocation (%d)", type); | |
| 1971 | + } | |
| 1958 | 1972 | } |
| 1959 | 1973 | } |
| 1960 | 1974 | } | ... | ... |