diff options
Diffstat (limited to 'scripts/mod')
| -rw-r--r-- | scripts/mod/file2alias.c | 63 | ||||
| -rw-r--r-- | scripts/mod/modpost.c | 109 | ||||
| -rw-r--r-- | scripts/mod/modpost.h | 43 |
3 files changed, 185 insertions, 30 deletions
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 220213e603db..88f3f07205f8 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c | |||
| @@ -796,6 +796,51 @@ static int do_platform_entry(const char *filename, | |||
| 796 | return 1; | 796 | return 1; |
| 797 | } | 797 | } |
| 798 | 798 | ||
| 799 | static int do_mdio_entry(const char *filename, | ||
| 800 | struct mdio_device_id *id, char *alias) | ||
| 801 | { | ||
| 802 | int i; | ||
| 803 | |||
| 804 | alias += sprintf(alias, MDIO_MODULE_PREFIX); | ||
| 805 | |||
| 806 | for (i = 0; i < 32; i++) { | ||
| 807 | if (!((id->phy_id_mask >> (31-i)) & 1)) | ||
| 808 | *(alias++) = '?'; | ||
| 809 | else if ((id->phy_id >> (31-i)) & 1) | ||
| 810 | *(alias++) = '1'; | ||
| 811 | else | ||
| 812 | *(alias++) = '0'; | ||
| 813 | } | ||
| 814 | |||
| 815 | /* Terminate the string */ | ||
| 816 | *alias = 0; | ||
| 817 | |||
| 818 | return 1; | ||
| 819 | } | ||
| 820 | |||
| 821 | /* Looks like: zorro:iN. */ | ||
| 822 | static int do_zorro_entry(const char *filename, struct zorro_device_id *id, | ||
| 823 | char *alias) | ||
| 824 | { | ||
| 825 | id->id = TO_NATIVE(id->id); | ||
| 826 | strcpy(alias, "zorro:"); | ||
| 827 | ADD(alias, "i", id->id != ZORRO_WILDCARD, id->id); | ||
| 828 | return 1; | ||
| 829 | } | ||
| 830 | |||
| 831 | /* looks like: "pnp:dD" */ | ||
| 832 | static int do_isapnp_entry(const char *filename, | ||
| 833 | struct isapnp_device_id *id, char *alias) | ||
| 834 | { | ||
| 835 | sprintf(alias, "pnp:d%c%c%c%x%x%x%x*", | ||
| 836 | 'A' + ((id->vendor >> 2) & 0x3f) - 1, | ||
| 837 | 'A' + (((id->vendor & 3) << 3) | ((id->vendor >> 13) & 7)) - 1, | ||
| 838 | 'A' + ((id->vendor >> 8) & 0x1f) - 1, | ||
| 839 | (id->function >> 4) & 0x0f, id->function & 0x0f, | ||
| 840 | (id->function >> 12) & 0x0f, (id->function >> 8) & 0x0f); | ||
| 841 | return 1; | ||
| 842 | } | ||
| 843 | |||
| 799 | /* Ignore any prefix, eg. some architectures prepend _ */ | 844 | /* Ignore any prefix, eg. some architectures prepend _ */ |
| 800 | static inline int sym_is(const char *symbol, const char *name) | 845 | static inline int sym_is(const char *symbol, const char *name) |
| 801 | { | 846 | { |
| @@ -839,16 +884,16 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, | |||
| 839 | char *zeros = NULL; | 884 | char *zeros = NULL; |
| 840 | 885 | ||
| 841 | /* We're looking for a section relative symbol */ | 886 | /* We're looking for a section relative symbol */ |
| 842 | if (!sym->st_shndx || sym->st_shndx >= info->hdr->e_shnum) | 887 | if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections) |
| 843 | return; | 888 | return; |
| 844 | 889 | ||
| 845 | /* Handle all-NULL symbols allocated into .bss */ | 890 | /* Handle all-NULL symbols allocated into .bss */ |
| 846 | if (info->sechdrs[sym->st_shndx].sh_type & SHT_NOBITS) { | 891 | if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) { |
| 847 | zeros = calloc(1, sym->st_size); | 892 | zeros = calloc(1, sym->st_size); |
| 848 | symval = zeros; | 893 | symval = zeros; |
| 849 | } else { | 894 | } else { |
| 850 | symval = (void *)info->hdr | 895 | symval = (void *)info->hdr |
| 851 | + info->sechdrs[sym->st_shndx].sh_offset | 896 | + info->sechdrs[get_secindex(info, sym)].sh_offset |
| 852 | + sym->st_value; | 897 | + sym->st_value; |
| 853 | } | 898 | } |
| 854 | 899 | ||
| @@ -943,6 +988,18 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, | |||
| 943 | do_table(symval, sym->st_size, | 988 | do_table(symval, sym->st_size, |
| 944 | sizeof(struct platform_device_id), "platform", | 989 | sizeof(struct platform_device_id), "platform", |
| 945 | do_platform_entry, mod); | 990 | do_platform_entry, mod); |
| 991 | else if (sym_is(symname, "__mod_mdio_device_table")) | ||
| 992 | do_table(symval, sym->st_size, | ||
| 993 | sizeof(struct mdio_device_id), "mdio", | ||
| 994 | do_mdio_entry, mod); | ||
| 995 | else if (sym_is(symname, "__mod_zorro_device_table")) | ||
| 996 | do_table(symval, sym->st_size, | ||
| 997 | sizeof(struct zorro_device_id), "zorro", | ||
| 998 | do_zorro_entry, mod); | ||
| 999 | else if (sym_is(symname, "__mod_isapnp_device_table")) | ||
| 1000 | do_table(symval, sym->st_size, | ||
| 1001 | sizeof(struct isapnp_device_id), "isa", | ||
| 1002 | do_isapnp_entry, mod); | ||
| 946 | free(zeros); | 1003 | free(zeros); |
| 947 | } | 1004 | } |
| 948 | 1005 | ||
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 3318692e4e76..c827309c29cf 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
| @@ -253,7 +253,7 @@ static enum export export_no(const char *s) | |||
| 253 | return export_unknown; | 253 | return export_unknown; |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | static enum export export_from_sec(struct elf_info *elf, Elf_Section sec) | 256 | static enum export export_from_sec(struct elf_info *elf, unsigned int sec) |
| 257 | { | 257 | { |
| 258 | if (sec == elf->export_sec) | 258 | if (sec == elf->export_sec) |
| 259 | return export_plain; | 259 | return export_plain; |
| @@ -373,6 +373,8 @@ static int parse_elf(struct elf_info *info, const char *filename) | |||
| 373 | Elf_Ehdr *hdr; | 373 | Elf_Ehdr *hdr; |
| 374 | Elf_Shdr *sechdrs; | 374 | Elf_Shdr *sechdrs; |
| 375 | Elf_Sym *sym; | 375 | Elf_Sym *sym; |
| 376 | const char *secstrings; | ||
| 377 | unsigned int symtab_idx = ~0U, symtab_shndx_idx = ~0U; | ||
| 376 | 378 | ||
| 377 | hdr = grab_file(filename, &info->size); | 379 | hdr = grab_file(filename, &info->size); |
| 378 | if (!hdr) { | 380 | if (!hdr) { |
| @@ -417,8 +419,27 @@ static int parse_elf(struct elf_info *info, const char *filename) | |||
| 417 | return 0; | 419 | return 0; |
| 418 | } | 420 | } |
| 419 | 421 | ||
| 422 | if (hdr->e_shnum == 0) { | ||
| 423 | /* | ||
| 424 | * There are more than 64k sections, | ||
| 425 | * read count from .sh_size. | ||
| 426 | * note: it doesn't need shndx2secindex() | ||
| 427 | */ | ||
| 428 | info->num_sections = TO_NATIVE(sechdrs[0].sh_size); | ||
| 429 | } | ||
| 430 | else { | ||
| 431 | info->num_sections = hdr->e_shnum; | ||
| 432 | } | ||
| 433 | if (hdr->e_shstrndx == SHN_XINDEX) { | ||
| 434 | info->secindex_strings = | ||
| 435 | shndx2secindex(TO_NATIVE(sechdrs[0].sh_link)); | ||
| 436 | } | ||
| 437 | else { | ||
| 438 | info->secindex_strings = hdr->e_shstrndx; | ||
| 439 | } | ||
| 440 | |||
| 420 | /* Fix endianness in section headers */ | 441 | /* Fix endianness in section headers */ |
| 421 | for (i = 0; i < hdr->e_shnum; i++) { | 442 | for (i = 0; i < info->num_sections; i++) { |
| 422 | sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name); | 443 | sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name); |
| 423 | sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type); | 444 | sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type); |
| 424 | sechdrs[i].sh_flags = TO_NATIVE(sechdrs[i].sh_flags); | 445 | sechdrs[i].sh_flags = TO_NATIVE(sechdrs[i].sh_flags); |
| @@ -431,9 +452,8 @@ static int parse_elf(struct elf_info *info, const char *filename) | |||
| 431 | sechdrs[i].sh_entsize = TO_NATIVE(sechdrs[i].sh_entsize); | 452 | sechdrs[i].sh_entsize = TO_NATIVE(sechdrs[i].sh_entsize); |
| 432 | } | 453 | } |
| 433 | /* Find symbol table. */ | 454 | /* Find symbol table. */ |
| 434 | for (i = 1; i < hdr->e_shnum; i++) { | 455 | secstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset; |
| 435 | const char *secstrings | 456 | for (i = 1; i < info->num_sections; i++) { |
| 436 | = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; | ||
| 437 | const char *secname; | 457 | const char *secname; |
| 438 | int nobits = sechdrs[i].sh_type == SHT_NOBITS; | 458 | int nobits = sechdrs[i].sh_type == SHT_NOBITS; |
| 439 | 459 | ||
| @@ -461,14 +481,26 @@ static int parse_elf(struct elf_info *info, const char *filename) | |||
| 461 | else if (strcmp(secname, "__ksymtab_gpl_future") == 0) | 481 | else if (strcmp(secname, "__ksymtab_gpl_future") == 0) |
| 462 | info->export_gpl_future_sec = i; | 482 | info->export_gpl_future_sec = i; |
| 463 | 483 | ||
| 464 | if (sechdrs[i].sh_type != SHT_SYMTAB) | 484 | if (sechdrs[i].sh_type == SHT_SYMTAB) { |
| 465 | continue; | 485 | unsigned int sh_link_idx; |
| 486 | symtab_idx = i; | ||
| 487 | info->symtab_start = (void *)hdr + | ||
| 488 | sechdrs[i].sh_offset; | ||
| 489 | info->symtab_stop = (void *)hdr + | ||
| 490 | sechdrs[i].sh_offset + sechdrs[i].sh_size; | ||
| 491 | sh_link_idx = shndx2secindex(sechdrs[i].sh_link); | ||
| 492 | info->strtab = (void *)hdr + | ||
| 493 | sechdrs[sh_link_idx].sh_offset; | ||
| 494 | } | ||
| 466 | 495 | ||
| 467 | info->symtab_start = (void *)hdr + sechdrs[i].sh_offset; | 496 | /* 32bit section no. table? ("more than 64k sections") */ |
| 468 | info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset | 497 | if (sechdrs[i].sh_type == SHT_SYMTAB_SHNDX) { |
| 469 | + sechdrs[i].sh_size; | 498 | symtab_shndx_idx = i; |
| 470 | info->strtab = (void *)hdr + | 499 | info->symtab_shndx_start = (void *)hdr + |
| 471 | sechdrs[sechdrs[i].sh_link].sh_offset; | 500 | sechdrs[i].sh_offset; |
| 501 | info->symtab_shndx_stop = (void *)hdr + | ||
| 502 | sechdrs[i].sh_offset + sechdrs[i].sh_size; | ||
| 503 | } | ||
| 472 | } | 504 | } |
| 473 | if (!info->symtab_start) | 505 | if (!info->symtab_start) |
| 474 | fatal("%s has no symtab?\n", filename); | 506 | fatal("%s has no symtab?\n", filename); |
| @@ -480,6 +512,21 @@ static int parse_elf(struct elf_info *info, const char *filename) | |||
| 480 | sym->st_value = TO_NATIVE(sym->st_value); | 512 | sym->st_value = TO_NATIVE(sym->st_value); |
| 481 | sym->st_size = TO_NATIVE(sym->st_size); | 513 | sym->st_size = TO_NATIVE(sym->st_size); |
| 482 | } | 514 | } |
| 515 | |||
| 516 | if (symtab_shndx_idx != ~0U) { | ||
| 517 | Elf32_Word *p; | ||
| 518 | if (symtab_idx != | ||
| 519 | shndx2secindex(sechdrs[symtab_shndx_idx].sh_link)) | ||
| 520 | fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n", | ||
| 521 | filename, | ||
| 522 | shndx2secindex(sechdrs[symtab_shndx_idx].sh_link), | ||
| 523 | symtab_idx); | ||
| 524 | /* Fix endianness */ | ||
| 525 | for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop; | ||
| 526 | p++) | ||
| 527 | *p = TO_NATIVE(*p); | ||
| 528 | } | ||
| 529 | |||
| 483 | return 1; | 530 | return 1; |
| 484 | } | 531 | } |
| 485 | 532 | ||
| @@ -503,6 +550,11 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname) | |||
| 503 | strncmp(symname, "_rest32gpr_", sizeof("_rest32gpr_") - 1) == 0 || | 550 | strncmp(symname, "_rest32gpr_", sizeof("_rest32gpr_") - 1) == 0 || |
| 504 | strncmp(symname, "_save32gpr_", sizeof("_save32gpr_") - 1) == 0) | 551 | strncmp(symname, "_save32gpr_", sizeof("_save32gpr_") - 1) == 0) |
| 505 | return 1; | 552 | return 1; |
| 553 | if (info->hdr->e_machine == EM_PPC64) | ||
| 554 | /* Special register function linked on all modules during final link of .ko */ | ||
| 555 | if (strncmp(symname, "_restgpr0_", sizeof("_restgpr0_") - 1) == 0 || | ||
| 556 | strncmp(symname, "_savegpr0_", sizeof("_savegpr0_") - 1) == 0) | ||
| 557 | return 1; | ||
| 506 | /* Do not ignore this symbol */ | 558 | /* Do not ignore this symbol */ |
| 507 | return 0; | 559 | return 0; |
| 508 | } | 560 | } |
| @@ -514,7 +566,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info, | |||
| 514 | Elf_Sym *sym, const char *symname) | 566 | Elf_Sym *sym, const char *symname) |
| 515 | { | 567 | { |
| 516 | unsigned int crc; | 568 | unsigned int crc; |
| 517 | enum export export = export_from_sec(info, sym->st_shndx); | 569 | enum export export = export_from_sec(info, get_secindex(info, sym)); |
| 518 | 570 | ||
| 519 | switch (sym->st_shndx) { | 571 | switch (sym->st_shndx) { |
| 520 | case SHN_COMMON: | 572 | case SHN_COMMON: |
| @@ -656,19 +708,19 @@ static const char *sym_name(struct elf_info *elf, Elf_Sym *sym) | |||
| 656 | return "(unknown)"; | 708 | return "(unknown)"; |
| 657 | } | 709 | } |
| 658 | 710 | ||
| 659 | static const char *sec_name(struct elf_info *elf, int shndx) | 711 | static const char *sec_name(struct elf_info *elf, int secindex) |
| 660 | { | 712 | { |
| 661 | Elf_Shdr *sechdrs = elf->sechdrs; | 713 | Elf_Shdr *sechdrs = elf->sechdrs; |
| 662 | return (void *)elf->hdr + | 714 | return (void *)elf->hdr + |
| 663 | elf->sechdrs[elf->hdr->e_shstrndx].sh_offset + | 715 | elf->sechdrs[elf->secindex_strings].sh_offset + |
| 664 | sechdrs[shndx].sh_name; | 716 | sechdrs[secindex].sh_name; |
| 665 | } | 717 | } |
| 666 | 718 | ||
| 667 | static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr) | 719 | static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr) |
| 668 | { | 720 | { |
| 669 | return (void *)elf->hdr + | 721 | return (void *)elf->hdr + |
| 670 | elf->sechdrs[elf->hdr->e_shstrndx].sh_offset + | 722 | elf->sechdrs[elf->secindex_strings].sh_offset + |
| 671 | sechdr->sh_name; | 723 | sechdr->sh_name; |
| 672 | } | 724 | } |
| 673 | 725 | ||
| 674 | /* if sym is empty or point to a string | 726 | /* if sym is empty or point to a string |
| @@ -1047,11 +1099,14 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr, | |||
| 1047 | Elf_Sym *near = NULL; | 1099 | Elf_Sym *near = NULL; |
| 1048 | Elf64_Sword distance = 20; | 1100 | Elf64_Sword distance = 20; |
| 1049 | Elf64_Sword d; | 1101 | Elf64_Sword d; |
| 1102 | unsigned int relsym_secindex; | ||
| 1050 | 1103 | ||
| 1051 | if (relsym->st_name != 0) | 1104 | if (relsym->st_name != 0) |
| 1052 | return relsym; | 1105 | return relsym; |
| 1106 | |||
| 1107 | relsym_secindex = get_secindex(elf, relsym); | ||
| 1053 | for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { | 1108 | for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { |
| 1054 | if (sym->st_shndx != relsym->st_shndx) | 1109 | if (get_secindex(elf, sym) != relsym_secindex) |
| 1055 | continue; | 1110 | continue; |
| 1056 | if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) | 1111 | if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) |
| 1057 | continue; | 1112 | continue; |
| @@ -1113,9 +1168,9 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr, | |||
| 1113 | for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { | 1168 | for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { |
| 1114 | const char *symsec; | 1169 | const char *symsec; |
| 1115 | 1170 | ||
| 1116 | if (sym->st_shndx >= SHN_LORESERVE) | 1171 | if (is_shndx_special(sym->st_shndx)) |
| 1117 | continue; | 1172 | continue; |
| 1118 | symsec = sec_name(elf, sym->st_shndx); | 1173 | symsec = sec_name(elf, get_secindex(elf, sym)); |
| 1119 | if (strcmp(symsec, sec) != 0) | 1174 | if (strcmp(symsec, sec) != 0) |
| 1120 | continue; | 1175 | continue; |
| 1121 | if (!is_valid_name(elf, sym)) | 1176 | if (!is_valid_name(elf, sym)) |
| @@ -1311,7 +1366,7 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf, | |||
| 1311 | const char *tosec; | 1366 | const char *tosec; |
| 1312 | const struct sectioncheck *mismatch; | 1367 | const struct sectioncheck *mismatch; |
| 1313 | 1368 | ||
| 1314 | tosec = sec_name(elf, sym->st_shndx); | 1369 | tosec = sec_name(elf, get_secindex(elf, sym)); |
| 1315 | mismatch = section_mismatch(fromsec, tosec); | 1370 | mismatch = section_mismatch(fromsec, tosec); |
| 1316 | if (mismatch) { | 1371 | if (mismatch) { |
| 1317 | Elf_Sym *to; | 1372 | Elf_Sym *to; |
| @@ -1339,10 +1394,10 @@ static unsigned int *reloc_location(struct elf_info *elf, | |||
| 1339 | Elf_Shdr *sechdr, Elf_Rela *r) | 1394 | Elf_Shdr *sechdr, Elf_Rela *r) |
| 1340 | { | 1395 | { |
| 1341 | Elf_Shdr *sechdrs = elf->sechdrs; | 1396 | Elf_Shdr *sechdrs = elf->sechdrs; |
| 1342 | int section = sechdr->sh_info; | 1397 | int section = shndx2secindex(sechdr->sh_info); |
| 1343 | 1398 | ||
| 1344 | return (void *)elf->hdr + sechdrs[section].sh_offset + | 1399 | return (void *)elf->hdr + sechdrs[section].sh_offset + |
| 1345 | (r->r_offset - sechdrs[section].sh_addr); | 1400 | r->r_offset - sechdrs[section].sh_addr; |
| 1346 | } | 1401 | } |
| 1347 | 1402 | ||
| 1348 | static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) | 1403 | static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) |
| @@ -1447,7 +1502,7 @@ static void section_rela(const char *modname, struct elf_info *elf, | |||
| 1447 | r.r_addend = TO_NATIVE(rela->r_addend); | 1502 | r.r_addend = TO_NATIVE(rela->r_addend); |
| 1448 | sym = elf->symtab_start + r_sym; | 1503 | sym = elf->symtab_start + r_sym; |
| 1449 | /* Skip special sections */ | 1504 | /* Skip special sections */ |
| 1450 | if (sym->st_shndx >= SHN_LORESERVE) | 1505 | if (is_shndx_special(sym->st_shndx)) |
| 1451 | continue; | 1506 | continue; |
| 1452 | check_section_mismatch(modname, elf, &r, sym, fromsec); | 1507 | check_section_mismatch(modname, elf, &r, sym, fromsec); |
| 1453 | } | 1508 | } |
| @@ -1505,7 +1560,7 @@ static void section_rel(const char *modname, struct elf_info *elf, | |||
| 1505 | } | 1560 | } |
| 1506 | sym = elf->symtab_start + r_sym; | 1561 | sym = elf->symtab_start + r_sym; |
| 1507 | /* Skip special sections */ | 1562 | /* Skip special sections */ |
| 1508 | if (sym->st_shndx >= SHN_LORESERVE) | 1563 | if (is_shndx_special(sym->st_shndx)) |
| 1509 | continue; | 1564 | continue; |
| 1510 | check_section_mismatch(modname, elf, &r, sym, fromsec); | 1565 | check_section_mismatch(modname, elf, &r, sym, fromsec); |
| 1511 | } | 1566 | } |
| @@ -1530,7 +1585,7 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
| 1530 | Elf_Shdr *sechdrs = elf->sechdrs; | 1585 | Elf_Shdr *sechdrs = elf->sechdrs; |
| 1531 | 1586 | ||
| 1532 | /* Walk through all sections */ | 1587 | /* Walk through all sections */ |
| 1533 | for (i = 0; i < elf->hdr->e_shnum; i++) { | 1588 | for (i = 0; i < elf->num_sections; i++) { |
| 1534 | check_section(modname, elf, &elf->sechdrs[i]); | 1589 | check_section(modname, elf, &elf->sechdrs[i]); |
| 1535 | /* We want to process only relocation sections and not .init */ | 1590 | /* We want to process only relocation sections and not .init */ |
| 1536 | if (sechdrs[i].sh_type == SHT_RELA) | 1591 | if (sechdrs[i].sh_type == SHT_RELA) |
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index be987a44f250..0388cfccac8d 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h | |||
| @@ -129,8 +129,51 @@ struct elf_info { | |||
| 129 | const char *strtab; | 129 | const char *strtab; |
| 130 | char *modinfo; | 130 | char *modinfo; |
| 131 | unsigned int modinfo_len; | 131 | unsigned int modinfo_len; |
| 132 | |||
| 133 | /* support for 32bit section numbers */ | ||
| 134 | |||
| 135 | unsigned int num_sections; /* max_secindex + 1 */ | ||
| 136 | unsigned int secindex_strings; | ||
| 137 | /* if Nth symbol table entry has .st_shndx = SHN_XINDEX, | ||
| 138 | * take shndx from symtab_shndx_start[N] instead */ | ||
| 139 | Elf32_Word *symtab_shndx_start; | ||
| 140 | Elf32_Word *symtab_shndx_stop; | ||
| 132 | }; | 141 | }; |
| 133 | 142 | ||
| 143 | static inline int is_shndx_special(unsigned int i) | ||
| 144 | { | ||
| 145 | return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE; | ||
| 146 | } | ||
| 147 | |||
| 148 | /* shndx is in [0..SHN_LORESERVE) U (SHN_HIRESERVE, 0xfffffff], thus: | ||
| 149 | * shndx == 0 <=> sechdrs[0] | ||
| 150 | * ...... | ||
| 151 | * shndx == SHN_LORESERVE-1 <=> sechdrs[SHN_LORESERVE-1] | ||
| 152 | * shndx == SHN_HIRESERVE+1 <=> sechdrs[SHN_LORESERVE] | ||
| 153 | * shndx == SHN_HIRESERVE+2 <=> sechdrs[SHN_LORESERVE+1] | ||
| 154 | * ...... | ||
| 155 | * fyi: sym->st_shndx is uint16, SHN_LORESERVE = ff00, SHN_HIRESERVE = ffff, | ||
| 156 | * so basically we map 0000..feff -> 0000..feff | ||
| 157 | * ff00..ffff -> (you are a bad boy, dont do it) | ||
| 158 | * 10000..xxxx -> ff00..(xxxx-0x100) | ||
| 159 | */ | ||
| 160 | static inline unsigned int shndx2secindex(unsigned int i) | ||
| 161 | { | ||
| 162 | if (i <= SHN_HIRESERVE) | ||
| 163 | return i; | ||
| 164 | return i - (SHN_HIRESERVE + 1 - SHN_LORESERVE); | ||
| 165 | } | ||
| 166 | |||
| 167 | /* Accessor for sym->st_shndx, hides ugliness of "64k sections" */ | ||
| 168 | static inline unsigned int get_secindex(const struct elf_info *info, | ||
| 169 | const Elf_Sym *sym) | ||
| 170 | { | ||
| 171 | if (sym->st_shndx != SHN_XINDEX) | ||
| 172 | return sym->st_shndx; | ||
| 173 | return shndx2secindex(info->symtab_shndx_start[sym - | ||
| 174 | info->symtab_start]); | ||
| 175 | } | ||
| 176 | |||
| 134 | /* file2alias.c */ | 177 | /* file2alias.c */ |
| 135 | extern unsigned int cross_build; | 178 | extern unsigned int cross_build; |
| 136 | void handle_moddevtable(struct module *mod, struct elf_info *info, | 179 | void handle_moddevtable(struct module *mod, struct elf_info *info, |
