diff options
author | Helge Deller <deller@gmx.de> | 2008-12-31 06:31:18 -0500 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2009-01-04 17:10:13 -0500 |
commit | 088af9a6e05d51e7c3dc85d45d8b7a52c3ee08d7 (patch) | |
tree | 86e2dd6be7fbc17cb01a42fc11f5eef794a824df | |
parent | d1e99d7ae4e6bbd1ebb5e81ecd3af2b8793efee0 (diff) |
module: fix module loading failure of large kernel modules for parisc
When creating the final layout of a kernel module in memory, allow the
module loader to reserve some additional memory in front of a given section.
This is currently only needed for the parisc port which needs to put the
stub entries there to fulfill the 17/22bit PCREL relocations with large
kernel modules like xfs.
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> (renamed fn)
-rw-r--r-- | include/linux/moduleloader.h | 3 | ||||
-rw-r--r-- | kernel/module.c | 16 |
2 files changed, 16 insertions, 3 deletions
diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h index eb1033957486..c1f40c2f7ffb 100644 --- a/include/linux/moduleloader.h +++ b/include/linux/moduleloader.h | |||
@@ -13,6 +13,9 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, | |||
13 | char *secstrings, | 13 | char *secstrings, |
14 | struct module *mod); | 14 | struct module *mod); |
15 | 15 | ||
16 | /* Additional bytes needed by arch in front of individual sections */ | ||
17 | unsigned int arch_mod_section_prepend(struct module *mod, unsigned int section); | ||
18 | |||
16 | /* Allocator used for allocating struct module, core sections and init | 19 | /* Allocator used for allocating struct module, core sections and init |
17 | sections. Returns NULL on failure. */ | 20 | sections. Returns NULL on failure. */ |
18 | void *module_alloc(unsigned long size); | 21 | void *module_alloc(unsigned long size); |
diff --git a/kernel/module.c b/kernel/module.c index d3d254571bda..4299aefc20b8 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -1578,11 +1578,21 @@ static int simplify_symbols(Elf_Shdr *sechdrs, | |||
1578 | return ret; | 1578 | return ret; |
1579 | } | 1579 | } |
1580 | 1580 | ||
1581 | /* Additional bytes needed by arch in front of individual sections */ | ||
1582 | unsigned int __weak arch_mod_section_prepend(struct module *mod, | ||
1583 | unsigned int section) | ||
1584 | { | ||
1585 | /* default implementation just returns zero */ | ||
1586 | return 0; | ||
1587 | } | ||
1588 | |||
1581 | /* Update size with this section: return offset. */ | 1589 | /* Update size with this section: return offset. */ |
1582 | static long get_offset(unsigned int *size, Elf_Shdr *sechdr) | 1590 | static long get_offset(struct module *mod, unsigned int *size, |
1591 | Elf_Shdr *sechdr, unsigned int section) | ||
1583 | { | 1592 | { |
1584 | long ret; | 1593 | long ret; |
1585 | 1594 | ||
1595 | *size += arch_mod_section_prepend(mod, section); | ||
1586 | ret = ALIGN(*size, sechdr->sh_addralign ?: 1); | 1596 | ret = ALIGN(*size, sechdr->sh_addralign ?: 1); |
1587 | *size = ret + sechdr->sh_size; | 1597 | *size = ret + sechdr->sh_size; |
1588 | return ret; | 1598 | return ret; |
@@ -1622,7 +1632,7 @@ static void layout_sections(struct module *mod, | |||
1622 | || strncmp(secstrings + s->sh_name, | 1632 | || strncmp(secstrings + s->sh_name, |
1623 | ".init", 5) == 0) | 1633 | ".init", 5) == 0) |
1624 | continue; | 1634 | continue; |
1625 | s->sh_entsize = get_offset(&mod->core_size, s); | 1635 | s->sh_entsize = get_offset(mod, &mod->core_size, s, i); |
1626 | DEBUGP("\t%s\n", secstrings + s->sh_name); | 1636 | DEBUGP("\t%s\n", secstrings + s->sh_name); |
1627 | } | 1637 | } |
1628 | if (m == 0) | 1638 | if (m == 0) |
@@ -1640,7 +1650,7 @@ static void layout_sections(struct module *mod, | |||
1640 | || strncmp(secstrings + s->sh_name, | 1650 | || strncmp(secstrings + s->sh_name, |
1641 | ".init", 5) != 0) | 1651 | ".init", 5) != 0) |
1642 | continue; | 1652 | continue; |
1643 | s->sh_entsize = (get_offset(&mod->init_size, s) | 1653 | s->sh_entsize = (get_offset(mod, &mod->init_size, s, i) |
1644 | | INIT_OFFSET_MASK); | 1654 | | INIT_OFFSET_MASK); |
1645 | DEBUGP("\t%s\n", secstrings + s->sh_name); | 1655 | DEBUGP("\t%s\n", secstrings + s->sh_name); |
1646 | } | 1656 | } |