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. |
