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) { |
