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 | } | ... | ... |