summaryrefslogtreecommitdiff
path: root/scripts/mod/modpost.h
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-07-29 03:47:53 +0400
committerMichal Marek <mmarek@suse.cz>2010-08-03 17:05:56 +0400
commit1ce53adf13a54375d2a5c7cdbe341b2558389615 (patch)
treeebd9f596daa9cdbf3eca2f964e2f58946d4b4d16 /scripts/mod/modpost.h
parent4696e2958b345189afebcb52e365d16ca6e403ef (diff)
downloadlinux-1ce53adf13a54375d2a5c7cdbe341b2558389615.tar.xz
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.h43
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 {
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,