From 56fc82c5360cdf0b250b5eb74f38657b0402faa5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 6 Feb 2009 00:48:02 +0900 Subject: [PATCH] modpost: NOBITS sections may point beyond the end of the file Impact: fix link failure on certain toolchains with specific configs Recent percpu change made x86_64 split .data.init section into three separate segments - data.init, percpu and data.init2. data.init2 gets .data.nosave and .bss.* and is followed by .notes segment. Depending on configuration both segments might contain no data, in which case the tool chain makes the section header to contain offset beyond the end of the file. modpost isn't too happy about it and fails build - as reported by Pawel Dziekonski: Building modules, stage 2. MODPOST 416 modules FATAL: vmlinux is truncated. sechdrs[i].sh_offset=10354688 > sizeof(*hrd)=64 make[1]: *** [__modpost] Error 1 Teach modpost that NOBITS section may point beyond the end of the file and that .modinfo can't be NOBITS. Reported-by: Pawel Dziekonski Signed-off-by: Tejun Heo Signed-off-by: Ingo Molnar --- scripts/mod/modpost.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 88921611b22e..7e62303133dc 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -415,8 +415,9 @@ static int parse_elf(struct elf_info *info, const char *filename) const char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; const char *secname; + int nobits = sechdrs[i].sh_type == SHT_NOBITS; - if (sechdrs[i].sh_offset > info->size) { + if (!nobits && sechdrs[i].sh_offset > info->size) { fatal("%s is truncated. sechdrs[i].sh_offset=%lu > " "sizeof(*hrd)=%zu\n", filename, (unsigned long)sechdrs[i].sh_offset, @@ -425,6 +426,8 @@ static int parse_elf(struct elf_info *info, const char *filename) } secname = secstrings + sechdrs[i].sh_name; if (strcmp(secname, ".modinfo") == 0) { + if (nobits) + fatal("%s has NOBITS .modinfo\n", filename); info->modinfo = (void *)hdr + sechdrs[i].sh_offset; info->modinfo_len = sechdrs[i].sh_size; } else if (strcmp(secname, "__ksymtab") == 0)