aboutsummaryrefslogtreecommitdiff
path: root/scripts/mod
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/mod')
-rw-r--r--scripts/mod/mk_elfconfig.c25
-rw-r--r--scripts/mod/modpost.c125
-rw-r--r--scripts/mod/modpost.h28
-rw-r--r--scripts/mod/sumversion.c6
-rw-r--r--scripts/mod/symsearch.c6
5 files changed, 79 insertions, 111 deletions
diff --git a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c
index 680eade89be1..e8cee4e4bc73 100644
--- a/scripts/mod/mk_elfconfig.c
+++ b/scripts/mod/mk_elfconfig.c
@@ -8,7 +8,6 @@ int
main(int argc, char **argv)
{
unsigned char ei[EI_NIDENT];
- union { short s; char c[2]; } endian_test;
if (fread(ei, 1, EI_NIDENT, stdin) != EI_NIDENT) {
fprintf(stderr, "Error: input truncated\n");
@@ -28,30 +27,6 @@ main(int argc, char **argv)
default:
exit(1);
}
- switch (ei[EI_DATA]) {
- case ELFDATA2LSB:
- printf("#define KERNEL_ELFDATA ELFDATA2LSB\n");
- break;
- case ELFDATA2MSB:
- printf("#define KERNEL_ELFDATA ELFDATA2MSB\n");
- break;
- default:
- exit(1);
- }
-
- if (sizeof(unsigned long) == 4) {
- printf("#define HOST_ELFCLASS ELFCLASS32\n");
- } else if (sizeof(unsigned long) == 8) {
- printf("#define HOST_ELFCLASS ELFCLASS64\n");
- }
-
- endian_test.s = 0x0102;
- if (memcmp(endian_test.c, "\x01\x02", 2) == 0)
- printf("#define HOST_ELFDATA ELFDATA2MSB\n");
- else if (memcmp(endian_test.c, "\x02\x01", 2) == 0)
- printf("#define HOST_ELFDATA ELFDATA2LSB\n");
- else
- exit(1);
return 0;
}
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index d16d0ace2775..107393a8c48a 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -23,6 +23,7 @@
#include <hashtable.h>
#include <list.h>
+#include <xalloc.h>
#include "modpost.h"
#include "../../include/linux/license.h"
@@ -50,6 +51,9 @@ static bool error_occurred;
static bool extra_warn;
+bool target_is_big_endian;
+bool host_is_big_endian;
+
/*
* Cut off the warnings when there are too many. This typically occurs when
* vmlinux is missing. ('make modules' without building vmlinux.)
@@ -63,20 +67,15 @@ static unsigned int nr_unresolved;
#define MODULE_NAME_LEN (64 - sizeof(Elf_Addr))
-void modpost_log(enum loglevel loglevel, const char *fmt, ...)
+void modpost_log(bool is_error, const char *fmt, ...)
{
va_list arglist;
- switch (loglevel) {
- case LOG_WARN:
- fprintf(stderr, "WARNING: ");
- break;
- case LOG_ERROR:
+ if (is_error) {
fprintf(stderr, "ERROR: ");
error_occurred = true;
- break;
- default: /* invalid loglevel, ignore */
- break;
+ } else {
+ fprintf(stderr, "WARNING: ");
}
fprintf(stderr, "modpost: ");
@@ -94,14 +93,6 @@ static inline bool strends(const char *str, const char *postfix)
return strcmp(str + strlen(str) - strlen(postfix), postfix) == 0;
}
-void *do_nofail(void *ptr, const char *expr)
-{
- if (!ptr)
- fatal("Memory allocation failure: %s.\n", expr);
-
- return ptr;
-}
-
char *read_text_file(const char *filename)
{
struct stat st;
@@ -120,7 +111,7 @@ char *read_text_file(const char *filename)
exit(1);
}
- buf = NOFAIL(malloc(st.st_size + 1));
+ buf = xmalloc(st.st_size + 1);
nbytes = st.st_size;
@@ -178,7 +169,7 @@ static struct module *new_module(const char *name, size_t namelen)
{
struct module *mod;
- mod = NOFAIL(malloc(sizeof(*mod) + namelen + 1));
+ mod = xmalloc(sizeof(*mod) + namelen + 1);
memset(mod, 0, sizeof(*mod));
INIT_LIST_HEAD(&mod->exported_symbols);
@@ -237,7 +228,7 @@ static inline unsigned int tdb_hash(const char *name)
**/
static struct symbol *alloc_symbol(const char *name)
{
- struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1));
+ struct symbol *s = xmalloc(sizeof(*s) + strlen(name) + 1);
memset(s, 0, sizeof(*s));
strcpy(s->name, name);
@@ -310,8 +301,7 @@ static void add_namespace(struct list_head *head, const char *namespace)
struct namespace_list *ns_entry;
if (!contains_namespace(head, namespace)) {
- ns_entry = NOFAIL(malloc(sizeof(*ns_entry) +
- strlen(namespace) + 1));
+ ns_entry = xmalloc(sizeof(*ns_entry) + strlen(namespace) + 1);
strcpy(ns_entry->namespace, namespace);
list_add_tail(&ns_entry->list, head);
}
@@ -366,7 +356,7 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod,
s = alloc_symbol(name);
s->module = mod;
s->is_gpl_only = gpl_only;
- s->namespace = NOFAIL(strdup(namespace));
+ s->namespace = xstrdup(namespace);
list_add_tail(&s->list, &mod->exported_symbols);
hash_add_symbol(s);
@@ -438,6 +428,18 @@ static int parse_elf(struct elf_info *info, const char *filename)
/* Not an ELF file - silently ignore it */
return 0;
}
+
+ switch (hdr->e_ident[EI_DATA]) {
+ case ELFDATA2LSB:
+ target_is_big_endian = false;
+ break;
+ case ELFDATA2MSB:
+ target_is_big_endian = true;
+ break;
+ default:
+ fatal("target endian is unknown\n");
+ }
+
/* Fix endianness in ELF header */
hdr->e_type = TO_NATIVE(hdr->e_type);
hdr->e_machine = TO_NATIVE(hdr->e_machine);
@@ -622,7 +624,7 @@ static void handle_symbol(struct module *mod, struct elf_info *info,
if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
break;
if (symname[0] == '.') {
- char *munged = NOFAIL(strdup(symname));
+ char *munged = xstrdup(symname);
munged[0] = '_';
munged[1] = toupper(munged[1]);
symname = munged;
@@ -690,10 +692,7 @@ static char *get_modinfo(struct elf_info *info, const char *tag)
static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
{
- if (sym)
- return elf->strtab + sym->st_name;
- else
- return "(unknown)";
+ return sym ? elf->strtab + sym->st_name : "";
}
/*
@@ -1006,6 +1005,7 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf,
Elf_Sym *from;
const char *tosym;
const char *fromsym;
+ char taddr_str[16];
from = find_fromsym(elf, faddr, fsecndx);
fromsym = sym_name(elf, from);
@@ -1019,10 +1019,17 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf,
sec_mismatch_count++;
- warn("%s: section mismatch in reference: %s+0x%x (section: %s) -> %s (section: %s)\n",
- modname, fromsym,
- (unsigned int)(faddr - (from ? from->st_value : 0)),
- fromsec, tosym, tosec);
+ if (!tosym[0])
+ snprintf(taddr_str, sizeof(taddr_str), "0x%x", (unsigned int)taddr);
+
+ /*
+ * The format for the reference source: <symbol_name>+<offset> or <address>
+ * The format for the reference destination: <symbol_name> or <address>
+ */
+ warn("%s: section mismatch in reference: %s%s0x%x (section: %s) -> %s (section: %s)\n",
+ modname, fromsym, fromsym[0] ? "+" : "",
+ (unsigned int)(faddr - (fromsym[0] ? from->st_value : 0)),
+ fromsec, tosym[0] ? tosym : taddr_str, tosec);
if (mismatch->mismatch == EXTABLE_TO_NON_TEXT) {
if (match(tosec, mismatch->bad_tosec))
@@ -1662,7 +1669,7 @@ void buf_write(struct buffer *buf, const char *s, int len)
{
if (buf->size - buf->pos < len) {
buf->size += len + SZ;
- buf->p = NOFAIL(realloc(buf->p, buf->size));
+ buf->p = xrealloc(buf->p, buf->size);
}
strncpy(buf->p + buf->pos, s, len);
buf->pos += len;
@@ -1677,7 +1684,7 @@ static void check_exports(struct module *mod)
exp = find_symbol(s->name);
if (!exp) {
if (!s->weak && nr_unresolved++ < MAX_UNRESOLVED_REPORTS)
- modpost_log(warn_unresolved ? LOG_WARN : LOG_ERROR,
+ modpost_log(!warn_unresolved,
"\"%s\" [%s.ko] undefined!\n",
s->name, mod->name);
continue;
@@ -1700,7 +1707,7 @@ static void check_exports(struct module *mod)
basename = mod->name;
if (!contains_namespace(&mod->imported_namespaces, exp->namespace)) {
- modpost_log(allow_missing_ns_imports ? LOG_WARN : LOG_ERROR,
+ modpost_log(!allow_missing_ns_imports,
"module %s uses symbol %s from namespace %s, but does not import it.\n",
basename, exp->name, exp->namespace);
add_namespace(&mod->missing_namespaces, exp->namespace);
@@ -1748,26 +1755,9 @@ static void check_modname_len(struct module *mod)
static void add_header(struct buffer *b, struct module *mod)
{
buf_printf(b, "#include <linux/module.h>\n");
- /*
- * Include build-salt.h after module.h in order to
- * inherit the definitions.
- */
- buf_printf(b, "#define INCLUDE_VERMAGIC\n");
- buf_printf(b, "#include <linux/build-salt.h>\n");
- buf_printf(b, "#include <linux/elfnote-lto.h>\n");
buf_printf(b, "#include <linux/export-internal.h>\n");
- buf_printf(b, "#include <linux/vermagic.h>\n");
buf_printf(b, "#include <linux/compiler.h>\n");
buf_printf(b, "\n");
- buf_printf(b, "#ifdef CONFIG_UNWINDER_ORC\n");
- buf_printf(b, "#include <asm/orc_header.h>\n");
- buf_printf(b, "ORC_HEADER;\n");
- buf_printf(b, "#endif\n");
- buf_printf(b, "\n");
- buf_printf(b, "BUILD_SALT;\n");
- buf_printf(b, "BUILD_LTO_INFO;\n");
- buf_printf(b, "\n");
- buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
buf_printf(b, "\n");
buf_printf(b, "__visible struct module __this_module\n");
@@ -1785,12 +1775,6 @@ static void add_header(struct buffer *b, struct module *mod)
if (!external_module)
buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n");
- buf_printf(b,
- "\n"
- "#ifdef CONFIG_MITIGATION_RETPOLINE\n"
- "MODULE_INFO(retpoline, \"Y\");\n"
- "#endif\n");
-
if (strstarts(mod->name, "drivers/staging"))
buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
@@ -1947,7 +1931,7 @@ static void write_if_changed(struct buffer *b, const char *fname)
if (st.st_size != b->pos)
goto close_write;
- tmp = NOFAIL(malloc(b->pos));
+ tmp = xmalloc(b->pos);
if (fread(tmp, 1, b->pos, file) != b->pos)
goto free_write;
@@ -2117,6 +2101,25 @@ struct dump_list {
const char *file;
};
+static void check_host_endian(void)
+{
+ static const union {
+ short s;
+ char c[2];
+ } endian_test = { .c = {0x01, 0x02} };
+
+ switch (endian_test.s) {
+ case 0x0102:
+ host_is_big_endian = true;
+ break;
+ case 0x0201:
+ host_is_big_endian = false;
+ break;
+ default:
+ fatal("Unknown host endian\n");
+ }
+}
+
int main(int argc, char **argv)
{
struct module *mod;
@@ -2133,7 +2136,7 @@ int main(int argc, char **argv)
external_module = true;
break;
case 'i':
- dl = NOFAIL(malloc(sizeof(*dl)));
+ dl = xmalloc(sizeof(*dl));
dl->file = optarg;
list_add_tail(&dl->list, &dump_lists);
break;
@@ -2181,6 +2184,8 @@ int main(int argc, char **argv)
}
}
+ check_host_endian();
+
list_for_each_entry_safe(dl, dl2, &dump_lists, list) {
read_dump(dl->file);
list_del(&dl->list);
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index 58197b34a3c8..ada3a36cc4bc 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -62,22 +62,11 @@
x); \
})
-#if KERNEL_ELFDATA != HOST_ELFDATA
-
-#define TO_NATIVE(x) (bswap(x))
-
-#else /* endianness matches */
-
-#define TO_NATIVE(x) (x)
-
-#endif
-
-#define NOFAIL(ptr) do_nofail((ptr), #ptr)
+#define TO_NATIVE(x) \
+ (target_is_big_endian == host_is_big_endian ? x : bswap(x))
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
-void *do_nofail(void *ptr, const char *expr);
-
struct buffer {
char *p;
int pos;
@@ -187,17 +176,14 @@ void add_moddevtable(struct buffer *buf, struct module *mod);
void get_src_version(const char *modname, char sum[], unsigned sumlen);
/* from modpost.c */
+extern bool target_is_big_endian;
+extern bool host_is_big_endian;
char *read_text_file(const char *filename);
char *get_line(char **stringp);
void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym);
-enum loglevel {
- LOG_WARN,
- LOG_ERROR,
-};
-
void __attribute__((format(printf, 2, 3)))
-modpost_log(enum loglevel loglevel, const char *fmt, ...);
+modpost_log(bool is_error, const char *fmt, ...);
/*
* warn - show the given message, then let modpost continue running, still
@@ -212,6 +198,6 @@ modpost_log(enum loglevel loglevel, const char *fmt, ...);
* fatal - show the given message, and bail out immediately. This should be
* used when there is no point to continue running modpost.
*/
-#define warn(fmt, args...) modpost_log(LOG_WARN, fmt, ##args)
-#define error(fmt, args...) modpost_log(LOG_ERROR, fmt, ##args)
+#define warn(fmt, args...) modpost_log(false, fmt, ##args)
+#define error(fmt, args...) modpost_log(true, fmt, ##args)
#define fatal(fmt, args...) do { error(fmt, ##args); exit(1); } while (1)
diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c
index dc4878502276..e7d2da45b0df 100644
--- a/scripts/mod/sumversion.c
+++ b/scripts/mod/sumversion.c
@@ -8,6 +8,8 @@
#include <errno.h>
#include <string.h>
#include <limits.h>
+
+#include <xalloc.h>
#include "modpost.h"
/*
@@ -305,7 +307,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md)
const char *base;
int dirlen, ret = 0, check_files = 0;
- cmd = NOFAIL(malloc(strlen(objfile) + sizeof("..cmd")));
+ cmd = xmalloc(strlen(objfile) + sizeof("..cmd"));
base = strrchr(objfile, '/');
if (base) {
@@ -316,7 +318,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md)
dirlen = 0;
sprintf(cmd, ".%s.cmd", objfile);
}
- dir = NOFAIL(malloc(dirlen + 1));
+ dir = xmalloc(dirlen + 1);
strncpy(dir, objfile, dirlen);
dir[dirlen] = '\0';
diff --git a/scripts/mod/symsearch.c b/scripts/mod/symsearch.c
index aa4ed51f9960..b9737b92f7f8 100644
--- a/scripts/mod/symsearch.c
+++ b/scripts/mod/symsearch.c
@@ -4,7 +4,7 @@
* Helper functions for finding the symbol in an ELF which is "nearest"
* to a given address.
*/
-
+#include <xalloc.h>
#include "modpost.h"
struct syminfo {
@@ -125,8 +125,8 @@ void symsearch_init(struct elf_info *elf)
{
unsigned int table_size = symbol_count(elf);
- elf->symsearch = NOFAIL(malloc(sizeof(struct symsearch) +
- sizeof(struct syminfo) * table_size));
+ elf->symsearch = xmalloc(sizeof(struct symsearch) +
+ sizeof(struct syminfo) * table_size);
elf->symsearch->table_size = table_size;
symsearch_populate(elf, elf->symsearch->table, table_size);