Commit 74f3ae74 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'module' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus

* 'module' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus:
  modpost: fix segfault with short symbol names
  module: handle ppc64 relocating kcrctabs when CONFIG_RELOCATABLE=y
  Kbuild: clear marker out of modpost
  module: make MODULE_SYMBOL_PREFIX into a CONFIG option
  ARM: unexport symbols used to implement floating point emulation
  ARM: use unified discard definition in linker script
  x86: don't export inline function
  sparc64: don't export static inline pci_ functions
parents d8bef0bb 8d99513c
......@@ -48,27 +48,7 @@ extern void __aeabi_uidivmod(void);
extern void __aeabi_ulcmp(void);
extern void fpundefinstr(void);
extern void fp_enter(void);
/*
* This has a special calling convention; it doesn't
* modify any of the usual registers, except for LR.
*/
#define EXPORT_CRC_ALIAS(sym) __CRC_SYMBOL(sym, "")
#define EXPORT_SYMBOL_ALIAS(sym,orig) \
EXPORT_CRC_ALIAS(sym) \
static const struct kernel_symbol __ksymtab_##sym \
__used __attribute__((section("__ksymtab"))) = \
{ (unsigned long)&orig, #sym };
/*
* floating point math emulator support.
* These symbols will never change their calling convention...
*/
EXPORT_SYMBOL_ALIAS(kern_fp_enter,fp_enter);
EXPORT_SYMBOL_ALIAS(fp_printk,printk);
EXPORT_SYMBOL_ALIAS(fp_send_sig,send_sig);
EXPORT_SYMBOL(__backtrace);
......
......@@ -65,11 +65,11 @@ SECTIONS
__init_end = .;
#endif
/DISCARD/ : { /* Exit code and data */
EXIT_TEXT
EXIT_DATA
*(.exitcall.exit)
*(.discard)
/*
* unwind exit sections must be discarded before the rest of the
* unwind sections get included.
*/
/DISCARD/ : {
*(.ARM.exidx.exit.text)
*(.ARM.extab.exit.text)
#ifndef CONFIG_HOTPLUG_CPU
......@@ -238,6 +238,9 @@ SECTIONS
STABS_DEBUG
.comment 0 : { *(.comment) }
/* Default discards */
DISCARDS
}
/*
......
......@@ -5,6 +5,10 @@
mainmenu "Blackfin Kernel Configuration"
config SYMBOL_PREFIX
string
default "_"
config MMU
def_bool n
......
......@@ -7,8 +7,6 @@
#ifndef _ASM_BFIN_MODULE_H
#define _ASM_BFIN_MODULE_H
#define MODULE_SYMBOL_PREFIX "_"
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
......
......@@ -4,8 +4,6 @@
* Licensed under the GPL-2 or later
*/
#define VMLINUX_SYMBOL(_sym_) _##_sym_
#include <asm-generic/vmlinux.lds.h>
#include <asm/mem_map.h>
#include <asm/page.h>
......
......@@ -10,6 +10,10 @@ config H8300
default y
select HAVE_IDE
config SYMBOL_PREFIX
string
default "_"
config MMU
bool
default n
......
......@@ -8,6 +8,4 @@ struct mod_arch_specific { };
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
#define MODULE_SYMBOL_PREFIX "_"
#endif /* _ASM_H8/300_MODULE_H */
#define VMLINUX_SYMBOL(_sym_) _##_sym_
#include <asm-generic/vmlinux.lds.h>
#include <asm/page.h>
......
......@@ -87,5 +87,10 @@ struct exception_table_entry;
void sort_ex_table(struct exception_table_entry *start,
struct exception_table_entry *finish);
#ifdef CONFIG_MODVERSIONS
#define ARCH_RELOCATES_KCRCTAB
extern const unsigned long reloc_start[];
#endif
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_MODULE_H */
......@@ -38,6 +38,9 @@ jiffies = jiffies_64 + 4;
#endif
SECTIONS
{
. = 0;
reloc_start = .;
. = KERNELBASE;
/*
......
......@@ -1064,7 +1064,6 @@ int pci64_dma_supported(struct pci_dev *pdev, u64 device_mask)
return (device_mask & dma_addr_mask) == dma_addr_mask;
}
EXPORT_SYMBOL(pci_dma_supported);
void pci_resource_to_user(const struct pci_dev *pdev, int bar,
const struct resource *rp, resource_size_t *start,
......
......@@ -38,17 +38,5 @@ EXPORT_SYMBOL(sun4v_niagara_setperf);
EXPORT_SYMBOL(sun4v_niagara2_getperf);
EXPORT_SYMBOL(sun4v_niagara2_setperf);
#ifdef CONFIG_PCI
/* inline functions in asm/pci_64.h */
EXPORT_SYMBOL(pci_alloc_consistent);
EXPORT_SYMBOL(pci_free_consistent);
EXPORT_SYMBOL(pci_map_single);
EXPORT_SYMBOL(pci_unmap_single);
EXPORT_SYMBOL(pci_map_sg);
EXPORT_SYMBOL(pci_unmap_sg);
EXPORT_SYMBOL(pci_dma_sync_single_for_cpu);
EXPORT_SYMBOL(pci_dma_sync_sg_for_cpu);
#endif
/* Exporting a symbol from /init/main.c */
EXPORT_SYMBOL(saved_command_line);
......@@ -56,4 +56,6 @@ EXPORT_SYMBOL(__memcpy);
EXPORT_SYMBOL(empty_zero_page);
EXPORT_SYMBOL(init_level4_pgt);
EXPORT_SYMBOL(load_gs_index);
#ifndef CONFIG_PARAVIRT
EXPORT_SYMBOL(native_load_gs_index);
#endif
......@@ -52,8 +52,12 @@
#define LOAD_OFFSET 0
#endif
#ifndef VMLINUX_SYMBOL
#define VMLINUX_SYMBOL(_sym_) _sym_
#ifndef SYMBOL_PREFIX
#define VMLINUX_SYMBOL(sym) sym
#else
#define PASTE2(x,y) x##y
#define PASTE(x,y) PASTE2(x,y)
#define VMLINUX_SYMBOL(sym) PASTE(SYMBOL_PREFIX, sym)
#endif
/* Align . to a 8 byte boundary equals to maximum function alignment. */
......
......@@ -25,8 +25,10 @@
/* Not Yet Implemented */
#define MODULE_SUPPORTED_DEVICE(name)
/* some toolchains uses a `_' prefix for all user symbols */
#ifndef MODULE_SYMBOL_PREFIX
/* Some toolchains use a `_' prefix for all user symbols. */
#ifdef CONFIG_SYMBOL_PREFIX
#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX
#else
#define MODULE_SYMBOL_PREFIX ""
#endif
......
......@@ -880,11 +880,23 @@ static int try_to_force_load(struct module *mod, const char *reason)
}
#ifdef CONFIG_MODVERSIONS
/* If the arch applies (non-zero) relocations to kernel kcrctab, unapply it. */
static unsigned long maybe_relocated(unsigned long crc,
const struct module *crc_owner)
{
#ifdef ARCH_RELOCATES_KCRCTAB
if (crc_owner == NULL)
return crc - (unsigned long)reloc_start;
#endif
return crc;
}
static int check_version(Elf_Shdr *sechdrs,
unsigned int versindex,
const char *symname,
struct module *mod,
const unsigned long *crc)
const unsigned long *crc,
const struct module *crc_owner)
{
unsigned int i, num_versions;
struct modversion_info *versions;
......@@ -905,10 +917,10 @@ static int check_version(Elf_Shdr *sechdrs,
if (strcmp(versions[i].name, symname) != 0)
continue;
if (versions[i].crc == *crc)
if (versions[i].crc == maybe_relocated(*crc, crc_owner))
return 1;
DEBUGP("Found checksum %lX vs module %lX\n",
*crc, versions[i].crc);
maybe_relocated(*crc, crc_owner), versions[i].crc);
goto bad_version;
}
......@@ -931,7 +943,8 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL,
&crc, true, false))
BUG();
return check_version(sechdrs, versindex, "module_layout", mod, crc);
return check_version(sechdrs, versindex, "module_layout", mod, crc,
NULL);
}
/* First part is kernel version, which we ignore if module has crcs. */
......@@ -949,7 +962,8 @@ static inline int check_version(Elf_Shdr *sechdrs,
unsigned int versindex,
const char *symname,
struct module *mod,
const unsigned long *crc)
const unsigned long *crc,
const struct module *crc_owner)
{
return 1;
}
......@@ -984,8 +998,8 @@ static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs,
/* use_module can fail due to OOM,
or module initialization or unloading */
if (sym) {
if (!check_version(sechdrs, versindex, name, mod, crc) ||
!use_module(mod, owner))
if (!check_version(sechdrs, versindex, name, mod, crc, owner)
|| !use_module(mod, owner))
sym = NULL;
}
return sym;
......
......@@ -127,6 +127,11 @@ _c_flags += $(if $(patsubst n%,, \
$(CFLAGS_GCOV))
endif
ifdef CONFIG_SYMBOL_PREFIX
_cpp_flags += -DSYMBOL_PREFIX=$(patsubst "%",%,$(CONFIG_SYMBOL_PREFIX))
endif
# If building the kernel in a separate objtree expand all occurrences
# of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/').
......
......@@ -8,7 +8,7 @@ modpost-objs := modpost.o file2alias.o sumversion.o
$(obj)/modpost.o $(obj)/file2alias.o $(obj)/sumversion.o: $(obj)/elfconfig.h
quiet_cmd_elfconfig = MKELF $@
cmd_elfconfig = $(obj)/mk_elfconfig $(ARCH) < $< > $@
cmd_elfconfig = $(obj)/mk_elfconfig < $< > $@
$(obj)/elfconfig.h: $(obj)/empty.o $(obj)/mk_elfconfig FORCE
$(call if_changed,elfconfig)
......
......@@ -9,9 +9,6 @@ main(int argc, char **argv)
unsigned char ei[EI_NIDENT];
union { short s; char c[2]; } endian_test;
if (argc != 2) {
fprintf(stderr, "Error: no arch\n");
}
if (fread(ei, 1, EI_NIDENT, stdin) != EI_NIDENT) {
fprintf(stderr, "Error: input truncated\n");
return 1;
......@@ -55,12 +52,6 @@ main(int argc, char **argv)
else
exit(1);
if ((strcmp(argv[1], "h8300") == 0)
|| (strcmp(argv[1], "blackfin") == 0))
printf("#define MODULE_SYMBOL_PREFIX \"_\"\n");
else
printf("#define MODULE_SYMBOL_PREFIX \"\"\n");
return 0;
}
......@@ -15,8 +15,17 @@
#include <stdio.h>
#include <ctype.h>
#include "modpost.h"
#include "../../include/linux/autoconf.h"
#include "../../include/linux/license.h"
/* Some toolchains use a `_' prefix for all user symbols. */
#ifdef CONFIG_SYMBOL_PREFIX
#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX
#else
#define MODULE_SYMBOL_PREFIX ""
#endif
/* Are we using CONFIG_MODVERSIONS? */
int modversions = 0;
/* Warn about undefined symbols? (do so if we have vmlinux) */
......@@ -451,8 +460,6 @@ static int parse_elf(struct elf_info *info, const char *filename)
info->export_unused_gpl_sec = i;
else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
info->export_gpl_future_sec = i;
else if (strcmp(secname, "__markers_strings") == 0)
info->markers_strings_sec = i;
if (sechdrs[i].sh_type != SHT_SYMTAB)
continue;
......@@ -515,7 +522,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
break;
case SHN_ABS:
/* CRC'd symbol */
if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
if (strncmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
crc = (unsigned int) sym->st_value;
sym_update_crc(symname + strlen(CRC_PFX), mod, crc,
export);
......@@ -559,7 +566,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
break;
default:
/* All exported symbols */
if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
if (strncmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
sym_add_exported(symname + strlen(KSYMTAB_PFX), mod,
export);
}
......@@ -1509,62 +1516,6 @@ static void check_sec_ref(struct module *mod, const char *modname,
}
}
static void get_markers(struct elf_info *info, struct module *mod)
{
const Elf_Shdr *sh = &info->sechdrs[info->markers_strings_sec];
const char *strings = (const char *) info->hdr + sh->sh_offset;
const Elf_Sym *sym, *first_sym, *last_sym;
size_t n;
if (!info->markers_strings_sec)
return;
/*
* First count the strings. We look for all the symbols defined
* in the __markers_strings section named __mstrtab_*. For
* these local names, the compiler puts a random .NNN suffix on,
* so the names don't correspond exactly.
*/
first_sym = last_sym = NULL;
n = 0;
for (sym = info->symtab_start; sym < info->symtab_stop; sym++)
if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT &&
sym->st_shndx == info->markers_strings_sec &&
!strncmp(info->strtab + sym->st_name,
"__mstrtab_", sizeof "__mstrtab_" - 1)) {
if (first_sym == NULL)
first_sym = sym;
last_sym = sym;
++n;
}
if (n == 0)
return;
/*
* Now collect each name and format into a line for the output.
* Lines look like:
* marker_name vmlinux marker %s format %d
* The format string after the second \t can use whitespace.
*/
mod->markers = NOFAIL(malloc(sizeof mod->markers[0] * n));
mod->nmarkers = n;
n = 0;
for (sym = first_sym; sym <= last_sym; sym++)
if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT &&
sym->st_shndx == info->markers_strings_sec &&
!strncmp(info->strtab + sym->st_name,
"__mstrtab_", sizeof "__mstrtab_" - 1)) {
const char *name = strings + sym->st_value;
const char *fmt = strchr(name, '\0') + 1;
char *line = NULL;
asprintf(&line, "%s\t%s\t%s\n", name, mod->name, fmt);
NOFAIL(line);
mod->markers[n++] = line;
}
}
static void read_symbols(char *modname)
{
const char *symname;
......@@ -1620,8 +1571,6 @@ static void read_symbols(char *modname)
get_src_version(modname, mod->srcversion,
sizeof(mod->srcversion)-1);
get_markers(&info, mod);
parse_elf_finish(&info);
/* Our trick to get versioning for module struct etc. - it's
......@@ -1976,96 +1925,6 @@ static void write_dump(const char *fname)
write_if_changed(&buf, fname);
}
static void add_marker(struct module *mod, const char *name, const char *fmt)
{
char *line = NULL;
asprintf(&line, "%s\t%s\t%s\n", name, mod->name, fmt);
NOFAIL(line);
mod->markers = NOFAIL(realloc(mod->markers, ((mod->nmarkers + 1) *
sizeof mod->markers[0])));
mod->markers[mod->nmarkers++] = line;
}
static void read_markers(const char *fname)
{
unsigned long size, pos = 0;
void *file = grab_file(fname, &size);
char *line;
if (!file) /* No old markers, silently ignore */
return;
while ((line = get_next_line(&pos, file, size))) {
char *marker, *modname, *fmt;
struct module *mod;
marker = line;
modname = strchr(marker, '\t');
if (!modname)
goto fail;
*modname++ = '\0';
fmt = strchr(modname, '\t');
if (!fmt)
goto fail;
*fmt++ = '\0';
if (*marker == '\0' || *modname == '\0')
goto fail;
mod = find_module(modname);
if (!mod) {
mod = new_module(modname);
mod->skip = 1;
}
if (is_vmlinux(modname)) {
have_vmlinux = 1;
mod->skip = 0;
}
if (!mod->skip)
add_marker(mod, marker, fmt);
}
release_file(file, size);
return;
fail:
fatal("parse error in markers list file\n");
}
static int compare_strings(const void *a, const void *b)
{
return strcmp(*(const char **) a, *(const char **) b);
}
static void write_markers(const char *fname)
{
struct buffer buf = { };
struct module *mod;
size_t i;
for (mod = modules; mod; mod = mod->next)
if ((!external_module || !mod->skip) && mod->markers != NULL) {
/*
* Sort the strings so we can skip duplicates when
* we write them out.
*/
qsort(mod->markers, mod->nmarkers,
sizeof mod->markers[0], &compare_strings);
for (i = 0; i < mod->nmarkers; ++i) {
char *line = mod->markers[i];
buf_write(&buf, line, strlen(line));
while (i + 1 < mod->nmarkers &&
!strcmp(mod->markers[i],
mod->markers[i + 1]))
free(mod->markers[i++]);
free(mod->markers[i]);
}
free(mod->markers);
mod->markers = NULL;
}
write_if_changed(&buf, fname);
}
struct ext_sym_list {
struct ext_sym_list *next;
const char *file;
......@@ -2077,8 +1936,6 @@ int main(int argc, char **argv)
struct buffer buf = { };
char *kernel_read = NULL, *module_read = NULL;
char *dump_write = NULL;
char *markers_read = NULL;
char *markers_write = NULL;
int opt;
int err;
struct ext_sym_list *extsym_iter;
......@@ -2122,12 +1979,6 @@ int main(int argc, char **argv)
case 'w':
warn_unresolved = 1;
break;
case 'M':
markers_write = optarg;
break;
case 'K':
markers_read = optarg;
break;
default:
exit(1);
}
......@@ -2182,11 +2033,5 @@ int main(int argc, char **argv)
"'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n",
sec_mismatch_count);
if (markers_read)
read_markers(markers_read);
if (markers_write)
write_markers(markers_write);
return err;
}
......@@ -112,8 +112,6 @@ struct module {
int has_init;
int has_cleanup;
struct buffer dev_table_buf;
char **markers;
size_t nmarkers;
char srcversion[25];
};
......@@ -128,7 +126,6 @@ struct elf_info {
Elf_Section export_gpl_sec;
Elf_Section export_unused_gpl_sec;
Elf_Section export_gpl_future_sec;
Elf_Section markers_strings_sec;
const char *strtab;
char *modinfo;
unsigned int modinfo_len;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment