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