aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/mod/modpost.c
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/mod/modpost.c')
-rw-r--r--scripts/mod/modpost.c177
1 files changed, 11 insertions, 166 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 801a16a17545..6c4ffc767b91 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -15,8 +15,17 @@
15#include <stdio.h> 15#include <stdio.h>
16#include <ctype.h> 16#include <ctype.h>
17#include "modpost.h" 17#include "modpost.h"
18#include "../../include/linux/autoconf.h"
18#include "../../include/linux/license.h" 19#include "../../include/linux/license.h"
19 20
21/* Some toolchains use a `_' prefix for all user symbols. */
22#ifdef CONFIG_SYMBOL_PREFIX
23#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX
24#else
25#define MODULE_SYMBOL_PREFIX ""
26#endif
27
28
20/* Are we using CONFIG_MODVERSIONS? */ 29/* Are we using CONFIG_MODVERSIONS? */
21int modversions = 0; 30int modversions = 0;
22/* Warn about undefined symbols? (do so if we have vmlinux) */ 31/* 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)
451 info->export_unused_gpl_sec = i; 460 info->export_unused_gpl_sec = i;
452 else if (strcmp(secname, "__ksymtab_gpl_future") == 0) 461 else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
453 info->export_gpl_future_sec = i; 462 info->export_gpl_future_sec = i;
454 else if (strcmp(secname, "__markers_strings") == 0)
455 info->markers_strings_sec = i;
456 463
457 if (sechdrs[i].sh_type != SHT_SYMTAB) 464 if (sechdrs[i].sh_type != SHT_SYMTAB)
458 continue; 465 continue;
@@ -515,7 +522,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
515 break; 522 break;
516 case SHN_ABS: 523 case SHN_ABS:
517 /* CRC'd symbol */ 524 /* CRC'd symbol */
518 if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { 525 if (strncmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
519 crc = (unsigned int) sym->st_value; 526 crc = (unsigned int) sym->st_value;
520 sym_update_crc(symname + strlen(CRC_PFX), mod, crc, 527 sym_update_crc(symname + strlen(CRC_PFX), mod, crc,
521 export); 528 export);
@@ -559,7 +566,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
559 break; 566 break;
560 default: 567 default:
561 /* All exported symbols */ 568 /* All exported symbols */
562 if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { 569 if (strncmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
563 sym_add_exported(symname + strlen(KSYMTAB_PFX), mod, 570 sym_add_exported(symname + strlen(KSYMTAB_PFX), mod,
564 export); 571 export);
565 } 572 }
@@ -1509,62 +1516,6 @@ static void check_sec_ref(struct module *mod, const char *modname,
1509 } 1516 }
1510} 1517}
1511 1518
1512static void get_markers(struct elf_info *info, struct module *mod)
1513{
1514 const Elf_Shdr *sh = &info->sechdrs[info->markers_strings_sec];
1515 const char *strings = (const char *) info->hdr + sh->sh_offset;
1516 const Elf_Sym *sym, *first_sym, *last_sym;
1517 size_t n;
1518
1519 if (!info->markers_strings_sec)
1520 return;
1521
1522 /*
1523 * First count the strings. We look for all the symbols defined
1524 * in the __markers_strings section named __mstrtab_*. For
1525 * these local names, the compiler puts a random .NNN suffix on,
1526 * so the names don't correspond exactly.
1527 */
1528 first_sym = last_sym = NULL;
1529 n = 0;
1530 for (sym = info->symtab_start; sym < info->symtab_stop; sym++)
1531 if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT &&
1532 sym->st_shndx == info->markers_strings_sec &&
1533 !strncmp(info->strtab + sym->st_name,
1534 "__mstrtab_", sizeof "__mstrtab_" - 1)) {
1535 if (first_sym == NULL)
1536 first_sym = sym;
1537 last_sym = sym;
1538 ++n;
1539 }
1540
1541 if (n == 0)
1542 return;
1543
1544 /*
1545 * Now collect each name and format into a line for the output.
1546 * Lines look like:
1547 * marker_name vmlinux marker %s format %d
1548 * The format string after the second \t can use whitespace.
1549 */
1550 mod->markers = NOFAIL(malloc(sizeof mod->markers[0] * n));
1551 mod->nmarkers = n;
1552
1553 n = 0;
1554 for (sym = first_sym; sym <= last_sym; sym++)
1555 if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT &&
1556 sym->st_shndx == info->markers_strings_sec &&
1557 !strncmp(info->strtab + sym->st_name,
1558 "__mstrtab_", sizeof "__mstrtab_" - 1)) {
1559 const char *name = strings + sym->st_value;
1560 const char *fmt = strchr(name, '\0') + 1;
1561 char *line = NULL;
1562 asprintf(&line, "%s\t%s\t%s\n", name, mod->name, fmt);
1563 NOFAIL(line);
1564 mod->markers[n++] = line;
1565 }
1566}
1567
1568static void read_symbols(char *modname) 1519static void read_symbols(char *modname)
1569{ 1520{
1570 const char *symname; 1521 const char *symname;
@@ -1620,8 +1571,6 @@ static void read_symbols(char *modname)
1620 get_src_version(modname, mod->srcversion, 1571 get_src_version(modname, mod->srcversion,
1621 sizeof(mod->srcversion)-1); 1572 sizeof(mod->srcversion)-1);
1622 1573
1623 get_markers(&info, mod);
1624
1625 parse_elf_finish(&info); 1574 parse_elf_finish(&info);
1626 1575
1627 /* Our trick to get versioning for module struct etc. - it's 1576 /* Our trick to get versioning for module struct etc. - it's
@@ -1976,96 +1925,6 @@ static void write_dump(const char *fname)
1976 write_if_changed(&buf, fname); 1925 write_if_changed(&buf, fname);
1977} 1926}
1978 1927
1979static void add_marker(struct module *mod, const char *name, const char *fmt)
1980{
1981 char *line = NULL;
1982 asprintf(&line, "%s\t%s\t%s\n", name, mod->name, fmt);
1983 NOFAIL(line);
1984
1985 mod->markers = NOFAIL(realloc(mod->markers, ((mod->nmarkers + 1) *
1986 sizeof mod->markers[0])));
1987 mod->markers[mod->nmarkers++] = line;
1988}
1989
1990static void read_markers(const char *fname)
1991{
1992 unsigned long size, pos = 0;
1993 void *file = grab_file(fname, &size);
1994 char *line;
1995
1996 if (!file) /* No old markers, silently ignore */
1997 return;
1998
1999 while ((line = get_next_line(&pos, file, size))) {
2000 char *marker, *modname, *fmt;
2001 struct module *mod;
2002
2003 marker = line;
2004 modname = strchr(marker, '\t');
2005 if (!modname)
2006 goto fail;
2007 *modname++ = '\0';
2008 fmt = strchr(modname, '\t');
2009 if (!fmt)
2010 goto fail;
2011 *fmt++ = '\0';
2012 if (*marker == '\0' || *modname == '\0')
2013 goto fail;
2014
2015 mod = find_module(modname);
2016 if (!mod) {
2017 mod = new_module(modname);
2018 mod->skip = 1;
2019 }
2020 if (is_vmlinux(modname)) {
2021 have_vmlinux = 1;
2022 mod->skip = 0;
2023 }
2024
2025 if (!mod->skip)
2026 add_marker(mod, marker, fmt);
2027 }
2028 release_file(file, size);
2029 return;
2030fail:
2031 fatal("parse error in markers list file\n");
2032}
2033
2034static int compare_strings(const void *a, const void *b)
2035{
2036 return strcmp(*(const char **) a, *(const char **) b);
2037}
2038
2039static void write_markers(const char *fname)
2040{
2041 struct buffer buf = { };
2042 struct module *mod;
2043 size_t i;
2044
2045 for (mod = modules; mod; mod = mod->next)
2046 if ((!external_module || !mod->skip) && mod->markers != NULL) {
2047 /*
2048 * Sort the strings so we can skip duplicates when
2049 * we write them out.
2050 */
2051 qsort(mod->markers, mod->nmarkers,
2052 sizeof mod->markers[0], &compare_strings);
2053 for (i = 0; i < mod->nmarkers; ++i) {
2054 char *line = mod->markers[i];
2055 buf_write(&buf, line, strlen(line));
2056 while (i + 1 < mod->nmarkers &&
2057 !strcmp(mod->markers[i],
2058 mod->markers[i + 1]))
2059 free(mod->markers[i++]);
2060 free(mod->markers[i]);
2061 }
2062 free(mod->markers);
2063 mod->markers = NULL;
2064 }
2065
2066 write_if_changed(&buf, fname);
2067}
2068
2069struct ext_sym_list { 1928struct ext_sym_list {
2070 struct ext_sym_list *next; 1929 struct ext_sym_list *next;
2071 const char *file; 1930 const char *file;
@@ -2077,8 +1936,6 @@ int main(int argc, char **argv)
2077 struct buffer buf = { }; 1936 struct buffer buf = { };
2078 char *kernel_read = NULL, *module_read = NULL; 1937 char *kernel_read = NULL, *module_read = NULL;
2079 char *dump_write = NULL; 1938 char *dump_write = NULL;
2080 char *markers_read = NULL;
2081 char *markers_write = NULL;
2082 int opt; 1939 int opt;
2083 int err; 1940 int err;
2084 struct ext_sym_list *extsym_iter; 1941 struct ext_sym_list *extsym_iter;
@@ -2122,12 +1979,6 @@ int main(int argc, char **argv)
2122 case 'w': 1979 case 'w':
2123 warn_unresolved = 1; 1980 warn_unresolved = 1;
2124 break; 1981 break;
2125 case 'M':
2126 markers_write = optarg;
2127 break;
2128 case 'K':
2129 markers_read = optarg;
2130 break;
2131 default: 1982 default:
2132 exit(1); 1983 exit(1);
2133 } 1984 }
@@ -2182,11 +2033,5 @@ int main(int argc, char **argv)
2182 "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n", 2033 "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n",
2183 sec_mismatch_count); 2034 sec_mismatch_count);
2184 2035
2185 if (markers_read)
2186 read_markers(markers_read);
2187
2188 if (markers_write)
2189 write_markers(markers_write);
2190
2191 return err; 2036 return err;
2192} 2037}