diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/module.c | 372 |
1 files changed, 157 insertions, 215 deletions
diff --git a/kernel/module.c b/kernel/module.c index a64b26cf1879..29dd232f8183 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -152,42 +152,38 @@ void __module_put_and_exit(struct module *mod, long code) | |||
| 152 | EXPORT_SYMBOL(__module_put_and_exit); | 152 | EXPORT_SYMBOL(__module_put_and_exit); |
| 153 | 153 | ||
| 154 | /* Find a module section: 0 means not found. */ | 154 | /* Find a module section: 0 means not found. */ |
| 155 | static unsigned int find_sec(Elf_Ehdr *hdr, | 155 | static unsigned int find_sec(const struct load_info *info, const char *name) |
| 156 | Elf_Shdr *sechdrs, | ||
| 157 | const char *secstrings, | ||
| 158 | const char *name) | ||
| 159 | { | 156 | { |
| 160 | unsigned int i; | 157 | unsigned int i; |
| 161 | 158 | ||
| 162 | for (i = 1; i < hdr->e_shnum; i++) | 159 | for (i = 1; i < info->hdr->e_shnum; i++) { |
| 160 | Elf_Shdr *shdr = &info->sechdrs[i]; | ||
| 163 | /* Alloc bit cleared means "ignore it." */ | 161 | /* Alloc bit cleared means "ignore it." */ |
| 164 | if ((sechdrs[i].sh_flags & SHF_ALLOC) | 162 | if ((shdr->sh_flags & SHF_ALLOC) |
| 165 | && strcmp(secstrings+sechdrs[i].sh_name, name) == 0) | 163 | && strcmp(info->secstrings + shdr->sh_name, name) == 0) |
| 166 | return i; | 164 | return i; |
| 165 | } | ||
| 167 | return 0; | 166 | return 0; |
| 168 | } | 167 | } |
| 169 | 168 | ||
| 170 | /* Find a module section, or NULL. */ | 169 | /* Find a module section, or NULL. */ |
| 171 | static void *section_addr(Elf_Ehdr *hdr, Elf_Shdr *shdrs, | 170 | static void *section_addr(const struct load_info *info, const char *name) |
| 172 | const char *secstrings, const char *name) | ||
| 173 | { | 171 | { |
| 174 | /* Section 0 has sh_addr 0. */ | 172 | /* Section 0 has sh_addr 0. */ |
| 175 | return (void *)shdrs[find_sec(hdr, shdrs, secstrings, name)].sh_addr; | 173 | return (void *)info->sechdrs[find_sec(info, name)].sh_addr; |
| 176 | } | 174 | } |
| 177 | 175 | ||
| 178 | /* Find a module section, or NULL. Fill in number of "objects" in section. */ | 176 | /* Find a module section, or NULL. Fill in number of "objects" in section. */ |
| 179 | static void *section_objs(Elf_Ehdr *hdr, | 177 | static void *section_objs(const struct load_info *info, |
| 180 | Elf_Shdr *sechdrs, | ||
| 181 | const char *secstrings, | ||
| 182 | const char *name, | 178 | const char *name, |
| 183 | size_t object_size, | 179 | size_t object_size, |
| 184 | unsigned int *num) | 180 | unsigned int *num) |
| 185 | { | 181 | { |
| 186 | unsigned int sec = find_sec(hdr, sechdrs, secstrings, name); | 182 | unsigned int sec = find_sec(info, name); |
| 187 | 183 | ||
| 188 | /* Section 0 has sh_addr 0 and sh_size 0. */ | 184 | /* Section 0 has sh_addr 0 and sh_size 0. */ |
| 189 | *num = sechdrs[sec].sh_size / object_size; | 185 | *num = info->sechdrs[sec].sh_size / object_size; |
| 190 | return (void *)sechdrs[sec].sh_addr; | 186 | return (void *)info->sechdrs[sec].sh_addr; |
| 191 | } | 187 | } |
| 192 | 188 | ||
| 193 | /* Provided by the linker */ | 189 | /* Provided by the linker */ |
| @@ -417,11 +413,9 @@ static void percpu_modfree(struct module *mod) | |||
| 417 | free_percpu(mod->percpu); | 413 | free_percpu(mod->percpu); |
| 418 | } | 414 | } |
| 419 | 415 | ||
| 420 | static unsigned int find_pcpusec(Elf_Ehdr *hdr, | 416 | static unsigned int find_pcpusec(struct load_info *info) |
| 421 | Elf_Shdr *sechdrs, | ||
| 422 | const char *secstrings) | ||
| 423 | { | 417 | { |
| 424 | return find_sec(hdr, sechdrs, secstrings, ".data..percpu"); | 418 | return find_sec(info, ".data..percpu"); |
| 425 | } | 419 | } |
| 426 | 420 | ||
| 427 | static void percpu_modcopy(struct module *mod, | 421 | static void percpu_modcopy(struct module *mod, |
| @@ -481,9 +475,7 @@ static inline int percpu_modalloc(struct module *mod, | |||
| 481 | static inline void percpu_modfree(struct module *mod) | 475 | static inline void percpu_modfree(struct module *mod) |
| 482 | { | 476 | { |
| 483 | } | 477 | } |
| 484 | static inline unsigned int find_pcpusec(Elf_Ehdr *hdr, | 478 | static unsigned int find_pcpusec(struct load_info *info) |
| 485 | Elf_Shdr *sechdrs, | ||
| 486 | const char *secstrings) | ||
| 487 | { | 479 | { |
| 488 | return 0; | 480 | return 0; |
| 489 | } | 481 | } |
| @@ -1067,10 +1059,9 @@ static inline int same_magic(const char *amagic, const char *bmagic, | |||
| 1067 | #endif /* CONFIG_MODVERSIONS */ | 1059 | #endif /* CONFIG_MODVERSIONS */ |
| 1068 | 1060 | ||
| 1069 | /* Resolve a symbol for this module. I.e. if we find one, record usage. */ | 1061 | /* Resolve a symbol for this module. I.e. if we find one, record usage. */ |
| 1070 | static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs, | 1062 | static const struct kernel_symbol *resolve_symbol(struct module *mod, |
| 1071 | unsigned int versindex, | 1063 | const struct load_info *info, |
| 1072 | const char *name, | 1064 | const char *name, |
| 1073 | struct module *mod, | ||
| 1074 | char ownername[]) | 1065 | char ownername[]) |
| 1075 | { | 1066 | { |
| 1076 | struct module *owner; | 1067 | struct module *owner; |
| @@ -1084,7 +1075,8 @@ static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs, | |||
| 1084 | if (!sym) | 1075 | if (!sym) |
| 1085 | goto unlock; | 1076 | goto unlock; |
| 1086 | 1077 | ||
| 1087 | if (!check_version(sechdrs, versindex, name, mod, crc, owner)) { | 1078 | if (!check_version(info->sechdrs, info->index.vers, name, mod, crc, |
| 1079 | owner)) { | ||
| 1088 | sym = ERR_PTR(-EINVAL); | 1080 | sym = ERR_PTR(-EINVAL); |
| 1089 | goto getname; | 1081 | goto getname; |
| 1090 | } | 1082 | } |
| @@ -1103,21 +1095,20 @@ unlock: | |||
| 1103 | return sym; | 1095 | return sym; |
| 1104 | } | 1096 | } |
| 1105 | 1097 | ||
| 1106 | static const struct kernel_symbol *resolve_symbol_wait(Elf_Shdr *sechdrs, | 1098 | static const struct kernel_symbol * |
| 1107 | unsigned int versindex, | 1099 | resolve_symbol_wait(struct module *mod, |
| 1108 | const char *name, | 1100 | const struct load_info *info, |
| 1109 | struct module *mod) | 1101 | const char *name) |
| 1110 | { | 1102 | { |
| 1111 | const struct kernel_symbol *ksym; | 1103 | const struct kernel_symbol *ksym; |
| 1112 | char ownername[MODULE_NAME_LEN]; | 1104 | char owner[MODULE_NAME_LEN]; |
| 1113 | 1105 | ||
| 1114 | if (wait_event_interruptible_timeout(module_wq, | 1106 | if (wait_event_interruptible_timeout(module_wq, |
| 1115 | !IS_ERR(ksym = resolve_symbol(sechdrs, versindex, name, | 1107 | !IS_ERR(ksym = resolve_symbol(mod, info, name, owner)) |
| 1116 | mod, ownername)) || | 1108 | || PTR_ERR(ksym) != -EBUSY, |
| 1117 | PTR_ERR(ksym) != -EBUSY, | ||
| 1118 | 30 * HZ) <= 0) { | 1109 | 30 * HZ) <= 0) { |
| 1119 | printk(KERN_WARNING "%s: gave up waiting for init of module %s.\n", | 1110 | printk(KERN_WARNING "%s: gave up waiting for init of module %s.\n", |
| 1120 | mod->name, ownername); | 1111 | mod->name, owner); |
| 1121 | } | 1112 | } |
| 1122 | return ksym; | 1113 | return ksym; |
| 1123 | } | 1114 | } |
| @@ -1640,25 +1631,23 @@ static int verify_export_symbols(struct module *mod) | |||
| 1640 | } | 1631 | } |
| 1641 | 1632 | ||
| 1642 | /* Change all symbols so that st_value encodes the pointer directly. */ | 1633 | /* Change all symbols so that st_value encodes the pointer directly. */ |
| 1643 | static int simplify_symbols(Elf_Shdr *sechdrs, | 1634 | static int simplify_symbols(struct module *mod, const struct load_info *info) |
| 1644 | unsigned int symindex, | 1635 | { |
| 1645 | const char *strtab, | 1636 | Elf_Shdr *symsec = &info->sechdrs[info->index.sym]; |
| 1646 | unsigned int versindex, | 1637 | Elf_Sym *sym = (void *)symsec->sh_addr; |
| 1647 | unsigned int pcpuindex, | ||
| 1648 | struct module *mod) | ||
| 1649 | { | ||
| 1650 | Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr; | ||
| 1651 | unsigned long secbase; | 1638 | unsigned long secbase; |
| 1652 | unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym); | 1639 | unsigned int i; |
| 1653 | int ret = 0; | 1640 | int ret = 0; |
| 1654 | const struct kernel_symbol *ksym; | 1641 | const struct kernel_symbol *ksym; |
| 1655 | 1642 | ||
| 1656 | for (i = 1; i < n; i++) { | 1643 | for (i = 1; i < symsec->sh_size / sizeof(Elf_Sym); i++) { |
| 1644 | const char *name = info->strtab + sym[i].st_name; | ||
| 1645 | |||
| 1657 | switch (sym[i].st_shndx) { | 1646 | switch (sym[i].st_shndx) { |
| 1658 | case SHN_COMMON: | 1647 | case SHN_COMMON: |
| 1659 | /* We compiled with -fno-common. These are not | 1648 | /* We compiled with -fno-common. These are not |
| 1660 | supposed to happen. */ | 1649 | supposed to happen. */ |
| 1661 | DEBUGP("Common symbol: %s\n", strtab + sym[i].st_name); | 1650 | DEBUGP("Common symbol: %s\n", name); |
| 1662 | printk("%s: please compile with -fno-common\n", | 1651 | printk("%s: please compile with -fno-common\n", |
| 1663 | mod->name); | 1652 | mod->name); |
| 1664 | ret = -ENOEXEC; | 1653 | ret = -ENOEXEC; |
| @@ -1671,9 +1660,7 @@ static int simplify_symbols(Elf_Shdr *sechdrs, | |||
| 1671 | break; | 1660 | break; |
| 1672 | 1661 | ||
| 1673 | case SHN_UNDEF: | 1662 | case SHN_UNDEF: |
| 1674 | ksym = resolve_symbol_wait(sechdrs, versindex, | 1663 | ksym = resolve_symbol_wait(mod, info, name); |
| 1675 | strtab + sym[i].st_name, | ||
| 1676 | mod); | ||
| 1677 | /* Ok if resolved. */ | 1664 | /* Ok if resolved. */ |
| 1678 | if (ksym && !IS_ERR(ksym)) { | 1665 | if (ksym && !IS_ERR(ksym)) { |
| 1679 | sym[i].st_value = ksym->value; | 1666 | sym[i].st_value = ksym->value; |
| @@ -1685,17 +1672,16 @@ static int simplify_symbols(Elf_Shdr *sechdrs, | |||
| 1685 | break; | 1672 | break; |
| 1686 | 1673 | ||
| 1687 | printk(KERN_WARNING "%s: Unknown symbol %s (err %li)\n", | 1674 | printk(KERN_WARNING "%s: Unknown symbol %s (err %li)\n", |
| 1688 | mod->name, strtab + sym[i].st_name, | 1675 | mod->name, name, PTR_ERR(ksym)); |
| 1689 | PTR_ERR(ksym)); | ||
| 1690 | ret = PTR_ERR(ksym) ?: -ENOENT; | 1676 | ret = PTR_ERR(ksym) ?: -ENOENT; |
| 1691 | break; | 1677 | break; |
| 1692 | 1678 | ||
| 1693 | default: | 1679 | default: |
| 1694 | /* Divert to percpu allocation if a percpu var. */ | 1680 | /* Divert to percpu allocation if a percpu var. */ |
| 1695 | if (sym[i].st_shndx == pcpuindex) | 1681 | if (sym[i].st_shndx == info->index.pcpu) |
| 1696 | secbase = (unsigned long)mod_percpu(mod); | 1682 | secbase = (unsigned long)mod_percpu(mod); |
| 1697 | else | 1683 | else |
| 1698 | secbase = sechdrs[sym[i].st_shndx].sh_addr; | 1684 | secbase = info->sechdrs[sym[i].st_shndx].sh_addr; |
| 1699 | sym[i].st_value += secbase; | 1685 | sym[i].st_value += secbase; |
| 1700 | break; | 1686 | break; |
| 1701 | } | 1687 | } |
| @@ -1704,33 +1690,29 @@ static int simplify_symbols(Elf_Shdr *sechdrs, | |||
| 1704 | return ret; | 1690 | return ret; |
| 1705 | } | 1691 | } |
| 1706 | 1692 | ||
| 1707 | static int apply_relocations(struct module *mod, | 1693 | static int apply_relocations(struct module *mod, const struct load_info *info) |
| 1708 | Elf_Ehdr *hdr, | ||
| 1709 | Elf_Shdr *sechdrs, | ||
| 1710 | unsigned int symindex, | ||
| 1711 | unsigned int strindex) | ||
| 1712 | { | 1694 | { |
| 1713 | unsigned int i; | 1695 | unsigned int i; |
| 1714 | int err = 0; | 1696 | int err = 0; |
| 1715 | 1697 | ||
| 1716 | /* Now do relocations. */ | 1698 | /* Now do relocations. */ |
| 1717 | for (i = 1; i < hdr->e_shnum; i++) { | 1699 | for (i = 1; i < info->hdr->e_shnum; i++) { |
| 1718 | const char *strtab = (char *)sechdrs[strindex].sh_addr; | 1700 | unsigned int infosec = info->sechdrs[i].sh_info; |
| 1719 | unsigned int info = sechdrs[i].sh_info; | ||
| 1720 | 1701 | ||
| 1721 | /* Not a valid relocation section? */ | 1702 | /* Not a valid relocation section? */ |
| 1722 | if (info >= hdr->e_shnum) | 1703 | if (infosec >= info->hdr->e_shnum) |
| 1723 | continue; | 1704 | continue; |
| 1724 | 1705 | ||
| 1725 | /* Don't bother with non-allocated sections */ | 1706 | /* Don't bother with non-allocated sections */ |
| 1726 | if (!(sechdrs[info].sh_flags & SHF_ALLOC)) | 1707 | if (!(info->sechdrs[infosec].sh_flags & SHF_ALLOC)) |
| 1727 | continue; | 1708 | continue; |
| 1728 | 1709 | ||
| 1729 | if (sechdrs[i].sh_type == SHT_REL) | 1710 | if (info->sechdrs[i].sh_type == SHT_REL) |
| 1730 | err = apply_relocate(sechdrs, strtab, symindex, i, mod); | 1711 | err = apply_relocate(info->sechdrs, info->strtab, |
| 1731 | else if (sechdrs[i].sh_type == SHT_RELA) | 1712 | info->index.sym, i, mod); |
| 1732 | err = apply_relocate_add(sechdrs, strtab, symindex, i, | 1713 | else if (info->sechdrs[i].sh_type == SHT_RELA) |
| 1733 | mod); | 1714 | err = apply_relocate_add(info->sechdrs, info->strtab, |
| 1715 | info->index.sym, i, mod); | ||
| 1734 | if (err < 0) | 1716 | if (err < 0) |
| 1735 | break; | 1717 | break; |
| 1736 | } | 1718 | } |
| @@ -1761,10 +1743,7 @@ static long get_offset(struct module *mod, unsigned int *size, | |||
| 1761 | might -- code, read-only data, read-write data, small data. Tally | 1743 | might -- code, read-only data, read-write data, small data. Tally |
| 1762 | sizes, and place the offsets into sh_entsize fields: high bit means it | 1744 | sizes, and place the offsets into sh_entsize fields: high bit means it |
| 1763 | belongs in init. */ | 1745 | belongs in init. */ |
| 1764 | static void layout_sections(struct module *mod, | 1746 | static void layout_sections(struct module *mod, struct load_info *info) |
| 1765 | const Elf_Ehdr *hdr, | ||
| 1766 | Elf_Shdr *sechdrs, | ||
| 1767 | const char *secstrings) | ||
| 1768 | { | 1747 | { |
| 1769 | static unsigned long const masks[][2] = { | 1748 | static unsigned long const masks[][2] = { |
| 1770 | /* NOTE: all executable code must be the first section | 1749 | /* NOTE: all executable code must be the first section |
| @@ -1777,21 +1756,22 @@ static void layout_sections(struct module *mod, | |||
| 1777 | }; | 1756 | }; |
| 1778 | unsigned int m, i; | 1757 | unsigned int m, i; |
| 1779 | 1758 | ||
| 1780 | for (i = 0; i < hdr->e_shnum; i++) | 1759 | for (i = 0; i < info->hdr->e_shnum; i++) |
| 1781 | sechdrs[i].sh_entsize = ~0UL; | 1760 | info->sechdrs[i].sh_entsize = ~0UL; |
| 1782 | 1761 | ||
| 1783 | DEBUGP("Core section allocation order:\n"); | 1762 | DEBUGP("Core section allocation order:\n"); |
| 1784 | for (m = 0; m < ARRAY_SIZE(masks); ++m) { | 1763 | for (m = 0; m < ARRAY_SIZE(masks); ++m) { |
| 1785 | for (i = 0; i < hdr->e_shnum; ++i) { | 1764 | for (i = 0; i < info->hdr->e_shnum; ++i) { |
| 1786 | Elf_Shdr *s = &sechdrs[i]; | 1765 | Elf_Shdr *s = &info->sechdrs[i]; |
| 1766 | const char *sname = info->secstrings + s->sh_name; | ||
| 1787 | 1767 | ||
| 1788 | if ((s->sh_flags & masks[m][0]) != masks[m][0] | 1768 | if ((s->sh_flags & masks[m][0]) != masks[m][0] |
| 1789 | || (s->sh_flags & masks[m][1]) | 1769 | || (s->sh_flags & masks[m][1]) |
| 1790 | || s->sh_entsize != ~0UL | 1770 | || s->sh_entsize != ~0UL |
| 1791 | || strstarts(secstrings + s->sh_name, ".init")) | 1771 | || strstarts(sname, ".init")) |
| 1792 | continue; | 1772 | continue; |
| 1793 | s->sh_entsize = get_offset(mod, &mod->core_size, s, i); | 1773 | s->sh_entsize = get_offset(mod, &mod->core_size, s, i); |
| 1794 | DEBUGP("\t%s\n", secstrings + s->sh_name); | 1774 | DEBUGP("\t%s\n", name); |
| 1795 | } | 1775 | } |
| 1796 | if (m == 0) | 1776 | if (m == 0) |
| 1797 | mod->core_text_size = mod->core_size; | 1777 | mod->core_text_size = mod->core_size; |
| @@ -1799,17 +1779,18 @@ static void layout_sections(struct module *mod, | |||
| 1799 | 1779 | ||
| 1800 | DEBUGP("Init section allocation order:\n"); | 1780 | DEBUGP("Init section allocation order:\n"); |
| 1801 | for (m = 0; m < ARRAY_SIZE(masks); ++m) { | 1781 | for (m = 0; m < ARRAY_SIZE(masks); ++m) { |
| 1802 | for (i = 0; i < hdr->e_shnum; ++i) { | 1782 | for (i = 0; i < info->hdr->e_shnum; ++i) { |
| 1803 | Elf_Shdr *s = &sechdrs[i]; | 1783 | Elf_Shdr *s = &info->sechdrs[i]; |
| 1784 | const char *sname = info->secstrings + s->sh_name; | ||
| 1804 | 1785 | ||
| 1805 | if ((s->sh_flags & masks[m][0]) != masks[m][0] | 1786 | if ((s->sh_flags & masks[m][0]) != masks[m][0] |
| 1806 | || (s->sh_flags & masks[m][1]) | 1787 | || (s->sh_flags & masks[m][1]) |
| 1807 | || s->sh_entsize != ~0UL | 1788 | || s->sh_entsize != ~0UL |
| 1808 | || !strstarts(secstrings + s->sh_name, ".init")) | 1789 | || !strstarts(sname, ".init")) |
| 1809 | continue; | 1790 | continue; |
| 1810 | s->sh_entsize = (get_offset(mod, &mod->init_size, s, i) | 1791 | s->sh_entsize = (get_offset(mod, &mod->init_size, s, i) |
| 1811 | | INIT_OFFSET_MASK); | 1792 | | INIT_OFFSET_MASK); |
| 1812 | DEBUGP("\t%s\n", secstrings + s->sh_name); | 1793 | DEBUGP("\t%s\n", sname); |
| 1813 | } | 1794 | } |
| 1814 | if (m == 0) | 1795 | if (m == 0) |
| 1815 | mod->init_text_size = mod->init_size; | 1796 | mod->init_text_size = mod->init_size; |
| @@ -1848,33 +1829,28 @@ static char *next_string(char *string, unsigned long *secsize) | |||
| 1848 | return string; | 1829 | return string; |
| 1849 | } | 1830 | } |
| 1850 | 1831 | ||
| 1851 | static char *get_modinfo(const Elf_Shdr *sechdrs, | 1832 | static char *get_modinfo(struct load_info *info, const char *tag) |
| 1852 | unsigned int info, | ||
| 1853 | const char *tag) | ||
| 1854 | { | 1833 | { |
| 1855 | char *p; | 1834 | char *p; |
| 1856 | unsigned int taglen = strlen(tag); | 1835 | unsigned int taglen = strlen(tag); |
| 1857 | unsigned long size = sechdrs[info].sh_size; | 1836 | Elf_Shdr *infosec = &info->sechdrs[info->index.info]; |
| 1837 | unsigned long size = infosec->sh_size; | ||
| 1858 | 1838 | ||
| 1859 | for (p = (char *)sechdrs[info].sh_addr; p; p = next_string(p, &size)) { | 1839 | for (p = (char *)infosec->sh_addr; p; p = next_string(p, &size)) { |
| 1860 | if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=') | 1840 | if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=') |
| 1861 | return p + taglen + 1; | 1841 | return p + taglen + 1; |
| 1862 | } | 1842 | } |
| 1863 | return NULL; | 1843 | return NULL; |
| 1864 | } | 1844 | } |
| 1865 | 1845 | ||
| 1866 | static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs, | 1846 | static void setup_modinfo(struct module *mod, struct load_info *info) |
| 1867 | unsigned int infoindex) | ||
| 1868 | { | 1847 | { |
| 1869 | struct module_attribute *attr; | 1848 | struct module_attribute *attr; |
| 1870 | int i; | 1849 | int i; |
| 1871 | 1850 | ||
| 1872 | for (i = 0; (attr = modinfo_attrs[i]); i++) { | 1851 | for (i = 0; (attr = modinfo_attrs[i]); i++) { |
| 1873 | if (attr->setup) | 1852 | if (attr->setup) |
| 1874 | attr->setup(mod, | 1853 | attr->setup(mod, get_modinfo(info, attr->attr.name)); |
| 1875 | get_modinfo(sechdrs, | ||
| 1876 | infoindex, | ||
| 1877 | attr->attr.name)); | ||
| 1878 | } | 1854 | } |
| 1879 | } | 1855 | } |
| 1880 | 1856 | ||
| @@ -1976,56 +1952,45 @@ static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs, | |||
| 1976 | return true; | 1952 | return true; |
| 1977 | } | 1953 | } |
| 1978 | 1954 | ||
| 1979 | static unsigned long layout_symtab(struct module *mod, | 1955 | static void layout_symtab(struct module *mod, struct load_info *info) |
| 1980 | Elf_Shdr *sechdrs, | ||
| 1981 | unsigned int symindex, | ||
| 1982 | unsigned int strindex, | ||
| 1983 | const Elf_Ehdr *hdr, | ||
| 1984 | const char *secstrings, | ||
| 1985 | unsigned long *pstroffs, | ||
| 1986 | unsigned long *strmap) | ||
| 1987 | { | 1956 | { |
| 1988 | unsigned long symoffs; | 1957 | Elf_Shdr *symsect = info->sechdrs + info->index.sym; |
| 1989 | Elf_Shdr *symsect = sechdrs + symindex; | 1958 | Elf_Shdr *strsect = info->sechdrs + info->index.str; |
| 1990 | Elf_Shdr *strsect = sechdrs + strindex; | ||
| 1991 | const Elf_Sym *src; | 1959 | const Elf_Sym *src; |
| 1992 | const char *strtab; | ||
| 1993 | unsigned int i, nsrc, ndst; | 1960 | unsigned int i, nsrc, ndst; |
| 1994 | 1961 | ||
| 1995 | /* Put symbol section at end of init part of module. */ | 1962 | /* Put symbol section at end of init part of module. */ |
| 1996 | symsect->sh_flags |= SHF_ALLOC; | 1963 | symsect->sh_flags |= SHF_ALLOC; |
| 1997 | symsect->sh_entsize = get_offset(mod, &mod->init_size, symsect, | 1964 | symsect->sh_entsize = get_offset(mod, &mod->init_size, symsect, |
| 1998 | symindex) | INIT_OFFSET_MASK; | 1965 | info->index.sym) | INIT_OFFSET_MASK; |
| 1999 | DEBUGP("\t%s\n", secstrings + symsect->sh_name); | 1966 | DEBUGP("\t%s\n", info->secstrings + symsect->sh_name); |
| 2000 | 1967 | ||
| 2001 | src = (void *)hdr + symsect->sh_offset; | 1968 | src = (void *)info->hdr + symsect->sh_offset; |
| 2002 | nsrc = symsect->sh_size / sizeof(*src); | 1969 | nsrc = symsect->sh_size / sizeof(*src); |
| 2003 | strtab = (void *)hdr + strsect->sh_offset; | ||
| 2004 | for (ndst = i = 1; i < nsrc; ++i, ++src) | 1970 | for (ndst = i = 1; i < nsrc; ++i, ++src) |
| 2005 | if (is_core_symbol(src, sechdrs, hdr->e_shnum)) { | 1971 | if (is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) { |
| 2006 | unsigned int j = src->st_name; | 1972 | unsigned int j = src->st_name; |
| 2007 | 1973 | ||
| 2008 | while(!__test_and_set_bit(j, strmap) && strtab[j]) | 1974 | while (!__test_and_set_bit(j, info->strmap) |
| 1975 | && info->strtab[j]) | ||
| 2009 | ++j; | 1976 | ++j; |
| 2010 | ++ndst; | 1977 | ++ndst; |
| 2011 | } | 1978 | } |
| 2012 | 1979 | ||
| 2013 | /* Append room for core symbols at end of core part. */ | 1980 | /* Append room for core symbols at end of core part. */ |
| 2014 | symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1); | 1981 | info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1); |
| 2015 | mod->core_size = symoffs + ndst * sizeof(Elf_Sym); | 1982 | mod->core_size = info->symoffs + ndst * sizeof(Elf_Sym); |
| 2016 | 1983 | ||
| 2017 | /* Put string table section at end of init part of module. */ | 1984 | /* Put string table section at end of init part of module. */ |
| 2018 | strsect->sh_flags |= SHF_ALLOC; | 1985 | strsect->sh_flags |= SHF_ALLOC; |
| 2019 | strsect->sh_entsize = get_offset(mod, &mod->init_size, strsect, | 1986 | strsect->sh_entsize = get_offset(mod, &mod->init_size, strsect, |
| 2020 | strindex) | INIT_OFFSET_MASK; | 1987 | info->index.str) | INIT_OFFSET_MASK; |
| 2021 | DEBUGP("\t%s\n", secstrings + strsect->sh_name); | 1988 | DEBUGP("\t%s\n", info->secstrings + strsect->sh_name); |
| 2022 | 1989 | ||
| 2023 | /* Append room for core symbols' strings at end of core part. */ | 1990 | /* Append room for core symbols' strings at end of core part. */ |
| 2024 | *pstroffs = mod->core_size; | 1991 | info->stroffs = mod->core_size; |
| 2025 | __set_bit(0, strmap); | 1992 | __set_bit(0, info->strmap); |
| 2026 | mod->core_size += bitmap_weight(strmap, strsect->sh_size); | 1993 | mod->core_size += bitmap_weight(info->strmap, strsect->sh_size); |
| 2027 | |||
| 2028 | return symoffs; | ||
| 2029 | } | 1994 | } |
| 2030 | 1995 | ||
| 2031 | static void add_kallsyms(struct module *mod, struct load_info *info) | 1996 | static void add_kallsyms(struct module *mod, struct load_info *info) |
| @@ -2064,16 +2029,8 @@ static void add_kallsyms(struct module *mod, struct load_info *info) | |||
| 2064 | *++s = mod->strtab[i]; | 2029 | *++s = mod->strtab[i]; |
| 2065 | } | 2030 | } |
| 2066 | #else | 2031 | #else |
| 2067 | static inline unsigned long layout_symtab(struct module *mod, | 2032 | static inline void layout_symtab(struct module *mod, struct load_info *info) |
| 2068 | Elf_Shdr *sechdrs, | ||
| 2069 | unsigned int symindex, | ||
| 2070 | unsigned int strindex, | ||
| 2071 | const Elf_Ehdr *hdr, | ||
| 2072 | const char *secstrings, | ||
| 2073 | unsigned long *pstroffs, | ||
| 2074 | unsigned long *strmap) | ||
| 2075 | { | 2033 | { |
| 2076 | return 0; | ||
| 2077 | } | 2034 | } |
| 2078 | 2035 | ||
| 2079 | static void add_kallsyms(struct module *mod, struct load_info *info) | 2036 | static void add_kallsyms(struct module *mod, struct load_info *info) |
| @@ -2113,30 +2070,28 @@ static void *module_alloc_update_bounds(unsigned long size) | |||
| 2113 | } | 2070 | } |
| 2114 | 2071 | ||
| 2115 | #ifdef CONFIG_DEBUG_KMEMLEAK | 2072 | #ifdef CONFIG_DEBUG_KMEMLEAK |
| 2116 | static void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr, | 2073 | static void kmemleak_load_module(const struct module *mod, |
| 2117 | const Elf_Shdr *sechdrs, | 2074 | const struct load_info *info) |
| 2118 | const char *secstrings) | ||
| 2119 | { | 2075 | { |
| 2120 | unsigned int i; | 2076 | unsigned int i; |
| 2121 | 2077 | ||
| 2122 | /* only scan the sections containing data */ | 2078 | /* only scan the sections containing data */ |
| 2123 | kmemleak_scan_area(mod, sizeof(struct module), GFP_KERNEL); | 2079 | kmemleak_scan_area(mod, sizeof(struct module), GFP_KERNEL); |
| 2124 | 2080 | ||
| 2125 | for (i = 1; i < hdr->e_shnum; i++) { | 2081 | for (i = 1; i < info->hdr->e_shnum; i++) { |
| 2126 | if (!(sechdrs[i].sh_flags & SHF_ALLOC)) | 2082 | const char *name = info->secstrings + info->sechdrs[i].sh_name; |
| 2083 | if (!(info->sechdrs[i].sh_flags & SHF_ALLOC)) | ||
| 2127 | continue; | 2084 | continue; |
| 2128 | if (strncmp(secstrings + sechdrs[i].sh_name, ".data", 5) != 0 | 2085 | if (!strstarts(name, ".data") && !strstarts(name, ".bss")) |
| 2129 | && strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) != 0) | ||
| 2130 | continue; | 2086 | continue; |
| 2131 | 2087 | ||
| 2132 | kmemleak_scan_area((void *)sechdrs[i].sh_addr, | 2088 | kmemleak_scan_area((void *)info->sechdrs[i].sh_addr, |
| 2133 | sechdrs[i].sh_size, GFP_KERNEL); | 2089 | info->sechdrs[i].sh_size, GFP_KERNEL); |
| 2134 | } | 2090 | } |
| 2135 | } | 2091 | } |
| 2136 | #else | 2092 | #else |
| 2137 | static inline void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr, | 2093 | static inline void kmemleak_load_module(const struct module *mod, |
| 2138 | Elf_Shdr *sechdrs, | 2094 | const struct load_info *info) |
| 2139 | const char *secstrings) | ||
| 2140 | { | 2095 | { |
| 2141 | } | 2096 | } |
| 2142 | #endif | 2097 | #endif |
| @@ -2227,8 +2182,8 @@ static int rewrite_section_headers(struct load_info *info) | |||
| 2227 | } | 2182 | } |
| 2228 | 2183 | ||
| 2229 | /* Track but don't keep modinfo and version sections. */ | 2184 | /* Track but don't keep modinfo and version sections. */ |
| 2230 | info->index.vers = find_sec(info->hdr, info->sechdrs, info->secstrings, "__versions"); | 2185 | info->index.vers = find_sec(info, "__versions"); |
| 2231 | info->index.info = find_sec(info->hdr, info->sechdrs, info->secstrings, ".modinfo"); | 2186 | info->index.info = find_sec(info, ".modinfo"); |
| 2232 | info->sechdrs[info->index.info].sh_flags &= ~(unsigned long)SHF_ALLOC; | 2187 | info->sechdrs[info->index.info].sh_flags &= ~(unsigned long)SHF_ALLOC; |
| 2233 | info->sechdrs[info->index.vers].sh_flags &= ~(unsigned long)SHF_ALLOC; | 2188 | info->sechdrs[info->index.vers].sh_flags &= ~(unsigned long)SHF_ALLOC; |
| 2234 | return 0; | 2189 | return 0; |
| @@ -2268,8 +2223,7 @@ static struct module *setup_load_info(struct load_info *info) | |||
| 2268 | } | 2223 | } |
| 2269 | } | 2224 | } |
| 2270 | 2225 | ||
| 2271 | info->index.mod = find_sec(info->hdr, info->sechdrs, info->secstrings, | 2226 | info->index.mod = find_sec(info, ".gnu.linkonce.this_module"); |
| 2272 | ".gnu.linkonce.this_module"); | ||
| 2273 | if (!info->index.mod) { | 2227 | if (!info->index.mod) { |
| 2274 | printk(KERN_WARNING "No module found in object\n"); | 2228 | printk(KERN_WARNING "No module found in object\n"); |
| 2275 | return ERR_PTR(-ENOEXEC); | 2229 | return ERR_PTR(-ENOEXEC); |
| @@ -2283,7 +2237,7 @@ static struct module *setup_load_info(struct load_info *info) | |||
| 2283 | return ERR_PTR(-ENOEXEC); | 2237 | return ERR_PTR(-ENOEXEC); |
| 2284 | } | 2238 | } |
| 2285 | 2239 | ||
| 2286 | info->index.pcpu = find_pcpusec(info->hdr, info->sechdrs, info->secstrings); | 2240 | info->index.pcpu = find_pcpusec(info); |
| 2287 | 2241 | ||
| 2288 | /* Check module struct version now, before we try to use module. */ | 2242 | /* Check module struct version now, before we try to use module. */ |
| 2289 | if (!check_modstruct_version(info->sechdrs, info->index.vers, mod)) | 2243 | if (!check_modstruct_version(info->sechdrs, info->index.vers, mod)) |
| @@ -2292,11 +2246,9 @@ static struct module *setup_load_info(struct load_info *info) | |||
| 2292 | return mod; | 2246 | return mod; |
| 2293 | } | 2247 | } |
| 2294 | 2248 | ||
| 2295 | static int check_modinfo(struct module *mod, | 2249 | static int check_modinfo(struct module *mod, struct load_info *info) |
| 2296 | const Elf_Shdr *sechdrs, | ||
| 2297 | unsigned int infoindex, unsigned int versindex) | ||
| 2298 | { | 2250 | { |
| 2299 | const char *modmagic = get_modinfo(sechdrs, infoindex, "vermagic"); | 2251 | const char *modmagic = get_modinfo(info, "vermagic"); |
| 2300 | int err; | 2252 | int err; |
| 2301 | 2253 | ||
| 2302 | /* This is allowed: modprobe --force will invalidate it. */ | 2254 | /* This is allowed: modprobe --force will invalidate it. */ |
| @@ -2304,13 +2256,13 @@ static int check_modinfo(struct module *mod, | |||
| 2304 | err = try_to_force_load(mod, "bad vermagic"); | 2256 | err = try_to_force_load(mod, "bad vermagic"); |
| 2305 | if (err) | 2257 | if (err) |
| 2306 | return err; | 2258 | return err; |
| 2307 | } else if (!same_magic(modmagic, vermagic, versindex)) { | 2259 | } else if (!same_magic(modmagic, vermagic, info->index.vers)) { |
| 2308 | printk(KERN_ERR "%s: version magic '%s' should be '%s'\n", | 2260 | printk(KERN_ERR "%s: version magic '%s' should be '%s'\n", |
| 2309 | mod->name, modmagic, vermagic); | 2261 | mod->name, modmagic, vermagic); |
| 2310 | return -ENOEXEC; | 2262 | return -ENOEXEC; |
| 2311 | } | 2263 | } |
| 2312 | 2264 | ||
| 2313 | if (get_modinfo(sechdrs, infoindex, "staging")) { | 2265 | if (get_modinfo(info, "staging")) { |
| 2314 | add_taint_module(mod, TAINT_CRAP); | 2266 | add_taint_module(mod, TAINT_CRAP); |
| 2315 | printk(KERN_WARNING "%s: module is from the staging directory," | 2267 | printk(KERN_WARNING "%s: module is from the staging directory," |
| 2316 | " the quality is unknown, you have been warned.\n", | 2268 | " the quality is unknown, you have been warned.\n", |
| @@ -2318,58 +2270,51 @@ static int check_modinfo(struct module *mod, | |||
| 2318 | } | 2270 | } |
| 2319 | 2271 | ||
| 2320 | /* Set up license info based on the info section */ | 2272 | /* Set up license info based on the info section */ |
| 2321 | set_license(mod, get_modinfo(sechdrs, infoindex, "license")); | 2273 | set_license(mod, get_modinfo(info, "license")); |
| 2322 | 2274 | ||
| 2323 | return 0; | 2275 | return 0; |
| 2324 | } | 2276 | } |
| 2325 | 2277 | ||
| 2326 | static void find_module_sections(struct module *mod, Elf_Ehdr *hdr, | 2278 | static void find_module_sections(struct module *mod, |
| 2327 | Elf_Shdr *sechdrs, const char *secstrings) | 2279 | const struct load_info *info) |
| 2328 | { | 2280 | { |
| 2329 | mod->kp = section_objs(hdr, sechdrs, secstrings, "__param", | 2281 | mod->kp = section_objs(info, "__param", |
| 2330 | sizeof(*mod->kp), &mod->num_kp); | 2282 | sizeof(*mod->kp), &mod->num_kp); |
| 2331 | mod->syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab", | 2283 | mod->syms = section_objs(info, "__ksymtab", |
| 2332 | sizeof(*mod->syms), &mod->num_syms); | 2284 | sizeof(*mod->syms), &mod->num_syms); |
| 2333 | mod->crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab"); | 2285 | mod->crcs = section_addr(info, "__kcrctab"); |
| 2334 | mod->gpl_syms = section_objs(hdr, sechdrs, secstrings, "__ksymtab_gpl", | 2286 | mod->gpl_syms = section_objs(info, "__ksymtab_gpl", |
| 2335 | sizeof(*mod->gpl_syms), | 2287 | sizeof(*mod->gpl_syms), |
| 2336 | &mod->num_gpl_syms); | 2288 | &mod->num_gpl_syms); |
| 2337 | mod->gpl_crcs = section_addr(hdr, sechdrs, secstrings, "__kcrctab_gpl"); | 2289 | mod->gpl_crcs = section_addr(info, "__kcrctab_gpl"); |
| 2338 | mod->gpl_future_syms = section_objs(hdr, sechdrs, secstrings, | 2290 | mod->gpl_future_syms = section_objs(info, |
| 2339 | "__ksymtab_gpl_future", | 2291 | "__ksymtab_gpl_future", |
| 2340 | sizeof(*mod->gpl_future_syms), | 2292 | sizeof(*mod->gpl_future_syms), |
| 2341 | &mod->num_gpl_future_syms); | 2293 | &mod->num_gpl_future_syms); |
| 2342 | mod->gpl_future_crcs = section_addr(hdr, sechdrs, secstrings, | 2294 | mod->gpl_future_crcs = section_addr(info, "__kcrctab_gpl_future"); |
| 2343 | "__kcrctab_gpl_future"); | ||
| 2344 | 2295 | ||
| 2345 | #ifdef CONFIG_UNUSED_SYMBOLS | 2296 | #ifdef CONFIG_UNUSED_SYMBOLS |
| 2346 | mod->unused_syms = section_objs(hdr, sechdrs, secstrings, | 2297 | mod->unused_syms = section_objs(info, "__ksymtab_unused", |
| 2347 | "__ksymtab_unused", | ||
| 2348 | sizeof(*mod->unused_syms), | 2298 | sizeof(*mod->unused_syms), |
| 2349 | &mod->num_unused_syms); | 2299 | &mod->num_unused_syms); |
| 2350 | mod->unused_crcs = section_addr(hdr, sechdrs, secstrings, | 2300 | mod->unused_crcs = section_addr(info, "__kcrctab_unused"); |
| 2351 | "__kcrctab_unused"); | 2301 | mod->unused_gpl_syms = section_objs(info, "__ksymtab_unused_gpl", |
| 2352 | mod->unused_gpl_syms = section_objs(hdr, sechdrs, secstrings, | ||
| 2353 | "__ksymtab_unused_gpl", | ||
| 2354 | sizeof(*mod->unused_gpl_syms), | 2302 | sizeof(*mod->unused_gpl_syms), |
| 2355 | &mod->num_unused_gpl_syms); | 2303 | &mod->num_unused_gpl_syms); |
| 2356 | mod->unused_gpl_crcs = section_addr(hdr, sechdrs, secstrings, | 2304 | mod->unused_gpl_crcs = section_addr(info, "__kcrctab_unused_gpl"); |
| 2357 | "__kcrctab_unused_gpl"); | ||
| 2358 | #endif | 2305 | #endif |
| 2359 | #ifdef CONFIG_CONSTRUCTORS | 2306 | #ifdef CONFIG_CONSTRUCTORS |
| 2360 | mod->ctors = section_objs(hdr, sechdrs, secstrings, ".ctors", | 2307 | mod->ctors = section_objs(info, ".ctors", |
| 2361 | sizeof(*mod->ctors), &mod->num_ctors); | 2308 | sizeof(*mod->ctors), &mod->num_ctors); |
| 2362 | #endif | 2309 | #endif |
| 2363 | 2310 | ||
| 2364 | #ifdef CONFIG_TRACEPOINTS | 2311 | #ifdef CONFIG_TRACEPOINTS |
| 2365 | mod->tracepoints = section_objs(hdr, sechdrs, secstrings, | 2312 | mod->tracepoints = section_objs(info, "__tracepoints", |
| 2366 | "__tracepoints", | ||
| 2367 | sizeof(*mod->tracepoints), | 2313 | sizeof(*mod->tracepoints), |
| 2368 | &mod->num_tracepoints); | 2314 | &mod->num_tracepoints); |
| 2369 | #endif | 2315 | #endif |
| 2370 | #ifdef CONFIG_EVENT_TRACING | 2316 | #ifdef CONFIG_EVENT_TRACING |
| 2371 | mod->trace_events = section_objs(hdr, sechdrs, secstrings, | 2317 | mod->trace_events = section_objs(info, "_ftrace_events", |
| 2372 | "_ftrace_events", | ||
| 2373 | sizeof(*mod->trace_events), | 2318 | sizeof(*mod->trace_events), |
| 2374 | &mod->num_trace_events); | 2319 | &mod->num_trace_events); |
| 2375 | /* | 2320 | /* |
| @@ -2381,20 +2326,17 @@ static void find_module_sections(struct module *mod, Elf_Ehdr *hdr, | |||
| 2381 | #endif | 2326 | #endif |
| 2382 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD | 2327 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD |
| 2383 | /* sechdrs[0].sh_size is always zero */ | 2328 | /* sechdrs[0].sh_size is always zero */ |
| 2384 | mod->ftrace_callsites = section_objs(hdr, sechdrs, secstrings, | 2329 | mod->ftrace_callsites = section_objs(info, "__mcount_loc", |
| 2385 | "__mcount_loc", | ||
| 2386 | sizeof(*mod->ftrace_callsites), | 2330 | sizeof(*mod->ftrace_callsites), |
| 2387 | &mod->num_ftrace_callsites); | 2331 | &mod->num_ftrace_callsites); |
| 2388 | #endif | 2332 | #endif |
| 2389 | 2333 | ||
| 2390 | if (section_addr(hdr, sechdrs, secstrings, "__obsparm")) | 2334 | if (section_addr(info, "__obsparm")) |
| 2391 | printk(KERN_WARNING "%s: Ignoring obsolete parameters\n", | 2335 | printk(KERN_WARNING "%s: Ignoring obsolete parameters\n", |
| 2392 | mod->name); | 2336 | mod->name); |
| 2393 | } | 2337 | } |
| 2394 | 2338 | ||
| 2395 | static int move_module(struct module *mod, | 2339 | static int move_module(struct module *mod, struct load_info *info) |
| 2396 | Elf_Ehdr *hdr, Elf_Shdr *sechdrs, | ||
| 2397 | const char *secstrings, unsigned modindex) | ||
| 2398 | { | 2340 | { |
| 2399 | int i; | 2341 | int i; |
| 2400 | void *ptr; | 2342 | void *ptr; |
| @@ -2430,32 +2372,31 @@ static int move_module(struct module *mod, | |||
| 2430 | 2372 | ||
| 2431 | /* Transfer each section which specifies SHF_ALLOC */ | 2373 | /* Transfer each section which specifies SHF_ALLOC */ |
| 2432 | DEBUGP("final section addresses:\n"); | 2374 | DEBUGP("final section addresses:\n"); |
| 2433 | for (i = 0; i < hdr->e_shnum; i++) { | 2375 | for (i = 0; i < info->hdr->e_shnum; i++) { |
| 2434 | void *dest; | 2376 | void *dest; |
| 2377 | Elf_Shdr *shdr = &info->sechdrs[i]; | ||
| 2435 | 2378 | ||
| 2436 | if (!(sechdrs[i].sh_flags & SHF_ALLOC)) | 2379 | if (!(shdr->sh_flags & SHF_ALLOC)) |
| 2437 | continue; | 2380 | continue; |
| 2438 | 2381 | ||
| 2439 | if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) | 2382 | if (shdr->sh_entsize & INIT_OFFSET_MASK) |
| 2440 | dest = mod->module_init | 2383 | dest = mod->module_init |
| 2441 | + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK); | 2384 | + (shdr->sh_entsize & ~INIT_OFFSET_MASK); |
| 2442 | else | 2385 | else |
| 2443 | dest = mod->module_core + sechdrs[i].sh_entsize; | 2386 | dest = mod->module_core + shdr->sh_entsize; |
| 2444 | 2387 | ||
| 2445 | if (sechdrs[i].sh_type != SHT_NOBITS) | 2388 | if (shdr->sh_type != SHT_NOBITS) |
| 2446 | memcpy(dest, (void *)sechdrs[i].sh_addr, | 2389 | memcpy(dest, (void *)shdr->sh_addr, shdr->sh_size); |
| 2447 | sechdrs[i].sh_size); | ||
| 2448 | /* Update sh_addr to point to copy in image. */ | 2390 | /* Update sh_addr to point to copy in image. */ |
| 2449 | sechdrs[i].sh_addr = (unsigned long)dest; | 2391 | shdr->sh_addr = (unsigned long)dest; |
| 2450 | DEBUGP("\t0x%lx %s\n", | 2392 | DEBUGP("\t0x%lx %s\n", |
| 2451 | sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name); | 2393 | shdr->sh_addr, info->secstrings + shdr->sh_name); |
| 2452 | } | 2394 | } |
| 2453 | 2395 | ||
| 2454 | return 0; | 2396 | return 0; |
| 2455 | } | 2397 | } |
| 2456 | 2398 | ||
| 2457 | static int check_module_license_and_versions(struct module *mod, | 2399 | static int check_module_license_and_versions(struct module *mod) |
| 2458 | Elf_Shdr *sechdrs) | ||
| 2459 | { | 2400 | { |
| 2460 | /* | 2401 | /* |
| 2461 | * ndiswrapper is under GPL by itself, but loads proprietary modules. | 2402 | * ndiswrapper is under GPL by itself, but loads proprietary modules. |
| @@ -2512,34 +2453,37 @@ static struct module *layout_and_allocate(struct load_info *info) | |||
| 2512 | { | 2453 | { |
| 2513 | /* Module within temporary copy. */ | 2454 | /* Module within temporary copy. */ |
| 2514 | struct module *mod; | 2455 | struct module *mod; |
| 2456 | Elf_Shdr *pcpusec; | ||
| 2515 | int err; | 2457 | int err; |
| 2516 | 2458 | ||
| 2517 | mod = setup_load_info(info); | 2459 | mod = setup_load_info(info); |
| 2518 | if (IS_ERR(mod)) | 2460 | if (IS_ERR(mod)) |
| 2519 | return mod; | 2461 | return mod; |
| 2520 | 2462 | ||
| 2521 | err = check_modinfo(mod, info->sechdrs, info->index.info, info->index.vers); | 2463 | err = check_modinfo(mod, info); |
| 2522 | if (err) | 2464 | if (err) |
| 2523 | return ERR_PTR(err); | 2465 | return ERR_PTR(err); |
| 2524 | 2466 | ||
| 2525 | /* Allow arches to frob section contents and sizes. */ | 2467 | /* Allow arches to frob section contents and sizes. */ |
| 2526 | err = module_frob_arch_sections(info->hdr, info->sechdrs, info->secstrings, mod); | 2468 | err = module_frob_arch_sections(info->hdr, info->sechdrs, |
| 2469 | info->secstrings, mod); | ||
| 2527 | if (err < 0) | 2470 | if (err < 0) |
| 2528 | goto free_args; | 2471 | goto free_args; |
| 2529 | 2472 | ||
| 2530 | if (info->index.pcpu) { | 2473 | pcpusec = &info->sechdrs[info->index.pcpu]; |
| 2474 | if (pcpusec->sh_size) { | ||
| 2531 | /* We have a special allocation for this section. */ | 2475 | /* We have a special allocation for this section. */ |
| 2532 | err = percpu_modalloc(mod, info->sechdrs[info->index.pcpu].sh_size, | 2476 | err = percpu_modalloc(mod, |
| 2533 | info->sechdrs[info->index.pcpu].sh_addralign); | 2477 | pcpusec->sh_size, pcpusec->sh_addralign); |
| 2534 | if (err) | 2478 | if (err) |
| 2535 | goto free_args; | 2479 | goto free_args; |
| 2536 | info->sechdrs[info->index.pcpu].sh_flags &= ~(unsigned long)SHF_ALLOC; | 2480 | pcpusec->sh_flags &= ~(unsigned long)SHF_ALLOC; |
| 2537 | } | 2481 | } |
| 2538 | 2482 | ||
| 2539 | /* Determine total sizes, and put offsets in sh_entsize. For now | 2483 | /* Determine total sizes, and put offsets in sh_entsize. For now |
| 2540 | this is done generically; there doesn't appear to be any | 2484 | this is done generically; there doesn't appear to be any |
| 2541 | special cases for the architectures. */ | 2485 | special cases for the architectures. */ |
| 2542 | layout_sections(mod, info->hdr, info->sechdrs, info->secstrings); | 2486 | layout_sections(mod, info); |
| 2543 | 2487 | ||
| 2544 | info->strmap = kzalloc(BITS_TO_LONGS(info->sechdrs[info->index.str].sh_size) | 2488 | info->strmap = kzalloc(BITS_TO_LONGS(info->sechdrs[info->index.str].sh_size) |
| 2545 | * sizeof(long), GFP_KERNEL); | 2489 | * sizeof(long), GFP_KERNEL); |
| @@ -2547,17 +2491,16 @@ static struct module *layout_and_allocate(struct load_info *info) | |||
| 2547 | err = -ENOMEM; | 2491 | err = -ENOMEM; |
| 2548 | goto free_percpu; | 2492 | goto free_percpu; |
| 2549 | } | 2493 | } |
| 2550 | info->symoffs = layout_symtab(mod, info->sechdrs, info->index.sym, info->index.str, info->hdr, | 2494 | layout_symtab(mod, info); |
| 2551 | info->secstrings, &info->stroffs, info->strmap); | ||
| 2552 | 2495 | ||
| 2553 | /* Allocate and move to the final place */ | 2496 | /* Allocate and move to the final place */ |
| 2554 | err = move_module(mod, info->hdr, info->sechdrs, info->secstrings, info->index.mod); | 2497 | err = move_module(mod, info); |
| 2555 | if (err) | 2498 | if (err) |
| 2556 | goto free_strmap; | 2499 | goto free_strmap; |
| 2557 | 2500 | ||
| 2558 | /* Module has been copied to its final place now: return it. */ | 2501 | /* Module has been copied to its final place now: return it. */ |
| 2559 | mod = (void *)info->sechdrs[info->index.mod].sh_addr; | 2502 | mod = (void *)info->sechdrs[info->index.mod].sh_addr; |
| 2560 | kmemleak_load_module(mod, info->hdr, info->sechdrs, info->secstrings); | 2503 | kmemleak_load_module(mod, info); |
| 2561 | return mod; | 2504 | return mod; |
| 2562 | 2505 | ||
| 2563 | free_strmap: | 2506 | free_strmap: |
| @@ -2605,34 +2548,33 @@ static noinline struct module *load_module(void __user *umod, | |||
| 2605 | goto free_copy; | 2548 | goto free_copy; |
| 2606 | } | 2549 | } |
| 2607 | 2550 | ||
| 2608 | /* Now we've moved module, initialize linked lists, etc. */ | 2551 | /* Now module is in final location, initialize linked lists, etc. */ |
| 2609 | err = module_unload_init(mod); | 2552 | err = module_unload_init(mod); |
| 2610 | if (err) | 2553 | if (err) |
| 2611 | goto free_module; | 2554 | goto free_module; |
| 2612 | 2555 | ||
| 2613 | /* Now we've got everything in the final locations, we can | 2556 | /* Now we've got everything in the final locations, we can |
| 2614 | * find optional sections. */ | 2557 | * find optional sections. */ |
| 2615 | find_module_sections(mod, info.hdr, info.sechdrs, info.secstrings); | 2558 | find_module_sections(mod, &info); |
| 2616 | 2559 | ||
| 2617 | err = check_module_license_and_versions(mod, info.sechdrs); | 2560 | err = check_module_license_and_versions(mod); |
| 2618 | if (err) | 2561 | if (err) |
| 2619 | goto free_unload; | 2562 | goto free_unload; |
| 2620 | 2563 | ||
| 2621 | /* Set up MODINFO_ATTR fields */ | 2564 | /* Set up MODINFO_ATTR fields */ |
| 2622 | setup_modinfo(mod, info.sechdrs, info.index.info); | 2565 | setup_modinfo(mod, &info); |
| 2623 | 2566 | ||
| 2624 | /* Fix up syms, so that st_value is a pointer to location. */ | 2567 | /* Fix up syms, so that st_value is a pointer to location. */ |
| 2625 | err = simplify_symbols(info.sechdrs, info.index.sym, info.strtab, info.index.vers, info.index.pcpu, | 2568 | err = simplify_symbols(mod, &info); |
| 2626 | mod); | ||
| 2627 | if (err < 0) | 2569 | if (err < 0) |
| 2628 | goto free_modinfo; | 2570 | goto free_modinfo; |
| 2629 | 2571 | ||
| 2630 | err = apply_relocations(mod, info.hdr, info.sechdrs, info.index.sym, info.index.str); | 2572 | err = apply_relocations(mod, &info); |
| 2631 | if (err < 0) | 2573 | if (err < 0) |
| 2632 | goto free_modinfo; | 2574 | goto free_modinfo; |
| 2633 | 2575 | ||
| 2634 | /* Set up and sort exception table */ | 2576 | /* Set up and sort exception table */ |
| 2635 | mod->extable = section_objs(info.hdr, info.sechdrs, info.secstrings, "__ex_table", | 2577 | mod->extable = section_objs(&info, "__ex_table", |
| 2636 | sizeof(*mod->extable), &mod->num_exentries); | 2578 | sizeof(*mod->extable), &mod->num_exentries); |
| 2637 | sort_extable(mod->extable, mod->extable + mod->num_exentries); | 2579 | sort_extable(mod->extable, mod->extable + mod->num_exentries); |
| 2638 | 2580 | ||
| @@ -2643,7 +2585,7 @@ static noinline struct module *load_module(void __user *umod, | |||
| 2643 | add_kallsyms(mod, &info); | 2585 | add_kallsyms(mod, &info); |
| 2644 | 2586 | ||
| 2645 | if (!mod->taints) | 2587 | if (!mod->taints) |
| 2646 | debug = section_objs(info.hdr, info.sechdrs, info.secstrings, "__verbose", | 2588 | debug = section_objs(&info, "__verbose", |
| 2647 | sizeof(*debug), &num_debug); | 2589 | sizeof(*debug), &num_debug); |
| 2648 | 2590 | ||
| 2649 | err = module_finalize(info.hdr, info.sechdrs, mod); | 2591 | err = module_finalize(info.hdr, info.sechdrs, mod); |
