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) { |