modpost: support objects with more than 64k sections

This patch makes modpost able to process object files with more than
64k sections. Needed for huge kernel builds (allyesconfig, for example)
with -ffunction-sections. 64k sections handling is covered, for example,
by this document:

"IA-64 gABI Proposal 74: Section Indexes"
http://www.codesourcery.com/public/cxx-abi/abi/prop-74-sindex.html

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Andi Kleen <andi@firstfloor.org>
Signed-off-by: Michal Marek <mmarek@suse.cz>
This commit is contained in:
Denys Vlasenko 2010-07-29 01:47:53 +02:00 committed by Michal Marek
parent 4696e2958b
commit 1ce53adf13
3 changed files with 122 additions and 29 deletions

View file

@ -129,8 +129,51 @@ struct elf_info {
const char *strtab;
char *modinfo;
unsigned int modinfo_len;
/* support for 32bit section numbers */
unsigned int num_sections; /* max_secindex + 1 */
unsigned int secindex_strings;
/* if Nth symbol table entry has .st_shndx = SHN_XINDEX,
* take shndx from symtab_shndx_start[N] instead */
Elf32_Word *symtab_shndx_start;
Elf32_Word *symtab_shndx_stop;
};
static inline int is_shndx_special(unsigned int i)
{
return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE;
}
/* shndx is in [0..SHN_LORESERVE) U (SHN_HIRESERVE, 0xfffffff], thus:
* shndx == 0 <=> sechdrs[0]
* ......
* shndx == SHN_LORESERVE-1 <=> sechdrs[SHN_LORESERVE-1]
* shndx == SHN_HIRESERVE+1 <=> sechdrs[SHN_LORESERVE]
* shndx == SHN_HIRESERVE+2 <=> sechdrs[SHN_LORESERVE+1]
* ......
* fyi: sym->st_shndx is uint16, SHN_LORESERVE = ff00, SHN_HIRESERVE = ffff,
* so basically we map 0000..feff -> 0000..feff
* ff00..ffff -> (you are a bad boy, dont do it)
* 10000..xxxx -> ff00..(xxxx-0x100)
*/
static inline unsigned int shndx2secindex(unsigned int i)
{
if (i <= SHN_HIRESERVE)
return i;
return i - (SHN_HIRESERVE + 1 - SHN_LORESERVE);
}
/* Accessor for sym->st_shndx, hides ugliness of "64k sections" */
static inline unsigned int get_secindex(const struct elf_info *info,
const Elf_Sym *sym)
{
if (sym->st_shndx != SHN_XINDEX)
return sym->st_shndx;
return shndx2secindex(info->symtab_shndx_start[sym -
info->symtab_start]);
}
/* file2alias.c */
extern unsigned int cross_build;
void handle_moddevtable(struct module *mod, struct elf_info *info,