diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-07-28 19:47:53 -0400 |
|---|---|---|
| committer | Michal Marek <mmarek@suse.cz> | 2010-08-03 09:05:56 -0400 |
| commit | 1ce53adf13a54375d2a5c7cdbe341b2558389615 (patch) | |
| tree | ebd9f596daa9cdbf3eca2f964e2f58946d4b4d16 /scripts/mod/modpost.h | |
| parent | 4696e2958b345189afebcb52e365d16ca6e403ef (diff) | |
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>
Diffstat (limited to 'scripts/mod/modpost.h')
| -rw-r--r-- | scripts/mod/modpost.h | 43 |
1 files changed, 43 insertions, 0 deletions
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, |
