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
This commit is contained in:
Linus Torvalds 2007-05-21 12:03:04 -07:00
commit 080e89270a
39 changed files with 234 additions and 132 deletions

View file

@ -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
}

View file

@ -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++)

View file

@ -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)

View file

@ -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)

View file

@ -7,6 +7,7 @@
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <limits.h>
#include "modpost.h"
/*