diff options
Diffstat (limited to 'scripts/mod/modpost.c')
-rw-r--r-- | scripts/mod/modpost.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 40610984a1b5..066355673930 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
@@ -623,7 +623,10 @@ static void handle_modversions(struct module *mod, struct elf_info *info, | |||
623 | 623 | ||
624 | switch (sym->st_shndx) { | 624 | switch (sym->st_shndx) { |
625 | case SHN_COMMON: | 625 | case SHN_COMMON: |
626 | warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name); | 626 | if (!strncmp(symname, "__gnu_lto_", sizeof("__gnu_lto_")-1)) { |
627 | /* Should warn here, but modpost runs before the linker */ | ||
628 | } else | ||
629 | warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name); | ||
627 | break; | 630 | break; |
628 | case SHN_UNDEF: | 631 | case SHN_UNDEF: |
629 | /* undefined symbol */ | 632 | /* undefined symbol */ |
@@ -849,6 +852,7 @@ static const char *section_white_list[] = | |||
849 | ".xt.lit", /* xtensa */ | 852 | ".xt.lit", /* xtensa */ |
850 | ".arcextmap*", /* arc */ | 853 | ".arcextmap*", /* arc */ |
851 | ".gnu.linkonce.arcext*", /* arc : modules */ | 854 | ".gnu.linkonce.arcext*", /* arc : modules */ |
855 | ".gnu.lto*", | ||
852 | NULL | 856 | NULL |
853 | }; | 857 | }; |
854 | 858 | ||
@@ -1455,6 +1459,10 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf, | |||
1455 | to = find_elf_symbol(elf, r->r_addend, sym); | 1459 | to = find_elf_symbol(elf, r->r_addend, sym); |
1456 | tosym = sym_name(elf, to); | 1460 | tosym = sym_name(elf, to); |
1457 | 1461 | ||
1462 | if (!strncmp(fromsym, "reference___initcall", | ||
1463 | sizeof("reference___initcall")-1)) | ||
1464 | return; | ||
1465 | |||
1458 | /* check whitelist - we may ignore it */ | 1466 | /* check whitelist - we may ignore it */ |
1459 | if (secref_whitelist(mismatch, | 1467 | if (secref_whitelist(mismatch, |
1460 | fromsec, fromsym, tosec, tosym)) { | 1468 | fromsec, fromsym, tosec, tosym)) { |
@@ -1502,6 +1510,16 @@ static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) | |||
1502 | #define R_ARM_JUMP24 29 | 1510 | #define R_ARM_JUMP24 29 |
1503 | #endif | 1511 | #endif |
1504 | 1512 | ||
1513 | #ifndef R_ARM_THM_CALL | ||
1514 | #define R_ARM_THM_CALL 10 | ||
1515 | #endif | ||
1516 | #ifndef R_ARM_THM_JUMP24 | ||
1517 | #define R_ARM_THM_JUMP24 30 | ||
1518 | #endif | ||
1519 | #ifndef R_ARM_THM_JUMP19 | ||
1520 | #define R_ARM_THM_JUMP19 51 | ||
1521 | #endif | ||
1522 | |||
1505 | static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) | 1523 | static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) |
1506 | { | 1524 | { |
1507 | unsigned int r_typ = ELF_R_TYPE(r->r_info); | 1525 | unsigned int r_typ = ELF_R_TYPE(r->r_info); |
@@ -1515,6 +1533,9 @@ static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) | |||
1515 | case R_ARM_PC24: | 1533 | case R_ARM_PC24: |
1516 | case R_ARM_CALL: | 1534 | case R_ARM_CALL: |
1517 | case R_ARM_JUMP24: | 1535 | case R_ARM_JUMP24: |
1536 | case R_ARM_THM_CALL: | ||
1537 | case R_ARM_THM_JUMP24: | ||
1538 | case R_ARM_THM_JUMP19: | ||
1518 | /* From ARM ABI: ((S + A) | T) - P */ | 1539 | /* From ARM ABI: ((S + A) | T) - P */ |
1519 | r->r_addend = (int)(long)(elf->hdr + | 1540 | r->r_addend = (int)(long)(elf->hdr + |
1520 | sechdr->sh_offset + | 1541 | sechdr->sh_offset + |
@@ -1680,6 +1701,19 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
1680 | } | 1701 | } |
1681 | } | 1702 | } |
1682 | 1703 | ||
1704 | static char *remove_dot(char *s) | ||
1705 | { | ||
1706 | char *end; | ||
1707 | int n = strcspn(s, "."); | ||
1708 | |||
1709 | if (n > 0 && s[n] != 0) { | ||
1710 | strtoul(s + n + 1, &end, 10); | ||
1711 | if (end > s + n + 1 && (*end == '.' || *end == 0)) | ||
1712 | s[n] = 0; | ||
1713 | } | ||
1714 | return s; | ||
1715 | } | ||
1716 | |||
1683 | static void read_symbols(char *modname) | 1717 | static void read_symbols(char *modname) |
1684 | { | 1718 | { |
1685 | const char *symname; | 1719 | const char *symname; |
@@ -1718,7 +1752,7 @@ static void read_symbols(char *modname) | |||
1718 | } | 1752 | } |
1719 | 1753 | ||
1720 | for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { | 1754 | for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { |
1721 | symname = info.strtab + sym->st_name; | 1755 | symname = remove_dot(info.strtab + sym->st_name); |
1722 | 1756 | ||
1723 | handle_modversions(mod, &info, sym, symname); | 1757 | handle_modversions(mod, &info, sym, symname); |
1724 | handle_moddevtable(mod, &info, sym, symname); | 1758 | handle_moddevtable(mod, &info, sym, symname); |