From a72cdb76a21f89c9c5355cbfc92f93bcba2c7793 Mon Sep 17 00:00:00 2001 From: "Keith M. Wesolowski" Date: Fri, 6 Feb 2004 00:25:56 -0800 Subject: [PATCH] [SPARC32]: Fix sparc32 module support. --- arch/sparc/kernel/Makefile | 4 +-- arch/sparc/kernel/sparc_ksyms.c | 48 ++++++++++++++++++++++----------- scripts/modpost.c | 16 +++++++++-- 3 files changed, 48 insertions(+), 20 deletions(-) diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index e3619bd1b387c..fcf149e002378 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -12,7 +12,7 @@ obj-y := entry.o wof.o wuf.o etrap.o rtrap.o traps.o $(IRQ_OBJS) \ sys_sparc.o sunos_asm.o systbls.o \ time.o windows.o cpu.o devices.o sclow.o \ tadpole.o tick14.o ptrace.o sys_solaris.o \ - unaligned.o muldiv.o semaphore.o sparc_ksyms.o + unaligned.o muldiv.o semaphore.o obj-$(CONFIG_PCI) += pcic.o obj-$(CONFIG_SUN4) += sun4setup.o @@ -20,7 +20,7 @@ obj-$(CONFIG_SMP) += trampoline.o smp.o sun4m_smp.o sun4d_smp.o obj-$(CONFIG_SUN_AUXIO) += auxio.o obj-$(CONFIG_PCI) += ebus.o obj-$(CONFIG_SUN_PM) += apc.o pmc.o -obj-$(CONFIG_MODULES) += module.o +obj-$(CONFIG_MODULES) += module.o sparc_ksyms.o ifdef CONFIG_SUNOS_EMUL obj-y += sys_sunos.o sunos_ioctl.o diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index 078c5db2cacb5..c23185b9d6d3a 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c @@ -85,22 +85,38 @@ extern int __divdi3(int, int); extern void dump_thread(struct pt_regs *, struct user *); +/* Private functions with odd calling conventions. */ +extern void ___atomic_add(void); +extern void ___atomic_sub(void); +extern void ___set_bit(void); +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: */ -#define EXPORT_SYMBOL_DOT(sym) \ -extern int __sparc_dot_ ## sym (int) __asm__("." #sym); \ -const struct kernel_symbol __ksymtab___sparc_dot_##sym \ -__attribute__((section("__ksymtab"))) \ -= { (unsigned long)&__sparc_dot_##sym , "." #sym } - -#define EXPORT_SYMBOL_PRIVATE(sym) \ -extern int __sparc_priv_ ## sym (int) __asm__("__" #sym); \ -const struct kernel_symbol __export_priv_##sym \ -__attribute__((section("__ksymtab"))) = \ -{ (unsigned long) &__sparc_priv_ ## sym, "__" #sym } +/* 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 /* used by various drivers */ EXPORT_SYMBOL(sparc_cpu_model); @@ -131,13 +147,13 @@ EXPORT_SYMBOL(sparc_valid_addr_bitmap); EXPORT_SYMBOL(phys_base); /* Atomic operations. */ -EXPORT_SYMBOL_PRIVATE(_atomic_add); -EXPORT_SYMBOL_PRIVATE(_atomic_sub); +EXPORT_SYMBOL(___atomic_add); +EXPORT_SYMBOL(___atomic_sub); /* Bit operations. */ -EXPORT_SYMBOL_PRIVATE(_set_bit); -EXPORT_SYMBOL_PRIVATE(_clear_bit); -EXPORT_SYMBOL_PRIVATE(_change_bit); +EXPORT_SYMBOL(___set_bit); +EXPORT_SYMBOL(___clear_bit); +EXPORT_SYMBOL(___change_bit); #ifdef CONFIG_SMP /* IRQ implementation. */ diff --git a/scripts/modpost.c b/scripts/modpost.c index 7e6a4bb035a71..1707171810e5e 100644 --- a/scripts/modpost.c +++ b/scripts/modpost.c @@ -141,14 +141,26 @@ new_symbol(const char *name, struct module *module, unsigned int *crc) symbolhash[hash] = new; } +#define DOTSYM_PFX "__dot_" + struct symbol * find_symbol(const char *name) { struct symbol *s; + char dotname[64 + sizeof(DOTSYM_PFX)]; - /* For our purposes, .foo matches foo. PPC64 needs this. */ - if (name[0] == '.') + /* .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) -- 2.53.0