diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-06 12:38:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-06 12:38:07 -0400 |
commit | 6f4c98e1c22c28e00b8f050cce895a6b74db15d1 (patch) | |
tree | b00da8b3367c6f3d0f74f44b8c4092a7b7cbbe18 /scripts | |
parent | 18a1a7a1d862ae0794a0179473d08a414dd49234 (diff) | |
parent | 22c9bcad859d5c969289b3b37084a96c621f8f2c (diff) |
Merge tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux
Pull module updates from Rusty Russell:
"Nothing major: the stricter permissions checking for sysfs broke a
staging driver; fix included. Greg KH said he'd take the patch but
hadn't as the merge window opened, so it's included here to avoid
breaking build"
* tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux:
staging: fix up speakup kobject mode
Use 'E' instead of 'X' for unsigned module taint flag.
VERIFY_OCTAL_PERMISSIONS: stricter checking for sysfs perms.
kallsyms: fix percpu vars on x86-64 with relocation.
kallsyms: generalize address range checking
module: LLVMLinux: Remove unused function warning from __param_check macro
Fix: module signature vs tracepoints: add new TAINT_UNSIGNED_MODULE
module: remove MODULE_GENERIC_TABLE
module: allow multiple calls to MODULE_DEVICE_TABLE() per module
module: use pr_cont
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/kallsyms.c | 74 | ||||
-rw-r--r-- | scripts/link-vmlinux.sh | 4 | ||||
-rw-r--r-- | scripts/mod/file2alias.c | 14 |
3 files changed, 66 insertions, 26 deletions
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 10085de886fe..1237dd7fb4ca 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c | |||
@@ -36,13 +36,13 @@ struct sym_entry { | |||
36 | unsigned char *sym; | 36 | unsigned char *sym; |
37 | }; | 37 | }; |
38 | 38 | ||
39 | struct text_range { | 39 | struct addr_range { |
40 | const char *stext, *etext; | 40 | const char *start_sym, *end_sym; |
41 | unsigned long long start, end; | 41 | unsigned long long start, end; |
42 | }; | 42 | }; |
43 | 43 | ||
44 | static unsigned long long _text; | 44 | static unsigned long long _text; |
45 | static struct text_range text_ranges[] = { | 45 | static struct addr_range text_ranges[] = { |
46 | { "_stext", "_etext" }, | 46 | { "_stext", "_etext" }, |
47 | { "_sinittext", "_einittext" }, | 47 | { "_sinittext", "_einittext" }, |
48 | { "_stext_l1", "_etext_l1" }, /* Blackfin on-chip L1 inst SRAM */ | 48 | { "_stext_l1", "_etext_l1" }, /* Blackfin on-chip L1 inst SRAM */ |
@@ -51,9 +51,14 @@ static struct text_range text_ranges[] = { | |||
51 | #define text_range_text (&text_ranges[0]) | 51 | #define text_range_text (&text_ranges[0]) |
52 | #define text_range_inittext (&text_ranges[1]) | 52 | #define text_range_inittext (&text_ranges[1]) |
53 | 53 | ||
54 | static struct addr_range percpu_range = { | ||
55 | "__per_cpu_start", "__per_cpu_end", -1ULL, 0 | ||
56 | }; | ||
57 | |||
54 | static struct sym_entry *table; | 58 | static struct sym_entry *table; |
55 | static unsigned int table_size, table_cnt; | 59 | static unsigned int table_size, table_cnt; |
56 | static int all_symbols = 0; | 60 | static int all_symbols = 0; |
61 | static int absolute_percpu = 0; | ||
57 | static char symbol_prefix_char = '\0'; | 62 | static char symbol_prefix_char = '\0'; |
58 | static unsigned long long kernel_start_addr = 0; | 63 | static unsigned long long kernel_start_addr = 0; |
59 | 64 | ||
@@ -83,19 +88,20 @@ static inline int is_arm_mapping_symbol(const char *str) | |||
83 | && (str[2] == '\0' || str[2] == '.'); | 88 | && (str[2] == '\0' || str[2] == '.'); |
84 | } | 89 | } |
85 | 90 | ||
86 | static int read_symbol_tr(const char *sym, unsigned long long addr) | 91 | static int check_symbol_range(const char *sym, unsigned long long addr, |
92 | struct addr_range *ranges, int entries) | ||
87 | { | 93 | { |
88 | size_t i; | 94 | size_t i; |
89 | struct text_range *tr; | 95 | struct addr_range *ar; |
90 | 96 | ||
91 | for (i = 0; i < ARRAY_SIZE(text_ranges); ++i) { | 97 | for (i = 0; i < entries; ++i) { |
92 | tr = &text_ranges[i]; | 98 | ar = &ranges[i]; |
93 | 99 | ||
94 | if (strcmp(sym, tr->stext) == 0) { | 100 | if (strcmp(sym, ar->start_sym) == 0) { |
95 | tr->start = addr; | 101 | ar->start = addr; |
96 | return 0; | 102 | return 0; |
97 | } else if (strcmp(sym, tr->etext) == 0) { | 103 | } else if (strcmp(sym, ar->end_sym) == 0) { |
98 | tr->end = addr; | 104 | ar->end = addr; |
99 | return 0; | 105 | return 0; |
100 | } | 106 | } |
101 | } | 107 | } |
@@ -130,7 +136,8 @@ static int read_symbol(FILE *in, struct sym_entry *s) | |||
130 | /* Ignore most absolute/undefined (?) symbols. */ | 136 | /* Ignore most absolute/undefined (?) symbols. */ |
131 | if (strcmp(sym, "_text") == 0) | 137 | if (strcmp(sym, "_text") == 0) |
132 | _text = s->addr; | 138 | _text = s->addr; |
133 | else if (read_symbol_tr(sym, s->addr) == 0) | 139 | else if (check_symbol_range(sym, s->addr, text_ranges, |
140 | ARRAY_SIZE(text_ranges)) == 0) | ||
134 | /* nothing to do */; | 141 | /* nothing to do */; |
135 | else if (toupper(stype) == 'A') | 142 | else if (toupper(stype) == 'A') |
136 | { | 143 | { |
@@ -164,18 +171,22 @@ static int read_symbol(FILE *in, struct sym_entry *s) | |||
164 | strcpy((char *)s->sym + 1, str); | 171 | strcpy((char *)s->sym + 1, str); |
165 | s->sym[0] = stype; | 172 | s->sym[0] = stype; |
166 | 173 | ||
174 | /* Record if we've found __per_cpu_start/end. */ | ||
175 | check_symbol_range(sym, s->addr, &percpu_range, 1); | ||
176 | |||
167 | return 0; | 177 | return 0; |
168 | } | 178 | } |
169 | 179 | ||
170 | static int symbol_valid_tr(struct sym_entry *s) | 180 | static int symbol_in_range(struct sym_entry *s, struct addr_range *ranges, |
181 | int entries) | ||
171 | { | 182 | { |
172 | size_t i; | 183 | size_t i; |
173 | struct text_range *tr; | 184 | struct addr_range *ar; |
174 | 185 | ||
175 | for (i = 0; i < ARRAY_SIZE(text_ranges); ++i) { | 186 | for (i = 0; i < entries; ++i) { |
176 | tr = &text_ranges[i]; | 187 | ar = &ranges[i]; |
177 | 188 | ||
178 | if (s->addr >= tr->start && s->addr <= tr->end) | 189 | if (s->addr >= ar->start && s->addr <= ar->end) |
179 | return 1; | 190 | return 1; |
180 | } | 191 | } |
181 | 192 | ||
@@ -214,7 +225,8 @@ static int symbol_valid(struct sym_entry *s) | |||
214 | /* if --all-symbols is not specified, then symbols outside the text | 225 | /* if --all-symbols is not specified, then symbols outside the text |
215 | * and inittext sections are discarded */ | 226 | * and inittext sections are discarded */ |
216 | if (!all_symbols) { | 227 | if (!all_symbols) { |
217 | if (symbol_valid_tr(s) == 0) | 228 | if (symbol_in_range(s, text_ranges, |
229 | ARRAY_SIZE(text_ranges)) == 0) | ||
218 | return 0; | 230 | return 0; |
219 | /* Corner case. Discard any symbols with the same value as | 231 | /* Corner case. Discard any symbols with the same value as |
220 | * _etext _einittext; they can move between pass 1 and 2 when | 232 | * _etext _einittext; they can move between pass 1 and 2 when |
@@ -223,9 +235,11 @@ static int symbol_valid(struct sym_entry *s) | |||
223 | * rules. | 235 | * rules. |
224 | */ | 236 | */ |
225 | if ((s->addr == text_range_text->end && | 237 | if ((s->addr == text_range_text->end && |
226 | strcmp((char *)s->sym + offset, text_range_text->etext)) || | 238 | strcmp((char *)s->sym + offset, |
239 | text_range_text->end_sym)) || | ||
227 | (s->addr == text_range_inittext->end && | 240 | (s->addr == text_range_inittext->end && |
228 | strcmp((char *)s->sym + offset, text_range_inittext->etext))) | 241 | strcmp((char *)s->sym + offset, |
242 | text_range_inittext->end_sym))) | ||
229 | return 0; | 243 | return 0; |
230 | } | 244 | } |
231 | 245 | ||
@@ -298,6 +312,11 @@ static int expand_symbol(unsigned char *data, int len, char *result) | |||
298 | return total; | 312 | return total; |
299 | } | 313 | } |
300 | 314 | ||
315 | static int symbol_absolute(struct sym_entry *s) | ||
316 | { | ||
317 | return toupper(s->sym[0]) == 'A'; | ||
318 | } | ||
319 | |||
301 | static void write_src(void) | 320 | static void write_src(void) |
302 | { | 321 | { |
303 | unsigned int i, k, off; | 322 | unsigned int i, k, off; |
@@ -325,7 +344,7 @@ static void write_src(void) | |||
325 | */ | 344 | */ |
326 | output_label("kallsyms_addresses"); | 345 | output_label("kallsyms_addresses"); |
327 | for (i = 0; i < table_cnt; i++) { | 346 | for (i = 0; i < table_cnt; i++) { |
328 | if (toupper(table[i].sym[0]) != 'A') { | 347 | if (!symbol_absolute(&table[i])) { |
329 | if (_text <= table[i].addr) | 348 | if (_text <= table[i].addr) |
330 | printf("\tPTR\t_text + %#llx\n", | 349 | printf("\tPTR\t_text + %#llx\n", |
331 | table[i].addr - _text); | 350 | table[i].addr - _text); |
@@ -646,6 +665,15 @@ static void sort_symbols(void) | |||
646 | qsort(table, table_cnt, sizeof(struct sym_entry), compare_symbols); | 665 | qsort(table, table_cnt, sizeof(struct sym_entry), compare_symbols); |
647 | } | 666 | } |
648 | 667 | ||
668 | static void make_percpus_absolute(void) | ||
669 | { | ||
670 | unsigned int i; | ||
671 | |||
672 | for (i = 0; i < table_cnt; i++) | ||
673 | if (symbol_in_range(&table[i], &percpu_range, 1)) | ||
674 | table[i].sym[0] = 'A'; | ||
675 | } | ||
676 | |||
649 | int main(int argc, char **argv) | 677 | int main(int argc, char **argv) |
650 | { | 678 | { |
651 | if (argc >= 2) { | 679 | if (argc >= 2) { |
@@ -653,6 +681,8 @@ int main(int argc, char **argv) | |||
653 | for (i = 1; i < argc; i++) { | 681 | for (i = 1; i < argc; i++) { |
654 | if(strcmp(argv[i], "--all-symbols") == 0) | 682 | if(strcmp(argv[i], "--all-symbols") == 0) |
655 | all_symbols = 1; | 683 | all_symbols = 1; |
684 | else if (strcmp(argv[i], "--absolute-percpu") == 0) | ||
685 | absolute_percpu = 1; | ||
656 | else if (strncmp(argv[i], "--symbol-prefix=", 16) == 0) { | 686 | else if (strncmp(argv[i], "--symbol-prefix=", 16) == 0) { |
657 | char *p = &argv[i][16]; | 687 | char *p = &argv[i][16]; |
658 | /* skip quote */ | 688 | /* skip quote */ |
@@ -669,6 +699,8 @@ int main(int argc, char **argv) | |||
669 | usage(); | 699 | usage(); |
670 | 700 | ||
671 | read_map(stdin); | 701 | read_map(stdin); |
702 | if (absolute_percpu) | ||
703 | make_percpus_absolute(); | ||
672 | sort_symbols(); | 704 | sort_symbols(); |
673 | optimize_token_table(); | 705 | optimize_token_table(); |
674 | write_src(); | 706 | write_src(); |
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 2dcb37736d84..86a4fe75f453 100644 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh | |||
@@ -86,6 +86,10 @@ kallsyms() | |||
86 | kallsymopt="${kallsymopt} --page-offset=$CONFIG_PAGE_OFFSET" | 86 | kallsymopt="${kallsymopt} --page-offset=$CONFIG_PAGE_OFFSET" |
87 | fi | 87 | fi |
88 | 88 | ||
89 | if [ -n "${CONFIG_X86_64}" ]; then | ||
90 | kallsymopt="${kallsymopt} --absolute-percpu" | ||
91 | fi | ||
92 | |||
89 | local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \ | 93 | local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \ |
90 | ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}" | 94 | ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}" |
91 | 95 | ||
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 25f6f5970552..1924990a737f 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c | |||
@@ -42,7 +42,7 @@ typedef unsigned char __u8; | |||
42 | 42 | ||
43 | /* This array collects all instances that use the generic do_table */ | 43 | /* This array collects all instances that use the generic do_table */ |
44 | struct devtable { | 44 | struct devtable { |
45 | const char *device_id; /* name of table, __mod_<name>_device_table. */ | 45 | const char *device_id; /* name of table, __mod_<name>__*_device_table. */ |
46 | unsigned long id_size; | 46 | unsigned long id_size; |
47 | void *function; | 47 | void *function; |
48 | }; | 48 | }; |
@@ -146,7 +146,8 @@ static void device_id_check(const char *modname, const char *device_id, | |||
146 | 146 | ||
147 | if (size % id_size || size < id_size) { | 147 | if (size % id_size || size < id_size) { |
148 | fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo " | 148 | fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo " |
149 | "of the size of section __mod_%s_device_table=%lu.\n" | 149 | "of the size of " |
150 | "section __mod_%s__<identifier>_device_table=%lu.\n" | ||
150 | "Fix definition of struct %s_device_id " | 151 | "Fix definition of struct %s_device_id " |
151 | "in mod_devicetable.h\n", | 152 | "in mod_devicetable.h\n", |
152 | modname, device_id, id_size, device_id, size, device_id); | 153 | modname, device_id, id_size, device_id, size, device_id); |
@@ -1216,7 +1217,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, | |||
1216 | { | 1217 | { |
1217 | void *symval; | 1218 | void *symval; |
1218 | char *zeros = NULL; | 1219 | char *zeros = NULL; |
1219 | const char *name; | 1220 | const char *name, *identifier; |
1220 | unsigned int namelen; | 1221 | unsigned int namelen; |
1221 | 1222 | ||
1222 | /* We're looking for a section relative symbol */ | 1223 | /* We're looking for a section relative symbol */ |
@@ -1227,7 +1228,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, | |||
1227 | if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) | 1228 | if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) |
1228 | return; | 1229 | return; |
1229 | 1230 | ||
1230 | /* All our symbols are of form <prefix>__mod_XXX_device_table. */ | 1231 | /* All our symbols are of form <prefix>__mod_<name>__<identifier>_device_table. */ |
1231 | name = strstr(symname, "__mod_"); | 1232 | name = strstr(symname, "__mod_"); |
1232 | if (!name) | 1233 | if (!name) |
1233 | return; | 1234 | return; |
@@ -1237,7 +1238,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, | |||
1237 | return; | 1238 | return; |
1238 | if (strcmp(name + namelen - strlen("_device_table"), "_device_table")) | 1239 | if (strcmp(name + namelen - strlen("_device_table"), "_device_table")) |
1239 | return; | 1240 | return; |
1240 | namelen -= strlen("_device_table"); | 1241 | identifier = strstr(name, "__"); |
1242 | if (!identifier) | ||
1243 | return; | ||
1244 | namelen = identifier - name; | ||
1241 | 1245 | ||
1242 | /* Handle all-NULL symbols allocated into .bss */ | 1246 | /* Handle all-NULL symbols allocated into .bss */ |
1243 | if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) { | 1247 | if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) { |