^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* Postprocess module symbol versions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright 2003 Kai Germaschewski
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright 2002-2004 Rusty Russell, IBM Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2006-2008 Sam Ravnborg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Based in part on module-init-tools/depmod.c,file2alias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This software may be used and distributed according to the terms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * of the GNU General Public License, incorporated herein by reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Usage: modpost vmlinux module1.o module2.o ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define _GNU_SOURCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <elf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <limits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "modpost.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "../../include/linux/license.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* Are we using CONFIG_MODVERSIONS? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static int modversions = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* Warn about undefined symbols? (do so if we have vmlinux) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static int have_vmlinux = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* Is CONFIG_MODULE_SRCVERSION_ALL set? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static int all_versions = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* If we are modposting external module set to 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static int external_module = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define MODULE_SCMVERSION_SIZE 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static char module_scmversion[MODULE_SCMVERSION_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* Only warn about unresolved symbols */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static int warn_unresolved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* How a symbol is exported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static int sec_mismatch_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static int sec_mismatch_warn_only = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* ignore missing files */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static int ignore_missing_files;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* If set to 1, only warn (instead of error) about missing ns imports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static int allow_missing_ns_imports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static bool error_occurred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) enum export {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) export_plain, export_unused, export_gpl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) export_unused_gpl, export_gpl_future, export_unknown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* In kernel, this size is defined in linux/module.h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * here we use Elf_Addr instead of long for covering cross-compile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define MODULE_NAME_LEN (64 - sizeof(Elf_Addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) void __attribute__((format(printf, 2, 3)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) modpost_log(enum loglevel loglevel, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) va_list arglist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) switch (loglevel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) case LOG_WARN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) fprintf(stderr, "WARNING: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) case LOG_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) fprintf(stderr, "ERROR: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) case LOG_FATAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) fprintf(stderr, "FATAL: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) default: /* invalid loglevel, ignore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) fprintf(stderr, "modpost: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) va_start(arglist, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) vfprintf(stderr, fmt, arglist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) va_end(arglist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (loglevel == LOG_FATAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (loglevel == LOG_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) error_occurred = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) void *do_nofail(void *ptr, const char *expr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (!ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) fatal("Memory allocation failure: %s.\n", expr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) char *read_text_file(const char *filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct stat st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) size_t nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) fd = open(filename, O_RDONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (fd < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) perror(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (fstat(fd, &st) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) perror(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) buf = NOFAIL(malloc(st.st_size + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) nbytes = st.st_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) while (nbytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) ssize_t bytes_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) bytes_read = read(fd, buf, nbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (bytes_read < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) perror(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) nbytes -= bytes_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) buf[st.st_size] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) char *get_line(char **stringp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) char *orig = *stringp, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* do not return the unwanted extra line at EOF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (!orig || *orig == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* don't use strsep here, it is not available everywhere */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) next = strchr(orig, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) *next++ = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) *stringp = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return orig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /* A list of all modules we processed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static struct module *modules;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static struct module *find_module(const char *modname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct module *mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) for (mod = modules; mod; mod = mod->next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (strcmp(mod->name, modname) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static struct module *new_module(const char *modname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct module *mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) mod = NOFAIL(malloc(sizeof(*mod) + strlen(modname) + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) memset(mod, 0, sizeof(*mod));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* add to list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) strcpy(mod->name, modname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) mod->is_vmlinux = (strcmp(modname, "vmlinux") == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) mod->gpl_compatible = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) mod->next = modules;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) modules = mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (mod->is_vmlinux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) have_vmlinux = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* A hash of all exported symbols,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * struct symbol is also used for lists of unresolved symbols */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define SYMBOL_HASH_SIZE 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct symbol {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct symbol *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct module *module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) unsigned int crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) int crc_valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) char *namespace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) unsigned int weak:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) unsigned int is_static:1; /* 1 if symbol is not global */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) enum export export; /* Type of export */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) char name[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static struct symbol *symbolhash[SYMBOL_HASH_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /* This is based on the hash agorithm from gdbm, via tdb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static inline unsigned int tdb_hash(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) unsigned value; /* Used to compute the hash value. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) unsigned i; /* Used to cycle through random values. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /* Set the initial value from the key size. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return (1103515243 * value + 12345);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * Allocate a new symbols for use in the hash of exported symbols or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * the list of unresolved symbols per module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static struct symbol *alloc_symbol(const char *name, unsigned int weak,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) struct symbol *next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) memset(s, 0, sizeof(*s));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) strcpy(s->name, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) s->weak = weak;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) s->next = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) s->is_static = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /* For the hash of exported symbols */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static struct symbol *new_symbol(const char *name, struct module *module,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) enum export export)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) unsigned int hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return symbolhash[hash];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static struct symbol *find_symbol(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct symbol *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* For our purposes, .foo matches foo. PPC64 needs this. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (name[0] == '.')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) name++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s = s->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (strcmp(s->name, name) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static bool contains_namespace(struct namespace_list *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) const char *namespace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) for (; list; list = list->next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (!strcmp(list->namespace, namespace))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static void add_namespace(struct namespace_list **list, const char *namespace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct namespace_list *ns_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (!contains_namespace(*list, namespace)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) ns_entry = NOFAIL(malloc(sizeof(struct namespace_list) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) strlen(namespace) + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) strcpy(ns_entry->namespace, namespace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) ns_entry->next = *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) *list = ns_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static bool module_imports_namespace(struct module *module,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) const char *namespace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return contains_namespace(module->imported_namespaces, namespace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) const char *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) enum export export;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) } export_list[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) { .str = "EXPORT_SYMBOL", .export = export_plain },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) { .str = "EXPORT_UNUSED_SYMBOL", .export = export_unused },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) { .str = "EXPORT_SYMBOL_GPL", .export = export_gpl },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) { .str = "EXPORT_UNUSED_SYMBOL_GPL", .export = export_unused_gpl },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) { .str = "EXPORT_SYMBOL_GPL_FUTURE", .export = export_gpl_future },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) { .str = "(unknown)", .export = export_unknown },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static const char *export_str(enum export ex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return export_list[ex].str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static enum export export_no(const char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (!s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return export_unknown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) for (i = 0; export_list[i].export != export_unknown; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (strcmp(export_list[i].str, s) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return export_list[i].export;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return export_unknown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static void *sym_get_data_by_offset(const struct elf_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) unsigned int secindex, unsigned long offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) Elf_Shdr *sechdr = &info->sechdrs[secindex];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (info->hdr->e_type != ET_REL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) offset -= sechdr->sh_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return (void *)info->hdr + sechdr->sh_offset + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return sym_get_data_by_offset(info, get_secindex(info, sym),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) sym->st_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static const char *sech_name(const struct elf_info *info, Elf_Shdr *sechdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return sym_get_data_by_offset(info, info->secindex_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) sechdr->sh_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static const char *sec_name(const struct elf_info *info, int secindex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return sech_name(info, &info->sechdrs[secindex]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) #define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static enum export export_from_secname(struct elf_info *elf, unsigned int sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) const char *secname = sec_name(elf, sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (strstarts(secname, "___ksymtab+"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return export_plain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) else if (strstarts(secname, "___ksymtab_unused+"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return export_unused;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) else if (strstarts(secname, "___ksymtab_gpl+"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return export_gpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) else if (strstarts(secname, "___ksymtab_unused_gpl+"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return export_unused_gpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) else if (strstarts(secname, "___ksymtab_gpl_future+"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return export_gpl_future;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return export_unknown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static enum export export_from_sec(struct elf_info *elf, unsigned int sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (sec == elf->export_sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return export_plain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) else if (sec == elf->export_unused_sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return export_unused;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) else if (sec == elf->export_gpl_sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return export_gpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) else if (sec == elf->export_unused_gpl_sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return export_unused_gpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) else if (sec == elf->export_gpl_future_sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return export_gpl_future;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return export_unknown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static const char *namespace_from_kstrtabns(const struct elf_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) const Elf_Sym *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) const char *value = sym_get_data(info, sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return value[0] ? value : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static void sym_update_namespace(const char *symname, const char *namespace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct symbol *s = find_symbol(symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * That symbol should have been created earlier and thus this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * actually an assertion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (!s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) error("Could not update namespace(%s) for symbol %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) namespace, symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) free(s->namespace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) s->namespace =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) namespace && namespace[0] ? NOFAIL(strdup(namespace)) : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * Add an exported symbol - it may have already been added without a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) * CRC, in this case just update the CRC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) static struct symbol *sym_add_exported(const char *name, struct module *mod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) enum export export)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct symbol *s = find_symbol(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (!s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) s = new_symbol(name, mod, export);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) } else if (!external_module || s->module->is_vmlinux ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) s->module == mod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) fatal("%s: '%s' exported twice. Previous export was in %s%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) mod->name, name, s->module->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) s->module->is_vmlinux ? "" : ".ko");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) s->module = mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) s->export = export;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static void sym_set_crc(const char *name, unsigned int crc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) struct symbol *s = find_symbol(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * Ignore stand-alone __crc_*, which might be auto-generated symbols
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) * such as __*_veneer in ARM ELF.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (!s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) s->crc = crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) s->crc_valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) static void *grab_file(const char *filename, size_t *size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct stat st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) void *map = MAP_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) fd = open(filename, O_RDONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (fstat(fd, &st))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) *size = st.st_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (map == MAP_FAILED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static void release_file(void *file, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) munmap(file, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) static int parse_elf(struct elf_info *info, const char *filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) Elf_Ehdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) Elf_Shdr *sechdrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) Elf_Sym *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) const char *secstrings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) unsigned int symtab_idx = ~0U, symtab_shndx_idx = ~0U;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) hdr = grab_file(filename, &info->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (!hdr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (ignore_missing_files) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) fprintf(stderr, "%s: %s (ignored)\n", filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) perror(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) info->hdr = hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (info->size < sizeof(*hdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /* file too small, assume this is an empty .o file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) /* Is this a valid ELF file? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if ((hdr->e_ident[EI_MAG0] != ELFMAG0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) (hdr->e_ident[EI_MAG1] != ELFMAG1) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) (hdr->e_ident[EI_MAG2] != ELFMAG2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) (hdr->e_ident[EI_MAG3] != ELFMAG3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /* Not an ELF file - silently ignore it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /* Fix endianness in ELF header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) hdr->e_type = TO_NATIVE(hdr->e_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) hdr->e_machine = TO_NATIVE(hdr->e_machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) hdr->e_version = TO_NATIVE(hdr->e_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) hdr->e_entry = TO_NATIVE(hdr->e_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) hdr->e_phoff = TO_NATIVE(hdr->e_phoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) hdr->e_shoff = TO_NATIVE(hdr->e_shoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) hdr->e_flags = TO_NATIVE(hdr->e_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) hdr->e_ehsize = TO_NATIVE(hdr->e_ehsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) hdr->e_phentsize = TO_NATIVE(hdr->e_phentsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) hdr->e_phnum = TO_NATIVE(hdr->e_phnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) hdr->e_shentsize = TO_NATIVE(hdr->e_shentsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) hdr->e_shnum = TO_NATIVE(hdr->e_shnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) sechdrs = (void *)hdr + hdr->e_shoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) info->sechdrs = sechdrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) /* Check if file offset is correct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (hdr->e_shoff > info->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) fatal("section header offset=%lu in file '%s' is bigger than filesize=%zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) (unsigned long)hdr->e_shoff, filename, info->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (hdr->e_shnum == SHN_UNDEF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * There are more than 64k sections,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * read count from .sh_size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) info->num_sections = TO_NATIVE(sechdrs[0].sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) info->num_sections = hdr->e_shnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (hdr->e_shstrndx == SHN_XINDEX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) info->secindex_strings = TO_NATIVE(sechdrs[0].sh_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) info->secindex_strings = hdr->e_shstrndx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) /* Fix endianness in section headers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) for (i = 0; i < info->num_sections; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) sechdrs[i].sh_flags = TO_NATIVE(sechdrs[i].sh_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) sechdrs[i].sh_addr = TO_NATIVE(sechdrs[i].sh_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) sechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) sechdrs[i].sh_info = TO_NATIVE(sechdrs[i].sh_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) sechdrs[i].sh_addralign = TO_NATIVE(sechdrs[i].sh_addralign);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) sechdrs[i].sh_entsize = TO_NATIVE(sechdrs[i].sh_entsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /* Find symbol table. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) secstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) for (i = 1; i < info->num_sections; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) const char *secname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) int nobits = sechdrs[i].sh_type == SHT_NOBITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (!nobits && sechdrs[i].sh_offset > info->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) fatal("%s is truncated. sechdrs[i].sh_offset=%lu > "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) "sizeof(*hrd)=%zu\n", filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) (unsigned long)sechdrs[i].sh_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) sizeof(*hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) secname = secstrings + sechdrs[i].sh_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (strcmp(secname, ".modinfo") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (nobits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) fatal("%s has NOBITS .modinfo\n", filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) info->modinfo_len = sechdrs[i].sh_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) } else if (strcmp(secname, "__ksymtab") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) info->export_sec = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) else if (strcmp(secname, "__ksymtab_unused") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) info->export_unused_sec = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) else if (strcmp(secname, "__ksymtab_gpl") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) info->export_gpl_sec = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) else if (strcmp(secname, "__ksymtab_unused_gpl") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) info->export_unused_gpl_sec = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) info->export_gpl_future_sec = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (sechdrs[i].sh_type == SHT_SYMTAB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) unsigned int sh_link_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) symtab_idx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) info->symtab_start = (void *)hdr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) sechdrs[i].sh_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) info->symtab_stop = (void *)hdr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) sechdrs[i].sh_offset + sechdrs[i].sh_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) sh_link_idx = sechdrs[i].sh_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) info->strtab = (void *)hdr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) sechdrs[sh_link_idx].sh_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) /* 32bit section no. table? ("more than 64k sections") */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (sechdrs[i].sh_type == SHT_SYMTAB_SHNDX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) symtab_shndx_idx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) info->symtab_shndx_start = (void *)hdr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) sechdrs[i].sh_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) info->symtab_shndx_stop = (void *)hdr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) sechdrs[i].sh_offset + sechdrs[i].sh_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (!info->symtab_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) fatal("%s has no symtab?\n", filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) /* Fix endianness in symbols */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) for (sym = info->symtab_start; sym < info->symtab_stop; sym++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) sym->st_shndx = TO_NATIVE(sym->st_shndx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) sym->st_name = TO_NATIVE(sym->st_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) sym->st_value = TO_NATIVE(sym->st_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) sym->st_size = TO_NATIVE(sym->st_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (symtab_shndx_idx != ~0U) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) Elf32_Word *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (symtab_idx != sechdrs[symtab_shndx_idx].sh_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) filename, sechdrs[symtab_shndx_idx].sh_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) symtab_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) /* Fix endianness */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) p++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) *p = TO_NATIVE(*p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) static void parse_elf_finish(struct elf_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) release_file(info->hdr, info->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) static int ignore_undef_symbol(struct elf_info *info, const char *symname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) /* ignore __this_module, it will be resolved shortly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (strcmp(symname, "__this_module") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) /* ignore global offset table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (info->hdr->e_machine == EM_PPC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) /* Special register function linked on all modules during final link of .ko */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (strstarts(symname, "_restgpr_") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) strstarts(symname, "_savegpr_") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) strstarts(symname, "_rest32gpr_") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) strstarts(symname, "_save32gpr_") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) strstarts(symname, "_restvr_") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) strstarts(symname, "_savevr_"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) if (info->hdr->e_machine == EM_PPC64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) /* Special register function linked on all modules during final link of .ko */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (strstarts(symname, "_restgpr0_") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) strstarts(symname, "_savegpr0_") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) strstarts(symname, "_restvr_") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) strstarts(symname, "_savevr_") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) strcmp(symname, ".TOC.") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) /* Do not ignore this symbol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) static void handle_modversion(const struct module *mod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) const struct elf_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) const Elf_Sym *sym, const char *symname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) unsigned int crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (sym->st_shndx == SHN_UNDEF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) symname, mod->name, mod->is_vmlinux ? "" : ".ko");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (sym->st_shndx == SHN_ABS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) crc = sym->st_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) unsigned int *crcp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) /* symbol points to the CRC in the ELF object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) crcp = sym_get_data(info, sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) crc = TO_NATIVE(*crcp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) sym_set_crc(symname, crc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) static void handle_symbol(struct module *mod, struct elf_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) const Elf_Sym *sym, const char *symname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) enum export export;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (strstarts(symname, "__ksymtab"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) export = export_from_secname(info, get_secindex(info, sym));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) export = export_from_sec(info, get_secindex(info, sym));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) switch (sym->st_shndx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) case SHN_COMMON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (strstarts(symname, "__gnu_lto_")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) /* Should warn here, but modpost runs before the linker */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) case SHN_UNDEF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) /* undefined symbol */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) ELF_ST_BIND(sym->st_info) != STB_WEAK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if (ignore_undef_symbol(info, symname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (info->hdr->e_machine == EM_SPARC ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) info->hdr->e_machine == EM_SPARCV9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /* Ignore register directives. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (symname[0] == '.') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) char *munged = NOFAIL(strdup(symname));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) munged[0] = '_';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) munged[1] = toupper(munged[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) symname = munged;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) mod->unres = alloc_symbol(symname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) ELF_ST_BIND(sym->st_info) == STB_WEAK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) mod->unres);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) /* All exported symbols */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (strstarts(symname, "__ksymtab_")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) name = symname + strlen("__ksymtab_");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) sym_add_exported(name, mod, export);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (strcmp(symname, "init_module") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) mod->has_init = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (strcmp(symname, "cleanup_module") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) mod->has_cleanup = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) * Parse tag=value strings from .modinfo section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) static char *next_string(char *string, unsigned long *secsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) /* Skip non-zero chars */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) while (string[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) string++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if ((*secsize)-- <= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) /* Skip any zero padding. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) while (!string[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) string++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if ((*secsize)-- <= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) static char *get_next_modinfo(struct elf_info *info, const char *tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) char *prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) unsigned int taglen = strlen(tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) char *modinfo = info->modinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) unsigned long size = info->modinfo_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (prev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) size -= prev - modinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) modinfo = next_string(prev, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) for (p = modinfo; p; p = next_string(p, &size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) return p + taglen + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) static char *get_modinfo(struct elf_info *info, const char *tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return get_next_modinfo(info, tag, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) * Test if string s ends in string sub
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) * return 0 if match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) static int strrcmp(const char *s, const char *sub)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) int slen, sublen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (!s || !sub)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) slen = strlen(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) sublen = strlen(sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if ((slen == 0) || (sublen == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (sublen > slen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return memcmp(s + slen - sublen, sub, sublen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) return elf->strtab + sym->st_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) return "(unknown)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) /* The pattern is an array of simple patterns.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * "foo" will match an exact string equal to "foo"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * "*foo" will match a string that ends with "foo"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) * "foo*" will match a string that begins with "foo"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) * "*foo*" will match a string that contains "foo"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) static int match(const char *sym, const char * const pat[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) const char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) while (*pat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) p = *pat++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) const char *endp = p + strlen(p) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) /* "*foo*" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) if (*p == '*' && *endp == '*') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) char *bare = NOFAIL(strndup(p + 1, strlen(p) - 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) char *here = strstr(sym, bare);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) free(bare);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) if (here != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) /* "*foo" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) else if (*p == '*') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (strrcmp(sym, p + 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) /* "foo*" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) else if (*endp == '*') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) if (strncmp(sym, p, strlen(p) - 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) /* no wildcards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (strcmp(p, sym) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) /* no match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) /* sections that we do not want to do full section mismatch check on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) static const char *const section_white_list[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) ".comment*",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) ".debug*",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) ".cranges", /* sh64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) ".zdebug*", /* Compressed debug sections. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) ".GCC.command.line", /* record-gcc-switches */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) ".mdebug*", /* alpha, score, mips etc. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) ".pdr", /* alpha, score, mips etc. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) ".stab*",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) ".note*",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) ".got*",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) ".toc*",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) ".xt.prop", /* xtensa */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) ".xt.lit", /* xtensa */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) ".arcextmap*", /* arc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) ".gnu.linkonce.arcext*", /* arc : modules */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) ".cmem*", /* EZchip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) ".fmt_slot*", /* EZchip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) ".gnu.lto*",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) ".discard.*",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) * This is used to find sections missing the SHF_ALLOC flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) * The cause of this is often a section specified in assembler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) * without "ax" / "aw".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) static void check_section(const char *modname, struct elf_info *elf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) Elf_Shdr *sechdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) const char *sec = sech_name(elf, sechdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) if (sechdr->sh_type == SHT_PROGBITS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) !(sechdr->sh_flags & SHF_ALLOC) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) !match(sec, section_white_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) warn("%s (%s): unexpected non-allocatable section.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) "Did you forget to use \"ax\"/\"aw\" in a .S file?\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) "Note that for example <linux/init.h> contains\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) "section definitions for use in .S files.\n\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) modname, sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) #define ALL_INIT_DATA_SECTIONS \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) ".init.setup", ".init.rodata", ".meminit.rodata", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) ".init.data", ".meminit.data"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) #define ALL_EXIT_DATA_SECTIONS \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) ".exit.data", ".memexit.data"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) #define ALL_INIT_TEXT_SECTIONS \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) ".init.text", ".meminit.text"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) #define ALL_EXIT_TEXT_SECTIONS \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) ".exit.text", ".memexit.text"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) #define ALL_PCI_INIT_SECTIONS \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) ".pci_fixup_early", ".pci_fixup_header", ".pci_fixup_final", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) ".pci_fixup_enable", ".pci_fixup_resume", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) ".pci_fixup_resume_early", ".pci_fixup_suspend"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) #define ALL_XXXINIT_SECTIONS MEM_INIT_SECTIONS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) #define ALL_XXXEXIT_SECTIONS MEM_EXIT_SECTIONS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) #define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) #define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) #define DATA_SECTIONS ".data", ".data.rel"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) #define TEXT_SECTIONS ".text", ".text.unlikely", ".sched.text", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) ".kprobes.text", ".cpuidle.text", ".noinstr.text"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) #define OTHER_TEXT_SECTIONS ".ref.text", ".head.text", ".spinlock.text", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) ".fixup", ".entry.text", ".exception.text", ".text.*", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) ".coldtext"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) #define INIT_SECTIONS ".init.*"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) #define MEM_INIT_SECTIONS ".meminit.*"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) #define EXIT_SECTIONS ".exit.*"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) #define MEM_EXIT_SECTIONS ".memexit.*"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) #define ALL_TEXT_SECTIONS ALL_INIT_TEXT_SECTIONS, ALL_EXIT_TEXT_SECTIONS, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) TEXT_SECTIONS, OTHER_TEXT_SECTIONS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) /* init data sections */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) static const char *const init_data_sections[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) { ALL_INIT_DATA_SECTIONS, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) /* all init sections */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) static const char *const init_sections[] = { ALL_INIT_SECTIONS, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) /* All init and exit sections (code + data) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) static const char *const init_exit_sections[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) {ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) /* all text sections */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) static const char *const text_sections[] = { ALL_TEXT_SECTIONS, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) /* data section */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) static const char *const data_sections[] = { DATA_SECTIONS, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) /* symbols in .data that may refer to init/exit sections */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) #define DEFAULT_SYMBOL_WHITE_LIST \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) "*driver", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) "*_template", /* scsi uses *_template a lot */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) "*_timer", /* arm uses ops structures named _timer a lot */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) "*_sht", /* scsi also used *_sht to some extent */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) "*_ops", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) "*_probe", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) "*_probe_one", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) "*_console"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) static const char *const head_sections[] = { ".head.text*", NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) static const char *const linker_symbols[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) { "__init_begin", "_sinittext", "_einittext", NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) static const char *const optim_symbols[] = { "*.constprop.*", NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) enum mismatch {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) TEXT_TO_ANY_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) DATA_TO_ANY_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) TEXT_TO_ANY_EXIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) DATA_TO_ANY_EXIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) XXXINIT_TO_SOME_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) XXXEXIT_TO_SOME_EXIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) ANY_INIT_TO_ANY_EXIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) ANY_EXIT_TO_ANY_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) EXPORT_TO_INIT_EXIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) EXTABLE_TO_NON_TEXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) * Describe how to match sections on different criterias:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) * @fromsec: Array of sections to be matched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) * @bad_tosec: Relocations applied to a section in @fromsec to a section in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) * this array is forbidden (black-list). Can be empty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) * @good_tosec: Relocations applied to a section in @fromsec must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) * targetting sections in this array (white-list). Can be empty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) * @mismatch: Type of mismatch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) * @symbol_white_list: Do not match a relocation to a symbol in this list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) * even if it is targetting a section in @bad_to_sec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) * @handler: Specific handler to call when a match is found. If NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) * default_mismatch_handler() will be called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) struct sectioncheck {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) const char *fromsec[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) const char *bad_tosec[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) const char *good_tosec[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) enum mismatch mismatch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) const char *symbol_white_list[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) void (*handler)(const char *modname, struct elf_info *elf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) const struct sectioncheck* const mismatch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) Elf_Rela *r, Elf_Sym *sym, const char *fromsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) static void extable_mismatch_handler(const char *modname, struct elf_info *elf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) const struct sectioncheck* const mismatch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) Elf_Rela *r, Elf_Sym *sym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) const char *fromsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) static const struct sectioncheck sectioncheck[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) /* Do not reference init/exit code/data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) * normal code and data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) .fromsec = { TEXT_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) .bad_tosec = { ALL_INIT_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) .mismatch = TEXT_TO_ANY_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) .fromsec = { DATA_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) .bad_tosec = { ALL_XXXINIT_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) .mismatch = DATA_TO_ANY_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) .fromsec = { DATA_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) .bad_tosec = { INIT_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) .mismatch = DATA_TO_ANY_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) .symbol_white_list = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) "*_template", "*_timer", "*_sht", "*_ops",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) "*_probe", "*_probe_one", "*_console", NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) .fromsec = { TEXT_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) .mismatch = TEXT_TO_ANY_EXIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) .fromsec = { DATA_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) .mismatch = DATA_TO_ANY_EXIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) /* Do not reference init code/data from meminit code/data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) .fromsec = { ALL_XXXINIT_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) .bad_tosec = { INIT_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) .mismatch = XXXINIT_TO_SOME_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) /* Do not reference exit code/data from memexit code/data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) .fromsec = { ALL_XXXEXIT_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) .bad_tosec = { EXIT_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) .mismatch = XXXEXIT_TO_SOME_EXIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) /* Do not use exit code/data from init code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) .fromsec = { ALL_INIT_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) .mismatch = ANY_INIT_TO_ANY_EXIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) /* Do not use init code/data from exit code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) .fromsec = { ALL_EXIT_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) .bad_tosec = { ALL_INIT_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) .mismatch = ANY_EXIT_TO_ANY_INIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) .fromsec = { ALL_PCI_INIT_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) .bad_tosec = { INIT_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) .mismatch = ANY_INIT_TO_ANY_EXIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) .symbol_white_list = { NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) /* Do not export init/exit functions or data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) .fromsec = { "__ksymtab*", NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) .bad_tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) .mismatch = EXPORT_TO_INIT_EXIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) .fromsec = { "__ex_table", NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) /* If you're adding any new black-listed sections in here, consider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * adding a special 'printer' for them in scripts/check_extable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) .bad_tosec = { ".altinstr_replacement", NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) .good_tosec = {ALL_TEXT_SECTIONS , NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) .mismatch = EXTABLE_TO_NON_TEXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) .handler = extable_mismatch_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) static const struct sectioncheck *section_mismatch(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) const char *fromsec, const char *tosec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) const struct sectioncheck *check = §ioncheck[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) * The target section could be the SHT_NUL section when we're
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) * handling relocations to un-resolved symbols, trying to match it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) * doesn't make much sense and causes build failures on parisc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) * architectures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (*tosec == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) for (i = 0; i < elems; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) if (match(fromsec, check->fromsec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) if (check->bad_tosec[0] && match(tosec, check->bad_tosec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) return check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) if (check->good_tosec[0] && !match(tosec, check->good_tosec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) return check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) check++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) * Whitelist to allow certain references to pass with no warning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) * Pattern 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) * If a module parameter is declared __initdata and permissions=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) * then this is legal despite the warning generated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) * We cannot see value of permissions here, so just ignore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) * this pattern.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) * The pattern is identified by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) * tosec = .init.data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) * fromsec = .data*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) * atsym =__param*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) * Pattern 1a:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) * module_param_call() ops can refer to __init set function if permissions=0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) * The pattern is identified by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) * tosec = .init.text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) * fromsec = .data*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) * atsym = __param_ops_*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) * Pattern 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) * Many drivers utilise a *driver container with references to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) * add, remove, probe functions etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) * the pattern is identified by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) * tosec = init or exit section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) * fromsec = data section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) * atsym = *driver, *_template, *_sht, *_ops, *_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) * *probe_one, *_console, *_timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) * Pattern 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) * Whitelist all references from .head.text to any init section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) * Pattern 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) * Some symbols belong to init section but still it is ok to reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) * these from non-init sections as these symbols don't have any memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) * allocated for them and symbol address and value are same. So even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) * if init section is freed, its ok to reference those symbols.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) * For ex. symbols marking the init section boundaries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) * This pattern is identified by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) * refsymname = __init_begin, _sinittext, _einittext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) * Pattern 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) * GCC may optimize static inlines when fed constant arg(s) resulting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) * in functions like cpumask_empty() -- generating an associated symbol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) * cpumask_empty.constprop.3 that appears in the audit. If the const that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) * is passed in comes from __init, like say nmi_ipi_mask, we get a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) * meaningless section warning. May need to add isra symbols too...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) * This pattern is identified by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) * tosec = init section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) * fromsec = text section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) * refsymname = *.constprop.*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) * Pattern 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) * Hide section mismatch warnings for ELF local symbols. The goal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) * is to eliminate false positive modpost warnings caused by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) * compiler-generated ELF local symbol names such as ".LANCHOR1".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) * Autogenerated symbol names bypass modpost's "Pattern 2"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) * whitelisting, which relies on pattern-matching against symbol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) * names to work. (One situation where gcc can autogenerate ELF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) * local symbols is when "-fsection-anchors" is used.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) static int secref_whitelist(const struct sectioncheck *mismatch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) const char *fromsec, const char *fromsym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) const char *tosec, const char *tosym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) /* Check for pattern 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) if (match(tosec, init_data_sections) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) match(fromsec, data_sections) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) strstarts(fromsym, "__param"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) /* Check for pattern 1a */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) if (strcmp(tosec, ".init.text") == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) match(fromsec, data_sections) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) strstarts(fromsym, "__param_ops_"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) /* Check for pattern 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) if (match(tosec, init_exit_sections) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) match(fromsec, data_sections) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) match(fromsym, mismatch->symbol_white_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) /* Check for pattern 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) if (match(fromsec, head_sections) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) match(tosec, init_sections))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) /* Check for pattern 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) if (match(tosym, linker_symbols))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) /* Check for pattern 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) if (match(fromsec, text_sections) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) match(tosec, init_sections) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) match(fromsym, optim_symbols))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) /* Check for pattern 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) if (strstarts(fromsym, ".L"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) static inline int is_arm_mapping_symbol(const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) return str[0] == '$' && strchr("axtd", str[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) && (str[2] == '\0' || str[2] == '.');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) * If there's no name there, ignore it; likewise, ignore it if it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) * one of the magic symbols emitted used by current ARM tools.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) * Otherwise if find_symbols_between() returns those symbols, they'll
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) * fail the whitelist tests and cause lots of false alarms ... fixable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) * only by merging __exit and __init sections into __text, bloating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) * the kernel (which is especially evil on embedded platforms).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) const char *name = elf->strtab + sym->st_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (!name || !strlen(name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) return !is_arm_mapping_symbol(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) * Find symbol based on relocation record info.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) * In some cases the symbol supplied is a valid symbol so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) * return refsym. If st_name != 0 we assume this is a valid symbol.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) * In other cases the symbol needs to be looked up in the symbol table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) * based on section and address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) * **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) Elf_Sym *relsym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) Elf_Sym *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) Elf_Sym *near = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) Elf64_Sword distance = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) Elf64_Sword d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) unsigned int relsym_secindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) if (relsym->st_name != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) return relsym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) relsym_secindex = get_secindex(elf, relsym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) if (get_secindex(elf, sym) != relsym_secindex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) if (!is_valid_name(elf, sym))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (sym->st_value == addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) return sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) /* Find a symbol nearby - addr are maybe negative */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) d = sym->st_value - addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) if (d < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) d = addr - sym->st_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) if (d < distance) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) distance = d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) near = sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) /* We need a close match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) if (distance < 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) return near;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) * Find symbols before or equal addr and after addr - in the section sec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) * If we find two symbols with equal offset prefer one with a valid name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) * The ELF format may have a better way to detect what type of symbol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) * it is, but this works for now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) const char *sec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) Elf_Sym *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) Elf_Sym *near = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) Elf_Addr distance = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) const char *symsec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) if (is_shndx_special(sym->st_shndx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) symsec = sec_name(elf, get_secindex(elf, sym));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) if (strcmp(symsec, sec) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) if (!is_valid_name(elf, sym))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) if (sym->st_value <= addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) if ((addr - sym->st_value) < distance) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) distance = addr - sym->st_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) near = sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) } else if ((addr - sym->st_value) == distance) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) near = sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) return near;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) * Convert a section name to the function/data attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) * .init.text => __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) * .memexitconst => __memconst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) * etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) * The memory of returned value has been allocated on a heap. The user of this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) * method should free it after usage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) static char *sec2annotation(const char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) if (match(s, init_exit_sections)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) char *p = NOFAIL(malloc(20));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) char *r = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) *p++ = '_';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) *p++ = '_';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) if (*s == '.')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) while (*s && *s != '.')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) *p++ = *s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) *p = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) if (*s == '.')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) if (strstr(s, "rodata") != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) strcat(p, "const ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) else if (strstr(s, "data") != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) strcat(p, "data ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) strcat(p, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) return NOFAIL(strdup(""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) static int is_function(Elf_Sym *sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) if (sym)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) return ELF_ST_TYPE(sym->st_info) == STT_FUNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) static void print_section_list(const char * const list[20])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) const char *const *s = list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) while (*s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) fprintf(stderr, "%s", *s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) if (*s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) fprintf(stderr, ", ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) fprintf(stderr, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) static inline void get_pretty_name(int is_func, const char** name, const char** name_p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) switch (is_func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) case 0: *name = "variable"; *name_p = ""; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) case 1: *name = "function"; *name_p = "()"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) default: *name = "(unknown reference)"; *name_p = ""; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) * Print a warning about a section mismatch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) * Try to find symbols near it so user can find it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) * Check whitelist before warning - it may be a false positive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) static void report_sec_mismatch(const char *modname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) const struct sectioncheck *mismatch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) const char *fromsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) unsigned long long fromaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) const char *fromsym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) int from_is_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) const char *tosec, const char *tosym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) int to_is_func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) const char *from, *from_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) const char *to, *to_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) char *prl_from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) char *prl_to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) sec_mismatch_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) get_pretty_name(from_is_func, &from, &from_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) get_pretty_name(to_is_func, &to, &to_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) warn("%s(%s+0x%llx): Section mismatch in reference from the %s %s%s "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) "to the %s %s:%s%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) tosym, to_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) switch (mismatch->mismatch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) case TEXT_TO_ANY_INIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) prl_from = sec2annotation(fromsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) prl_to = sec2annotation(tosec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) "The function %s%s() references\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) "the %s %s%s%s.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) "This is often because %s lacks a %s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) "annotation or the annotation of %s is wrong.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) prl_from, fromsym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) to, prl_to, tosym, to_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) fromsym, prl_to, tosym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) free(prl_from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) free(prl_to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) case DATA_TO_ANY_INIT: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) prl_to = sec2annotation(tosec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) "The variable %s references\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) "the %s %s%s%s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) "If the reference is valid then annotate the\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) "variable with __init* or __refdata (see linux/init.h) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) "or name the variable:\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) fromsym, to, prl_to, tosym, to_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) print_section_list(mismatch->symbol_white_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) free(prl_to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) case TEXT_TO_ANY_EXIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) prl_to = sec2annotation(tosec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) "The function %s() references a %s in an exit section.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) "Often the %s %s%s has valid usage outside the exit section\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) "and the fix is to remove the %sannotation of %s.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) fromsym, to, to, tosym, to_p, prl_to, tosym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) free(prl_to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) case DATA_TO_ANY_EXIT: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) prl_to = sec2annotation(tosec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) "The variable %s references\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) "the %s %s%s%s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) "If the reference is valid then annotate the\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) "variable with __exit* (see linux/init.h) or "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) "name the variable:\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) fromsym, to, prl_to, tosym, to_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) print_section_list(mismatch->symbol_white_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) free(prl_to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) case XXXINIT_TO_SOME_INIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) case XXXEXIT_TO_SOME_EXIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) prl_from = sec2annotation(fromsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) prl_to = sec2annotation(tosec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) "The %s %s%s%s references\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) "a %s %s%s%s.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) "If %s is only used by %s then\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) "annotate %s with a matching annotation.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) from, prl_from, fromsym, from_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) to, prl_to, tosym, to_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) tosym, fromsym, tosym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) free(prl_from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) free(prl_to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) case ANY_INIT_TO_ANY_EXIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) prl_from = sec2annotation(fromsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) prl_to = sec2annotation(tosec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) "The %s %s%s%s references\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) "a %s %s%s%s.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) "This is often seen when error handling "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) "in the init function\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) "uses functionality in the exit path.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) "The fix is often to remove the %sannotation of\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) "%s%s so it may be used outside an exit section.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) from, prl_from, fromsym, from_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) to, prl_to, tosym, to_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) prl_to, tosym, to_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) free(prl_from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) free(prl_to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) case ANY_EXIT_TO_ANY_INIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) prl_from = sec2annotation(fromsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) prl_to = sec2annotation(tosec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) "The %s %s%s%s references\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) "a %s %s%s%s.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) "This is often seen when error handling "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) "in the exit function\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) "uses functionality in the init path.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) "The fix is often to remove the %sannotation of\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) "%s%s so it may be used outside an init section.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) from, prl_from, fromsym, from_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) to, prl_to, tosym, to_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) prl_to, tosym, to_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) free(prl_from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) free(prl_to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) case EXPORT_TO_INIT_EXIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) prl_to = sec2annotation(tosec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) "The symbol %s is exported and annotated %s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) "Fix this by removing the %sannotation of %s "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) "or drop the export.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) tosym, prl_to, prl_to, tosym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) free(prl_to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) case EXTABLE_TO_NON_TEXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) fatal("There's a special handler for this mismatch type, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) "we should never get here.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) fprintf(stderr, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) static void default_mismatch_handler(const char *modname, struct elf_info *elf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) const struct sectioncheck* const mismatch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) const char *tosec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) Elf_Sym *to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) Elf_Sym *from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) const char *tosym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) const char *fromsym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) from = find_elf_symbol2(elf, r->r_offset, fromsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) fromsym = sym_name(elf, from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) if (strstarts(fromsym, "reference___initcall"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) tosec = sec_name(elf, get_secindex(elf, sym));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) to = find_elf_symbol(elf, r->r_addend, sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) tosym = sym_name(elf, to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) /* check whitelist - we may ignore it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) if (secref_whitelist(mismatch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) fromsec, fromsym, tosec, tosym)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) report_sec_mismatch(modname, mismatch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) fromsec, r->r_offset, fromsym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) is_function(from), tosec, tosym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) is_function(to));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) static int is_executable_section(struct elf_info* elf, unsigned int section_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) if (section_index > elf->num_sections)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) fatal("section_index is outside elf->num_sections!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) return ((elf->sechdrs[section_index].sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) * We rely on a gross hack in section_rel[a]() calling find_extable_entry_size()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) * to know the sizeof(struct exception_table_entry) for the target architecture.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) static unsigned int extable_entry_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) static void find_extable_entry_size(const char* const sec, const Elf_Rela* r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) * If we're currently checking the second relocation within __ex_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) * that relocation offset tells us the offsetof(struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) * exception_table_entry, fixup) which is equal to sizeof(struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) * exception_table_entry) divided by two. We use that to our advantage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) * since there's no portable way to get that size as every architecture
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) * seems to go with different sized types. Not pretty but better than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) * hard-coding the size for every architecture..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) if (!extable_entry_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) extable_entry_size = r->r_offset * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) static inline bool is_extable_fault_address(Elf_Rela *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) * extable_entry_size is only discovered after we've handled the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) * _second_ relocation in __ex_table, so only abort when we're not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) * handling the first reloc and extable_entry_size is zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) if (r->r_offset && extable_entry_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) fatal("extable_entry size hasn't been discovered!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) return ((r->r_offset == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) (r->r_offset % extable_entry_size == 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) #define is_second_extable_reloc(Start, Cur, Sec) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) (((Cur) == (Start) + 1) && (strcmp("__ex_table", (Sec)) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) static void report_extable_warnings(const char* modname, struct elf_info* elf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) const struct sectioncheck* const mismatch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) Elf_Rela* r, Elf_Sym* sym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) const char* fromsec, const char* tosec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) Elf_Sym* fromsym = find_elf_symbol2(elf, r->r_offset, fromsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) const char* fromsym_name = sym_name(elf, fromsym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) Elf_Sym* tosym = find_elf_symbol(elf, r->r_addend, sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) const char* tosym_name = sym_name(elf, tosym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) const char* from_pretty_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) const char* from_pretty_name_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) const char* to_pretty_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) const char* to_pretty_name_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) get_pretty_name(is_function(fromsym),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) &from_pretty_name, &from_pretty_name_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) get_pretty_name(is_function(tosym),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) &to_pretty_name, &to_pretty_name_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) warn("%s(%s+0x%lx): Section mismatch in reference"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) " from the %s %s%s to the %s %s:%s%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) modname, fromsec, (long)r->r_offset, from_pretty_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) fromsym_name, from_pretty_name_p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) to_pretty_name, tosec, tosym_name, to_pretty_name_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) if (!match(tosec, mismatch->bad_tosec) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) is_executable_section(elf, get_secindex(elf, sym)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) "The relocation at %s+0x%lx references\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) "section \"%s\" which is not in the list of\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) "authorized sections. If you're adding a new section\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) "and/or if this reference is valid, add \"%s\" to the\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) "list of authorized sections to jump to on fault.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) "This can be achieved by adding \"%s\" to \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) "OTHER_TEXT_SECTIONS in scripts/mod/modpost.c.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) fromsec, (long)r->r_offset, tosec, tosec, tosec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) static void extable_mismatch_handler(const char* modname, struct elf_info *elf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) const struct sectioncheck* const mismatch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) Elf_Rela* r, Elf_Sym* sym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) const char *fromsec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) const char* tosec = sec_name(elf, get_secindex(elf, sym));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) sec_mismatch_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) report_extable_warnings(modname, elf, mismatch, r, sym, fromsec, tosec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) if (match(tosec, mismatch->bad_tosec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) fatal("The relocation at %s+0x%lx references\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) "section \"%s\" which is black-listed.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) "Something is seriously wrong and should be fixed.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) "You might get more information about where this is\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) "coming from by using scripts/check_extable.sh %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) fromsec, (long)r->r_offset, tosec, modname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) else if (!is_executable_section(elf, get_secindex(elf, sym))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) if (is_extable_fault_address(r))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) fatal("The relocation at %s+0x%lx references\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) "section \"%s\" which is not executable, IOW\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) "it is not possible for the kernel to fault\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) "at that address. Something is seriously wrong\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) "and should be fixed.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) fromsec, (long)r->r_offset, tosec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) fatal("The relocation at %s+0x%lx references\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) "section \"%s\" which is not executable, IOW\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) "the kernel will fault if it ever tries to\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) "jump to it. Something is seriously wrong\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) "and should be fixed.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) fromsec, (long)r->r_offset, tosec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) static void check_section_mismatch(const char *modname, struct elf_info *elf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) const char *tosec = sec_name(elf, get_secindex(elf, sym));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) const struct sectioncheck *mismatch = section_mismatch(fromsec, tosec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) if (mismatch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) if (mismatch->handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) mismatch->handler(modname, elf, mismatch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) r, sym, fromsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) default_mismatch_handler(modname, elf, mismatch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) r, sym, fromsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) static unsigned int *reloc_location(struct elf_info *elf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) Elf_Shdr *sechdr, Elf_Rela *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) return sym_get_data_by_offset(elf, sechdr->sh_info, r->r_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) unsigned int r_typ = ELF_R_TYPE(r->r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) unsigned int *location = reloc_location(elf, sechdr, r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) switch (r_typ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) case R_386_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) r->r_addend = TO_NATIVE(*location);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) case R_386_PC32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) r->r_addend = TO_NATIVE(*location) + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) /* For CONFIG_RELOCATABLE=y */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) if (elf->hdr->e_type == ET_EXEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) r->r_addend += r->r_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) #ifndef R_ARM_CALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) #define R_ARM_CALL 28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) #ifndef R_ARM_JUMP24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) #define R_ARM_JUMP24 29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) #ifndef R_ARM_THM_CALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) #define R_ARM_THM_CALL 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) #ifndef R_ARM_THM_JUMP24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) #define R_ARM_THM_JUMP24 30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) #ifndef R_ARM_THM_JUMP19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) #define R_ARM_THM_JUMP19 51
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) unsigned int r_typ = ELF_R_TYPE(r->r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) switch (r_typ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) case R_ARM_ABS32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) /* From ARM ABI: (S + A) | T */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) r->r_addend = (int)(long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) (elf->symtab_start + ELF_R_SYM(r->r_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) case R_ARM_PC24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) case R_ARM_CALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) case R_ARM_JUMP24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) case R_ARM_THM_CALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) case R_ARM_THM_JUMP24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) case R_ARM_THM_JUMP19:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) /* From ARM ABI: ((S + A) | T) - P */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) r->r_addend = (int)(long)(elf->hdr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) sechdr->sh_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) (r->r_offset - sechdr->sh_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) unsigned int r_typ = ELF_R_TYPE(r->r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) unsigned int *location = reloc_location(elf, sechdr, r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) unsigned int inst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) if (r_typ == R_MIPS_HI16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) return 1; /* skip this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) inst = TO_NATIVE(*location);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) switch (r_typ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) case R_MIPS_LO16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) r->r_addend = inst & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) case R_MIPS_26:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) r->r_addend = (inst & 0x03ffffff) << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) case R_MIPS_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) r->r_addend = inst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) static void section_rela(const char *modname, struct elf_info *elf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) Elf_Shdr *sechdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) Elf_Sym *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) Elf_Rela *rela;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) Elf_Rela r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) unsigned int r_sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) const char *fromsec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) Elf_Rela *stop = (void *)start + sechdr->sh_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) fromsec = sech_name(elf, sechdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) fromsec += strlen(".rela");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) /* if from section (name) is know good then skip it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) if (match(fromsec, section_white_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) for (rela = start; rela < stop; rela++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) r.r_offset = TO_NATIVE(rela->r_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) #if KERNEL_ELFCLASS == ELFCLASS64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) if (elf->hdr->e_machine == EM_MIPS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) unsigned int r_typ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) r_sym = ELF64_MIPS_R_SYM(rela->r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) r_sym = TO_NATIVE(r_sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) r_typ = ELF64_MIPS_R_TYPE(rela->r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) r.r_info = ELF64_R_INFO(r_sym, r_typ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) r.r_info = TO_NATIVE(rela->r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) r_sym = ELF_R_SYM(r.r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) r.r_info = TO_NATIVE(rela->r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) r_sym = ELF_R_SYM(r.r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) r.r_addend = TO_NATIVE(rela->r_addend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) sym = elf->symtab_start + r_sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) /* Skip special sections */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) if (is_shndx_special(sym->st_shndx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) if (is_second_extable_reloc(start, rela, fromsec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) find_extable_entry_size(fromsec, &r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) check_section_mismatch(modname, elf, &r, sym, fromsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) static void section_rel(const char *modname, struct elf_info *elf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) Elf_Shdr *sechdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) Elf_Sym *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) Elf_Rel *rel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) Elf_Rela r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) unsigned int r_sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) const char *fromsec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) Elf_Rel *stop = (void *)start + sechdr->sh_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) fromsec = sech_name(elf, sechdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) fromsec += strlen(".rel");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) /* if from section (name) is know good then skip it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) if (match(fromsec, section_white_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) for (rel = start; rel < stop; rel++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) r.r_offset = TO_NATIVE(rel->r_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) #if KERNEL_ELFCLASS == ELFCLASS64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) if (elf->hdr->e_machine == EM_MIPS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) unsigned int r_typ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) r_sym = ELF64_MIPS_R_SYM(rel->r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) r_sym = TO_NATIVE(r_sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) r_typ = ELF64_MIPS_R_TYPE(rel->r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) r.r_info = ELF64_R_INFO(r_sym, r_typ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) r.r_info = TO_NATIVE(rel->r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) r_sym = ELF_R_SYM(r.r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) r.r_info = TO_NATIVE(rel->r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) r_sym = ELF_R_SYM(r.r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) r.r_addend = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) switch (elf->hdr->e_machine) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) case EM_386:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) if (addend_386_rel(elf, sechdr, &r))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) case EM_ARM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) if (addend_arm_rel(elf, sechdr, &r))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) case EM_MIPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) if (addend_mips_rel(elf, sechdr, &r))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) sym = elf->symtab_start + r_sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) /* Skip special sections */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) if (is_shndx_special(sym->st_shndx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) if (is_second_extable_reloc(start, rel, fromsec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) find_extable_entry_size(fromsec, &r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) check_section_mismatch(modname, elf, &r, sym, fromsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) * A module includes a number of sections that are discarded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) * either when loaded or when used as built-in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) * For loaded modules all functions marked __init and all data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) * marked __initdata will be discarded when the module has been initialized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) * Likewise for modules used built-in the sections marked __exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) * are discarded because __exit marked function are supposed to be called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) * only when a module is unloaded which never happens for built-in modules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) * The check_sec_ref() function traverses all relocation records
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) * to find all references to a section that reference a section that will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) * be discarded and warns about it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) static void check_sec_ref(struct module *mod, const char *modname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) struct elf_info *elf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) Elf_Shdr *sechdrs = elf->sechdrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) /* Walk through all sections */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) for (i = 0; i < elf->num_sections; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) check_section(modname, elf, &elf->sechdrs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) /* We want to process only relocation sections and not .init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) if (sechdrs[i].sh_type == SHT_RELA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) section_rela(modname, elf, &elf->sechdrs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) else if (sechdrs[i].sh_type == SHT_REL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) section_rel(modname, elf, &elf->sechdrs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) static char *remove_dot(char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) size_t n = strcspn(s, ".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) if (n && s[n]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) size_t m = strspn(s + n + 1, "0123456789");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) if (m && (s[n + m] == '.' || s[n + m] == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) s[n] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) /* strip trailing .lto */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) if (strends(s, ".lto"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) s[strlen(s) - 4] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) return s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) static void read_symbols(const char *modname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) const char *symname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) char *version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) char *license;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) char *namespace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) struct module *mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) struct elf_info info = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) Elf_Sym *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) if (!parse_elf(&info, modname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) char *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) /* strip trailing .o */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) tmp = NOFAIL(strdup(modname));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) tmp[strlen(tmp) - 2] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) /* strip trailing .lto */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) if (strends(tmp, ".lto"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) tmp[strlen(tmp) - 4] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) mod = new_module(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) free(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) if (!mod->is_vmlinux) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) license = get_modinfo(&info, "license");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) if (!license)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) error("missing MODULE_LICENSE() in %s\n", modname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) while (license) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) if (license_is_gpl_compatible(license))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) mod->gpl_compatible = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) mod->gpl_compatible = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) license = get_next_modinfo(&info, "license", license);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) namespace = get_modinfo(&info, "import_ns");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) while (namespace) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) add_namespace(&mod->imported_namespaces, namespace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) namespace = get_next_modinfo(&info, "import_ns",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) namespace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) symname = remove_dot(info.strtab + sym->st_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) handle_symbol(mod, &info, sym, symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) handle_moddevtable(mod, &info, sym, symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) symname = remove_dot(info.strtab + sym->st_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) /* Apply symbol namespaces from __kstrtabns_<symbol> entries. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) if (strstarts(symname, "__kstrtabns_"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) sym_update_namespace(symname + strlen("__kstrtabns_"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) namespace_from_kstrtabns(&info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) sym));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) if (strstarts(symname, "__crc_"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) handle_modversion(mod, &info, sym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) symname + strlen("__crc_"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) // check for static EXPORT_SYMBOL_* functions && global vars
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) unsigned char bind = ELF_ST_BIND(sym->st_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) if (bind == STB_GLOBAL || bind == STB_WEAK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) struct symbol *s =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) find_symbol(remove_dot(info.strtab +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) sym->st_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) if (s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) s->is_static = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) check_sec_ref(mod, modname, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) if (!mod->is_vmlinux) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) version = get_modinfo(&info, "version");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) if (version || all_versions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) get_src_version(modname, mod->srcversion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) sizeof(mod->srcversion) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) parse_elf_finish(&info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) /* Our trick to get versioning for module struct etc. - it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) * never passed as an argument to an exported function, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) * the automatic versioning doesn't pick it up, but it's really
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) * important anyhow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) if (modversions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) mod->unres = alloc_symbol("module_layout", 0, mod->unres);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) static void read_symbols_from_files(const char *filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) FILE *in = stdin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) char fname[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) if (strcmp(filename, "-") != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) in = fopen(filename, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) if (!in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) fatal("Can't open filenames file %s: %m", filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) while (fgets(fname, PATH_MAX, in) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) if (strends(fname, "\n"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) fname[strlen(fname)-1] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) read_symbols(fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) if (in != stdin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) fclose(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) #define SZ 500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) /* We first write the generated file into memory using the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) * following helper, then compare to the file on disk and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) * only update the later if anything changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) char tmp[SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) va_list ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) va_start(ap, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) len = vsnprintf(tmp, SZ, fmt, ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) buf_write(buf, tmp, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) va_end(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) void buf_write(struct buffer *buf, const char *s, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) if (buf->size - buf->pos < len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) buf->size += len + SZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) buf->p = NOFAIL(realloc(buf->p, buf->size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) strncpy(buf->p + buf->pos, s, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) buf->pos += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) static void check_for_gpl_usage(enum export exp, const char *m, const char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) switch (exp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) case export_gpl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) error("GPL-incompatible module %s.ko uses GPL-only symbol '%s'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) m, s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) case export_unused_gpl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) error("GPL-incompatible module %s.ko uses GPL-only symbol marked UNUSED '%s'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) m, s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) case export_gpl_future:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) warn("GPL-incompatible module %s.ko uses future GPL-only symbol '%s'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) m, s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) case export_plain:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) case export_unused:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) case export_unknown:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) /* ignore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) static void check_for_unused(enum export exp, const char *m, const char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) switch (exp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) case export_unused:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) case export_unused_gpl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) warn("module %s.ko uses symbol '%s' marked UNUSED\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) m, s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) /* ignore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) static void check_exports(struct module *mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) struct symbol *s, *exp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) for (s = mod->unres; s; s = s->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) const char *basename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) exp = find_symbol(s->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) if (!exp || exp->module == mod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) if (have_vmlinux && !s->weak)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) modpost_log(warn_unresolved ? LOG_WARN : LOG_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) "\"%s\" [%s.ko] undefined!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) s->name, mod->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) basename = strrchr(mod->name, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) if (basename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) basename++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) basename = mod->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) if (exp->namespace &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) !module_imports_namespace(mod, exp->namespace)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) modpost_log(allow_missing_ns_imports ? LOG_WARN : LOG_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) "module %s uses symbol %s from namespace %s, but does not import it.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) basename, exp->name, exp->namespace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) add_namespace(&mod->missing_namespaces, exp->namespace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) if (!mod->gpl_compatible)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) check_for_gpl_usage(exp->export, basename, exp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) check_for_unused(exp->export, basename, exp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) static void check_modname_len(struct module *mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) const char *mod_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) mod_name = strrchr(mod->name, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) if (mod_name == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) mod_name = mod->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) mod_name++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) if (strlen(mod_name) >= MODULE_NAME_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) error("module name is too long [%s.ko]\n", mod->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) * Header for the generated file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) static void add_header(struct buffer *b, struct module *mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) buf_printf(b, "#include <linux/module.h>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) * Include build-salt.h after module.h in order to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) * inherit the definitions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) buf_printf(b, "#define INCLUDE_VERMAGIC\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) buf_printf(b, "#include <linux/build-salt.h>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) buf_printf(b, "#include <linux/vermagic.h>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) buf_printf(b, "#include <linux/compiler.h>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) buf_printf(b, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) buf_printf(b, "BUILD_SALT;\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) buf_printf(b, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) buf_printf(b, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) buf_printf(b, "__visible struct module __this_module\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) buf_printf(b, "__section(\".gnu.linkonce.this_module\") = {\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) buf_printf(b, "\t.name = KBUILD_MODNAME,\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) if (mod->has_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) buf_printf(b, "\t.init = init_module,\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) if (mod->has_cleanup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) "\t.exit = cleanup_module,\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) "#endif\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) buf_printf(b, "\t.arch = MODULE_ARCH_INIT,\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) buf_printf(b, "};\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) static void add_intree_flag(struct buffer *b, int is_intree)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) if (is_intree)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) * add_scmversion() - Adds the MODULE_INFO macro for the scmversion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) * @b: Buffer to append to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) * This function fills in the module attribute `scmversion` for the kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) * module. This is useful for determining a given module's SCM version on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) * device via /sys/modules/<module>/scmversion and/or using the modinfo tool.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) static void add_scmversion(struct buffer *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) if (module_scmversion[0] != '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) buf_printf(b, "\nMODULE_INFO(scmversion, \"%s\");\n", module_scmversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) /* Cannot check for assembler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) static void add_retpoline(struct buffer *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) buf_printf(b, "\n#ifdef CONFIG_RETPOLINE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) buf_printf(b, "MODULE_INFO(retpoline, \"Y\");\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) buf_printf(b, "#endif\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) static void add_staging_flag(struct buffer *b, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) if (strstarts(name, "drivers/staging"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) * Record CRCs for unresolved symbols
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) static void add_versions(struct buffer *b, struct module *mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) struct symbol *s, *exp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) for (s = mod->unres; s; s = s->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) exp = find_symbol(s->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) if (!exp || exp->module == mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) s->module = exp->module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) s->crc_valid = exp->crc_valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) s->crc = exp->crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) if (!modversions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) buf_printf(b, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) buf_printf(b, "static const struct modversion_info ____versions[]\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) buf_printf(b, "__used __section(\"__versions\") = {\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) for (s = mod->unres; s; s = s->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) if (!s->module)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) if (!s->crc_valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) warn("\"%s\" [%s.ko] has no CRC!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) s->name, mod->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) if (strlen(s->name) >= MODULE_NAME_LEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) error("too long symbol \"%s\" [%s.ko]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) s->name, mod->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) buf_printf(b, "\t{ %#8x, \"%s\" },\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) s->crc, s->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) buf_printf(b, "};\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) static void add_depends(struct buffer *b, struct module *mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) struct symbol *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) int first = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) /* Clear ->seen flag of modules that own symbols needed by this. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) for (s = mod->unres; s; s = s->next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) if (s->module)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) s->module->seen = s->module->is_vmlinux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) buf_printf(b, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) buf_printf(b, "MODULE_INFO(depends, \"");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) for (s = mod->unres; s; s = s->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) const char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) if (!s->module)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) if (s->module->seen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) s->module->seen = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) p = strrchr(s->module->name, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) if (p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) p = s->module->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) buf_printf(b, "%s%s", first ? "" : ",", p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) first = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) buf_printf(b, "\");\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) static void add_srcversion(struct buffer *b, struct module *mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) if (mod->srcversion[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) buf_printf(b, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) mod->srcversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) static void write_buf(struct buffer *b, const char *fname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) FILE *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) file = fopen(fname, "w");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) if (!file) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) perror(fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) if (fwrite(b->p, 1, b->pos, file) != b->pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) perror(fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) if (fclose(file) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) perror(fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) static void write_if_changed(struct buffer *b, const char *fname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) char *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) FILE *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) struct stat st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) file = fopen(fname, "r");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) if (!file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) goto write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) if (fstat(fileno(file), &st) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) goto close_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) if (st.st_size != b->pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) goto close_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) tmp = NOFAIL(malloc(b->pos));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) if (fread(tmp, 1, b->pos, file) != b->pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) goto free_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) if (memcmp(tmp, b->p, b->pos) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) goto free_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) free(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) fclose(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) free_write:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) free(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) close_write:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) fclose(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) write:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) write_buf(b, fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) /* parse Module.symvers file. line format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) * 0x12345678<tab>symbol<tab>module<tab>export<tab>namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) static void read_dump(const char *fname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) char *buf, *pos, *line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) buf = read_text_file(fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) /* No symbol versions, silently ignore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) pos = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) while ((line = get_line(&pos))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) char *symname, *namespace, *modname, *d, *export;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) unsigned int crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) struct module *mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) struct symbol *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) if (!(symname = strchr(line, '\t')))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) *symname++ = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) if (!(modname = strchr(symname, '\t')))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) *modname++ = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) if (!(export = strchr(modname, '\t')))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) *export++ = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) if (!(namespace = strchr(export, '\t')))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) *namespace++ = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) crc = strtoul(line, &d, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) if (*symname == '\0' || *modname == '\0' || *d != '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) mod = find_module(modname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) if (!mod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) mod = new_module(modname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) mod->from_dump = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) s = sym_add_exported(symname, mod, export_no(export));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) s->is_static = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) sym_set_crc(symname, crc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) sym_update_namespace(symname, namespace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) free(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) free(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) fatal("parse error in symbol dump file\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) static void write_dump(const char *fname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) struct buffer buf = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) struct symbol *symbol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) const char *namespace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) symbol = symbolhash[n];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) while (symbol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) if (!symbol->module->from_dump) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) namespace = symbol->namespace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) buf_printf(&buf, "0x%08x\t%s\t%s\t%s\t%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) symbol->crc, symbol->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) symbol->module->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) export_str(symbol->export),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) namespace ? namespace : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) symbol = symbol->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) write_buf(&buf, fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) free(buf.p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) static void write_namespace_deps_files(const char *fname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) struct module *mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) struct namespace_list *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) struct buffer ns_deps_buf = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) for (mod = modules; mod; mod = mod->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) if (mod->from_dump || !mod->missing_namespaces)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) buf_printf(&ns_deps_buf, "%s.ko:", mod->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) for (ns = mod->missing_namespaces; ns; ns = ns->next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) buf_printf(&ns_deps_buf, " %s", ns->namespace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) buf_printf(&ns_deps_buf, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) write_if_changed(&ns_deps_buf, fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) free(ns_deps_buf.p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) struct dump_list {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) struct dump_list *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) const char *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) int main(int argc, char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) struct module *mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) struct buffer buf = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) char *missing_namespace_deps = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) char *dump_write = NULL, *files_source = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) int opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) struct dump_list *dump_read_start = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) struct dump_list **dump_read_iter = &dump_read_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) while ((opt = getopt(argc, argv, "ei:mnT:o:awENd:v:")) != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) switch (opt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) case 'e':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) external_module = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) case 'i':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) *dump_read_iter =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) NOFAIL(calloc(1, sizeof(**dump_read_iter)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) (*dump_read_iter)->file = optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) dump_read_iter = &(*dump_read_iter)->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) case 'm':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) modversions = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) case 'n':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) ignore_missing_files = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) case 'o':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) dump_write = optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) case 'a':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) all_versions = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) case 'T':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) files_source = optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) case 'w':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) warn_unresolved = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) case 'E':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) sec_mismatch_warn_only = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) case 'N':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) allow_missing_ns_imports = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) case 'd':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) missing_namespace_deps = optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) case 'v':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) strncpy(module_scmversion, optarg, sizeof(module_scmversion) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) exit(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) while (dump_read_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) struct dump_list *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) read_dump(dump_read_start->file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) tmp = dump_read_start->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) free(dump_read_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) dump_read_start = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) while (optind < argc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) read_symbols(argv[optind++]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) if (files_source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) read_symbols_from_files(files_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) * When there's no vmlinux, don't print warnings about
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) * unresolved symbols (since there'll be too many ;)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) if (!have_vmlinux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) warn("Symbol info of vmlinux is missing. Unresolved symbol check will be entirely skipped.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) for (mod = modules; mod; mod = mod->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) char fname[PATH_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) if (mod->is_vmlinux || mod->from_dump)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) buf.pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) check_modname_len(mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) check_exports(mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) add_header(&buf, mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) add_intree_flag(&buf, !external_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) add_retpoline(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) add_staging_flag(&buf, mod->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) add_versions(&buf, mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) add_depends(&buf, mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) add_moddevtable(&buf, mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) add_srcversion(&buf, mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) add_scmversion(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) sprintf(fname, "%s.mod.c", mod->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) write_if_changed(&buf, fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) if (missing_namespace_deps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) write_namespace_deps_files(missing_namespace_deps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) if (dump_write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) write_dump(dump_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) if (sec_mismatch_count && !sec_mismatch_warn_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) error("Section mismatches detected.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) "Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) for (n = 0; n < SYMBOL_HASH_SIZE; n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) struct symbol *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) for (s = symbolhash[n]; s; s = s->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) if (s->is_static)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) error("\"%s\" [%s] is a static %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) s->name, s->module->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) export_str(s->export));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) free(buf.p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) return error_occurred ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) }