Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild

* git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild: (38 commits)
  kconfig: fix mconf segmentation fault
  kbuild: enable use of code from a different dir
  kconfig: error out if recursive dependencies are found
  kbuild: scripts/basic/fixdep segfault on pathological string-o-death
  kconfig: correct minor typo in Kconfig warning message.
  kconfig: fix path to modules.txt in Kconfig help
  usr/Kconfig: fix typo
  kernel-doc: alphabetically-sorted entries in index.html of 'htmldocs'
  kbuild: be more explicit on missing .config file
  kbuild: clarify the creation of the LOCALVERSION_AUTO string.
  kbuild: propagate errors from find in scripts/gen_initramfs_list.sh
  kconfig: refer to qt3 if we cannot find qt libraries
  kbuild: handle compressed cpio initramfs-es
  kbuild: ignore section mismatch warning for references from .paravirtprobe to .init.text
  kbuild: remove stale comment in modpost.c
  kbuild/mkuboot.sh: allow spaces in CROSS_COMPILE
  kbuild: fix make mrproper for Documentation/DocBook/man
  kbuild: remove kconfig binaries during make mrproper
  kconfig/menuconfig: do not hardcode '.config'
  kbuild: override build timestamp & version
  ...
This commit is contained in:
Linus Torvalds 2007-05-06 13:21:57 -07:00
commit 15700770ef
47 changed files with 766 additions and 168 deletions

View file

