Revert "ANDROID: Revert "Merge tag 'modules-for-v5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux""
This reverts commit 3fde1dfb00
.
Revert to the upstream version by reinstating the original
modules-for-v5.4 merge.
Bug: 142892219
Bug: 144336692
Change-Id: I3871c67dd3cba0a5b9b2e1a87be8653a14cb9de5
Signed-off-by: Matthias Maennich <maennich@google.com>
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -32,6 +32,7 @@
|
|||||||
*.lzo
|
*.lzo
|
||||||
*.mod
|
*.mod
|
||||||
*.mod.c
|
*.mod.c
|
||||||
|
*.ns_deps
|
||||||
*.o
|
*.o
|
||||||
*.o.*
|
*.o.*
|
||||||
*.patch
|
*.patch
|
||||||
|
@@ -470,9 +470,12 @@ build.
|
|||||||
|
|
||||||
The syntax of the Module.symvers file is::
|
The syntax of the Module.symvers file is::
|
||||||
|
|
||||||
<CRC> <Symbol> <module>
|
<CRC> <Symbol> <Namespace> <Module> <Export Type>
|
||||||
|
|
||||||
0x2d036834 scsi_remove_host drivers/scsi/scsi_mod
|
0xe1cc2a05 usb_stor_suspend USB_STORAGE drivers/usb/storage/usb-storage EXPORT_SYMBOL_GPL
|
||||||
|
|
||||||
|
The fields are separated by tabs and values may be empty (e.g.
|
||||||
|
if no namespace is defined for an exported symbol).
|
||||||
|
|
||||||
For a kernel build without CONFIG_MODVERSIONS enabled, the CRC
|
For a kernel build without CONFIG_MODVERSIONS enabled, the CRC
|
||||||
would read 0x00000000.
|
would read 0x00000000.
|
||||||
|
@@ -594,6 +594,24 @@ internal implementation issue, and not really an interface. Some
|
|||||||
maintainers and developers may however require EXPORT_SYMBOL_GPL()
|
maintainers and developers may however require EXPORT_SYMBOL_GPL()
|
||||||
when adding any new APIs or functionality.
|
when adding any new APIs or functionality.
|
||||||
|
|
||||||
|
:c:func:`EXPORT_SYMBOL_NS()`
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Defined in ``include/linux/export.h``
|
||||||
|
|
||||||
|
This is the variant of `EXPORT_SYMBOL()` that allows specifying a symbol
|
||||||
|
namespace. Symbol Namespaces are documented in
|
||||||
|
``Documentation/kbuild/namespaces.rst``.
|
||||||
|
|
||||||
|
:c:func:`EXPORT_SYMBOL_NS_GPL()`
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
Defined in ``include/linux/export.h``
|
||||||
|
|
||||||
|
This is the variant of `EXPORT_SYMBOL_GPL()` that allows specifying a symbol
|
||||||
|
namespace. Symbol Namespaces are documented in
|
||||||
|
``Documentation/kbuild/namespaces.rst``.
|
||||||
|
|
||||||
Routines and Conventions
|
Routines and Conventions
|
||||||
========================
|
========================
|
||||||
|
|
||||||
|
14
Makefile
14
Makefile
@@ -1481,6 +1481,9 @@ help:
|
|||||||
@echo ' headerdep - Detect inclusion cycles in headers'
|
@echo ' headerdep - Detect inclusion cycles in headers'
|
||||||
@echo ' coccicheck - Check with Coccinelle'
|
@echo ' coccicheck - Check with Coccinelle'
|
||||||
@echo ''
|
@echo ''
|
||||||
|
@echo 'Tools:'
|
||||||
|
@echo ' nsdeps - Generate missing symbol namespace dependencies'
|
||||||
|
@echo ''
|
||||||
@echo 'Kernel selftest:'
|
@echo 'Kernel selftest:'
|
||||||
@echo ' kselftest - Build and run kernel selftest (run as root)'
|
@echo ' kselftest - Build and run kernel selftest (run as root)'
|
||||||
@echo ' Build, install, and boot kernel before'
|
@echo ' Build, install, and boot kernel before'
|
||||||
@@ -1662,7 +1665,7 @@ clean: $(clean-dirs)
|
|||||||
-o -name '*.ko.*' \
|
-o -name '*.ko.*' \
|
||||||
-o -name '*.dtb' -o -name '*.dtb.S' -o -name '*.dt.yaml' \
|
-o -name '*.dtb' -o -name '*.dtb.S' -o -name '*.dt.yaml' \
|
||||||
-o -name '*.dwo' -o -name '*.lst' \
|
-o -name '*.dwo' -o -name '*.lst' \
|
||||||
-o -name '*.su' -o -name '*.mod' \
|
-o -name '*.su' -o -name '*.mod' -o -name '*.ns_deps' \
|
||||||
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
|
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
|
||||||
-o -name '*.lex.c' -o -name '*.tab.[ch]' \
|
-o -name '*.lex.c' -o -name '*.tab.[ch]' \
|
||||||
-o -name '*.asn1.[ch]' \
|
-o -name '*.asn1.[ch]' \
|
||||||
@@ -1680,6 +1683,15 @@ quiet_cmd_tags = GEN $@
|
|||||||
tags TAGS cscope gtags: FORCE
|
tags TAGS cscope gtags: FORCE
|
||||||
$(call cmd,tags)
|
$(call cmd,tags)
|
||||||
|
|
||||||
|
# Script to generate missing namespace dependencies
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
PHONY += nsdeps
|
||||||
|
|
||||||
|
nsdeps: modules
|
||||||
|
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost nsdeps
|
||||||
|
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/$@
|
||||||
|
|
||||||
# Scripts to check various things for consistency
|
# Scripts to check various things for consistency
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@@ -1,3 +1,2 @@
|
|||||||
#define KSYM_ALIGN 2
|
|
||||||
#define KCRC_ALIGN 2
|
#define KCRC_ALIGN 2
|
||||||
#include <asm-generic/export.h>
|
#include <asm-generic/export.h>
|
||||||
|
@@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
ccflags-y := -I $(srctree)/drivers/scsi
|
ccflags-y := -I $(srctree)/drivers/scsi
|
||||||
|
|
||||||
|
ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=USB_STORAGE
|
||||||
|
|
||||||
obj-$(CONFIG_USB_UAS) += uas.o
|
obj-$(CONFIG_USB_UAS) += uas.o
|
||||||
obj-$(CONFIG_USB_STORAGE) += usb-storage.o
|
obj-$(CONFIG_USB_STORAGE) += usb-storage.o
|
||||||
|
|
||||||
|
@@ -36,6 +36,7 @@
|
|||||||
MODULE_DESCRIPTION("Driver for Alauda-based card readers");
|
MODULE_DESCRIPTION("Driver for Alauda-based card readers");
|
||||||
MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>");
|
MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_IMPORT_NS(USB_STORAGE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Status bytes
|
* Status bytes
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
MODULE_DESCRIPTION("SAT support for Cypress USB/ATA bridges with ATACB");
|
MODULE_DESCRIPTION("SAT support for Cypress USB/ATA bridges with ATACB");
|
||||||
MODULE_AUTHOR("Matthieu Castet <castet.matthieu@free.fr>");
|
MODULE_AUTHOR("Matthieu Castet <castet.matthieu@free.fr>");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_IMPORT_NS(USB_STORAGE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The table of devices
|
* The table of devices
|
||||||
|
@@ -54,6 +54,7 @@
|
|||||||
MODULE_DESCRIPTION("Driver for Datafab USB Compact Flash reader");
|
MODULE_DESCRIPTION("Driver for Datafab USB Compact Flash reader");
|
||||||
MODULE_AUTHOR("Jimmie Mayfield <mayfield+datafab@sackheads.org>");
|
MODULE_AUTHOR("Jimmie Mayfield <mayfield+datafab@sackheads.org>");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_IMPORT_NS(USB_STORAGE);
|
||||||
|
|
||||||
struct datafab_info {
|
struct datafab_info {
|
||||||
unsigned long sectors; /* total sector count */
|
unsigned long sectors; /* total sector count */
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
MODULE_DESCRIPTION("Driver for ENE UB6250 reader");
|
MODULE_DESCRIPTION("Driver for ENE UB6250 reader");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_IMPORT_NS(USB_STORAGE);
|
||||||
MODULE_FIRMWARE(SD_INIT1_FIRMWARE);
|
MODULE_FIRMWARE(SD_INIT1_FIRMWARE);
|
||||||
MODULE_FIRMWARE(SD_INIT2_FIRMWARE);
|
MODULE_FIRMWARE(SD_INIT2_FIRMWARE);
|
||||||
MODULE_FIRMWARE(SD_RW_FIRMWARE);
|
MODULE_FIRMWARE(SD_RW_FIRMWARE);
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
MODULE_DESCRIPTION("Driver for Freecom USB/IDE adaptor");
|
MODULE_DESCRIPTION("Driver for Freecom USB/IDE adaptor");
|
||||||
MODULE_AUTHOR("David Brown <usb-storage@davidb.org>");
|
MODULE_AUTHOR("David Brown <usb-storage@davidb.org>");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_IMPORT_NS(USB_STORAGE);
|
||||||
|
|
||||||
#ifdef CONFIG_USB_STORAGE_DEBUG
|
#ifdef CONFIG_USB_STORAGE_DEBUG
|
||||||
static void pdump(struct us_data *us, void *ibuffer, int length);
|
static void pdump(struct us_data *us, void *ibuffer, int length);
|
||||||
|
@@ -53,6 +53,7 @@
|
|||||||
MODULE_DESCRIPTION("Driver for In-System Design, Inc. ISD200 ASIC");
|
MODULE_DESCRIPTION("Driver for In-System Design, Inc. ISD200 ASIC");
|
||||||
MODULE_AUTHOR("Björn Stenberg <bjorn@haxx.se>");
|
MODULE_AUTHOR("Björn Stenberg <bjorn@haxx.se>");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_IMPORT_NS(USB_STORAGE);
|
||||||
|
|
||||||
static int isd200_Initialization(struct us_data *us);
|
static int isd200_Initialization(struct us_data *us);
|
||||||
|
|
||||||
|
@@ -51,6 +51,7 @@
|
|||||||
MODULE_DESCRIPTION("Driver for Lexar \"Jumpshot\" Compact Flash reader");
|
MODULE_DESCRIPTION("Driver for Lexar \"Jumpshot\" Compact Flash reader");
|
||||||
MODULE_AUTHOR("Jimmie Mayfield <mayfield+usb@sackheads.org>");
|
MODULE_AUTHOR("Jimmie Mayfield <mayfield+usb@sackheads.org>");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_IMPORT_NS(USB_STORAGE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The table of devices
|
* The table of devices
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
MODULE_DESCRIPTION("Driver for Rio Karma");
|
MODULE_DESCRIPTION("Driver for Rio Karma");
|
||||||
MODULE_AUTHOR("Bob Copeland <me@bobcopeland.com>, Keith Bennett <keith@mcs.st-and.ac.uk>");
|
MODULE_AUTHOR("Bob Copeland <me@bobcopeland.com>, Keith Bennett <keith@mcs.st-and.ac.uk>");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_IMPORT_NS(USB_STORAGE);
|
||||||
|
|
||||||
#define RIO_PREFIX "RIOP\x00"
|
#define RIO_PREFIX "RIOP\x00"
|
||||||
#define RIO_PREFIX_LEN 5
|
#define RIO_PREFIX_LEN 5
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
MODULE_DESCRIPTION("Maxtor USB OneTouch hard drive button driver");
|
MODULE_DESCRIPTION("Maxtor USB OneTouch hard drive button driver");
|
||||||
MODULE_AUTHOR("Nick Sillik <n.sillik@temple.edu>");
|
MODULE_AUTHOR("Nick Sillik <n.sillik@temple.edu>");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_IMPORT_NS(USB_STORAGE);
|
||||||
|
|
||||||
#define ONETOUCH_PKT_LEN 0x02
|
#define ONETOUCH_PKT_LEN 0x02
|
||||||
#define ONETOUCH_BUTTON KEY_PROG1
|
#define ONETOUCH_BUTTON KEY_PROG1
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
MODULE_DESCRIPTION("Driver for Realtek USB Card Reader");
|
MODULE_DESCRIPTION("Driver for Realtek USB Card Reader");
|
||||||
MODULE_AUTHOR("wwang <wei_wang@realsil.com.cn>");
|
MODULE_AUTHOR("wwang <wei_wang@realsil.com.cn>");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_IMPORT_NS(USB_STORAGE);
|
||||||
|
|
||||||
static int auto_delink_en = 1;
|
static int auto_delink_en = 1;
|
||||||
module_param(auto_delink_en, int, S_IRUGO | S_IWUSR);
|
module_param(auto_delink_en, int, S_IRUGO | S_IWUSR);
|
||||||
|
@@ -47,6 +47,7 @@
|
|||||||
MODULE_DESCRIPTION("Driver for SanDisk SDDR-09 SmartMedia reader");
|
MODULE_DESCRIPTION("Driver for SanDisk SDDR-09 SmartMedia reader");
|
||||||
MODULE_AUTHOR("Andries Brouwer <aeb@cwi.nl>, Robert Baruch <autophile@starband.net>");
|
MODULE_AUTHOR("Andries Brouwer <aeb@cwi.nl>, Robert Baruch <autophile@starband.net>");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_IMPORT_NS(USB_STORAGE);
|
||||||
|
|
||||||
static int usb_stor_sddr09_dpcm_init(struct us_data *us);
|
static int usb_stor_sddr09_dpcm_init(struct us_data *us);
|
||||||
static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us);
|
static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us);
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
MODULE_DESCRIPTION("Driver for SanDisk SDDR-55 SmartMedia reader");
|
MODULE_DESCRIPTION("Driver for SanDisk SDDR-55 SmartMedia reader");
|
||||||
MODULE_AUTHOR("Simon Munton");
|
MODULE_AUTHOR("Simon Munton");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_IMPORT_NS(USB_STORAGE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The table of devices
|
* The table of devices
|
||||||
|
@@ -48,6 +48,7 @@
|
|||||||
MODULE_DESCRIPTION("Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable");
|
MODULE_DESCRIPTION("Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable");
|
||||||
MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>, Robert Baruch <autophile@starband.net>");
|
MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>, Robert Baruch <autophile@starband.net>");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_IMPORT_NS(USB_STORAGE);
|
||||||
|
|
||||||
/* Supported device types */
|
/* Supported device types */
|
||||||
#define USBAT_DEV_HP8200 0x01
|
#define USBAT_DEV_HP8200 0x01
|
||||||
|
@@ -1199,5 +1199,6 @@ static struct usb_driver uas_driver = {
|
|||||||
module_usb_driver(uas_driver);
|
module_usb_driver(uas_driver);
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_IMPORT_NS(USB_STORAGE);
|
||||||
MODULE_AUTHOR(
|
MODULE_AUTHOR(
|
||||||
"Hans de Goede <hdegoede@redhat.com>, Matthew Wilcox and Sarah Sharp");
|
"Hans de Goede <hdegoede@redhat.com>, Matthew Wilcox and Sarah Sharp");
|
||||||
|
@@ -4,14 +4,12 @@
|
|||||||
#ifndef KSYM_FUNC
|
#ifndef KSYM_FUNC
|
||||||
#define KSYM_FUNC(x) x
|
#define KSYM_FUNC(x) x
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_64BIT
|
#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
|
||||||
#ifndef KSYM_ALIGN
|
#define KSYM_ALIGN 4
|
||||||
#define KSYM_ALIGN 8
|
#elif defined(CONFIG_64BIT)
|
||||||
#endif
|
#define KSYM_ALIGN 8
|
||||||
#else
|
#else
|
||||||
#ifndef KSYM_ALIGN
|
|
||||||
#define KSYM_ALIGN 4
|
#define KSYM_ALIGN 4
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#ifndef KCRC_ALIGN
|
#ifndef KCRC_ALIGN
|
||||||
#define KCRC_ALIGN 4
|
#define KCRC_ALIGN 4
|
||||||
@@ -19,11 +17,11 @@
|
|||||||
|
|
||||||
.macro __put, val, name
|
.macro __put, val, name
|
||||||
#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
|
#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
|
||||||
.long \val - ., \name - .
|
.long \val - ., \name - ., 0
|
||||||
#elif defined(CONFIG_64BIT)
|
#elif defined(CONFIG_64BIT)
|
||||||
.quad \val, \name
|
.quad \val, \name, 0
|
||||||
#else
|
#else
|
||||||
.long \val, \name
|
.long \val, \name, 0
|
||||||
#endif
|
#endif
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@@ -57,7 +55,6 @@ __kcrctab_\name:
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
.endm
|
.endm
|
||||||
#undef __put
|
|
||||||
|
|
||||||
#if defined(CONFIG_TRIM_UNUSED_KSYMS)
|
#if defined(CONFIG_TRIM_UNUSED_KSYMS)
|
||||||
|
|
||||||
|
@@ -18,6 +18,8 @@ extern struct module __this_module;
|
|||||||
#define THIS_MODULE ((struct module *)0)
|
#define THIS_MODULE ((struct module *)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define NS_SEPARATOR "."
|
||||||
|
|
||||||
#ifdef CONFIG_MODVERSIONS
|
#ifdef CONFIG_MODVERSIONS
|
||||||
/* Mark the CRC weak since genksyms apparently decides not to
|
/* Mark the CRC weak since genksyms apparently decides not to
|
||||||
* generate a checksums for some symbols */
|
* generate a checksums for some symbols */
|
||||||
@@ -26,13 +28,13 @@ extern struct module __this_module;
|
|||||||
asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \
|
asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \
|
||||||
" .weak __crc_" #sym " \n" \
|
" .weak __crc_" #sym " \n" \
|
||||||
" .long __crc_" #sym " - . \n" \
|
" .long __crc_" #sym " - . \n" \
|
||||||
" .previous \n");
|
" .previous \n")
|
||||||
#else
|
#else
|
||||||
#define __CRC_SYMBOL(sym, sec) \
|
#define __CRC_SYMBOL(sym, sec) \
|
||||||
asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \
|
asm(" .section \"___kcrctab" sec "+" #sym "\", \"a\" \n" \
|
||||||
" .weak __crc_" #sym " \n" \
|
" .weak __crc_" #sym " \n" \
|
||||||
" .long __crc_" #sym " \n" \
|
" .long __crc_" #sym " \n" \
|
||||||
" .previous \n");
|
" .previous \n")
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define __CRC_SYMBOL(sym, sec)
|
#define __CRC_SYMBOL(sym, sec)
|
||||||
@@ -46,44 +48,77 @@ extern struct module __this_module;
|
|||||||
* absolute relocations that require runtime processing on relocatable
|
* absolute relocations that require runtime processing on relocatable
|
||||||
* kernels.
|
* kernels.
|
||||||
*/
|
*/
|
||||||
|
#define __KSYMTAB_ENTRY_NS(sym, sec, ns) \
|
||||||
|
__ADDRESSABLE(sym) \
|
||||||
|
asm(" .section \"___ksymtab" sec "+" #sym "\", \"a\" \n" \
|
||||||
|
" .balign 4 \n" \
|
||||||
|
"__ksymtab_" #ns NS_SEPARATOR #sym ": \n" \
|
||||||
|
" .long " #sym "- . \n" \
|
||||||
|
" .long __kstrtab_" #sym "- . \n" \
|
||||||
|
" .long __kstrtabns_" #sym "- . \n" \
|
||||||
|
" .previous \n")
|
||||||
|
|
||||||
#define __KSYMTAB_ENTRY(sym, sec) \
|
#define __KSYMTAB_ENTRY(sym, sec) \
|
||||||
__ADDRESSABLE(sym) \
|
__ADDRESSABLE(sym) \
|
||||||
asm(" .section \"___ksymtab" sec "+" #sym "\", \"a\" \n" \
|
asm(" .section \"___ksymtab" sec "+" #sym "\", \"a\" \n" \
|
||||||
" .balign 8 \n" \
|
" .balign 4 \n" \
|
||||||
"__ksymtab_" #sym ": \n" \
|
"__ksymtab_" #sym ": \n" \
|
||||||
" .long " #sym "- . \n" \
|
" .long " #sym "- . \n" \
|
||||||
" .long __kstrtab_" #sym "- . \n" \
|
" .long __kstrtab_" #sym "- . \n" \
|
||||||
|
" .long 0 \n" \
|
||||||
" .previous \n")
|
" .previous \n")
|
||||||
|
|
||||||
struct kernel_symbol {
|
struct kernel_symbol {
|
||||||
int value_offset;
|
int value_offset;
|
||||||
int name_offset;
|
int name_offset;
|
||||||
|
int namespace_offset;
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
|
#define __KSYMTAB_ENTRY_NS(sym, sec, ns) \
|
||||||
|
static const struct kernel_symbol __ksymtab_##sym##__##ns \
|
||||||
|
asm("__ksymtab_" #ns NS_SEPARATOR #sym) \
|
||||||
|
__attribute__((section("___ksymtab" sec "+" #sym), used)) \
|
||||||
|
__aligned(sizeof(void *)) \
|
||||||
|
= { (unsigned long)&sym, __kstrtab_##sym, __kstrtabns_##sym }
|
||||||
|
|
||||||
#define __KSYMTAB_ENTRY(sym, sec) \
|
#define __KSYMTAB_ENTRY(sym, sec) \
|
||||||
static const struct kernel_symbol __ksymtab_##sym \
|
static const struct kernel_symbol __ksymtab_##sym \
|
||||||
|
asm("__ksymtab_" #sym) \
|
||||||
__attribute__((section("___ksymtab" sec "+" #sym), used)) \
|
__attribute__((section("___ksymtab" sec "+" #sym), used)) \
|
||||||
= { (unsigned long)&sym, __kstrtab_##sym }
|
__aligned(sizeof(void *)) \
|
||||||
|
= { (unsigned long)&sym, __kstrtab_##sym, NULL }
|
||||||
|
|
||||||
struct kernel_symbol {
|
struct kernel_symbol {
|
||||||
unsigned long value;
|
unsigned long value;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
const char *namespace;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GENKSYMS__
|
#ifdef __GENKSYMS__
|
||||||
|
|
||||||
#define ___EXPORT_SYMBOL(sym, sec) __GENKSYMS_EXPORT_SYMBOL(sym)
|
#define ___EXPORT_SYMBOL(sym,sec) __GENKSYMS_EXPORT_SYMBOL(sym)
|
||||||
|
#define ___EXPORT_SYMBOL_NS(sym,sec,ns) __GENKSYMS_EXPORT_SYMBOL(sym)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* For every exported symbol, place a struct in the __ksymtab section */
|
#define ___export_symbol_common(sym, sec) \
|
||||||
#define ___EXPORT_SYMBOL(sym, sec) \
|
|
||||||
extern typeof(sym) sym; \
|
extern typeof(sym) sym; \
|
||||||
__CRC_SYMBOL(sym, sec) \
|
__CRC_SYMBOL(sym, sec); \
|
||||||
static const char __kstrtab_##sym[] \
|
static const char __kstrtab_##sym[] \
|
||||||
__attribute__((section("__ksymtab_strings"), used, aligned(1))) \
|
__attribute__((section("__ksymtab_strings"), used, aligned(1))) \
|
||||||
= #sym; \
|
= #sym \
|
||||||
|
|
||||||
|
/* For every exported symbol, place a struct in the __ksymtab section */
|
||||||
|
#define ___EXPORT_SYMBOL_NS(sym, sec, ns) \
|
||||||
|
___export_symbol_common(sym, sec); \
|
||||||
|
static const char __kstrtabns_##sym[] \
|
||||||
|
__attribute__((section("__ksymtab_strings"), used, aligned(1))) \
|
||||||
|
= #ns; \
|
||||||
|
__KSYMTAB_ENTRY_NS(sym, sec, ns)
|
||||||
|
|
||||||
|
#define ___EXPORT_SYMBOL(sym, sec) \
|
||||||
|
___export_symbol_common(sym, sec); \
|
||||||
__KSYMTAB_ENTRY(sym, sec)
|
__KSYMTAB_ENTRY(sym, sec)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -95,6 +130,7 @@ struct kernel_symbol {
|
|||||||
* be reused in other execution contexts such as the UEFI stub or the
|
* be reused in other execution contexts such as the UEFI stub or the
|
||||||
* decompressor.
|
* decompressor.
|
||||||
*/
|
*/
|
||||||
|
#define __EXPORT_SYMBOL_NS(sym, sec, ns)
|
||||||
#define __EXPORT_SYMBOL(sym, sec)
|
#define __EXPORT_SYMBOL(sym, sec)
|
||||||
|
|
||||||
#elif defined(CONFIG_TRIM_UNUSED_KSYMS)
|
#elif defined(CONFIG_TRIM_UNUSED_KSYMS)
|
||||||
@@ -121,15 +157,35 @@ struct kernel_symbol {
|
|||||||
#define __cond_export_sym_1(sym, sec) ___EXPORT_SYMBOL(sym, sec)
|
#define __cond_export_sym_1(sym, sec) ___EXPORT_SYMBOL(sym, sec)
|
||||||
#define __cond_export_sym_0(sym, sec) /* nothing */
|
#define __cond_export_sym_0(sym, sec) /* nothing */
|
||||||
|
|
||||||
|
#define __EXPORT_SYMBOL_NS(sym, sec, ns) \
|
||||||
|
__ksym_marker(sym); \
|
||||||
|
__cond_export_ns_sym(sym, sec, ns, __is_defined(__KSYM_##sym))
|
||||||
|
#define __cond_export_ns_sym(sym, sec, ns, conf) \
|
||||||
|
___cond_export_ns_sym(sym, sec, ns, conf)
|
||||||
|
#define ___cond_export_ns_sym(sym, sec, ns, enabled) \
|
||||||
|
__cond_export_ns_sym_##enabled(sym, sec, ns)
|
||||||
|
#define __cond_export_ns_sym_1(sym, sec, ns) ___EXPORT_SYMBOL_NS(sym, sec, ns)
|
||||||
|
#define __cond_export_ns_sym_0(sym, sec, ns) /* nothing */
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define __EXPORT_SYMBOL(sym, sec) ___EXPORT_SYMBOL(sym, sec)
|
#define __EXPORT_SYMBOL_NS(sym,sec,ns) ___EXPORT_SYMBOL_NS(sym,sec,ns)
|
||||||
|
#define __EXPORT_SYMBOL(sym,sec) ___EXPORT_SYMBOL(sym,sec)
|
||||||
|
|
||||||
#endif /* CONFIG_MODULES */
|
#endif /* CONFIG_MODULES */
|
||||||
|
|
||||||
|
#ifdef DEFAULT_SYMBOL_NAMESPACE
|
||||||
|
#undef __EXPORT_SYMBOL
|
||||||
|
#define __EXPORT_SYMBOL(sym, sec) \
|
||||||
|
__EXPORT_SYMBOL_NS(sym, sec, DEFAULT_SYMBOL_NAMESPACE)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define EXPORT_SYMBOL(sym) __EXPORT_SYMBOL(sym, "")
|
#define EXPORT_SYMBOL(sym) __EXPORT_SYMBOL(sym, "")
|
||||||
#define EXPORT_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_gpl")
|
#define EXPORT_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_gpl")
|
||||||
#define EXPORT_SYMBOL_GPL_FUTURE(sym) __EXPORT_SYMBOL(sym, "_gpl_future")
|
#define EXPORT_SYMBOL_GPL_FUTURE(sym) __EXPORT_SYMBOL(sym, "_gpl_future")
|
||||||
|
#define EXPORT_SYMBOL_NS(sym, ns) __EXPORT_SYMBOL_NS(sym, "", ns)
|
||||||
|
#define EXPORT_SYMBOL_NS_GPL(sym, ns) __EXPORT_SYMBOL_NS(sym, "_gpl", ns)
|
||||||
|
|
||||||
#ifdef CONFIG_UNUSED_SYMBOLS
|
#ifdef CONFIG_UNUSED_SYMBOLS
|
||||||
#define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused")
|
#define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused")
|
||||||
#define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl")
|
#define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl")
|
||||||
|
35
init/Kconfig
35
init/Kconfig
@@ -2051,8 +2051,7 @@ config MODULE_SRCVERSION_ALL
|
|||||||
|
|
||||||
config MODULE_SIG
|
config MODULE_SIG
|
||||||
bool "Module signature verification"
|
bool "Module signature verification"
|
||||||
depends on MODULES
|
select MODULE_SIG_FORMAT
|
||||||
select SYSTEM_DATA_VERIFICATION
|
|
||||||
help
|
help
|
||||||
Check modules for valid signatures upon load: the signature
|
Check modules for valid signatures upon load: the signature
|
||||||
is simply appended to the module. For more information see
|
is simply appended to the module. For more information see
|
||||||
@@ -2133,7 +2132,6 @@ config MODULE_SIG_HASH
|
|||||||
|
|
||||||
config MODULE_COMPRESS
|
config MODULE_COMPRESS
|
||||||
bool "Compress modules on installation"
|
bool "Compress modules on installation"
|
||||||
depends on MODULES
|
|
||||||
help
|
help
|
||||||
|
|
||||||
Compresses kernel modules when 'make modules_install' is run; gzip or
|
Compresses kernel modules when 'make modules_install' is run; gzip or
|
||||||
@@ -2169,9 +2167,38 @@ config MODULE_COMPRESS_XZ
|
|||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
|
config MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS
|
||||||
|
bool "Allow loading of modules with missing namespace imports"
|
||||||
|
help
|
||||||
|
Symbols exported with EXPORT_SYMBOL_NS*() are considered exported in
|
||||||
|
a namespace. A module that makes use of a symbol exported with such a
|
||||||
|
namespace is required to import the namespace via MODULE_IMPORT_NS().
|
||||||
|
There is no technical reason to enforce correct namespace imports,
|
||||||
|
but it creates consistency between symbols defining namespaces and
|
||||||
|
users importing namespaces they make use of. This option relaxes this
|
||||||
|
requirement and lifts the enforcement when loading a module.
|
||||||
|
|
||||||
|
If unsure, say N.
|
||||||
|
|
||||||
|
config UNUSED_SYMBOLS
|
||||||
|
bool "Enable unused/obsolete exported symbols"
|
||||||
|
default y if X86
|
||||||
|
help
|
||||||
|
Unused but exported symbols make the kernel needlessly bigger. For
|
||||||
|
that reason most of these unused exports will soon be removed. This
|
||||||
|
option is provided temporarily to provide a transition period in case
|
||||||
|
some external kernel module needs one of these symbols anyway. If you
|
||||||
|
encounter such a case in your module, consider if you are actually
|
||||||
|
using the right API. (rationale: since nobody in the kernel is using
|
||||||
|
this in a module, there is a pretty good chance it's actually the
|
||||||
|
wrong interface to use). If you really need the symbol, please send a
|
||||||
|
mail to the linux kernel mailing list mentioning the symbol and why
|
||||||
|
you really need it, and what the merge plan to the mainline kernel for
|
||||||
|
your module is.
|
||||||
|
|
||||||
config TRIM_UNUSED_KSYMS
|
config TRIM_UNUSED_KSYMS
|
||||||
bool "Trim unused exported kernel symbols"
|
bool "Trim unused exported kernel symbols"
|
||||||
depends on MODULES && !UNUSED_SYMBOLS
|
depends on !UNUSED_SYMBOLS
|
||||||
help
|
help
|
||||||
The kernel and some modules make many symbols available for
|
The kernel and some modules make many symbols available for
|
||||||
other modules to use via EXPORT_SYMBOL() and variants. Depending
|
other modules to use via EXPORT_SYMBOL() and variants. Depending
|
||||||
|
@@ -545,12 +545,20 @@ static const char *kernel_symbol_name(const struct kernel_symbol *sym)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmp_name(const void *va, const void *vb)
|
static const char *kernel_symbol_namespace(const struct kernel_symbol *sym)
|
||||||
{
|
{
|
||||||
const char *a;
|
#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
|
||||||
const struct kernel_symbol *b;
|
if (!sym->namespace_offset)
|
||||||
a = va; b = vb;
|
return NULL;
|
||||||
return strcmp(a, kernel_symbol_name(b));
|
return offset_to_ptr(&sym->namespace_offset);
|
||||||
|
#else
|
||||||
|
return sym->namespace;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmp_name(const void *name, const void *sym)
|
||||||
|
{
|
||||||
|
return strcmp(name, kernel_symbol_name(sym));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool find_exported_symbol_in_section(const struct symsearch *syms,
|
static bool find_exported_symbol_in_section(const struct symsearch *syms,
|
||||||
@@ -1380,6 +1388,41 @@ static inline int same_magic(const char *amagic, const char *bmagic,
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_MODVERSIONS */
|
#endif /* CONFIG_MODVERSIONS */
|
||||||
|
|
||||||
|
static char *get_modinfo(const struct load_info *info, const char *tag);
|
||||||
|
static char *get_next_modinfo(const struct load_info *info, const char *tag,
|
||||||
|
char *prev);
|
||||||
|
|
||||||
|
static int verify_namespace_is_imported(const struct load_info *info,
|
||||||
|
const struct kernel_symbol *sym,
|
||||||
|
struct module *mod)
|
||||||
|
{
|
||||||
|
const char *namespace;
|
||||||
|
char *imported_namespace;
|
||||||
|
|
||||||
|
namespace = kernel_symbol_namespace(sym);
|
||||||
|
if (namespace) {
|
||||||
|
imported_namespace = get_modinfo(info, "import_ns");
|
||||||
|
while (imported_namespace) {
|
||||||
|
if (strcmp(namespace, imported_namespace) == 0)
|
||||||
|
return 0;
|
||||||
|
imported_namespace = get_next_modinfo(
|
||||||
|
info, "import_ns", imported_namespace);
|
||||||
|
}
|
||||||
|
#ifdef CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS
|
||||||
|
pr_warn(
|
||||||
|
#else
|
||||||
|
pr_err(
|
||||||
|
#endif
|
||||||
|
"%s: module uses symbol (%s) from namespace %s, but does not import it.\n",
|
||||||
|
mod->name, kernel_symbol_name(sym), namespace);
|
||||||
|
#ifndef CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS
|
||||||
|
return -EINVAL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Resolve a symbol for this module. I.e. if we find one, record usage. */
|
/* Resolve a symbol for this module. I.e. if we find one, record usage. */
|
||||||
static const struct kernel_symbol *resolve_symbol(struct module *mod,
|
static const struct kernel_symbol *resolve_symbol(struct module *mod,
|
||||||
const struct load_info *info,
|
const struct load_info *info,
|
||||||
@@ -1408,6 +1451,12 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
|
|||||||
goto getname;
|
goto getname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = verify_namespace_is_imported(info, sym, mod);
|
||||||
|
if (err) {
|
||||||
|
sym = ERR_PTR(err);
|
||||||
|
goto getname;
|
||||||
|
}
|
||||||
|
|
||||||
err = ref_module(mod, owner);
|
err = ref_module(mod, owner);
|
||||||
if (err) {
|
if (err) {
|
||||||
sym = ERR_PTR(err);
|
sym = ERR_PTR(err);
|
||||||
@@ -2482,7 +2531,8 @@ static char *next_string(char *string, unsigned long *secsize)
|
|||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *get_modinfo(struct load_info *info, const char *tag)
|
static char *get_next_modinfo(const struct load_info *info, const char *tag,
|
||||||
|
char *prev)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
unsigned int taglen = strlen(tag);
|
unsigned int taglen = strlen(tag);
|
||||||
@@ -2493,13 +2543,25 @@ static char *get_modinfo(struct load_info *info, const char *tag)
|
|||||||
* get_modinfo() calls made before rewrite_section_headers()
|
* get_modinfo() calls made before rewrite_section_headers()
|
||||||
* must use sh_offset, as sh_addr isn't set!
|
* must use sh_offset, as sh_addr isn't set!
|
||||||
*/
|
*/
|
||||||
for (p = (char *)info->hdr + infosec->sh_offset; p; p = next_string(p, &size)) {
|
char *modinfo = (char *)info->hdr + infosec->sh_offset;
|
||||||
|
|
||||||
|
if (prev) {
|
||||||
|
size -= prev - modinfo;
|
||||||
|
modinfo = next_string(prev, &size);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (p = modinfo; p; p = next_string(p, &size)) {
|
||||||
if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
|
if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
|
||||||
return p + taglen + 1;
|
return p + taglen + 1;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *get_modinfo(const struct load_info *info, const char *tag)
|
||||||
|
{
|
||||||
|
return get_next_modinfo(info, tag, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void setup_modinfo(struct module *mod, struct load_info *info)
|
static void setup_modinfo(struct module *mod, struct load_info *info)
|
||||||
{
|
{
|
||||||
struct module_attribute *attr;
|
struct module_attribute *attr;
|
||||||
|
@@ -277,22 +277,6 @@ config READABLE_ASM
|
|||||||
to keep kernel developers who have to stare a lot at assembler listings
|
to keep kernel developers who have to stare a lot at assembler listings
|
||||||
sane.
|
sane.
|
||||||
|
|
||||||
config UNUSED_SYMBOLS
|
|
||||||
bool "Enable unused/obsolete exported symbols"
|
|
||||||
default y if X86
|
|
||||||
help
|
|
||||||
Unused but exported symbols make the kernel needlessly bigger. For
|
|
||||||
that reason most of these unused exports will soon be removed. This
|
|
||||||
option is provided temporarily to provide a transition period in case
|
|
||||||
some external kernel module needs one of these symbols anyway. If you
|
|
||||||
encounter such a case in your module, consider if you are actually
|
|
||||||
using the right API. (rationale: since nobody in the kernel is using
|
|
||||||
this in a module, there is a pretty good chance it's actually the
|
|
||||||
wrong interface to use). If you really need the symbol, please send a
|
|
||||||
mail to the linux kernel mailing list mentioning the symbol and why
|
|
||||||
you really need it, and what the merge plan to the mainline kernel for
|
|
||||||
your module is.
|
|
||||||
|
|
||||||
config DEBUG_FS
|
config DEBUG_FS
|
||||||
bool "Debug Filesystem"
|
bool "Debug Filesystem"
|
||||||
help
|
help
|
||||||
|
@@ -54,7 +54,8 @@ MODPOST = scripts/mod/modpost \
|
|||||||
$(if $(KBUILD_EXTMOD),$(addprefix -e ,$(KBUILD_EXTRA_SYMBOLS))) \
|
$(if $(KBUILD_EXTMOD),$(addprefix -e ,$(KBUILD_EXTRA_SYMBOLS))) \
|
||||||
$(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
|
$(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
|
||||||
$(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \
|
$(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \
|
||||||
$(if $(KBUILD_MODPOST_WARN),-w)
|
$(if $(KBUILD_MODPOST_WARN),-w) \
|
||||||
|
$(if $(filter nsdeps,$(MAKECMDGOALS)),-d)
|
||||||
|
|
||||||
ifdef MODPOST_VMLINUX
|
ifdef MODPOST_VMLINUX
|
||||||
|
|
||||||
@@ -95,6 +96,8 @@ ifneq ($(KBUILD_MODPOST_NOFINAL),1)
|
|||||||
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modfinal
|
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modfinal
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
nsdeps: __modpost
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
.PHONY: $(PHONY)
|
.PHONY: $(PHONY)
|
||||||
|
@@ -94,7 +94,7 @@ if (defined $opt{'o'}) {
|
|||||||
#
|
#
|
||||||
while ( <$module_symvers> ) {
|
while ( <$module_symvers> ) {
|
||||||
chomp;
|
chomp;
|
||||||
my (undef, $symbol, $module, $gpl) = split;
|
my (undef, $symbol, $namespace, $module, $gpl) = split('\t');
|
||||||
$SYMBOL { $symbol } = [ $module , "0" , $symbol, $gpl];
|
$SYMBOL { $symbol } = [ $module , "0" , $symbol, $gpl];
|
||||||
}
|
}
|
||||||
close($module_symvers);
|
close($module_symvers);
|
||||||
|
@@ -38,6 +38,8 @@ static int sec_mismatch_count = 0;
|
|||||||
static int sec_mismatch_fatal = 0;
|
static int sec_mismatch_fatal = 0;
|
||||||
/* ignore missing files */
|
/* ignore missing files */
|
||||||
static int ignore_missing_files;
|
static int ignore_missing_files;
|
||||||
|
/* write namespace dependencies */
|
||||||
|
static int write_namespace_deps;
|
||||||
|
|
||||||
enum export {
|
enum export {
|
||||||
export_plain, export_unused, export_gpl,
|
export_plain, export_unused, export_gpl,
|
||||||
@@ -164,6 +166,7 @@ struct symbol {
|
|||||||
struct module *module;
|
struct module *module;
|
||||||
unsigned int crc;
|
unsigned int crc;
|
||||||
int crc_valid;
|
int crc_valid;
|
||||||
|
char *namespace;
|
||||||
unsigned int weak:1;
|
unsigned int weak:1;
|
||||||
unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */
|
unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */
|
||||||
unsigned int kernel:1; /* 1 if symbol is from kernel
|
unsigned int kernel:1; /* 1 if symbol is from kernel
|
||||||
@@ -235,6 +238,37 @@ static struct symbol *find_symbol(const char *name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool contains_namespace(struct namespace_list *list,
|
||||||
|
const char *namespace)
|
||||||
|
{
|
||||||
|
struct namespace_list *ns_entry;
|
||||||
|
|
||||||
|
for (ns_entry = list; ns_entry != NULL; ns_entry = ns_entry->next)
|
||||||
|
if (strcmp(ns_entry->namespace, namespace) == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_namespace(struct namespace_list **list, const char *namespace)
|
||||||
|
{
|
||||||
|
struct namespace_list *ns_entry;
|
||||||
|
|
||||||
|
if (!contains_namespace(*list, namespace)) {
|
||||||
|
ns_entry = NOFAIL(malloc(sizeof(struct namespace_list) +
|
||||||
|
strlen(namespace) + 1));
|
||||||
|
strcpy(ns_entry->namespace, namespace);
|
||||||
|
ns_entry->next = *list;
|
||||||
|
*list = ns_entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool module_imports_namespace(struct module *module,
|
||||||
|
const char *namespace)
|
||||||
|
{
|
||||||
|
return contains_namespace(module->imported_namespaces, namespace);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
const char *str;
|
const char *str;
|
||||||
enum export export;
|
enum export export;
|
||||||
@@ -314,12 +348,26 @@ static enum export export_from_sec(struct elf_info *elf, unsigned int sec)
|
|||||||
return export_unknown;
|
return export_unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *sym_extract_namespace(const char **symname)
|
||||||
|
{
|
||||||
|
char *namespace = NULL;
|
||||||
|
char *ns_separator;
|
||||||
|
|
||||||
|
ns_separator = strchr(*symname, '.');
|
||||||
|
if (ns_separator) {
|
||||||
|
namespace = NOFAIL(strndup(*symname, ns_separator - *symname));
|
||||||
|
*symname = ns_separator + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return namespace;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an exported symbol - it may have already been added without a
|
* Add an exported symbol - it may have already been added without a
|
||||||
* CRC, in this case just update the CRC
|
* CRC, in this case just update the CRC
|
||||||
**/
|
**/
|
||||||
static struct symbol *sym_add_exported(const char *name, struct module *mod,
|
static struct symbol *sym_add_exported(const char *name, const char *namespace,
|
||||||
enum export export)
|
struct module *mod, enum export export)
|
||||||
{
|
{
|
||||||
struct symbol *s = find_symbol(name);
|
struct symbol *s = find_symbol(name);
|
||||||
|
|
||||||
@@ -327,15 +375,16 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod,
|
|||||||
s = new_symbol(name, mod, export);
|
s = new_symbol(name, mod, export);
|
||||||
} else {
|
} else {
|
||||||
if (!s->preloaded) {
|
if (!s->preloaded) {
|
||||||
warn("%s: '%s' exported twice. Previous export "
|
warn("%s: '%s' exported twice. Previous export was in %s%s\n",
|
||||||
"was in %s%s\n", mod->name, name,
|
mod->name, name, s->module->name,
|
||||||
s->module->name,
|
is_vmlinux(s->module->name) ? "" : ".ko");
|
||||||
is_vmlinux(s->module->name) ?"":".ko");
|
|
||||||
} else {
|
} else {
|
||||||
/* In case Module.symvers was out of date */
|
/* In case Module.symvers was out of date */
|
||||||
s->module = mod;
|
s->module = mod;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(s->namespace);
|
||||||
|
s->namespace = namespace ? strdup(namespace) : NULL;
|
||||||
s->preloaded = 0;
|
s->preloaded = 0;
|
||||||
s->vmlinux = is_vmlinux(mod->name);
|
s->vmlinux = is_vmlinux(mod->name);
|
||||||
s->kernel = 0;
|
s->kernel = 0;
|
||||||
@@ -626,6 +675,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
|
|||||||
unsigned int crc;
|
unsigned int crc;
|
||||||
enum export export;
|
enum export export;
|
||||||
bool is_crc = false;
|
bool is_crc = false;
|
||||||
|
const char *name;
|
||||||
|
char *namespace;
|
||||||
|
|
||||||
if ((!is_vmlinux(mod->name) || mod->is_dot_o) &&
|
if ((!is_vmlinux(mod->name) || mod->is_dot_o) &&
|
||||||
strstarts(symname, "__ksymtab"))
|
strstarts(symname, "__ksymtab"))
|
||||||
@@ -697,8 +748,10 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
|
|||||||
default:
|
default:
|
||||||
/* All exported symbols */
|
/* All exported symbols */
|
||||||
if (strstarts(symname, "__ksymtab_")) {
|
if (strstarts(symname, "__ksymtab_")) {
|
||||||
sym_add_exported(symname + strlen("__ksymtab_"), mod,
|
name = symname + strlen("__ksymtab_");
|
||||||
export);
|
namespace = sym_extract_namespace(&name);
|
||||||
|
sym_add_exported(name, namespace, mod, export);
|
||||||
|
free(namespace);
|
||||||
}
|
}
|
||||||
if (strcmp(symname, "init_module") == 0)
|
if (strcmp(symname, "init_module") == 0)
|
||||||
mod->has_init = 1;
|
mod->has_init = 1;
|
||||||
@@ -1949,6 +2002,7 @@ static void read_symbols(const char *modname)
|
|||||||
const char *symname;
|
const char *symname;
|
||||||
char *version;
|
char *version;
|
||||||
char *license;
|
char *license;
|
||||||
|
char *namespace;
|
||||||
struct module *mod;
|
struct module *mod;
|
||||||
struct elf_info info = { };
|
struct elf_info info = { };
|
||||||
Elf_Sym *sym;
|
Elf_Sym *sym;
|
||||||
@@ -1980,6 +2034,12 @@ static void read_symbols(const char *modname)
|
|||||||
license = get_next_modinfo(&info, "license", license);
|
license = get_next_modinfo(&info, "license", license);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace = get_modinfo(&info, "import_ns");
|
||||||
|
while (namespace) {
|
||||||
|
add_namespace(&mod->imported_namespaces, namespace);
|
||||||
|
namespace = get_next_modinfo(&info, "import_ns", namespace);
|
||||||
|
}
|
||||||
|
|
||||||
for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
|
for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
|
||||||
symname = remove_dot(info.strtab + sym->st_name);
|
symname = remove_dot(info.strtab + sym->st_name);
|
||||||
|
|
||||||
@@ -2139,6 +2199,18 @@ static int check_exports(struct module *mod)
|
|||||||
basename++;
|
basename++;
|
||||||
else
|
else
|
||||||
basename = mod->name;
|
basename = mod->name;
|
||||||
|
|
||||||
|
if (exp->namespace && exp->namespace[0]) {
|
||||||
|
add_namespace(&mod->required_namespaces,
|
||||||
|
exp->namespace);
|
||||||
|
|
||||||
|
if (!write_namespace_deps &&
|
||||||
|
!module_imports_namespace(mod, exp->namespace)) {
|
||||||
|
warn("module %s uses symbol %s from namespace %s, but does not import it.\n",
|
||||||
|
basename, exp->name, exp->namespace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!mod->gpl_compatible)
|
if (!mod->gpl_compatible)
|
||||||
check_for_gpl_usage(exp->export, basename, exp->name);
|
check_for_gpl_usage(exp->export, basename, exp->name);
|
||||||
check_for_unused(exp->export, basename, exp->name);
|
check_for_unused(exp->export, basename, exp->name);
|
||||||
@@ -2358,7 +2430,7 @@ static void read_dump(const char *fname, unsigned int kernel)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
while ((line = get_next_line(&pos, file, size))) {
|
while ((line = get_next_line(&pos, file, size))) {
|
||||||
char *symname, *modname, *d, *export, *end;
|
char *symname, *namespace, *modname, *d, *export, *end;
|
||||||
unsigned int crc;
|
unsigned int crc;
|
||||||
struct module *mod;
|
struct module *mod;
|
||||||
struct symbol *s;
|
struct symbol *s;
|
||||||
@@ -2366,7 +2438,10 @@ static void read_dump(const char *fname, unsigned int kernel)
|
|||||||
if (!(symname = strchr(line, '\t')))
|
if (!(symname = strchr(line, '\t')))
|
||||||
goto fail;
|
goto fail;
|
||||||
*symname++ = '\0';
|
*symname++ = '\0';
|
||||||
if (!(modname = strchr(symname, '\t')))
|
if (!(namespace = strchr(symname, '\t')))
|
||||||
|
goto fail;
|
||||||
|
*namespace++ = '\0';
|
||||||
|
if (!(modname = strchr(namespace, '\t')))
|
||||||
goto fail;
|
goto fail;
|
||||||
*modname++ = '\0';
|
*modname++ = '\0';
|
||||||
if ((export = strchr(modname, '\t')) != NULL)
|
if ((export = strchr(modname, '\t')) != NULL)
|
||||||
@@ -2383,7 +2458,8 @@ static void read_dump(const char *fname, unsigned int kernel)
|
|||||||
mod = new_module(modname);
|
mod = new_module(modname);
|
||||||
mod->skip = 1;
|
mod->skip = 1;
|
||||||
}
|
}
|
||||||
s = sym_add_exported(symname, mod, export_no(export));
|
s = sym_add_exported(symname, namespace, mod,
|
||||||
|
export_no(export));
|
||||||
s->kernel = kernel;
|
s->kernel = kernel;
|
||||||
s->preloaded = 1;
|
s->preloaded = 1;
|
||||||
s->is_static = 0;
|
s->is_static = 0;
|
||||||
@@ -2413,16 +2489,20 @@ static void write_dump(const char *fname)
|
|||||||
{
|
{
|
||||||
struct buffer buf = { };
|
struct buffer buf = { };
|
||||||
struct symbol *symbol;
|
struct symbol *symbol;
|
||||||
|
const char *namespace;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
|
for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
|
||||||
symbol = symbolhash[n];
|
symbol = symbolhash[n];
|
||||||
while (symbol) {
|
while (symbol) {
|
||||||
if (dump_sym(symbol))
|
if (dump_sym(symbol)) {
|
||||||
buf_printf(&buf, "0x%08x\t%s\t%s\t%s\n",
|
namespace = symbol->namespace;
|
||||||
symbol->crc, symbol->name,
|
buf_printf(&buf, "0x%08x\t%s\t%s\t%s\t%s\n",
|
||||||
symbol->module->name,
|
symbol->crc, symbol->name,
|
||||||
export_str(symbol->export));
|
namespace ? namespace : "",
|
||||||
|
symbol->module->name,
|
||||||
|
export_str(symbol->export));
|
||||||
|
}
|
||||||
symbol = symbol->next;
|
symbol = symbol->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2430,6 +2510,31 @@ static void write_dump(const char *fname)
|
|||||||
free(buf.p);
|
free(buf.p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void write_namespace_deps_files(void)
|
||||||
|
{
|
||||||
|
struct module *mod;
|
||||||
|
struct namespace_list *ns;
|
||||||
|
struct buffer ns_deps_buf = {};
|
||||||
|
|
||||||
|
for (mod = modules; mod; mod = mod->next) {
|
||||||
|
char fname[PATH_MAX];
|
||||||
|
|
||||||
|
if (mod->skip)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ns_deps_buf.pos = 0;
|
||||||
|
|
||||||
|
for (ns = mod->required_namespaces; ns; ns = ns->next)
|
||||||
|
buf_printf(&ns_deps_buf, "%s\n", ns->namespace);
|
||||||
|
|
||||||
|
if (ns_deps_buf.pos == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sprintf(fname, "%s.ns_deps", mod->name);
|
||||||
|
write_if_changed(&ns_deps_buf, fname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct ext_sym_list {
|
struct ext_sym_list {
|
||||||
struct ext_sym_list *next;
|
struct ext_sym_list *next;
|
||||||
const char *file;
|
const char *file;
|
||||||
@@ -2447,7 +2552,7 @@ int main(int argc, char **argv)
|
|||||||
struct ext_sym_list *extsym_iter;
|
struct ext_sym_list *extsym_iter;
|
||||||
struct ext_sym_list *extsym_start = NULL;
|
struct ext_sym_list *extsym_start = NULL;
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "i:I:e:mnsT:o:awE")) != -1) {
|
while ((opt = getopt(argc, argv, "i:I:e:mnsT:o:awEd")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'i':
|
case 'i':
|
||||||
kernel_read = optarg;
|
kernel_read = optarg;
|
||||||
@@ -2488,6 +2593,9 @@ int main(int argc, char **argv)
|
|||||||
case 'E':
|
case 'E':
|
||||||
sec_mismatch_fatal = 1;
|
sec_mismatch_fatal = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'd':
|
||||||
|
write_namespace_deps = 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -2522,6 +2630,9 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
err |= check_modname_len(mod);
|
err |= check_modname_len(mod);
|
||||||
err |= check_exports(mod);
|
err |= check_exports(mod);
|
||||||
|
if (write_namespace_deps)
|
||||||
|
continue;
|
||||||
|
|
||||||
add_header(&buf, mod);
|
add_header(&buf, mod);
|
||||||
add_intree_flag(&buf, !external_module);
|
add_intree_flag(&buf, !external_module);
|
||||||
add_retpoline(&buf);
|
add_retpoline(&buf);
|
||||||
@@ -2534,6 +2645,12 @@ int main(int argc, char **argv)
|
|||||||
sprintf(fname, "%s.mod.c", mod->name);
|
sprintf(fname, "%s.mod.c", mod->name);
|
||||||
write_if_changed(&buf, fname);
|
write_if_changed(&buf, fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (write_namespace_deps) {
|
||||||
|
write_namespace_deps_files();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (dump_write)
|
if (dump_write)
|
||||||
write_dump(dump_write);
|
write_dump(dump_write);
|
||||||
if (sec_mismatch_count && sec_mismatch_fatal)
|
if (sec_mismatch_count && sec_mismatch_fatal)
|
||||||
|
@@ -109,6 +109,11 @@ buf_printf(struct buffer *buf, const char *fmt, ...);
|
|||||||
void
|
void
|
||||||
buf_write(struct buffer *buf, const char *s, int len);
|
buf_write(struct buffer *buf, const char *s, int len);
|
||||||
|
|
||||||
|
struct namespace_list {
|
||||||
|
struct namespace_list *next;
|
||||||
|
char namespace[0];
|
||||||
|
};
|
||||||
|
|
||||||
struct module {
|
struct module {
|
||||||
struct module *next;
|
struct module *next;
|
||||||
const char *name;
|
const char *name;
|
||||||
@@ -121,6 +126,10 @@ struct module {
|
|||||||
struct buffer dev_table_buf;
|
struct buffer dev_table_buf;
|
||||||
char srcversion[25];
|
char srcversion[25];
|
||||||
int is_dot_o;
|
int is_dot_o;
|
||||||
|
// Required namespace dependencies
|
||||||
|
struct namespace_list *required_namespaces;
|
||||||
|
// Actual imported namespaces
|
||||||
|
struct namespace_list *imported_namespaces;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct elf_info {
|
struct elf_info {
|
||||||
|
Reference in New Issue
Block a user