diff options
Diffstat (limited to 'scripts/mod/modpost.c')
-rw-r--r-- | scripts/mod/modpost.c | 49 |
1 files changed, 28 insertions, 21 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 1ec7158b6c1f..413c53693e62 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
@@ -420,11 +420,10 @@ static int parse_elf(struct elf_info *info, const char *filename) | |||
420 | return 0; | 420 | return 0; |
421 | } | 421 | } |
422 | 422 | ||
423 | if (hdr->e_shnum == 0) { | 423 | if (hdr->e_shnum == SHN_UNDEF) { |
424 | /* | 424 | /* |
425 | * There are more than 64k sections, | 425 | * There are more than 64k sections, |
426 | * read count from .sh_size. | 426 | * read count from .sh_size. |
427 | * note: it doesn't need shndx2secindex() | ||
428 | */ | 427 | */ |
429 | info->num_sections = TO_NATIVE(sechdrs[0].sh_size); | 428 | info->num_sections = TO_NATIVE(sechdrs[0].sh_size); |
430 | } | 429 | } |
@@ -432,8 +431,7 @@ static int parse_elf(struct elf_info *info, const char *filename) | |||
432 | info->num_sections = hdr->e_shnum; | 431 | info->num_sections = hdr->e_shnum; |
433 | } | 432 | } |
434 | if (hdr->e_shstrndx == SHN_XINDEX) { | 433 | if (hdr->e_shstrndx == SHN_XINDEX) { |
435 | info->secindex_strings = | 434 | info->secindex_strings = TO_NATIVE(sechdrs[0].sh_link); |
436 | shndx2secindex(TO_NATIVE(sechdrs[0].sh_link)); | ||
437 | } | 435 | } |
438 | else { | 436 | else { |
439 | info->secindex_strings = hdr->e_shstrndx; | 437 | info->secindex_strings = hdr->e_shstrndx; |
@@ -489,7 +487,7 @@ static int parse_elf(struct elf_info *info, const char *filename) | |||
489 | sechdrs[i].sh_offset; | 487 | sechdrs[i].sh_offset; |
490 | info->symtab_stop = (void *)hdr + | 488 | info->symtab_stop = (void *)hdr + |
491 | sechdrs[i].sh_offset + sechdrs[i].sh_size; | 489 | sechdrs[i].sh_offset + sechdrs[i].sh_size; |
492 | sh_link_idx = shndx2secindex(sechdrs[i].sh_link); | 490 | sh_link_idx = sechdrs[i].sh_link; |
493 | info->strtab = (void *)hdr + | 491 | info->strtab = (void *)hdr + |
494 | sechdrs[sh_link_idx].sh_offset; | 492 | sechdrs[sh_link_idx].sh_offset; |
495 | } | 493 | } |
@@ -516,11 +514,9 @@ static int parse_elf(struct elf_info *info, const char *filename) | |||
516 | 514 | ||
517 | if (symtab_shndx_idx != ~0U) { | 515 | if (symtab_shndx_idx != ~0U) { |
518 | Elf32_Word *p; | 516 | Elf32_Word *p; |
519 | if (symtab_idx != | 517 | if (symtab_idx != sechdrs[symtab_shndx_idx].sh_link) |
520 | shndx2secindex(sechdrs[symtab_shndx_idx].sh_link)) | ||
521 | fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n", | 518 | fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n", |
522 | filename, | 519 | filename, sechdrs[symtab_shndx_idx].sh_link, |
523 | shndx2secindex(sechdrs[symtab_shndx_idx].sh_link), | ||
524 | symtab_idx); | 520 | symtab_idx); |
525 | /* Fix endianness */ | 521 | /* Fix endianness */ |
526 | for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop; | 522 | for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop; |
@@ -790,6 +786,7 @@ static const char *section_white_list[] = | |||
790 | { | 786 | { |
791 | ".comment*", | 787 | ".comment*", |
792 | ".debug*", | 788 | ".debug*", |
789 | ".zdebug*", /* Compressed debug sections. */ | ||
793 | ".GCC-command-line", /* mn10300 */ | 790 | ".GCC-command-line", /* mn10300 */ |
794 | ".mdebug*", /* alpha, score, mips etc. */ | 791 | ".mdebug*", /* alpha, score, mips etc. */ |
795 | ".pdr", /* alpha, score, mips etc. */ | 792 | ".pdr", /* alpha, score, mips etc. */ |
@@ -1208,6 +1205,9 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr, | |||
1208 | * .cpuinit.data => __cpudata | 1205 | * .cpuinit.data => __cpudata |
1209 | * .memexitconst => __memconst | 1206 | * .memexitconst => __memconst |
1210 | * etc. | 1207 | * etc. |
1208 | * | ||
1209 | * The memory of returned value has been allocated on a heap. The user of this | ||
1210 | * method should free it after usage. | ||
1211 | */ | 1211 | */ |
1212 | static char *sec2annotation(const char *s) | 1212 | static char *sec2annotation(const char *s) |
1213 | { | 1213 | { |
@@ -1230,7 +1230,7 @@ static char *sec2annotation(const char *s) | |||
1230 | strcat(p, "data "); | 1230 | strcat(p, "data "); |
1231 | else | 1231 | else |
1232 | strcat(p, " "); | 1232 | strcat(p, " "); |
1233 | return r; /* we leak her but we do not care */ | 1233 | return r; |
1234 | } else { | 1234 | } else { |
1235 | return strdup(""); | 1235 | return strdup(""); |
1236 | } | 1236 | } |
@@ -1244,6 +1244,19 @@ static int is_function(Elf_Sym *sym) | |||
1244 | return -1; | 1244 | return -1; |
1245 | } | 1245 | } |
1246 | 1246 | ||
1247 | static void print_section_list(const char * const list[20]) | ||
1248 | { | ||
1249 | const char *const *s = list; | ||
1250 | |||
1251 | while (*s) { | ||
1252 | fprintf(stderr, "%s", *s); | ||
1253 | s++; | ||
1254 | if (*s) | ||
1255 | fprintf(stderr, ", "); | ||
1256 | } | ||
1257 | fprintf(stderr, "\n"); | ||
1258 | } | ||
1259 | |||
1247 | /* | 1260 | /* |
1248 | * Print a warning about a section mismatch. | 1261 | * Print a warning about a section mismatch. |
1249 | * Try to find symbols near it so user can find it. | 1262 | * Try to find symbols near it so user can find it. |
@@ -1300,7 +1313,6 @@ static void report_sec_mismatch(const char *modname, | |||
1300 | break; | 1313 | break; |
1301 | case DATA_TO_ANY_INIT: { | 1314 | case DATA_TO_ANY_INIT: { |
1302 | prl_to = sec2annotation(tosec); | 1315 | prl_to = sec2annotation(tosec); |
1303 | const char *const *s = mismatch->symbol_white_list; | ||
1304 | fprintf(stderr, | 1316 | fprintf(stderr, |
1305 | "The variable %s references\n" | 1317 | "The variable %s references\n" |
1306 | "the %s %s%s%s\n" | 1318 | "the %s %s%s%s\n" |
@@ -1308,9 +1320,7 @@ static void report_sec_mismatch(const char *modname, | |||
1308 | "variable with __init* or __refdata (see linux/init.h) " | 1320 | "variable with __init* or __refdata (see linux/init.h) " |
1309 | "or name the variable:\n", | 1321 | "or name the variable:\n", |
1310 | fromsym, to, prl_to, tosym, to_p); | 1322 | fromsym, to, prl_to, tosym, to_p); |
1311 | while (*s) | 1323 | print_section_list(mismatch->symbol_white_list); |
1312 | fprintf(stderr, "%s, ", *s++); | ||
1313 | fprintf(stderr, "\n"); | ||
1314 | free(prl_to); | 1324 | free(prl_to); |
1315 | break; | 1325 | break; |
1316 | } | 1326 | } |
@@ -1325,7 +1335,6 @@ static void report_sec_mismatch(const char *modname, | |||
1325 | break; | 1335 | break; |
1326 | case DATA_TO_ANY_EXIT: { | 1336 | case DATA_TO_ANY_EXIT: { |
1327 | prl_to = sec2annotation(tosec); | 1337 | prl_to = sec2annotation(tosec); |
1328 | const char *const *s = mismatch->symbol_white_list; | ||
1329 | fprintf(stderr, | 1338 | fprintf(stderr, |
1330 | "The variable %s references\n" | 1339 | "The variable %s references\n" |
1331 | "the %s %s%s%s\n" | 1340 | "the %s %s%s%s\n" |
@@ -1333,9 +1342,7 @@ static void report_sec_mismatch(const char *modname, | |||
1333 | "variable with __exit* (see linux/init.h) or " | 1342 | "variable with __exit* (see linux/init.h) or " |
1334 | "name the variable:\n", | 1343 | "name the variable:\n", |
1335 | fromsym, to, prl_to, tosym, to_p); | 1344 | fromsym, to, prl_to, tosym, to_p); |
1336 | while (*s) | 1345 | print_section_list(mismatch->symbol_white_list); |
1337 | fprintf(stderr, "%s, ", *s++); | ||
1338 | fprintf(stderr, "\n"); | ||
1339 | free(prl_to); | 1346 | free(prl_to); |
1340 | break; | 1347 | break; |
1341 | } | 1348 | } |
@@ -1435,10 +1442,10 @@ static unsigned int *reloc_location(struct elf_info *elf, | |||
1435 | Elf_Shdr *sechdr, Elf_Rela *r) | 1442 | Elf_Shdr *sechdr, Elf_Rela *r) |
1436 | { | 1443 | { |
1437 | Elf_Shdr *sechdrs = elf->sechdrs; | 1444 | Elf_Shdr *sechdrs = elf->sechdrs; |
1438 | int section = shndx2secindex(sechdr->sh_info); | 1445 | int section = sechdr->sh_info; |
1439 | 1446 | ||
1440 | return (void *)elf->hdr + sechdrs[section].sh_offset + | 1447 | return (void *)elf->hdr + sechdrs[section].sh_offset + |
1441 | r->r_offset - sechdrs[section].sh_addr; | 1448 | r->r_offset; |
1442 | } | 1449 | } |
1443 | 1450 | ||
1444 | static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) | 1451 | static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) |
@@ -1611,7 +1618,7 @@ static void section_rel(const char *modname, struct elf_info *elf, | |||
1611 | * A module includes a number of sections that are discarded | 1618 | * A module includes a number of sections that are discarded |
1612 | * either when loaded or when used as built-in. | 1619 | * either when loaded or when used as built-in. |
1613 | * For loaded modules all functions marked __init and all data | 1620 | * For loaded modules all functions marked __init and all data |
1614 | * marked __initdata will be discarded when the module has been intialized. | 1621 | * marked __initdata will be discarded when the module has been initialized. |
1615 | * Likewise for modules used built-in the sections marked __exit | 1622 | * Likewise for modules used built-in the sections marked __exit |
1616 | * are discarded because __exit marked function are supposed to be called | 1623 | * are discarded because __exit marked function are supposed to be called |
1617 | * only when a module is unloaded which never happens for built-in modules. | 1624 | * only when a module is unloaded which never happens for built-in modules. |