From 7caaeabb17758295edff9703c18a840073c5b8f4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 11 Sep 2005 20:14:07 -0700 Subject: [PATCH] [SPARC]: Fix dot-symbol exporting for good. From: Al Viro Instead of playing all of these hand-coded assembler aliasing games, just translate symbol names in the name space ".sym" to "_Sym" at module load time. Signed-off-by: David S. Miller --- arch/sparc/kernel/module.c | 9 ++++++--- arch/sparc/kernel/sparc_ksyms.c | 31 ++++++++++++------------------- arch/sparc/lib/mul.S | 2 ++ arch/sparc/lib/rem.S | 2 ++ arch/sparc/lib/sdiv.S | 2 ++ arch/sparc/lib/udiv.S | 2 ++ arch/sparc/lib/umul.S | 2 ++ arch/sparc/lib/urem.S | 2 ++ scripts/mod/modpost.c | 6 ++++++ 9 files changed, 36 insertions(+), 22 deletions(-) diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c index 7931d6f92819..787d5f1347ec 100644 --- a/arch/sparc/kernel/module.c +++ b/arch/sparc/kernel/module.c @@ -10,6 +10,7 @@ #include #include #include +#include void *module_alloc(unsigned long size) { @@ -37,7 +38,7 @@ void module_free(struct module *mod, void *module_region) } /* Make generic code ignore STT_REGISTER dummy undefined symbols, - * and replace references to .func with func as in ppc64's dedotify. + * and replace references to .func with _Func */ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, @@ -64,8 +65,10 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, sym[i].st_shndx = SHN_ABS; else { char *name = strtab + sym[i].st_name; - if (name[0] == '.') - memmove(name, name+1, strlen(name)); + if (name[0] == '.') { + name[0] = '_'; + name[1] = toupper(name[1]); + } } } } diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index f84809333624..1c8fd0fd9305 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c @@ -97,19 +97,12 @@ extern void ___rw_write_enter(void); /* 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); \ - asm(".weak " #__x);\ - asm(#__x "=." #__x); - -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 +extern int _Div(int, int); +extern int _Mul(int, int); +extern int _Rem(int, int); +extern unsigned _Udiv(unsigned, unsigned); +extern unsigned _Umul(unsigned, unsigned); +extern unsigned _Urem(unsigned, unsigned); /* used by various drivers */ EXPORT_SYMBOL(sparc_cpu_model); @@ -320,12 +313,12 @@ EXPORT_SYMBOL(__lshrdi3); EXPORT_SYMBOL(__muldi3); EXPORT_SYMBOL(__divdi3); -EXPORT_SYMBOL(rem); -EXPORT_SYMBOL(urem); -EXPORT_SYMBOL(mul); -EXPORT_SYMBOL(umul); -EXPORT_SYMBOL(div); -EXPORT_SYMBOL(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); diff --git a/arch/sparc/lib/mul.S b/arch/sparc/lib/mul.S index 83dffbc2f62f..da693560d878 100644 --- a/arch/sparc/lib/mul.S +++ b/arch/sparc/lib/mul.S @@ -16,7 +16,9 @@ */ .globl .mul + .globl _Mul .mul: +_Mul: /* needed for export */ mov %o0, %y ! multiplier -> Y andncc %o0, 0xfff, %g0 ! test bits 12..31 be Lmul_shortway ! if zero, can do it the short way diff --git a/arch/sparc/lib/rem.S b/arch/sparc/lib/rem.S index 44508148d055..bf015a90d07e 100644 --- a/arch/sparc/lib/rem.S +++ b/arch/sparc/lib/rem.S @@ -43,7 +43,9 @@ .globl .rem + .globl _Rem .rem: +_Rem: /* needed for export */ ! compute sign of result; if neither is negative, no problem orcc %o1, %o0, %g0 ! either negative? bge 2f ! no, go do the divide diff --git a/arch/sparc/lib/sdiv.S b/arch/sparc/lib/sdiv.S index e0ad80b6f63d..af9451629d0b 100644 --- a/arch/sparc/lib/sdiv.S +++ b/arch/sparc/lib/sdiv.S @@ -43,7 +43,9 @@ .globl .div + .globl _Div .div: +_Div: /* needed for export */ ! compute sign of result; if neither is negative, no problem orcc %o1, %o0, %g0 ! either negative? bge 2f ! no, go do the divide diff --git a/arch/sparc/lib/udiv.S b/arch/sparc/lib/udiv.S index 2abfc6b0f3e9..169e01da6715 100644 --- a/arch/sparc/lib/udiv.S +++ b/arch/sparc/lib/udiv.S @@ -43,7 +43,9 @@ .globl .udiv + .globl _Udiv .udiv: +_Udiv: /* needed for export */ ! Ready to divide. Compute size of quotient; scale comparand. orcc %o1, %g0, %o5 diff --git a/arch/sparc/lib/umul.S b/arch/sparc/lib/umul.S index a784720a8a22..f0e5b20a2536 100644 --- a/arch/sparc/lib/umul.S +++ b/arch/sparc/lib/umul.S @@ -21,7 +21,9 @@ */ .globl .umul + .globl _Umul .umul: +_Umul: /* needed for export */ or %o0, %o1, %o4 mov %o0, %y ! multiplier -> Y diff --git a/arch/sparc/lib/urem.S b/arch/sparc/lib/urem.S index ec7f0c502c56..6b92bdc8b04c 100644 --- a/arch/sparc/lib/urem.S +++ b/arch/sparc/lib/urem.S @@ -41,7 +41,9 @@ */ .globl .urem + .globl _Urem .urem: +_Urem: /* needed for export */ ! Ready to divide. Compute size of quotient; scale comparand. orcc %o1, %g0, %o5 diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 09ffca54b373..3bed09e625c0 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -370,6 +370,12 @@ handle_modversions(struct module *mod, struct elf_info *info, /* Ignore register directives. */ if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER) break; + if (symname[0] == '.') { + char *munged = strdup(symname); + munged[0] = '_'; + munged[1] = toupper(munged[1]); + symname = munged; + } } #endif -- 2.20.1