aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/mod
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/mod')
-rw-r--r--scripts/mod/file2alias.c4
-rw-r--r--scripts/mod/modpost.c36
-rw-r--r--scripts/mod/modpost.h1
3 files changed, 38 insertions, 3 deletions
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index e26e2fb..f210eae 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -905,6 +905,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
return;
+ /* We're looking for an object */
+ if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
+ return;
+
/* Handle all-NULL symbols allocated into .bss */
if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) {
zeros = calloc(1, sym->st_size);
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 413c536..e3cd345 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -132,8 +132,10 @@ static struct module *new_module(char *modname)
/* strip trailing .o */
s = strrchr(p, '.');
if (s != NULL)
- if (strcmp(s, ".o") == 0)
+ if (strcmp(s, ".o") == 0) {
*s = '\0';
+ mod->is_dot_o = 1;
+ }
/* add to list */
mod->name = p;
@@ -254,6 +256,28 @@ static enum export export_no(const char *s)
return export_unknown;
}
+static const char *sec_name(struct elf_info *elf, int secindex);
+
+#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0)
+
+static enum export export_from_secname(struct elf_info *elf, unsigned int sec)
+{
+ const char *secname = sec_name(elf, sec);
+
+ if (strstarts(secname, "___ksymtab+"))
+ return export_plain;
+ else if (strstarts(secname, "___ksymtab_unused+"))
+ return export_unused;
+ else if (strstarts(secname, "___ksymtab_gpl+"))
+ return export_gpl;
+ else if (strstarts(secname, "___ksymtab_unused_gpl+"))
+ return export_unused_gpl;
+ else if (strstarts(secname, "___ksymtab_gpl_future+"))
+ return export_gpl_future;
+ else
+ return export_unknown;
+}
+
static enum export export_from_sec(struct elf_info *elf, unsigned int sec)
{
if (sec == elf->export_sec)
@@ -563,7 +587,13 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
Elf_Sym *sym, const char *symname)
{
unsigned int crc;
- enum export export = export_from_sec(info, get_secindex(info, sym));
+ enum export export;
+
+ if ((!is_vmlinux(mod->name) || mod->is_dot_o) &&
+ strncmp(symname, "__ksymtab", 9) == 0)
+ export = export_from_secname(info, get_secindex(info, sym));
+ else
+ export = export_from_sec(info, get_secindex(info, sym));
switch (sym->st_shndx) {
case SHN_COMMON:
@@ -822,7 +852,7 @@ static void check_section(const char *modname, struct elf_info *elf,
#define ALL_INIT_DATA_SECTIONS \
".init.setup$", ".init.rodata$", \
- ".devinit.rodata$", ".cpuinit.rodata$", ".meminit.rodata$" \
+ ".devinit.rodata$", ".cpuinit.rodata$", ".meminit.rodata$", \
".init.data$", ".devinit.data$", ".cpuinit.data$", ".meminit.data$"
#define ALL_EXIT_DATA_SECTIONS \
".exit.data$", ".devexit.data$", ".cpuexit.data$", ".memexit.data$"
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index 2031119..51207e4 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -113,6 +113,7 @@ struct module {
int has_cleanup;
struct buffer dev_table_buf;
char srcversion[25];
+ int is_dot_o;
};
struct elf_info {