Commit 90426a4e2d1994026a3ca6fdc149f55730aa2b8a

Authored by bellard
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,10 +1910,11 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1910 char relname[256]; 1910 char relname[256];
1911 int type; 1911 int type;
1912 int addend; 1912 int addend;
  1913 + int is_label;
1913 int reloc_offset; 1914 int reloc_offset;
1914 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { 1915 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
1915 if (rel->r_offset >= start_offset && 1916 if (rel->r_offset >= start_offset &&
1916 - rel->r_offset < start_offset + copy_size) { 1917 + rel->r_offset < start_offset + copy_size) {
1917 sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name; 1918 sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
1918 reloc_offset = rel->r_offset - start_offset; 1919 reloc_offset = rel->r_offset - start_offset;
1919 if (strstart(sym_name, "__op_jmp", &p)) { 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,31 +1931,44 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1930 1931
1931 get_reloc_expr(relname, sizeof(relname), sym_name); 1932 get_reloc_expr(relname, sizeof(relname), sym_name);
1932 type = ELF32_R_TYPE(rel->r_info); 1933 type = ELF32_R_TYPE(rel->r_info);
  1934 + is_label = get_reloc_expr(relname, sizeof(relname), sym_name);
1933 addend = rel->r_addend; 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 }