[SPARC]: Fix dot-symbol exporting for good.

From: Al Viro <viro@ZenIV.linux.org.uk>

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 <davem@davemloft.net>

authored by Al Viro and committed by David S. Miller 7caaeabb 357d596b

+36 -22
+6 -3
arch/sparc/kernel/module.c
··· 10 10 #include <linux/vmalloc.h> 11 11 #include <linux/fs.h> 12 12 #include <linux/string.h> 13 + #include <linux/ctype.h> 13 14 14 15 void *module_alloc(unsigned long size) 15 16 { ··· 38 37 } 39 38 40 39 /* Make generic code ignore STT_REGISTER dummy undefined symbols, 41 - * and replace references to .func with func as in ppc64's dedotify. 40 + * and replace references to .func with _Func 42 41 */ 43 42 int module_frob_arch_sections(Elf_Ehdr *hdr, 44 43 Elf_Shdr *sechdrs, ··· 65 64 sym[i].st_shndx = SHN_ABS; 66 65 else { 67 66 char *name = strtab + sym[i].st_name; 68 - if (name[0] == '.') 69 - memmove(name, name+1, strlen(name)); 67 + if (name[0] == '.') { 68 + name[0] = '_'; 69 + name[1] = toupper(name[1]); 70 + } 70 71 } 71 72 } 72 73 }
+12 -19
arch/sparc/kernel/sparc_ksyms.c
··· 97 97 /* Alias functions whose names begin with "." and export the aliases. 98 98 * The module references will be fixed up by module_frob_arch_sections. 99 99 */ 100 - #define DOT_ALIAS2(__ret, __x, __arg1, __arg2) \ 101 - extern __ret __x(__arg1, __arg2); \ 102 - asm(".weak " #__x);\ 103 - asm(#__x "=." #__x); 104 - 105 - DOT_ALIAS2(int, div, int, int) 106 - DOT_ALIAS2(int, mul, int, int) 107 - DOT_ALIAS2(int, rem, int, int) 108 - DOT_ALIAS2(unsigned, udiv, unsigned, unsigned) 109 - DOT_ALIAS2(unsigned, umul, unsigned, unsigned) 110 - DOT_ALIAS2(unsigned, urem, unsigned, unsigned) 111 - 112 - #undef DOT_ALIAS2 100 + extern int _Div(int, int); 101 + extern int _Mul(int, int); 102 + extern int _Rem(int, int); 103 + extern unsigned _Udiv(unsigned, unsigned); 104 + extern unsigned _Umul(unsigned, unsigned); 105 + extern unsigned _Urem(unsigned, unsigned); 113 106 114 107 /* used by various drivers */ 115 108 EXPORT_SYMBOL(sparc_cpu_model); ··· 313 320 EXPORT_SYMBOL(__muldi3); 314 321 EXPORT_SYMBOL(__divdi3); 315 322 316 - EXPORT_SYMBOL(rem); 317 - EXPORT_SYMBOL(urem); 318 - EXPORT_SYMBOL(mul); 319 - EXPORT_SYMBOL(umul); 320 - EXPORT_SYMBOL(div); 321 - EXPORT_SYMBOL(udiv); 323 + EXPORT_SYMBOL(_Rem); 324 + EXPORT_SYMBOL(_Urem); 325 + EXPORT_SYMBOL(_Mul); 326 + EXPORT_SYMBOL(_Umul); 327 + EXPORT_SYMBOL(_Div); 328 + EXPORT_SYMBOL(_Udiv); 322 329 323 330 #ifdef CONFIG_DEBUG_BUGVERBOSE 324 331 EXPORT_SYMBOL(do_BUG);
+2
arch/sparc/lib/mul.S
··· 16 16 */ 17 17 18 18 .globl .mul 19 + .globl _Mul 19 20 .mul: 21 + _Mul: /* needed for export */ 20 22 mov %o0, %y ! multiplier -> Y 21 23 andncc %o0, 0xfff, %g0 ! test bits 12..31 22 24 be Lmul_shortway ! if zero, can do it the short way
+2
arch/sparc/lib/rem.S
··· 43 43 44 44 45 45 .globl .rem 46 + .globl _Rem 46 47 .rem: 48 + _Rem: /* needed for export */ 47 49 ! compute sign of result; if neither is negative, no problem 48 50 orcc %o1, %o0, %g0 ! either negative? 49 51 bge 2f ! no, go do the divide
+2
arch/sparc/lib/sdiv.S
··· 43 43 44 44 45 45 .globl .div 46 + .globl _Div 46 47 .div: 48 + _Div: /* needed for export */ 47 49 ! compute sign of result; if neither is negative, no problem 48 50 orcc %o1, %o0, %g0 ! either negative? 49 51 bge 2f ! no, go do the divide
+2
arch/sparc/lib/udiv.S
··· 43 43 44 44 45 45 .globl .udiv 46 + .globl _Udiv 46 47 .udiv: 48 + _Udiv: /* needed for export */ 47 49 48 50 ! Ready to divide. Compute size of quotient; scale comparand. 49 51 orcc %o1, %g0, %o5
+2
arch/sparc/lib/umul.S
··· 21 21 */ 22 22 23 23 .globl .umul 24 + .globl _Umul 24 25 .umul: 26 + _Umul: /* needed for export */ 25 27 or %o0, %o1, %o4 26 28 mov %o0, %y ! multiplier -> Y 27 29
+2
arch/sparc/lib/urem.S
··· 41 41 */ 42 42 43 43 .globl .urem 44 + .globl _Urem 44 45 .urem: 46 + _Urem: /* needed for export */ 45 47 46 48 ! Ready to divide. Compute size of quotient; scale comparand. 47 49 orcc %o1, %g0, %o5
+6
scripts/mod/modpost.c
··· 370 370 /* Ignore register directives. */ 371 371 if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER) 372 372 break; 373 + if (symname[0] == '.') { 374 + char *munged = strdup(symname); 375 + munged[0] = '_'; 376 + munged[1] = toupper(munged[1]); 377 + symname = munged; 378 + } 373 379 } 374 380 #endif 375 381