Commit bef79c34a293f8f8c27a928ad5b770dd053a4434
1 parent
83b34f8b
support for dyngen labels on more hosts
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1231 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
32 additions
and
64 deletions
dyngen.c
| @@ -1185,6 +1185,26 @@ int load_object(const char *filename) | @@ -1185,6 +1185,26 @@ int load_object(const char *filename) | ||
| 1185 | 1185 | ||
| 1186 | #endif /* CONFIG_FORMAT_MACH */ | 1186 | #endif /* CONFIG_FORMAT_MACH */ |
| 1187 | 1187 | ||
| 1188 | +void get_reloc_expr(char *name, int name_size, const char *sym_name) | ||
| 1189 | +{ | ||
| 1190 | + const char *p; | ||
| 1191 | + | ||
| 1192 | + if (strstart(sym_name, "__op_param", &p)) { | ||
| 1193 | + snprintf(name, name_size, "param%s", p); | ||
| 1194 | + } else if (strstart(sym_name, "__op_gen_label", &p)) { | ||
| 1195 | + snprintf(name, name_size, "gen_labels[param%s]", p); | ||
| 1196 | + } else { | ||
| 1197 | +#ifdef HOST_SPARC | ||
| 1198 | + if (sym_name[0] == '.') | ||
| 1199 | + snprintf(name, sizeof(name), | ||
| 1200 | + "(long)(&__dot_%s)", | ||
| 1201 | + sym_name + 1); | ||
| 1202 | + else | ||
| 1203 | +#endif | ||
| 1204 | + snprintf(name, name_size, "(long)(&%s)", sym_name); | ||
| 1205 | + } | ||
| 1206 | +} | ||
| 1207 | + | ||
| 1188 | #ifdef HOST_ARM | 1208 | #ifdef HOST_ARM |
| 1189 | 1209 | ||
| 1190 | int arm_emit_ldr_info(const char *name, unsigned long start_offset, | 1210 | int arm_emit_ldr_info(const char *name, unsigned long start_offset, |
| @@ -1244,11 +1264,7 @@ int arm_emit_ldr_info(const char *name, unsigned long start_offset, | @@ -1244,11 +1264,7 @@ int arm_emit_ldr_info(const char *name, unsigned long start_offset, | ||
| 1244 | if (rel->r_offset == (pc_offset + start_offset)) { | 1264 | if (rel->r_offset == (pc_offset + start_offset)) { |
| 1245 | sym_name = get_rel_sym_name(rel); | 1265 | sym_name = get_rel_sym_name(rel); |
| 1246 | /* the compiler leave some unnecessary references to the code */ | 1266 | /* the compiler leave some unnecessary references to the code */ |
| 1247 | - if (strstart(sym_name, "__op_param", &p)) { | ||
| 1248 | - snprintf(relname, sizeof(relname), "param%s", p); | ||
| 1249 | - } else { | ||
| 1250 | - snprintf(relname, sizeof(relname), "(long)(&%s)", sym_name); | ||
| 1251 | - } | 1267 | + get_reloc_expr(relname, sizeof(relname), sym_name); |
| 1252 | type = ELF32_R_TYPE(rel->r_info); | 1268 | type = ELF32_R_TYPE(rel->r_info); |
| 1253 | if (type != R_ARM_ABS32) | 1269 | if (type != R_ARM_ABS32) |
| 1254 | error("%s: unsupported data relocation", name); | 1270 | error("%s: unsupported data relocation", name); |
| @@ -1641,13 +1657,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | @@ -1641,13 +1657,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | ||
| 1641 | continue; | 1657 | continue; |
| 1642 | } | 1658 | } |
| 1643 | 1659 | ||
| 1644 | - if (strstart(sym_name, "__op_param", &p)) { | ||
| 1645 | - snprintf(name, sizeof(name), "param%s", p); | ||
| 1646 | - } else if (strstart(sym_name, "__op_gen_label", &p)) { | ||
| 1647 | - snprintf(name, sizeof(name), "gen_labels[param%s]", p); | ||
| 1648 | - } else { | ||
| 1649 | - snprintf(name, sizeof(name), "(long)(&%s)", sym_name); | ||
| 1650 | - } | 1660 | + get_reloc_expr(name, sizeof(name), sym_name); |
| 1651 | addend = get32((uint32_t *)(text + rel->r_offset)); | 1661 | addend = get32((uint32_t *)(text + rel->r_offset)); |
| 1652 | #ifdef CONFIG_FORMAT_ELF | 1662 | #ifdef CONFIG_FORMAT_ELF |
| 1653 | type = ELF32_R_TYPE(rel->r_info); | 1663 | type = ELF32_R_TYPE(rel->r_info); |
| @@ -1705,11 +1715,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | @@ -1705,11 +1715,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | ||
| 1705 | if (rel->r_offset >= start_offset && | 1715 | if (rel->r_offset >= start_offset && |
| 1706 | rel->r_offset < start_offset + copy_size) { | 1716 | rel->r_offset < start_offset + copy_size) { |
| 1707 | sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name; | 1717 | sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name; |
| 1708 | - if (strstart(sym_name, "__op_param", &p)) { | ||
| 1709 | - snprintf(name, sizeof(name), "param%s", p); | ||
| 1710 | - } else { | ||
| 1711 | - snprintf(name, sizeof(name), "(long)(&%s)", sym_name); | ||
| 1712 | - } | 1718 | + get_reloc_expr(name, sizeof(name), sym_name); |
| 1713 | type = ELF32_R_TYPE(rel->r_info); | 1719 | type = ELF32_R_TYPE(rel->r_info); |
| 1714 | addend = rel->r_addend; | 1720 | addend = rel->r_addend; |
| 1715 | switch(type) { | 1721 | switch(type) { |
| @@ -1753,11 +1759,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | @@ -1753,11 +1759,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | ||
| 1753 | continue; | 1759 | continue; |
| 1754 | } | 1760 | } |
| 1755 | 1761 | ||
| 1756 | - if (strstart(sym_name, "__op_param", &p)) { | ||
| 1757 | - snprintf(name, sizeof(name), "param%s", p); | ||
| 1758 | - } else { | ||
| 1759 | - snprintf(name, sizeof(name), "(long)(&%s)", sym_name); | ||
| 1760 | - } | 1762 | + get_reloc_expr(name, sizeof(name), sym_name); |
| 1761 | type = ELF32_R_TYPE(rel->r_info); | 1763 | type = ELF32_R_TYPE(rel->r_info); |
| 1762 | addend = rel->r_addend; | 1764 | addend = rel->r_addend; |
| 1763 | switch(type) { | 1765 | switch(type) { |
| @@ -1842,12 +1844,8 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | @@ -1842,12 +1844,8 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | ||
| 1842 | continue; /* dunno how to handle without final_sym_name */ | 1844 | continue; /* dunno how to handle without final_sym_name */ |
| 1843 | } | 1845 | } |
| 1844 | 1846 | ||
| 1845 | - if (strstart(sym_name, "__op_param", &p)) { | ||
| 1846 | - snprintf(final_sym_name, sizeof(final_sym_name), "param%s", p); | ||
| 1847 | - } else { | ||
| 1848 | - snprintf(final_sym_name, sizeof(final_sym_name), "(long)(&%s)", sym_name); | ||
| 1849 | - } | ||
| 1850 | - | 1847 | + get_reloc_expr(final_sym_name, sizeof(final_sym_name), |
| 1848 | + sym_name); | ||
| 1851 | switch(type) { | 1849 | switch(type) { |
| 1852 | case PPC_RELOC_BR24: | 1850 | case PPC_RELOC_BR24: |
| 1853 | fprintf(outfile, "{\n"); | 1851 | fprintf(outfile, "{\n"); |
| @@ -1885,11 +1883,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | @@ -1885,11 +1883,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | ||
| 1885 | if (rel->r_offset >= start_offset && | 1883 | if (rel->r_offset >= start_offset && |
| 1886 | rel->r_offset < start_offset + copy_size) { | 1884 | rel->r_offset < start_offset + copy_size) { |
| 1887 | sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name; | 1885 | sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name; |
| 1888 | - if (strstart(sym_name, "__op_param", &p)) { | ||
| 1889 | - snprintf(name, sizeof(name), "param%s", p); | ||
| 1890 | - } else { | ||
| 1891 | - snprintf(name, sizeof(name), "(long)(&%s)", sym_name); | ||
| 1892 | - } | 1886 | + get_reloc_expr(name, sizeof(name), sym_name); |
| 1893 | type = ELF32_R_TYPE(rel->r_info); | 1887 | type = ELF32_R_TYPE(rel->r_info); |
| 1894 | addend = rel->r_addend; | 1888 | addend = rel->r_addend; |
| 1895 | switch(type) { | 1889 | switch(type) { |
| @@ -1973,11 +1967,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | @@ -1973,11 +1967,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | ||
| 1973 | for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { | 1967 | for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { |
| 1974 | if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) { | 1968 | if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) { |
| 1975 | sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name; | 1969 | sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name; |
| 1976 | - if (strstart(sym_name, "__op_param", &p)) { | ||
| 1977 | - snprintf(name, sizeof(name), "param%s", p); | ||
| 1978 | - } else { | ||
| 1979 | - snprintf(name, sizeof(name), "(long)(&%s)", sym_name); | ||
| 1980 | - } | 1970 | + get_reloc_expr(name, sizeof(name), sym_name); |
| 1981 | type = ELF64_R_TYPE(rel->r_info); | 1971 | type = ELF64_R_TYPE(rel->r_info); |
| 1982 | addend = rel->r_addend; | 1972 | addend = rel->r_addend; |
| 1983 | switch(type) { | 1973 | switch(type) { |
| @@ -2000,17 +1990,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | @@ -2000,17 +1990,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | ||
| 2000 | if (rel->r_offset >= start_offset && | 1990 | if (rel->r_offset >= start_offset && |
| 2001 | rel->r_offset < start_offset + copy_size) { | 1991 | rel->r_offset < start_offset + copy_size) { |
| 2002 | sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name; | 1992 | sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name; |
| 2003 | - if (strstart(sym_name, "__op_param", &p)) { | ||
| 2004 | - snprintf(name, sizeof(name), "param%s", p); | ||
| 2005 | - } else { | ||
| 2006 | - if (sym_name[0] == '.') | ||
| 2007 | - snprintf(name, sizeof(name), | ||
| 2008 | - "(long)(&__dot_%s)", | ||
| 2009 | - sym_name + 1); | ||
| 2010 | - else | ||
| 2011 | - snprintf(name, sizeof(name), | ||
| 2012 | - "(long)(&%s)", sym_name); | ||
| 2013 | - } | 1993 | + get_reloc_expr(name, sizeof(name), sym_name); |
| 2014 | type = ELF32_R_TYPE(rel->r_info); | 1994 | type = ELF32_R_TYPE(rel->r_info); |
| 2015 | addend = rel->r_addend; | 1995 | addend = rel->r_addend; |
| 2016 | switch(type) { | 1996 | switch(type) { |
| @@ -2065,11 +2045,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | @@ -2065,11 +2045,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | ||
| 2065 | if (rel->r_offset >= start_offset && | 2045 | if (rel->r_offset >= start_offset && |
| 2066 | rel->r_offset < start_offset + copy_size) { | 2046 | rel->r_offset < start_offset + copy_size) { |
| 2067 | sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name; | 2047 | sym_name = strtab + symtab[ELF64_R_SYM(rel->r_info)].st_name; |
| 2068 | - if (strstart(sym_name, "__op_param", &p)) { | ||
| 2069 | - snprintf(name, sizeof(name), "param%s", p); | ||
| 2070 | - } else { | ||
| 2071 | - snprintf(name, sizeof(name), "(long)(&%s)", sym_name); | ||
| 2072 | - } | 2048 | + get_reloc_expr(name, sizeof(name), sym_name); |
| 2073 | type = ELF64_R_TYPE(rel->r_info); | 2049 | type = ELF64_R_TYPE(rel->r_info); |
| 2074 | addend = rel->r_addend; | 2050 | addend = rel->r_addend; |
| 2075 | switch(type) { | 2051 | switch(type) { |
| @@ -2131,11 +2107,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | @@ -2131,11 +2107,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | ||
| 2131 | /* the compiler leave some unnecessary references to the code */ | 2107 | /* the compiler leave some unnecessary references to the code */ |
| 2132 | if (sym_name[0] == '\0') | 2108 | if (sym_name[0] == '\0') |
| 2133 | continue; | 2109 | continue; |
| 2134 | - if (strstart(sym_name, "__op_param", &p)) { | ||
| 2135 | - snprintf(name, sizeof(name), "param%s", p); | ||
| 2136 | - } else { | ||
| 2137 | - snprintf(name, sizeof(name), "(long)(&%s)", sym_name); | ||
| 2138 | - } | 2110 | + get_reloc_expr(name, sizeof(name), sym_name); |
| 2139 | type = ELF32_R_TYPE(rel->r_info); | 2111 | type = ELF32_R_TYPE(rel->r_info); |
| 2140 | addend = get32((uint32_t *)(text + rel->r_offset)); | 2112 | addend = get32((uint32_t *)(text + rel->r_offset)); |
| 2141 | switch(type) { | 2113 | switch(type) { |
| @@ -2164,11 +2136,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | @@ -2164,11 +2136,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, | ||
| 2164 | rel->r_offset < start_offset + copy_size) { | 2136 | rel->r_offset < start_offset + copy_size) { |
| 2165 | sym = &(symtab[ELFW(R_SYM)(rel->r_info)]); | 2137 | sym = &(symtab[ELFW(R_SYM)(rel->r_info)]); |
| 2166 | sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name; | 2138 | sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name; |
| 2167 | - if (strstart(sym_name, "__op_param", &p)) { | ||
| 2168 | - snprintf(name, sizeof(name), "param%s", p); | ||
| 2169 | - } else { | ||
| 2170 | - snprintf(name, sizeof(name), "(long)(&%s)", sym_name); | ||
| 2171 | - } | 2139 | + get_reloc_expr(name, sizeof(name), sym_name); |
| 2172 | type = ELF32_R_TYPE(rel->r_info); | 2140 | type = ELF32_R_TYPE(rel->r_info); |
| 2173 | addend = get32((uint32_t *)(text + rel->r_offset)) + rel->r_addend; | 2141 | addend = get32((uint32_t *)(text + rel->r_offset)) + rel->r_addend; |
| 2174 | switch(type) { | 2142 | switch(type) { |