diff options
Diffstat (limited to 'scripts/mod')
-rw-r--r-- | scripts/mod/Makefile | 2 | ||||
-rw-r--r-- | scripts/mod/file2alias.c | 95 | ||||
-rw-r--r-- | scripts/mod/mk_elfconfig.c | 9 | ||||
-rw-r--r-- | scripts/mod/modpost.c | 177 | ||||
-rw-r--r-- | scripts/mod/modpost.h | 3 |
5 files changed, 94 insertions, 192 deletions
diff --git a/scripts/mod/Makefile b/scripts/mod/Makefile index 11d69c35e5b..ff954f8168c 100644 --- a/scripts/mod/Makefile +++ b/scripts/mod/Makefile @@ -8,7 +8,7 @@ modpost-objs := modpost.o file2alias.o sumversion.o $(obj)/modpost.o $(obj)/file2alias.o $(obj)/sumversion.o: $(obj)/elfconfig.h quiet_cmd_elfconfig = MKELF $@ - cmd_elfconfig = $(obj)/mk_elfconfig $(ARCH) < $< > $@ + cmd_elfconfig = $(obj)/mk_elfconfig < $< > $@ $(obj)/elfconfig.h: $(obj)/empty.o $(obj)/mk_elfconfig FORCE $(call if_changed,elfconfig) diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 62a9025cdcc..6f426afbc52 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -104,7 +104,7 @@ static void device_id_check(const char *modname, const char *device_id, static void do_usb_entry(struct usb_device_id *id, unsigned int bcdDevice_initial, int bcdDevice_initial_digits, unsigned char range_lo, unsigned char range_hi, - struct module *mod) + unsigned char max, struct module *mod) { char alias[500]; strcpy(alias, "usb:"); @@ -118,9 +118,22 @@ static void do_usb_entry(struct usb_device_id *id, sprintf(alias + strlen(alias), "%0*X", bcdDevice_initial_digits, bcdDevice_initial); if (range_lo == range_hi) - sprintf(alias + strlen(alias), "%u", range_lo); - else if (range_lo > 0 || range_hi < 9) - sprintf(alias + strlen(alias), "[%u-%u]", range_lo, range_hi); + sprintf(alias + strlen(alias), "%X", range_lo); + else if (range_lo > 0 || range_hi < max) { + if (range_lo > 0x9 || range_hi < 0xA) + sprintf(alias + strlen(alias), + "[%X-%X]", + range_lo, + range_hi); + else { + sprintf(alias + strlen(alias), + range_lo < 0x9 ? "[%X-9" : "[%X", + range_lo); + sprintf(alias + strlen(alias), + range_hi > 0xA ? "a-%X]" : "%X]", + range_lo); + } + } if (bcdDevice_initial_digits < (sizeof(id->bcdDevice_lo) * 2 - 1)) strcat(alias, "*"); @@ -147,10 +160,49 @@ static void do_usb_entry(struct usb_device_id *id, "MODULE_ALIAS(\"%s\");\n", alias); } +/* Handles increment/decrement of BCD formatted integers */ +/* Returns the previous value, so it works like i++ or i-- */ +static unsigned int incbcd(unsigned int *bcd, + int inc, + unsigned char max, + size_t chars) +{ + unsigned int init = *bcd, i, j; + unsigned long long c, dec = 0; + + /* If bcd is not in BCD format, just increment */ + if (max > 0x9) { + *bcd += inc; + return init; + } + + /* Convert BCD to Decimal */ + for (i=0 ; i < chars ; i++) { + c = (*bcd >> (i << 2)) & 0xf; + c = c > 9 ? 9 : c; /* force to bcd just in case */ + for (j=0 ; j < i ; j++) + c = c * 10; + dec += c; + } + + /* Do our increment/decrement */ + dec += inc; + *bcd = 0; + + /* Convert back to BCD */ + for (i=0 ; i < chars ; i++) { + for (c=1,j=0 ; j < i ; j++) + c = c * 10; + c = (dec / c) % 10; + *bcd += c << (i << 2); + } + return init; +} + static void do_usb_entry_multi(struct usb_device_id *id, struct module *mod) { unsigned int devlo, devhi; - unsigned char chi, clo; + unsigned char chi, clo, max; int ndigits; id->match_flags = TO_NATIVE(id->match_flags); @@ -162,6 +214,17 @@ static void do_usb_entry_multi(struct usb_device_id *id, struct module *mod) devhi = id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI ? TO_NATIVE(id->bcdDevice_hi) : ~0x0U; + /* Figure out if this entry is in bcd or hex format */ + max = 0x9; /* Default to decimal format */ + for (ndigits = 0 ; ndigits < sizeof(id->bcdDevice_lo) * 2 ; ndigits++) { + clo = (devlo >> (ndigits << 2)) & 0xf; + chi = ((devhi > 0x9999 ? 0x9999 : devhi) >> (ndigits << 2)) & 0xf; + if (clo > max || chi > max) { + max = 0xf; + break; + } + } + /* * Some modules (visor) have empty slots as placeholder for * run-time specification that results in catch-all alias @@ -173,21 +236,27 @@ static void do_usb_entry_multi(struct usb_device_id *id, struct module *mod) for (ndigits = sizeof(id->bcdDevice_lo) * 2 - 1; devlo <= devhi; ndigits--) { clo = devlo & 0xf; chi = devhi & 0xf; - if (chi > 9) /* it's bcd not hex */ - chi = 9; + if (chi > max) /* If we are in bcd mode, truncate if necessary */ + chi = max; devlo >>= 4; devhi >>= 4; if (devlo == devhi || !ndigits) { - do_usb_entry(id, devlo, ndigits, clo, chi, mod); + do_usb_entry(id, devlo, ndigits, clo, chi, max, mod); break; } - if (clo > 0) - do_usb_entry(id, devlo++, ndigits, clo, 9, mod); - - if (chi < 9) - do_usb_entry(id, devhi--, ndigits, 0, chi, mod); + if (clo > 0x0) + do_usb_entry(id, + incbcd(&devlo, 1, max, + sizeof(id->bcdDevice_lo) * 2), + ndigits, clo, max, max, mod); + + if (chi < max) + do_usb_entry(id, + incbcd(&devhi, -1, max, + sizeof(id->bcdDevice_lo) * 2), + ndigits, 0x0, chi, max, mod); } } diff --git a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c index 6a96d47bd1e..639bca7ba55 100644 --- a/scripts/mod/mk_elfconfig.c +++ b/scripts/mod/mk_elfconfig.c @@ -9,9 +9,6 @@ main(int argc, char **argv) unsigned char ei[EI_NIDENT]; union { short s; char c[2]; } endian_test; - if (argc != 2) { - fprintf(stderr, "Error: no arch\n"); - } if (fread(ei, 1, EI_NIDENT, stdin) != EI_NIDENT) { fprintf(stderr, "Error: input truncated\n"); return 1; @@ -55,12 +52,6 @@ main(int argc, char **argv) else exit(1); - if ((strcmp(argv[1], "h8300") == 0) - || (strcmp(argv[1], "blackfin") == 0)) - printf("#define MODULE_SYMBOL_PREFIX \"_\"\n"); - else - printf("#define MODULE_SYMBOL_PREFIX \"\"\n"); - return 0; } diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 801a16a1754..20923613467 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -15,8 +15,17 @@ #include <stdio.h> #include <ctype.h> #include "modpost.h" +#include "../../include/generated/autoconf.h" #include "../../include/linux/license.h" +/* Some toolchains use a `_' prefix for all user symbols. */ +#ifdef CONFIG_SYMBOL_PREFIX +#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX +#else +#define MODULE_SYMBOL_PREFIX "" +#endif + + /* Are we using CONFIG_MODVERSIONS? */ int modversions = 0; /* Warn about undefined symbols? (do so if we have vmlinux) */ @@ -451,8 +460,6 @@ static int parse_elf(struct elf_info *info, const char *filename) info->export_unused_gpl_sec = i; else if (strcmp(secname, "__ksymtab_gpl_future") == 0) info->export_gpl_future_sec = i; - else if (strcmp(secname, "__markers_strings") == 0) - info->markers_strings_sec = i; if (sechdrs[i].sh_type != SHT_SYMTAB) continue; @@ -515,7 +522,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info, break; case SHN_ABS: /* CRC'd symbol */ - if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { + if (strncmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { crc = (unsigned int) sym->st_value; sym_update_crc(symname + strlen(CRC_PFX), mod, crc, export); @@ -559,7 +566,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info, break; default: /* All exported symbols */ - if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { + if (strncmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { sym_add_exported(symname + strlen(KSYMTAB_PFX), mod, export); } @@ -1509,62 +1516,6 @@ static void check_sec_ref(struct module *mod, const char *modname, } } -static void get_markers(struct elf_info *info, struct module *mod) -{ - const Elf_Shdr *sh = &info->sechdrs[info->markers_strings_sec]; - const char *strings = (const char *) info->hdr + sh->sh_offset; - const Elf_Sym *sym, *first_sym, *last_sym; - size_t n; - - if (!info->markers_strings_sec) - return; - - /* - * First count the strings. We look for all the symbols defined - * in the __markers_strings section named __mstrtab_*. For - * these local names, the compiler puts a random .NNN suffix on, - * so the names don't correspond exactly. - */ - first_sym = last_sym = NULL; - n = 0; - for (sym = info->symtab_start; sym < info->symtab_stop; sym++) - if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT && - sym->st_shndx == info->markers_strings_sec && - !strncmp(info->strtab + sym->st_name, - "__mstrtab_", sizeof "__mstrtab_" - 1)) { - if (first_sym == NULL) - first_sym = sym; - last_sym = sym; - ++n; - } - - if (n == 0) - return; - - /* - * Now collect each name and format into a line for the output. - * Lines look like: - * marker_name vmlinux marker %s format %d - * The format string after the second \t can use whitespace. - */ - mod->markers = NOFAIL(malloc(sizeof mod->markers[0] * n)); - mod->nmarkers = n; - - n = 0; - for (sym = first_sym; sym <= last_sym; sym++) - if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT && - sym->st_shndx == info->markers_strings_sec && - !strncmp(info->strtab + sym->st_name, - "__mstrtab_", sizeof "__mstrtab_" - 1)) { - const char *name = strings + sym->st_value; - const char *fmt = strchr(name, '\0') + 1; - char *line = NULL; - asprintf(&line, "%s\t%s\t%s\n", name, mod->name, fmt); - NOFAIL(line); - mod->markers[n++] = line; - } -} - static void read_symbols(char *modname) { const char *symname; @@ -1620,8 +1571,6 @@ static void read_symbols(char *modname) get_src_version(modname, mod->srcversion, sizeof(mod->srcversion)-1); - get_markers(&info, mod); - parse_elf_finish(&info); /* Our trick to get versioning for module struct etc. - it's @@ -1976,96 +1925,6 @@ static void write_dump(const char *fname) write_if_changed(&buf, fname); } -static void add_marker(struct module *mod, const char *name, const char *fmt) -{ - char *line = NULL; - asprintf(&line, "%s\t%s\t%s\n", name, mod->name, fmt); - NOFAIL(line); - - mod->markers = NOFAIL(realloc(mod->markers, ((mod->nmarkers + 1) * - sizeof mod->markers[0]))); - mod->markers[mod->nmarkers++] = line; -} - -static void read_markers(const char *fname) -{ - unsigned long size, pos = 0; - void *file = grab_file(fname, &size); - char *line; - - if (!file) /* No old markers, silently ignore */ - return; - - while ((line = get_next_line(&pos, file, size))) { - char *marker, *modname, *fmt; - struct module *mod; - - marker = line; - modname = strchr(marker, '\t'); - if (!modname) - goto fail; - *modname++ = '\0'; - fmt = strchr(modname, '\t'); - if (!fmt) - goto fail; - *fmt++ = '\0'; - if (*marker == '\0' || *modname == '\0') - goto fail; - - mod = find_module(modname); - if (!mod) { - mod = new_module(modname); - mod->skip = 1; - } - if (is_vmlinux(modname)) { - have_vmlinux = 1; - mod->skip = 0; - } - - if (!mod->skip) - add_marker(mod, marker, fmt); - } - release_file(file, size); - return; -fail: - fatal("parse error in markers list file\n"); -} - -static int compare_strings(const void *a, const void *b) -{ - return strcmp(*(const char **) a, *(const char **) b); -} - -static void write_markers(const char *fname) -{ - struct buffer buf = { }; - struct module *mod; - size_t i; - - for (mod = modules; mod; mod = mod->next) - if ((!external_module || !mod->skip) && mod->markers != NULL) { - /* - * Sort the strings so we can skip duplicates when - * we write them out. - */ - qsort(mod->markers, mod->nmarkers, - sizeof mod->markers[0], &compare_strings); - for (i = 0; i < mod->nmarkers; ++i) { - char *line = mod->markers[i]; - buf_write(&buf, line, strlen(line)); - while (i + 1 < mod->nmarkers && - !strcmp(mod->markers[i], - mod->markers[i + 1])) - free(mod->markers[i++]); - free(mod->markers[i]); - } - free(mod->markers); - mod->markers = NULL; - } - - write_if_changed(&buf, fname); -} - struct ext_sym_list { struct ext_sym_list *next; const char *file; @@ -2077,8 +1936,6 @@ int main(int argc, char **argv) struct buffer buf = { }; char *kernel_read = NULL, *module_read = NULL; char *dump_write = NULL; - char *markers_read = NULL; - char *markers_write = NULL; int opt; int err; struct ext_sym_list *extsym_iter; @@ -2122,12 +1979,6 @@ int main(int argc, char **argv) case 'w': warn_unresolved = 1; break; - case 'M': - markers_write = optarg; - break; - case 'K': - markers_read = optarg; - break; default: exit(1); } @@ -2182,11 +2033,5 @@ int main(int argc, char **argv) "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n", sec_mismatch_count); - if (markers_read) - read_markers(markers_read); - - if (markers_write) - write_markers(markers_write); - return err; } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 09f58e33d22..be987a44f25 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -112,8 +112,6 @@ struct module { int has_init; int has_cleanup; struct buffer dev_table_buf; - char **markers; - size_t nmarkers; char srcversion[25]; }; @@ -128,7 +126,6 @@ struct elf_info { Elf_Section export_gpl_sec; Elf_Section export_unused_gpl_sec; Elf_Section export_gpl_future_sec; - Elf_Section markers_strings_sec; const char *strtab; char *modinfo; unsigned int modinfo_len; |