@ -55,6 +55,17 @@ void warn(const char *fmt, ...)
va_end(arglist);
}
void merror(const char *fmt, ...)
{
va_list arglist;
fprintf(stderr, "ERROR: ");
va_start(arglist, fmt);
vfprintf(stderr, fmt, arglist);
va_end(arglist);
}
static int is_vmlinux(const char *modname)
{
const char *myname;
@ -333,10 +344,10 @@ void release_file(void *file, unsigned long size)
munmap(file, size);
}
static void parse_elf(struct elf_info *info, const char *filename)
static int parse_elf(struct elf_info *info, const char *filename)
{
unsigned int i;
Elf_Ehdr *hdr = info->hdr;
Elf_Ehdr *hdr;
Elf_Shdr *sechdrs;
Elf_Sym *sym;
@ -346,9 +357,18 @@ static void parse_elf(struct elf_info *info, const char *filename)
exit(1);
}
info->hdr = hdr;
if (info->size < sizeof(*hdr))
goto truncated;
if (info->size < sizeof(*hdr)) {
/* file too small, assume this is an empty .o file */
return 0;
}
/* Is this a valid ELF file? */
if ((hdr->e_ident[EI_MAG0] != ELFMAG0) ||
(hdr->e_ident[EI_MAG1] != ELFMAG1) ||
(hdr->e_ident[EI_MAG2] != ELFMAG2) ||
(hdr->e_ident[EI_MAG3] != ELFMAG3)) {
/* Not an ELF file - silently ignore it */
return 0;
}
/* Fix endianness in ELF header */
hdr->e_shoff = TO_NATIVE(hdr->e_shoff);
hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx);
@ -371,8 +391,10 @@ static void parse_elf(struct elf_info *info, const char *filename)
= (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
const char *secname;
if (sechdrs[i].sh_offset > info->size)
goto truncated;
if (sechdrs[i].sh_offset > info->size) {
fatal("%s is truncated. sechdrs[i].sh_offset=%u > sizeof(*hrd)=%ul\n", filename, (unsigned int)sechdrs[i].sh_offset, sizeof(*hdr));
return 0;
}
secname = secstrings + sechdrs[i].sh_name;
if (strcmp(secname, ".modinfo") == 0) {
info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
@ -407,10 +429,7 @@ static void parse_elf(struct elf_info *info, const char *filename)
sym->st_value = TO_NATIVE(sym->st_value);
sym->st_size = TO_NATIVE(sym->st_size);
}
return;
truncated:
fatal("%s is truncated.\n", filename);
return 1;
}
static void parse_elf_finish(struct elf_info *info)
@ -581,9 +600,17 @@ static int strrcmp(const char *s, const char *sub)
* the pattern is identified by:
* tosec = .init.text | .exit.text | .init.data
* fromsec = .data
* atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one
* atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console
*
* Pattern 3:
* Whitelist all references from .pci_fixup* section to .init.text
* This is part of the PCI init when built-in
*
* Pattern 4:
* Whitelist all refereces from .text.head to .init.data
* Whitelist all refereces from .text.head to .init.text
*
* Pattern 5:
* Some symbols belong to init section but still it is ok to reference
* these from non-init sections as these symbols don't have any memory
* allocated for them and symbol address and value are same. So even
@ -591,6 +618,30 @@ static int strrcmp(const char *s, const char *sub)
* For ex. symbols marking the init section boundaries.
* 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
* marker __init. So we whitelist them here.
* The pattern is:
* tosec = .init.data
* fromsec = .text*
* refsymname = logo_
*
* Pattern 8:
* Symbols contained in .paravirtprobe may safely reference .init.text.
* The pattern is:
* tosec = .init.text
* fromsec = .paravirtprobe
*
**/
static int secref_whitelist(const char *modname, const char *tosec,
const char *fromsec, const char *atsym,
@ -642,25 +693,39 @@ static int secref_whitelist(const char *modname, const char *tosec,
if (f1 && f2)
return 1;
/* Whitelist all references from .pci_fixup section if vmlinux
* Whitelist all refereces from .text.head to .init.data if vmlinux
* Whitelist all refereces from .text.head to .init.text if vmlinux
*/
if (is_vmlinux(modname)) {
if ((strcmp(fromsec, ".pci_fixup") == 0) &&
(strcmp(tosec, ".init.text") == 0))
/* Check for pattern 3 */
if ((strncmp(fromsec, ".pci_fixup", strlen(".pci_fixup")) == 0) &&
(strcmp(tosec, ".init.text") == 0))
return 1;
/* Check for pattern 4 */
if ((strcmp(fromsec, ".text.head") == 0) &&
((strcmp(tosec, ".init.data") == 0) ||
(strcmp(tosec, ".init.text") == 0)))
return 1;
/* Check for pattern 5 */
for (s = pat3refsym; *s; s++)
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;
if ((strcmp(fromsec, ".text.head") == 0) &&
((strcmp(tosec, ".init.data") == 0) ||
(strcmp(tosec, ".init.text") == 0)))
/* Check for pattern 7 */
if ((strcmp(tosec, ".init.data") == 0) &&
(strncmp(fromsec, ".text", strlen(".text")) == 0) &&
(strncmp(refsymname, "logo_", strlen("logo_")) == 0))
return 1;
/* Check for pattern 8 */
if ((strcmp(tosec, ".init.text") == 0) &&
(strcmp(fromsec, ".paravirtprobe") == 0))
return 1;
/* Check for pattern 3 */
for (s = pat3refsym; *s; s++)
if (strcmp(refsymname, *s) == 0)
return 1;
}
return 0;
}
@ -1090,7 +1155,8 @@ static void read_symbols(char *modname)
struct elf_info info = { };
Elf_Sym *sym;
parse_elf(&info, modname);
if (!parse_elf(&info, modname))
return;
mod = new_module(modname);
@ -1265,9 +1331,14 @@ static int add_versions(struct buffer *b, struct module *mod)
exp = find_symbol(s->name);
if (!exp || exp->module == mod) {
if (have_vmlinux && !s->weak) {
warn("\"%s\" [%s.ko] undefined!\n",
s->name, mod->name);
err = warn_unresolved ? 0 : 1;
if (warn_unresolved) {
warn("\"%s\" [%s.ko] undefined!\n",
s->name, mod->name);
} else {
merror("\"%s\" [%s.ko] undefined!\n",
s->name, mod->name);
err = 1;
}
}
continue;
}
@ -1318,6 +1389,7 @@ static void add_depends(struct buffer *b, struct module *mod,
buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n");
buf_printf(b, "\"depends=");
for (s = mod->unres; s; s = s->next) {
const char *p;
if (!s->module)
continue;
@ -1325,8 +1397,11 @@ static void add_depends(struct buffer *b, struct module *mod,
continue;
s->module->seen = 1;
buf_printf(b, "%s%s", first ? "" : ",",
strrchr(s->module->name, '/') + 1);
if ((p = strrchr(s->module->name, '/')) != NULL)
p++;
else
p = s->module->name;
buf_printf(b, "%s%s", first ? "" : ",", p);
first = 0;
}
buf_printf(b, "\";\n");