diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-21 12:03:04 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-21 12:03:04 -0700 |
commit | 080e89270a7bfb7d01fac9a67050f8ac6d6cdd11 (patch) | |
tree | 489e467292ca06420e85f185095323efb80c75b7 /scripts | |
parent | 4b85df0419d1fb135d9d845876e8c7ee1393f83c (diff) | |
parent | 38bdc32af442b6ab09ed61b8b669072098c95dd2 (diff) | |
download | linux-080e89270a7bfb7d01fac9a67050f8ac6d6cdd11.tar.bz2 |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-fix
* git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-fix:
mm/slab: fix section mismatch warning
mm: fix section mismatch warnings
init/main: use __init_refok to fix section mismatch
kbuild: introduce __init_refok/__initdata_refok to supress section mismatch warnings
all-archs: consolidate .data section definition in asm-generic
all-archs: consolidate .text section definition in asm-generic
kbuild: add "Section mismatch" warning whitelist for powerpc
kbuild: make better section mismatch reports on i386, arm and mips
kbuild: make modpost section warnings clearer
kconfig: search harder for curses library in check-lxdialog.sh
kbuild: include limits.h in sumversion.c for PATH_MAX
powerpc: Fix the MODALIAS generation in modpost for of devices
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/kconfig/lxdialog/check-lxdialog.sh | 24 | ||||
-rw-r--r-- | scripts/mod/file2alias.c | 11 | ||||
-rw-r--r-- | scripts/mod/modpost.c | 169 | ||||
-rw-r--r-- | scripts/mod/modpost.h | 3 | ||||
-rw-r--r-- | scripts/mod/sumversion.c | 1 |
5 files changed, 137 insertions, 71 deletions
diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh index 120d624e672c..cdca7388e0f1 100644 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh @@ -4,21 +4,15 @@ # What library to link ldflags() { - $cc -print-file-name=libncursesw.so | grep -q / - if [ $? -eq 0 ]; then - echo '-lncursesw' - exit - fi - $cc -print-file-name=libncurses.so | grep -q / - if [ $? -eq 0 ]; then - echo '-lncurses' - exit - fi - $cc -print-file-name=libcurses.so | grep -q / - if [ $? -eq 0 ]; then - echo '-lcurses' - exit - fi + for ext in so a dylib ; do + for lib in ncursesw ncurses curses ; do + $cc -print-file-name=lib${lib}.${ext} | grep -q / + if [ $? -eq 0 ]; then + echo "-l${lib}" + exit + fi + done + done exit 1 } diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index ed1244dd58d0..f646381dc015 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -353,11 +353,16 @@ static int do_pcmcia_entry(const char *filename, static int do_of_entry (const char *filename, struct of_device_id *of, char *alias) { + int len; char *tmp; - sprintf (alias, "of:N%sT%sC%s", + len = sprintf (alias, "of:N%sT%s", of->name[0] ? of->name : "*", - of->type[0] ? of->type : "*", - of->compatible[0] ? of->compatible : "*"); + of->type[0] ? of->type : "*"); + + if (of->compatible[0]) + sprintf (&alias[len], "%sC%s", + of->type[0] ? "*" : "", + of->compatible); /* Replace all whitespace with underscores */ for (tmp = alias; tmp && *tmp; tmp++) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 113dc77b9f60..8424d1f53bbe 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -384,6 +384,7 @@ static int parse_elf(struct elf_info *info, const char *filename) sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size); sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link); sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name); + sechdrs[i].sh_info = TO_NATIVE(sechdrs[i].sh_info); } /* Find symbol table. */ for (i = 1; i < hdr->e_shnum; i++) { @@ -582,6 +583,12 @@ static int strrcmp(const char *s, const char *sub) /** * Whitelist to allow certain references to pass with no warning. + * + * Pattern 0: + * Do not warn if funtion/data are marked with __init_refok/__initdata_refok. + * The pattern is identified by: + * fromsec = .text.init.refok | .data.init.refok + * * Pattern 1: * If a module parameter is declared __initdata and permissions=0 * then this is legal despite the warning generated. @@ -619,14 +626,6 @@ static int strrcmp(const char *s, const char *sub) * This pattern is identified by * refsymname = __init_begin, _sinittext, _einittext * - * Pattern 6: - * During the early init phase we have references from .init.text to - * .text we have an intended section mismatch - do not warn about it. - * See kernel_init() in init/main.c - * tosec = .init.text - * fromsec = .text - * atsym = kernel_init - * * Pattern 7: * Logos used in drivers/video/logo reside in __initdata but the * funtion that references them are EXPORT_SYMBOL() so cannot be @@ -642,16 +641,11 @@ static int strrcmp(const char *s, const char *sub) * tosec = .init.text * fromsec = .paravirtprobe * - * Pattern 9: - * Some of functions are common code between boot time and hotplug - * time. The bootmem allocater is called only boot time in its - * functions. So it's ok to reference. - * tosec = .init.text - * * Pattern 10: - * ia64 has machvec table for each platform. It is mixture of function - * pointer of .init.text and .text. - * fromsec = .machvec + * ia64 has machvec table for each platform and + * powerpc has a machine desc table for each platform. + * It is mixture of function pointers of .init.text and .text. + * fromsec = .machvec | .machine.desc **/ static int secref_whitelist(const char *modname, const char *tosec, const char *fromsec, const char *atsym, @@ -678,11 +672,10 @@ static int secref_whitelist(const char *modname, const char *tosec, NULL }; - const char *pat4sym[] = { - "sparse_index_alloc", - "zone_wait_table_init", - NULL - }; + /* Check for pattern 0 */ + if ((strcmp(fromsec, ".text.init.refok") == 0) || + (strcmp(fromsec, ".data.init.refok") == 0)) + return 1; /* Check for pattern 1 */ if (strcmp(tosec, ".init.data") != 0) @@ -725,12 +718,6 @@ static int secref_whitelist(const char *modname, const char *tosec, if (strcmp(refsymname, *s) == 0) return 1; - /* Check for pattern 6 */ - if ((strcmp(tosec, ".init.text") == 0) && - (strcmp(fromsec, ".text") == 0) && - (strcmp(refsymname, "kernel_init") == 0)) - return 1; - /* Check for pattern 7 */ if ((strcmp(tosec, ".init.data") == 0) && (strncmp(fromsec, ".text", strlen(".text")) == 0) && @@ -742,15 +729,9 @@ static int secref_whitelist(const char *modname, const char *tosec, (strcmp(fromsec, ".paravirtprobe") == 0)) return 1; - /* Check for pattern 9 */ - if ((strcmp(tosec, ".init.text") == 0) && - (strcmp(fromsec, ".text") == 0)) - for (s = pat4sym; *s; s++) - if (strcmp(atsym, *s) == 0) - return 1; - /* Check for pattern 10 */ - if (strcmp(fromsec, ".machvec") == 0) + if ((strcmp(fromsec, ".machvec") == 0) || + (strcmp(fromsec, ".machine.desc") == 0)) return 1; return 0; @@ -773,6 +754,8 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf_Addr addr, for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { if (sym->st_shndx != relsym->st_shndx) continue; + if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) + continue; if (sym->st_value == addr) return sym; } @@ -884,33 +867,99 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec, elf->strtab + before->st_name, refsymname)) return; + /* fromsec whitelist - without a valid 'before' + * powerpc has a GOT table in .got2 section */ + if (strcmp(fromsec, ".got2") == 0) + return; + if (before && after) { - warn("%s - Section mismatch: reference to %s:%s from %s " - "between '%s' (at offset 0x%llx) and '%s'\n", - modname, secname, refsymname, fromsec, + warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " + "(between '%s' and '%s')\n", + modname, fromsec, (unsigned long long)r.r_offset, + secname, refsymname, elf->strtab + before->st_name, - (long long)r.r_offset, elf->strtab + after->st_name); } else if (before) { - warn("%s - Section mismatch: reference to %s:%s from %s " - "after '%s' (at offset 0x%llx)\n", - modname, secname, refsymname, fromsec, - elf->strtab + before->st_name, - (long long)r.r_offset); + warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " + "(after '%s')\n", + modname, fromsec, (unsigned long long)r.r_offset, + secname, refsymname, + elf->strtab + before->st_name); } else if (after) { - warn("%s - Section mismatch: reference to %s:%s from %s " + warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " "before '%s' (at offset -0x%llx)\n", - modname, secname, refsymname, fromsec, - elf->strtab + after->st_name, - (long long)r.r_offset); + modname, fromsec, (unsigned long long)r.r_offset, + secname, refsymname, + elf->strtab + after->st_name); } else { - warn("%s - Section mismatch: reference to %s:%s from %s " - "(offset 0x%llx)\n", - modname, secname, fromsec, refsymname, - (long long)r.r_offset); + warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s\n", + modname, fromsec, (unsigned long long)r.r_offset, + secname, refsymname); } } +static void addend_386_rel(struct elf_info *elf, int section, Elf_Rela *r) +{ + Elf_Shdr *sechdrs = elf->sechdrs; + unsigned int r_typ; + unsigned int *location; + + r_typ = ELF_R_TYPE(r->r_info); + location = (void *)elf->hdr + + sechdrs[sechdrs[section].sh_info].sh_offset + r->r_offset; + switch (r_typ) { + case R_386_32: + r->r_addend = TO_NATIVE(*location); + break; + case R_386_PC32: + r->r_addend = TO_NATIVE(*location) + 4; + break; + } +} + +static void addend_arm_rel(struct elf_info *elf, int section, Elf_Rela *r) +{ + Elf_Shdr *sechdrs = elf->sechdrs; + unsigned int r_typ; + unsigned int *location; + + r_typ = ELF_R_TYPE(r->r_info); + location = (void *)elf->hdr + + sechdrs[sechdrs[section].sh_info].sh_offset + r->r_offset; + switch (r_typ) { + case R_ARM_ABS32: + r->r_addend = TO_NATIVE(*location); + break; + case R_ARM_PC24: + r->r_addend = ((TO_NATIVE(*location) & 0x00ffffff) << 2) + 8; + break; + } +} + +static int addend_mips_rel(struct elf_info *elf, int section, Elf_Rela *r) +{ + Elf_Shdr *sechdrs = elf->sechdrs; + unsigned int r_typ; + unsigned int *location; + unsigned int inst; + + r_typ = ELF_R_TYPE(r->r_info); + if (r_typ == R_MIPS_HI16) + return 1; /* skip this */ + location = (void *)elf->hdr + + sechdrs[sechdrs[section].sh_info].sh_offset + r->r_offset; + inst = TO_NATIVE(*location); + switch (r_typ) { + case R_MIPS_LO16: + r->r_addend = ((inst & 0xffff) ^ 0x8000) - 0x8000; + break; + case R_MIPS_26: + r->r_addend = (inst & 0x03ffffff) << 2; + break; + } + return 0; +} + /** * A module includes a number of sections that are discarded * either when loaded or when used as built-in. @@ -954,8 +1003,11 @@ static void check_sec_ref(struct module *mod, const char *modname, r.r_offset = TO_NATIVE(rela->r_offset); #if KERNEL_ELFCLASS == ELFCLASS64 if (hdr->e_machine == EM_MIPS) { + unsigned int r_typ; r_sym = ELF64_MIPS_R_SYM(rela->r_info); r_sym = TO_NATIVE(r_sym); + r_typ = ELF64_MIPS_R_TYPE(rela->r_info); + r.r_info = ELF64_R_INFO(r_sym, r_typ); } else { r.r_info = TO_NATIVE(rela->r_info); r_sym = ELF_R_SYM(r.r_info); @@ -988,8 +1040,11 @@ static void check_sec_ref(struct module *mod, const char *modname, r.r_offset = TO_NATIVE(rel->r_offset); #if KERNEL_ELFCLASS == ELFCLASS64 if (hdr->e_machine == EM_MIPS) { + unsigned int r_typ; r_sym = ELF64_MIPS_R_SYM(rel->r_info); r_sym = TO_NATIVE(r_sym); + r_typ = ELF64_MIPS_R_TYPE(rel->r_info); + r.r_info = ELF64_R_INFO(r_sym, r_typ); } else { r.r_info = TO_NATIVE(rel->r_info); r_sym = ELF_R_SYM(r.r_info); @@ -999,6 +1054,14 @@ static void check_sec_ref(struct module *mod, const char *modname, r_sym = ELF_R_SYM(r.r_info); #endif r.r_addend = 0; + if (hdr->e_machine == EM_386) + addend_386_rel(elf, i, &r); + else if (hdr->e_machine == EM_ARM) + addend_arm_rel(elf, i, &r); + else if (hdr->e_machine == EM_MIPS) { + if (addend_mips_rel(elf, i, &r)) + continue; + } sym = elf->symtab_start + r_sym; /* Skip special sections */ if (sym->st_shndx >= SHN_LORESERVE) diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 0858caa9c03f..4156dd34c5de 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -60,6 +60,9 @@ typedef union #define ELF64_MIPS_R_SYM(i) \ ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym) +#define ELF64_MIPS_R_TYPE(i) \ + ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_type1) + #if KERNEL_ELFDATA != HOST_ELFDATA static inline void __endian(const void *src, void *dest, unsigned int size) diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c index 6873d5af80d5..d9cc6901d680 100644 --- a/scripts/mod/sumversion.c +++ b/scripts/mod/sumversion.c @@ -7,6 +7,7 @@ #include <ctype.h> #include <errno.h> #include <string.h> +#include <limits.h> #include "modpost.h" /* |