aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/marker.h9
-rw-r--r--scripts/Makefile.modpost11
-rw-r--r--scripts/mod/modpost.c164
-rw-r--r--scripts/mod/modpost.h3
4 files changed, 180 insertions, 7 deletions
<
diff --git a/include/linux/marker.h b/include/linux/marker.h
index b5f95637f289..5df879dc3776 100644
--- a/include/linux/marker.h
+++ b/include/linux/marker.h
@@ -61,15 +61,12 @@ struct marker {
61 */ 61 */
62#define __trace_mark(name, call_private, format, args...) \ 62#define __trace_mark(name, call_private, format, args...) \
63 do { \ 63 do { \
64 static const char __mstrtab_name_##name[] \ 64 static const char __mstrtab_##name[] \
65 __attribute__((section("__markers_strings"))) \ 65 __attribute__((section("__markers_strings"))) \
66 = #name; \ 66 = #name "\0" format; \
67 static const char __mstrtab_format_##name[] \
68 __attribute__((section("__markers_strings"))) \
69 = format; \
70 static struct marker __mark_##name \ 67 static struct marker __mark_##name \
71 __attribute__((section("__markers"), aligned(8))) = \ 68 __attribute__((section("__markers"), aligned(8))) = \
72 { __mstrtab_name_##name, __mstrtab_format_##name, \ 69 { __mstrtab_##name, &__mstrtab_##name[sizeof(#name)], \
73 0, 0, marker_probe_cb, \ 70 0, 0, marker_probe_cb, \
74 { __mark_empty_function, NULL}, NULL }; \ 71 { __mark_empty_function, NULL}, NULL }; \
75 __mark_check_format(format, ## args); \ 72 __mark_check_format(format, ## args); \
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 65e707e1ffc3..cfc004e04417 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -13,6 +13,7 @@
13# 2) modpost is then used to 13# 2) modpost is then used to
14# 3) create one <module>.mod.c file pr. module 14# 3) create one <module>.mod.c file pr. module
15# 4) create one Module.symvers file with CRC for all exported symbols 15# 4) create one Module.symvers file with CRC for all exported symbols
16# 4a) [CONFIG_MARKERS] create one Module.markers file listing defined markers
16# 5) compile all <module>.mod.c files 17# 5) compile all <module>.mod.c files
17# 6) final link of the module to a <module.ko> file 18# 6) final link of the module to a <module.ko> file
18 19
@@ -45,6 +46,10 @@ include scripts/Makefile.lib
45 46
46kernelsymfile := $(objtree)/Module.symvers 47kernelsymfile := $(objtree)/Module.symvers
47modulesymfile := $(firstword $(KBUILD_EXTMOD))/Module.symvers 48modulesymfile := $(firstword $(KBUILD_EXTMOD))/Module.symvers
49kernelmarkersfile := $(objtree)/Module.markers
50modulemarkersfile := $(firstword $(KBUILD_EXTMOD))/Module.markers
51
52markersfile = $(if $(KBUILD_EXTMOD),$(modulemarkersfile),$(kernelmarkersfile))
48 53
49# Step 1), find all modules listed in $(MODVERDIR)/ 54# Step 1), find all modules listed in $(MODVERDIR)/
50__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) 55__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
@@ -63,6 +68,8 @@ modpost = scripts/mod/modpost \
63 $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \ 68 $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \
64 $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ 69 $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
65 $(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \ 70 $(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \
71 $(if $(CONFIG_MARKERS),-K $(kernelmarkersfile)) \
72 $(if $(CONFIG_MARKERS),-M $(markersfile)) \
66 $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) 73 $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w)
67 74
68quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules 75quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules
@@ -82,6 +89,10 @@ vmlinux.o: FORCE
82$(symverfile): __modpost ; 89$(symverfile): __modpost ;
83$(modules:.ko=.mod.c): __modpost ; 90$(modules:.ko=.mod.c): __modpost ;
84 91
92ifdef CONFIG_MARKERS
93$(markersfile): __modpost ;
94endif
95
85 96
86# Step 5), compile all *.mod.c files 97# Step 5), compile all *.mod.c files
87 98
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index dbe1fb5e8cc0..61742771c65d 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -11,6 +11,8 @@
11 * Usage: modpost vmlinux module1.o module2.o ... 11 * Usage: modpost vmlinux module1.o module2.o ...
12 */ 12 */
13 13
14#define _GNU_SOURCE
15#include <stdio.h>
14#include <ctype.h> 16#include <ctype.h>
15#include "modpost.h" 17#include "modpost.h"
16#include "../../include/linux/license.h" 18#include "../../include/linux/license.h"
@@ -435,6 +437,8 @@ static int parse_elf(struct elf_info *info, const char *filename)
435 info->export_unused_gpl_sec = i; 437 info->export_unused_gpl_sec = i;
436 else if (strcmp(secname, "__ksymtab_gpl_future") == 0) 438 else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
437 info->export_gpl_future_sec = i; 439 info->export_gpl_future_sec = i;
440 else if (strcmp(secname, "__markers_strings") == 0)
441 info->markers_strings_sec = i;
438 442
439 if (sechdrs[i].sh_type != SHT_SYMTAB) 443 if (sechdrs[i].sh_type != SHT_SYMTAB)
440 continue; 444 continue;
@@ -1470,6 +1474,62 @@ static void check_sec_ref(struct module *mod, const char *modname,
1470 } 1474 }
1471} 1475}
1472 1476
1477static void get_markers(struct elf_info *info, struct module *mod)
1478{
1479 const Elf_Shdr *sh = &info->sechdrs[info->markers_strings_sec];
1480 const char *strings = (const char *) info->hdr + sh->sh_offset;
1481 const Elf_Sym *sym, *first_sym, *last_sym;
1482 size_t n;
1483
1484 if (!info->markers_strings_sec)
1485 return;
1486
1487 /*
1488 * First count the strings. We look for all the symbols defined
1489 * in the __markers_strings section named __mstrtab_*. For
1490 * these local names, the compiler puts a random .NNN suffix on,
1491 * so the names don't correspond exactly.
1492 */
1493 first_sym = last_sym = NULL;
1494 n = 0;
1495 for (sym = info->symtab_start; sym < info->symtab_stop; sym++)
1496 if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT &&
1497 sym->st_shndx == info->markers_strings_sec &&
1498 !strncmp(info->strtab + sym->st_name,
1499 "__mstrtab_", sizeof "__mstrtab_" - 1)) {
1500 if (first_sym == NULL)
1501 first_sym = sym;
1502 last_sym = sym;
1503 ++n;
1504 }
1505
1506 if (n == 0)
1507 return;
1508
1509 /*
1510 * Now collect each name and format into a line for the output.
1511 * Lines look like:
1512 * marker_name vmlinux marker %s format %d
1513 * The format string after the second \t can use whitespace.
1514 */
1515 mod->markers = NOFAIL(malloc(sizeof mod->markers[0] * n));
1516 mod->nmarkers = n;
1517
1518 n = 0;
1519 for (sym = first_sym; sym <= last_sym; sym++)
1520 if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT &&
1521 sym->st_shndx == info->markers_strings_sec &&
1522 !strncmp(info->strtab + sym->st_name,
1523 "__mstrtab_", sizeof "__mstrtab_" - 1)) {
1524 const char *name = strings + sym->st_value;
1525 const char *fmt = strchr(name, '\0') + 1;
1526 char *line = NULL;
1527 asprintf(&line, "%s\t%s\t%s\n", name, mod->name, fmt);
1528 NOFAIL(line);
1529 mod->markers[n++] = line;
1530 }
1531}
1532
1473static void read_symbols(char *modname) 1533static void read_symbols(char *modname)
1474{ 1534{
1475 const char *symname; 1535 const char *symname;
@@ -1521,6 +1581,8 @@ static void read_symbols(char *modname)
1521 get_src_version(modname, mod->srcversion, 1581 get_src_version(modname, mod->srcversion,
1522 sizeof(mod->srcversion)-1); 1582 sizeof(mod->srcversion)-1);
1523 1583
1584 get_markers(&info, mod);
1585
1524 parse_elf_finish(&info); 1586 parse_elf_finish(&info);
1525 1587
1526 /* Our trick to get versioning for struct_module - it's 1588 /* Our trick to get versioning for struct_module - it's
@@ -1867,16 +1929,104 @@ static void write_dump(const char *fname)
1867 write_if_changed(&buf, fname); 1929 write_if_changed(&buf, fname);
1868} 1930}
1869 1931
1932static void add_marker(struct module *mod, const char *name, const char *fmt)
1933{
1934 char *line = NULL;
1935 asprintf(&line, "%s\t%s\t%s\n", name, mod->name, fmt);
1936 NOFAIL(line);
1937
1938 mod->markers = NOFAIL(realloc(mod->markers, ((mod->nmarkers + 1) *
1939 sizeof mod->markers[0])));
1940 mod->markers[mod->nmarkers++] = line;
1941}
1942
1943static void read_markers(const char *fname)