table entries. */
}
-/* Make generic code ignore STT_REGISTER dummy undefined symbols. */
+/* Make generic code ignore STT_REGISTER dummy undefined symbols,
+ * and replace references to .func with func as in ppc64's dedotify.
+ */
int module_frob_arch_sections(Elf_Ehdr *hdr,
Elf_Shdr *sechdrs,
char *secstrings,
{
unsigned int symidx;
Elf32_Sym *sym;
- const char *strtab;
+ char *strtab;
int i;
for (symidx = 0; sechdrs[symidx].sh_type != SHT_SYMTAB; symidx++) {
strtab = (char *)sechdrs[sechdrs[symidx].sh_link].sh_addr;
for (i = 1; i < sechdrs[symidx].sh_size / sizeof(Elf_Sym); i++) {
- if (sym[i].st_shndx == SHN_UNDEF &&
- ELF32_ST_TYPE(sym[i].st_info) == STT_REGISTER)
- sym[i].st_shndx = SHN_ABS;
+ if (sym[i].st_shndx == SHN_UNDEF) {
+ if (ELF32_ST_TYPE(sym[i].st_info) == STT_REGISTER)
+ sym[i].st_shndx = SHN_ABS;
+ else {
+ char *name = strtab + sym[i].st_name;
+ if (name[0] == '.')
+ memmove(name, name+1, strlen(name));
+ }
+ }
}
return 0;
}
extern void ___clear_bit(void);
extern void ___change_bit(void);
-/* One thing to note is that the way the symbols of the mul/div
- * support routines are named is a mess, they all start with
- * a '.' which makes it a bitch to export, here is the trick:
+/* Alias functions whose names begin with "." and export the aliases.
+ * The module references will be fixed up by module_frob_arch_sections.
*/
+#define DOT_ALIAS2(__ret, __x, __arg1, __arg2) \
+ extern __ret __x(__arg1, __arg2) \
+ __attribute__((weak, alias("." # __x)));
-/* If the interface of any of these special functions does ever
- * change in an incompatible way, you must modify this.
- */
-#define DOT_PROTO(sym) extern int __dot_##sym(int, int)
-
-#ifdef __GENKSYMS__
-#define EXPORT_SYMBOL_DOT(sym) \
- DOT_PROTO(sym); \
- EXPORT_SYMBOL(__dot_ ## sym)
-#else /* !__GENKSYMS__ */
-#define EXPORT_SYMBOL_DOT(sym) \
- DOT_PROTO(sym) __asm__("." # sym); \
- __CRC_SYMBOL(__dot_##sym, "") \
- static const char __kstrtab___dot_##sym[] \
- __attribute__((section("__ksymtab_strings"))) \
- = "." #sym; \
- static const struct kernel_symbol __ksymtab___dot_##sym \
- __attribute__((section("__ksymtab"))) \
- = { (unsigned long)&__dot_##sym, __kstrtab___dot_##sym }
-#endif
+DOT_ALIAS2(int, div, int, int)
+DOT_ALIAS2(int, mul, int, int)
+DOT_ALIAS2(int, rem, int, int)
+DOT_ALIAS2(unsigned, udiv, unsigned, unsigned)
+DOT_ALIAS2(unsigned, umul, unsigned, unsigned)
+DOT_ALIAS2(unsigned, urem, unsigned, unsigned)
+
+#undef DOT_ALIAS2
/* used by various drivers */
EXPORT_SYMBOL(sparc_cpu_model);
EXPORT_SYMBOL_NOVERS(__muldi3);
EXPORT_SYMBOL_NOVERS(__divdi3);
-EXPORT_SYMBOL_DOT(rem);
-EXPORT_SYMBOL_DOT(urem);
-EXPORT_SYMBOL_DOT(mul);
-EXPORT_SYMBOL_DOT(umul);
-EXPORT_SYMBOL_DOT(div);
-EXPORT_SYMBOL_DOT(udiv);
+EXPORT_SYMBOL(rem);
+EXPORT_SYMBOL(urem);
+EXPORT_SYMBOL(mul);
+EXPORT_SYMBOL(umul);
+EXPORT_SYMBOL(div);
+EXPORT_SYMBOL(udiv);
#ifdef CONFIG_DEBUG_BUGVERBOSE
EXPORT_SYMBOL(do_BUG);
symbolhash[hash] = new;
}
-#define DOTSYM_PFX "__dot_"
-
struct symbol *
find_symbol(const char *name)
{
struct symbol *s;
- char dotname[64 + sizeof(DOTSYM_PFX)];
- /* .foo matches foo. PPC64 needs this. */
- if (name[0] == '.') {
+ /* For our purposes, .foo matches foo. PPC64 needs this. */
+ if (name[0] == '.')
name++;
- strcpy(dotname, DOTSYM_PFX);
- strncat(dotname, name, sizeof(dotname) - sizeof(DOTSYM_PFX) - 1);
- dotname[sizeof(dotname)-1] = 0;
- /* Sparc32 wants .foo to match __dot_foo, try this first. */
- for (s = symbolhash[tdb_hash(dotname) % SYMBOL_HASH_SIZE]; s; s=s->next) {
- if (strcmp(s->name, dotname) == 0)
- return s;
- }
- }
for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s=s->next) {
if (strcmp(s->name, name) == 0)