Commit 2ec523a3 authored by Keith M. Wesolowski's avatar Keith M. Wesolowski

[SPARC32]: Update module linking for symbols starting with "."

Rusty did not like the __dot_sym approach and suggested instead:

1) make rem, urem, mul, umul, div and udiv aliases to .rem, .urem etc:

   extern int rem(int, int) __attribute__((weak,alias(".rem")));

2) EXPORT_SYMBOL(rem) etc.
3) Check genksyms recognises that prototype (it should).
4) Copy "dedotify" from ppc64 to handle them on load.

The only real downside is the risk that someone else will export
those names, but I think that's pretty unlikely.
parent 8e764e0d
...@@ -36,7 +36,9 @@ void module_free(struct module *mod, void *module_region) ...@@ -36,7 +36,9 @@ void module_free(struct module *mod, void *module_region)
table entries. */ 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, int module_frob_arch_sections(Elf_Ehdr *hdr,
Elf_Shdr *sechdrs, Elf_Shdr *sechdrs,
char *secstrings, char *secstrings,
...@@ -44,7 +46,7 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, ...@@ -44,7 +46,7 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
{ {
unsigned int symidx; unsigned int symidx;
Elf32_Sym *sym; Elf32_Sym *sym;
const char *strtab; char *strtab;
int i; int i;
for (symidx = 0; sechdrs[symidx].sh_type != SHT_SYMTAB; symidx++) { for (symidx = 0; sechdrs[symidx].sh_type != SHT_SYMTAB; symidx++) {
...@@ -57,9 +59,15 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, ...@@ -57,9 +59,15 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
strtab = (char *)sechdrs[sechdrs[symidx].sh_link].sh_addr; strtab = (char *)sechdrs[sechdrs[symidx].sh_link].sh_addr;
for (i = 1; i < sechdrs[symidx].sh_size / sizeof(Elf_Sym); i++) { for (i = 1; i < sechdrs[symidx].sh_size / sizeof(Elf_Sym); i++) {
if (sym[i].st_shndx == SHN_UNDEF && if (sym[i].st_shndx == SHN_UNDEF) {
ELF32_ST_TYPE(sym[i].st_info) == STT_REGISTER) if (ELF32_ST_TYPE(sym[i].st_info) == STT_REGISTER)
sym[i].st_shndx = SHN_ABS; 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; return 0;
} }
......
...@@ -92,31 +92,21 @@ extern void ___set_bit(void); ...@@ -92,31 +92,21 @@ extern void ___set_bit(void);
extern void ___clear_bit(void); extern void ___clear_bit(void);
extern void ___change_bit(void); extern void ___change_bit(void);
/* One thing to note is that the way the symbols of the mul/div /* Alias functions whose names begin with "." and export the aliases.
* support routines are named is a mess, they all start with * The module references will be fixed up by module_frob_arch_sections.
* a '.' which makes it a bitch to export, here is the trick:
*/ */
#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 DOT_ALIAS2(int, div, int, int)
* change in an incompatible way, you must modify this. DOT_ALIAS2(int, mul, int, int)
*/ DOT_ALIAS2(int, rem, int, int)
#define DOT_PROTO(sym) extern int __dot_##sym(int, int) DOT_ALIAS2(unsigned, udiv, unsigned, unsigned)
DOT_ALIAS2(unsigned, umul, unsigned, unsigned)
#ifdef __GENKSYMS__ DOT_ALIAS2(unsigned, urem, unsigned, unsigned)
#define EXPORT_SYMBOL_DOT(sym) \
DOT_PROTO(sym); \ #undef DOT_ALIAS2
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
/* used by various drivers */ /* used by various drivers */
EXPORT_SYMBOL(sparc_cpu_model); EXPORT_SYMBOL(sparc_cpu_model);
...@@ -325,12 +315,12 @@ EXPORT_SYMBOL_NOVERS(__lshrdi3); ...@@ -325,12 +315,12 @@ EXPORT_SYMBOL_NOVERS(__lshrdi3);
EXPORT_SYMBOL_NOVERS(__muldi3); EXPORT_SYMBOL_NOVERS(__muldi3);
EXPORT_SYMBOL_NOVERS(__divdi3); EXPORT_SYMBOL_NOVERS(__divdi3);
EXPORT_SYMBOL_DOT(rem); EXPORT_SYMBOL(rem);
EXPORT_SYMBOL_DOT(urem); EXPORT_SYMBOL(urem);
EXPORT_SYMBOL_DOT(mul); EXPORT_SYMBOL(mul);
EXPORT_SYMBOL_DOT(umul); EXPORT_SYMBOL(umul);
EXPORT_SYMBOL_DOT(div); EXPORT_SYMBOL(div);
EXPORT_SYMBOL_DOT(udiv); EXPORT_SYMBOL(udiv);
#ifdef CONFIG_DEBUG_BUGVERBOSE #ifdef CONFIG_DEBUG_BUGVERBOSE
EXPORT_SYMBOL(do_BUG); EXPORT_SYMBOL(do_BUG);
......
...@@ -141,26 +141,14 @@ new_symbol(const char *name, struct module *module, unsigned int *crc) ...@@ -141,26 +141,14 @@ new_symbol(const char *name, struct module *module, unsigned int *crc)
symbolhash[hash] = new; symbolhash[hash] = new;
} }
#define DOTSYM_PFX "__dot_"
struct symbol * struct symbol *
find_symbol(const char *name) find_symbol(const char *name)
{ {
struct symbol *s; struct symbol *s;
char dotname[64 + sizeof(DOTSYM_PFX)];
/* .foo matches foo. PPC64 needs this. */ /* For our purposes, .foo matches foo. PPC64 needs this. */
if (name[0] == '.') { if (name[0] == '.')
name++; 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) { for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s=s->next) {
if (strcmp(s->name, name) == 0) if (strcmp(s->name, name) == 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment