summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorAlan Jenkins <alan-jenkins@tuffmail.co.uk>2009-11-23 22:47:22 +0000
committerStephen Rothwell <sfr@canb.auug.org.au>2009-11-25 13:16:25 +1100
commit3dc22f849769679a01bc66eb85c011d07d8738f1 (patch)
tree716efe20ffc437aaae55ecf58b7ea780e47b688d /scripts
parent215143067b9bfacdfd475c5b2fa5536ee30f50ec (diff)
modpost: fix modules on ia64 - use @fptr() on exported function symbols
On function descriptor architectures (powerpc and ia64), we need to export the address of the function descriptor and not the actual function. The C compiler naturally does this for us. However we now export vmlinux symbols using the assembler, in order to sort the exports. This is not a problem on powerpc. On powerpc, the function descriptor is simply "printk" (the action function entry point is ".printk"). But ia64 assembly needs special handling. The function descriptor for printk(), for example, is "@fptr(printk)". I have tested that modpost now generates the desired assembly code when run against an IA64 module. I have not tested with an actual IA64 vmlinux, assembler, compiler or processor. I assume that the IA64 assembler defines __ia64__, just as the i386 assembler defines __i386__. Reported-by: Alex Chiang <achiang@hp.com> Signed-off-by: Alan Jenkins <alan-jenkins@tuffmail.co.uk> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/mod/modpost.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index f6be2e91cafc..542bd0597592 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -158,6 +158,7 @@ struct symbol {
unsigned int kernel:1; /* 1 if symbol is from kernel
* (only for external modules) **/
unsigned int preloaded:1; /* 1 if symbol from Module.symvers */
+ unsigned int function:1; /* 1 if symbol refers to a function */
enum export export; /* Type of export */
char name[0];
};
@@ -582,6 +583,17 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
}
}
+static void mark_function_symbols(Elf_Sym *sym, const char *symname)
+{
+ struct symbol *export_symbol;
+
+ export_symbol = find_symbol(symname);
+ if (!export_symbol)
+ return;
+
+ export_symbol->function = (ELF_ST_TYPE(sym->st_info) == STT_FUNC);
+}
+
/**
* Parse tag=value strings from .modinfo section
**/
@@ -1632,6 +1644,13 @@ static void read_symbols(char *modname)
handle_modversions(mod, &info, sym, symname);
handle_moddevtable(mod, &info, sym, symname);
}
+
+ for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
+ symname = info.strtab + sym->st_name;
+
+ mark_function_symbols(sym, symname);
+ }
+
if (!is_vmlinux(modname) ||
(is_vmlinux(modname) && vmlinux_section_warnings))
check_sec_ref(mod, modname, &info);
@@ -2040,10 +2059,11 @@ static void write_exports(const char *fname)
for (i = 0; i < n; i++) {
sym = symbols[i];
- buf_printf(&buf, "__EXPORT_SYMBOL(%s,"
+ buf_printf(&buf, "__EXPORT_%s_SYMBOL(%s,"
" __ksymtab%s_sorted,"
" __ksymtab_strings_sorted,"
" __kcrctab%s_sorted)\n",
+ sym->function ? "FUNCTION" : "DATA",
sym->name,
section_names[sym->export],
section_names[sym->export]);