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 | 1185 | |
1186 | 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 | 1208 | #ifdef HOST_ARM |
1189 | 1209 | |
1190 | 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 | 1264 | if (rel->r_offset == (pc_offset + start_offset)) { |
1245 | 1265 | sym_name = get_rel_sym_name(rel); |
1246 | 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 | 1268 | type = ELF32_R_TYPE(rel->r_info); |
1253 | 1269 | if (type != R_ARM_ABS32) |
1254 | 1270 | error("%s: unsupported data relocation", name); |
... | ... | @@ -1641,13 +1657,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, |
1641 | 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 | 1661 | addend = get32((uint32_t *)(text + rel->r_offset)); |
1652 | 1662 | #ifdef CONFIG_FORMAT_ELF |
1653 | 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 | 1715 | if (rel->r_offset >= start_offset && |
1706 | 1716 | rel->r_offset < start_offset + copy_size) { |
1707 | 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 | 1719 | type = ELF32_R_TYPE(rel->r_info); |
1714 | 1720 | addend = rel->r_addend; |
1715 | 1721 | switch(type) { |
... | ... | @@ -1753,11 +1759,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, |
1753 | 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 | 1763 | type = ELF32_R_TYPE(rel->r_info); |
1762 | 1764 | addend = rel->r_addend; |
1763 | 1765 | switch(type) { |
... | ... | @@ -1842,12 +1844,8 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, |
1842 | 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 | 1849 | switch(type) { |
1852 | 1850 | case PPC_RELOC_BR24: |
1853 | 1851 | fprintf(outfile, "{\n"); |
... | ... | @@ -1885,11 +1883,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, |
1885 | 1883 | if (rel->r_offset >= start_offset && |
1886 | 1884 | rel->r_offset < start_offset + copy_size) { |
1887 | 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 | 1887 | type = ELF32_R_TYPE(rel->r_info); |
1894 | 1888 | addend = rel->r_addend; |
1895 | 1889 | switch(type) { |
... | ... | @@ -1973,11 +1967,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, |
1973 | 1967 | for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { |
1974 | 1968 | if (rel->r_offset >= start_offset && rel->r_offset < start_offset + copy_size) { |
1975 | 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 | 1971 | type = ELF64_R_TYPE(rel->r_info); |
1982 | 1972 | addend = rel->r_addend; |
1983 | 1973 | switch(type) { |
... | ... | @@ -2000,17 +1990,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, |
2000 | 1990 | if (rel->r_offset >= start_offset && |
2001 | 1991 | rel->r_offset < start_offset + copy_size) { |
2002 | 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 | 1994 | type = ELF32_R_TYPE(rel->r_info); |
2015 | 1995 | addend = rel->r_addend; |
2016 | 1996 | switch(type) { |
... | ... | @@ -2065,11 +2045,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, |
2065 | 2045 | if (rel->r_offset >= start_offset && |
2066 | 2046 | rel->r_offset < start_offset + copy_size) { |
2067 | 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 | 2049 | type = ELF64_R_TYPE(rel->r_info); |
2074 | 2050 | addend = rel->r_addend; |
2075 | 2051 | switch(type) { |
... | ... | @@ -2131,11 +2107,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, |
2131 | 2107 | /* the compiler leave some unnecessary references to the code */ |
2132 | 2108 | if (sym_name[0] == '\0') |
2133 | 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 | 2111 | type = ELF32_R_TYPE(rel->r_info); |
2140 | 2112 | addend = get32((uint32_t *)(text + rel->r_offset)); |
2141 | 2113 | switch(type) { |
... | ... | @@ -2164,11 +2136,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, |
2164 | 2136 | rel->r_offset < start_offset + copy_size) { |
2165 | 2137 | sym = &(symtab[ELFW(R_SYM)(rel->r_info)]); |
2166 | 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 | 2140 | type = ELF32_R_TYPE(rel->r_info); |
2173 | 2141 | addend = get32((uint32_t *)(text + rel->r_offset)) + rel->r_addend; |
2174 | 2142 | switch(type) { | ... | ... |