[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4 07/16] tables.h: add linker table support
On Fri, Aug 19, 2016 at 2:32 PM, <mcgrof@xxxxxxxxxx> wrote: > From: "Luis R. Rodriguez" <mcgrof@xxxxxxxxxx> > > A linker table is a data structure that is stitched together from items > in multiple object files. Linux has historically implicitly used linker > tables for ages, however they were all built in an adhoc manner which > requires linker script modifications, per architecture. This adds a > general linker table solution so that a new linker table can be > implemented by changing C code only. The Linux linker table was > inspired by Michael Brown's iPXE's linker table solution, it has been > been completely re-written and adapted for integration and use on Linux. > > The same philosophy is borrowed, extended and further simplified: > > Linker tables enable an extremely light weight linker build time > solution for feature ordering and selection, this can help to both > simplify init sequences in a generic fashion and helps avoiding code > bit-rotting when desirable. Further changes will be added later > which will make more evident how code bit rot can be avoided using > linker tables. > > v4: > > o Split out kbuild additions to help with code bit rot into > its own patch > o tons of documentation love > o fix arch/x86/tools/relocs.c typo - which caused compilation issues > on old toolchains > o add c6x toolchain work around as discussed with Mark Salter > o sprinkle a few more needed VMLINUX_SYMBOL() - fixes > compilation on blackfin > o suggested name changes by boris: > - %s/SECTION_TYPE_RANGES/rng/g > - %s/SECTION_TYPE/SECTION_CORE/g > - %s/section_type_asmtype/section_core_type/g > - %s/section_type/section_core/g > - %s/section_rng/set_section_rng/g > - Drop DECLARE_SECTION_TBL() -- this is an asm equivalent > DEFINE_LINKTABLE() -- this however is not used yet, and it requires > a bit more work to match the C code definitions. > o drop tools/include/linux/sections.h in favor of the more popular open > coding the names for tools > o expand documentation to include module support > o add maintaners > o Use generic-y > o move .text.tbl before unlikely to match the other sections > > v3: > > o addressed initial modular support test cases > o added generic asm macros so linker tables can be used in > asm code / C asm calls > o section ranges are now split up into their own set of files > o use asm/sections.h instead of linux/sections.h for the linker > script > o add a sections.h file for each architecture that was missing one, > this is needed now as we'll be relying on sections.h for custom > section types in code rather than custom architecture specific > linker script hacks. > o full rewrite at this point, decided to pick copyleft-next license > for this work > > v2: > > o modified completely to match feedback by community, made equivalent > modifications to userspace solution. This is pretty much a complete > rewrite of how we present and use linker tables. By using standard > sections we no longer have to make custom linker script extensions > for each new linker table solution, you just pick a linker table > type by section type. > o extend documention considerably, including use of kdoc > o drop ICC hacks per popular request to ignore such issues for now > o use sections.h - this lets us streamline a clean use case of > well documented sections. To help further with this make use of > SECTION_TBL() to allow use of these in code and SECTION_TBL_ALL() > on linker scripts, as well as SECTION_TBL_ALL_STR() on relocs.c > when needed. > > Cc: Michael Brown <mcb30@xxxxxxxx> > Signed-off-by: Luis R. Rodriguez <mcgrof@xxxxxxxxxx> > --- > Documentation/sections/index.rst | 1 + > Documentation/sections/linker-tables.rst | 187 ++++++++++ > MAINTAINERS | 12 + > arch/alpha/include/asm/Kbuild | 1 + > arch/arc/include/asm/Kbuild | 1 + > arch/arm/include/asm/Kbuild | 1 + > arch/arm64/include/asm/Kbuild | 1 + > arch/avr32/include/asm/Kbuild | 1 + > arch/blackfin/include/asm/Kbuild | 1 + > arch/c6x/include/asm/tables.h | 26 ++ > arch/cris/include/asm/Kbuild | 1 + > arch/frv/include/asm/Kbuild | 1 + > arch/h8300/include/asm/Kbuild | 1 + > arch/hexagon/include/asm/Kbuild | 1 + > arch/ia64/include/asm/Kbuild | 1 + > arch/m32r/include/asm/Kbuild | 1 + > arch/m68k/include/asm/Kbuild | 1 + > arch/metag/include/asm/Kbuild | 1 + > arch/microblaze/include/asm/Kbuild | 1 + > arch/mips/include/asm/Kbuild | 1 + > arch/mn10300/include/asm/Kbuild | 1 + > arch/nios2/include/asm/Kbuild | 1 + > arch/openrisc/include/asm/Kbuild | 1 + > arch/parisc/include/asm/Kbuild | 1 + > arch/powerpc/include/asm/Kbuild | 1 + > arch/s390/include/asm/Kbuild | 1 + > arch/score/include/asm/Kbuild | 1 + > arch/sh/include/asm/Kbuild | 1 + > arch/sparc/include/asm/Kbuild | 1 + > arch/tile/include/asm/Kbuild | 1 + > arch/um/include/asm/Kbuild | 1 + > arch/unicore32/include/asm/Kbuild | 1 + > arch/x86/include/asm/Kbuild | 1 + > arch/x86/tools/relocs.c | 2 + > arch/xtensa/include/asm/Kbuild | 1 + > include/asm-generic/ranges.h | 14 + > include/asm-generic/tables.h | 50 +++ > include/asm-generic/vmlinux.lds.h | 6 + > include/linux/tables.h | 567 > +++++++++++++++++++++++++++++++ > scripts/Makefile.clean | 2 + > 40 files changed, 897 insertions(+) > create mode 100644 Documentation/sections/linker-tables.rst > create mode 100644 arch/c6x/include/asm/tables.h > create mode 100644 include/asm-generic/tables.h > create mode 100644 include/linux/tables.h > > diff --git a/Documentation/sections/index.rst > b/Documentation/sections/index.rst > index 6dd93ddd5dbe..4514c5738b33 100644 > --- a/Documentation/sections/index.rst > +++ b/Documentation/sections/index.rst > @@ -10,3 +10,4 @@ used throughout the kernel to help declare and define them. > > section-core > ranges > + linker-tables > diff --git a/Documentation/sections/linker-tables.rst > b/Documentation/sections/linker-tables.rst > new file mode 100644 > index 000000000000..df11c632dca7 > --- /dev/null > +++ b/Documentation/sections/linker-tables.rst > @@ -0,0 +1,187 @@ > +=================== > +Linux linker tables > +=================== > + > +This documents Linux linker tables, it explains what they are, where they > +came from, how they work, the benefits of using them and more importantly > +how you can use them. > + > +About Linker tables > +=================== > +.. kernel-doc:: include/linux/tables.h > + :doc: Introduction > + > +Linker table provenance > +--------------------------------------------- > + > +.. kernel-doc:: include/linux/tables.h > + :doc: Linker table provenance > + > +Benefits of using Linker tables > +=============================== > + > +Avoids modifying architecture linker scripts > +---------------------------------------------- > +.. kernel-doc:: include/linux/tables.h > + :doc: Avoids modifying architecture linker scripts > + > +How linker tables simplify initialization code > +---------------------------------------------- > +.. kernel-doc:: include/linux/tables.h > + :doc: How linker tables simplify initialization code > + > +Using linker tables in Linux > +============================ > + > +Linker table module support > +--------------------------- > + > +.. kernel-doc:: include/linux/tables.h > + :doc: Linker table module support > + > +Linker table helpers > +==================== > + > +.. kernel-doc:: include/linux/tables.h > + :doc: Linker table helpers > + > +LINKTABLE_ADDR_WITHIN > +--------------------- > +.. kernel-doc:: include/linux/tables.h > + :functions: LINKTABLE_ADDR_WITHIN > + > +Constructing linker tables > +========================== > + > +.. kernel-doc:: include/linux/tables.h > + :doc: Constructing linker tables > + > +Weak linker tables constructors > +------------------------------- > + > +.. kernel-doc:: include/linux/tables.h > + :doc: Weak linker tables constructors > + > +LINKTABLE_WEAK > +-------------- > +.. kernel-doc:: include/linux/tables.h > + :functions: LINKTABLE_WEAK > + > +LINKTABLE_TEXT_WEAK > +------------------- > +.. kernel-doc:: include/linux/tables.h > + :functions: LINKTABLE_TEXT_WEAK > + > +LINKTABLE_RO_WEAK > +----------------- > +.. kernel-doc:: include/linux/tables.h > + :functions: LINKTABLE_RO_WEAK > + > +LINKTABLE_INIT_WEAK > +------------------- > +.. kernel-doc:: include/linux/tables.h > + :functions: LINKTABLE_INIT_WEAK > + > +LINKTABLE_INIT_DATA_WEAK > +------------------------ > +.. kernel-doc:: include/linux/tables.h > + :functions: LINKTABLE_INIT_DATA_WEAK > + > +Regular linker linker table constructors > +---------------------------------------- > + > +.. kernel-doc:: include/linux/tables.h > + :doc: Regular linker linker table constructors > + > +LINKTABLE > +--------- > +.. kernel-doc:: include/linux/tables.h > + :functions: LINKTABLE > + > +LINKTABLE_TEXT > +-------------- > +.. kernel-doc:: include/linux/tables.h > + :functions: LINKTABLE_TEXT > + > +LINKTABLE_RO > +------------ > +.. kernel-doc:: include/linux/tables.h > + :functions: LINKTABLE_RO > + > +LINKTABLE_INIT > +-------------- > +.. kernel-doc:: include/linux/tables.h > + :functions: LINKTABLE_INIT > + > +LINKTABLE_INIT_DATA > +------------------- > +.. kernel-doc:: include/linux/tables.h > + :functions: LINKTABLE_INIT_DATA > + > +Declaring Linker tables > +======================= > + > +.. kernel-doc:: include/linux/tables.h > + :doc: Declaring Linker tables > + > +DECLARE_LINKTABLE > +---------------------- > +.. kernel-doc:: include/linux/tables.h > + :functions: DECLARE_LINKTABLE > + > +DECLARE_LINKTABLE_RO > +-------------------- > +.. kernel-doc:: include/linux/tables.h > + :functions: DECLARE_LINKTABLE_RO > + > +Defining Linker tables > +====================== > + > +.. kernel-doc:: include/linux/tables.h > + :doc: Defining Linker tables > + > +DEFINE_LINKTABLE > +---------------- > +.. kernel-doc:: include/linux/tables.h > + :functions: DEFINE_LINKTABLE > + > +DEFINE_LINKTABLE_TEXT > +--------------------- > +.. kernel-doc:: include/linux/tables.h > + :functions: DEFINE_LINKTABLE_TEXT > + > +DEFINE_LINKTABLE_RO > +------------------- > +.. kernel-doc:: include/linux/tables.h > + :functions: DEFINE_LINKTABLE_RO > + > +DEFINE_LINKTABLE_INIT > +--------------------- > +.. kernel-doc:: include/linux/tables.h > + :functions: DEFINE_LINKTABLE_INIT > + > +DEFINE_LINKTABLE_INIT_DATA > +-------------------------- > +.. kernel-doc:: include/linux/tables.h > + :functions: DEFINE_LINKTABLE_INIT_DATA > + > +Iterating over Linker tables > +============================ > + > +.. kernel-doc:: include/linux/tables.h > + :doc: Iterating over Linker tables > + > +LINKTABLE_FOR_EACH > +------------------ > +.. kernel-doc:: include/linux/tables.h > + :functions: LINKTABLE_FOR_EACH > + > +LINKTABLE_RUN_ALL > +----------------- > +.. kernel-doc:: include/linux/tables.h > + :functions: LINKTABLE_RUN_ALL > + > +LINKTABLE_RUN_ERR > +----------------- > +.. kernel-doc:: include/linux/tables.h > + :functions: LINKTABLE_RUN_ERR > diff --git a/MAINTAINERS b/MAINTAINERS > index 1a217751aa8a..e3569ed12c86 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -5200,6 +5200,18 @@ S: Maintained > F: include/asm-generic/ > F: include/uapi/asm-generic/ > > +GENERIC LINKER TABLES > +M: "Luis R. Rodriguez" <mcgrof@xxxxxxxxxx> > +M: "H. Peter Anvin" <hpa@xxxxxxxxx> > +L: linux-arch@xxxxxxxxxxxxxxx > +L: linux-kernel@xxxxxxxxxxxxxxx > +T: git git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux.git > sections > +T: git > git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux-next.git sections > +S: Supported > +F: include/asm-generic/tables.h > +F: include/linux/tables.h > +F: Documentation/sections/linker-tables.rst > + > GENERIC PHY FRAMEWORK > M: Kishon Vijay Abraham I <kishon@xxxxxx> > L: linux-kernel@xxxxxxxxxxxxxxx > diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild > index e44c896b91c4..f3bdc31d3c97 100644 > --- a/arch/alpha/include/asm/Kbuild > +++ b/arch/alpha/include/asm/Kbuild > @@ -12,3 +12,4 @@ generic-y += sections.h > generic-y += trace_clock.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild > index e5295413fdf8..70f252472cb9 100644 > --- a/arch/arc/include/asm/Kbuild > +++ b/arch/arc/include/asm/Kbuild > @@ -52,3 +52,4 @@ generic-y += word-at-a-time.h > generic-y += xor.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild > index 8e52300e1eed..d13700f573d0 100644 > --- a/arch/arm/include/asm/Kbuild > +++ b/arch/arm/include/asm/Kbuild > @@ -41,3 +41,4 @@ generic-y += trace_clock.h > generic-y += unaligned.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild > index 5ff184574976..a1991517aad6 100644 > --- a/arch/arm64/include/asm/Kbuild > +++ b/arch/arm64/include/asm/Kbuild > @@ -54,3 +54,4 @@ generic-y += vga.h > generic-y += xor.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/avr32/include/asm/Kbuild b/arch/avr32/include/asm/Kbuild > index edc176348d7c..a6cd145515ae 100644 > --- a/arch/avr32/include/asm/Kbuild > +++ b/arch/avr32/include/asm/Kbuild > @@ -24,3 +24,4 @@ generic-y += word-at-a-time.h > generic-y += xor.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/blackfin/include/asm/Kbuild > b/arch/blackfin/include/asm/Kbuild > index 35b7752e65c0..b71893b1cd53 100644 > --- a/arch/blackfin/include/asm/Kbuild > +++ b/arch/blackfin/include/asm/Kbuild > @@ -50,3 +50,4 @@ generic-y += word-at-a-time.h > generic-y += xor.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/c6x/include/asm/tables.h b/arch/c6x/include/asm/tables.h > new file mode 100644 > index 000000000000..09a9e31c573a > --- /dev/null > +++ b/arch/c6x/include/asm/tables.h > @@ -0,0 +1,26 @@ > +#ifndef _ASM_C6X_ASM_TABLES_H > +#define _ASM_C6X_ASM_TABLES_H > +/* > + * Copyright (C) 2016 Luis R. Rodriguez <mcgrof@xxxxxxxxxx> > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of copyleft-next (version 0.3.1 or later) as published > + * at http://copyleft-next.org/. > + */ > + > +/* > + * The c6x toolchain has a bug present even on gcc-6 when non-weak attributes > + * are used and sends them to .rodata even though const data with weak > + * attributes are put in .const, this forces the linker to believe the > address > + * is relative relative to the a base + offset and you end up with > SB-relative > + * reloc error upon linking. Work around this by by forcing both start and > + * ending const RO waek linker table entry to be .const to fix this for now. Type: waek -> weak > + * > + * [0] https://lkml.kernel.org/r/1470798247.3551.94.camel@xxxxxxxxxx > + */ > + > +#define SECTION_TBL_RO .const > + > +#include <asm-generic/tables.h> > + > +#endif /* _ASM_C6X_ASM_TABLES_H */ > diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild > index fb8bb4112773..7062c1be7913 100644 > --- a/arch/cris/include/asm/Kbuild > +++ b/arch/cris/include/asm/Kbuild > @@ -47,3 +47,4 @@ generic-y += word-at-a-time.h > generic-y += xor.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/frv/include/asm/Kbuild b/arch/frv/include/asm/Kbuild > index 5191fec655d7..4a59cbda5091 100644 > --- a/arch/frv/include/asm/Kbuild > +++ b/arch/frv/include/asm/Kbuild > @@ -10,3 +10,4 @@ generic-y += trace_clock.h > generic-y += word-at-a-time.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/h8300/include/asm/Kbuild b/arch/h8300/include/asm/Kbuild > index 7929a992566c..d79968d93c12 100644 > --- a/arch/h8300/include/asm/Kbuild > +++ b/arch/h8300/include/asm/Kbuild > @@ -77,3 +77,4 @@ generic-y += word-at-a-time.h > generic-y += xor.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild > index af17ee334788..d59ac1c1858b 100644 > --- a/arch/hexagon/include/asm/Kbuild > +++ b/arch/hexagon/include/asm/Kbuild > @@ -62,3 +62,4 @@ generic-y += word-at-a-time.h > generic-y += xor.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild > index d8f226b35a0a..76540f143473 100644 > --- a/arch/ia64/include/asm/Kbuild > +++ b/arch/ia64/include/asm/Kbuild > @@ -11,3 +11,4 @@ generic-y += vtime.h > generic-y += word-at-a-time.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/m32r/include/asm/Kbuild b/arch/m32r/include/asm/Kbuild > index 1c6504d29312..24088f3c733c 100644 > --- a/arch/m32r/include/asm/Kbuild > +++ b/arch/m32r/include/asm/Kbuild > @@ -13,3 +13,4 @@ generic-y += trace_clock.h > generic-y += word-at-a-time.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild > index d465f51c2088..65c0df17f70e 100644 > --- a/arch/m68k/include/asm/Kbuild > +++ b/arch/m68k/include/asm/Kbuild > @@ -37,3 +37,4 @@ generic-y += word-at-a-time.h > generic-y += xor.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/metag/include/asm/Kbuild b/arch/metag/include/asm/Kbuild > index c869b1ebd583..2538224899fd 100644 > --- a/arch/metag/include/asm/Kbuild > +++ b/arch/metag/include/asm/Kbuild > @@ -58,3 +58,4 @@ generic-y += word-at-a-time.h > generic-y += xor.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/microblaze/include/asm/Kbuild > b/arch/microblaze/include/asm/Kbuild > index 63c083a1f8da..01afb1b420f5 100644 > --- a/arch/microblaze/include/asm/Kbuild > +++ b/arch/microblaze/include/asm/Kbuild > @@ -13,3 +13,4 @@ generic-y += trace_clock.h > generic-y += word-at-a-time.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild > index ed225600c8a4..07009c0863f6 100644 > --- a/arch/mips/include/asm/Kbuild > +++ b/arch/mips/include/asm/Kbuild > @@ -22,3 +22,4 @@ generic-y += word-at-a-time.h > generic-y += xor.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/mn10300/include/asm/Kbuild b/arch/mn10300/include/asm/Kbuild > index 656af7b69940..6c8d12f3fe44 100644 > --- a/arch/mn10300/include/asm/Kbuild > +++ b/arch/mn10300/include/asm/Kbuild > @@ -12,3 +12,4 @@ generic-y += trace_clock.h > generic-y += word-at-a-time.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/nios2/include/asm/Kbuild b/arch/nios2/include/asm/Kbuild > index c55880659d67..ee6220dac1e8 100644 > --- a/arch/nios2/include/asm/Kbuild > +++ b/arch/nios2/include/asm/Kbuild > @@ -65,3 +65,4 @@ generic-y += word-at-a-time.h > generic-y += xor.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/openrisc/include/asm/Kbuild > b/arch/openrisc/include/asm/Kbuild > index 7d6a704b808c..ceafe458e295 100644 > --- a/arch/openrisc/include/asm/Kbuild > +++ b/arch/openrisc/include/asm/Kbuild > @@ -73,3 +73,4 @@ generic-y += word-at-a-time.h > generic-y += xor.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild > index 1a263a7158e2..99211477bfb2 100644 > --- a/arch/parisc/include/asm/Kbuild > +++ b/arch/parisc/include/asm/Kbuild > @@ -31,3 +31,4 @@ generic-y += word-at-a-time.h > generic-y += xor.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild > index 065c6e84fb67..bbd54aa1571e 100644 > --- a/arch/powerpc/include/asm/Kbuild > +++ b/arch/powerpc/include/asm/Kbuild > @@ -9,3 +9,4 @@ generic-y += rwsem.h > generic-y += vtime.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild > index 3e8b95927cb5..92c2250a1521 100644 > --- a/arch/s390/include/asm/Kbuild > +++ b/arch/s390/include/asm/Kbuild > @@ -10,3 +10,4 @@ generic-y += trace_clock.h > generic-y += word-at-a-time.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild > index f0cdb2cbca4d..16ea15a3e432 100644 > --- a/arch/score/include/asm/Kbuild > +++ b/arch/score/include/asm/Kbuild > @@ -16,3 +16,4 @@ generic-y += serial.h > generic-y += word-at-a-time.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild > index c9bb7932a3d1..d0ea768d15ae 100644 > --- a/arch/sh/include/asm/Kbuild > +++ b/arch/sh/include/asm/Kbuild > @@ -41,3 +41,4 @@ generic-y += ucontext.h > generic-y += xor.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild > index 79664d10e63b..0e7663749c97 100644 > --- a/arch/sparc/include/asm/Kbuild > +++ b/arch/sparc/include/asm/Kbuild > @@ -24,3 +24,4 @@ generic-y += types.h > generic-y += word-at-a-time.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild > index 951fa4be571d..8f3e38c981cd 100644 > --- a/arch/tile/include/asm/Kbuild > +++ b/arch/tile/include/asm/Kbuild > @@ -43,3 +43,4 @@ generic-y += types.h > generic-y += xor.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild > index 99be54949b99..eea5dd842992 100644 > --- a/arch/um/include/asm/Kbuild > +++ b/arch/um/include/asm/Kbuild > @@ -29,3 +29,4 @@ generic-y += word-at-a-time.h > generic-y += xor.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/unicore32/include/asm/Kbuild > b/arch/unicore32/include/asm/Kbuild > index 6c35905fe371..5c31eafbf1fd 100644 > --- a/arch/unicore32/include/asm/Kbuild > +++ b/arch/unicore32/include/asm/Kbuild > @@ -65,3 +65,4 @@ generic-y += vga.h > generic-y += word-at-a-time.h > generic-y += xor.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild > index f790756fdb48..cd0fa76b32a3 100644 > --- a/arch/x86/include/asm/Kbuild > +++ b/arch/x86/include/asm/Kbuild > @@ -18,3 +18,4 @@ generic-y += mcs_spinlock.h > generic-y += mm-arch-hooks.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c > index c215db049920..45733a182ac2 100644 > --- a/arch/x86/tools/relocs.c > +++ b/arch/x86/tools/relocs.c > @@ -69,7 +69,9 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = { > "__initramfs_start|" > "(jiffies|jiffies_64)|" > ".rodata.rng.*|" > + ".rodata.tbl.*|" > ".init.text.rng.*|" > + ".init.text.tbl.*|" > #if ELF_BITS == 64 > "__per_cpu_load|" > "init_per_cpu__.*|" > diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild > index 221b6b652500..ae48f8fd9212 100644 > --- a/arch/xtensa/include/asm/Kbuild > +++ b/arch/xtensa/include/asm/Kbuild > @@ -33,3 +33,4 @@ generic-y += word-at-a-time.h > generic-y += xor.h > generic-y += section-core.h > generic-y += ranges.h > +generic-y += tables.h > diff --git a/include/asm-generic/ranges.h b/include/asm-generic/ranges.h > index 74cd941aa2f8..8cf21a1497c6 100644 > --- a/include/asm-generic/ranges.h > +++ b/include/asm-generic/ranges.h > @@ -86,4 +86,18 @@ > > #endif /* __ASSEMBLY__ */ > > +#ifdef __ASSEMBLER__ > + > +#ifndef DEFINE_SECTION_RANGE > +#define DEFINE_SECTION_RANGE(section, name) \ > + push_section_rng_level(section, name,,) ; > \ > + .globl name ; > \ > +name: ; > \ > + .popsection \ > + \ > + push_section_rng_level(section, name, ~,) ; > \ > + .popsection > +#endif > +#endif /* __ASSEMBLER__ */ > + > #endif /* _ASM_GENERIC_RANGES_H_ */ > diff --git a/include/asm-generic/tables.h b/include/asm-generic/tables.h > new file mode 100644 > index 000000000000..43cd03a83bd2 > --- /dev/null > +++ b/include/asm-generic/tables.h > @@ -0,0 +1,50 @@ > +#ifndef _ASM_GENERIC_TABLES_H_ > +#define _ASM_GENERIC_TABLES_H_ > +/* > + * Linux linker tables > + * > + * Copyright (C) 2016 Luis R. Rodriguez <mcgrof@xxxxxxxxxx> > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of copyleft-next (version 0.3.1 or later) as published > + * at http://copyleft-next.org/. > + */ > +#include <asm/section-core.h> > + > +#define SECTION_TBL(section, name, level) \ > + SECTION_CORE(section, tbl, name, level) > + > +#define SECTION_TBL_ALL(section) \ > + SECTION_CORE_ALL(section,tbl) > + > +/* Some toolchains are buggy, let them override */ > +#ifndef SECTION_TBL_RO > +# define SECTION_TBL_RO SECTION_RODATA > +#endif > + > +#ifndef set_section_tbl > +# define set_section_tbl(section, name, level, flags) \ > + set_section_core(section, tbl, name, level, flags) > +#endif > + > +#ifndef set_section_tbl_any > +# define set_section_tbl_any(section, name, flags) > \ > + set_section_core(section, tbl, name, SECTION_ORDER_ANY, flags) > +#endif > + > +#ifndef set_section_tbl_type > +# define set_section_tbl_type(section, name, level, flags, type) > \ > + set_section_core_type(section, tbl, name, level, flags, type) > +#endif > + > +#ifndef push_section_tbl > +# define push_section_tbl(section, name, level, flags) \ > + push_section_core(section, tbl, name, level, flags) > +#endif > + > +#ifndef push_section_tbl_any > +# define push_section_tbl_any(section, name, flags) \ > + push_section_core(section, tbl, name, SECTION_ORDER_ANY, flags) > +#endif > + > +#endif /* _ASM_GENERIC_TABLES_H_ */ > diff --git a/include/asm-generic/vmlinux.lds.h > b/include/asm-generic/vmlinux.lds.h > index ad843555e6a4..4b6a3d820883 100644 > --- a/include/asm-generic/vmlinux.lds.h > +++ b/include/asm-generic/vmlinux.lds.h > @@ -57,6 +57,7 @@ > #include <linux/export.h> > #include <asm/section-core.h> > #include <asm/ranges.h> > +#include <asm/tables.h> > > /* Align . to a 8 byte boundary equals to maximum function alignment. */ > #define ALIGN_FUNCTION() . = ALIGN(8) > @@ -202,6 +203,7 @@ > #define DATA_DATA \ > *(SECTION_DATA) \ > *(SORT(SECTION_RNG_ALL(SECTION_DATA))) \ > + *(SORT(SECTION_TBL_ALL(SECTION_DATA))) \ > *(SECTION_REF_DATA) \ > *(.data..shared_aligned) /* percpu related */ \ > MEM_KEEP(init.data) \ > @@ -269,6 +271,7 @@ > VMLINUX_SYMBOL(__start_rodata) = .; \ > *(SECTION_RODATA) \ > *(SORT(SECTION_RNG_ALL(SECTION_RODATA))) \ > + *(SORT(SECTION_TBL_ALL(SECTION_RODATA))) \ > *(SECTION_ALL(SECTION_RODATA)) \ > RO_AFTER_INIT_DATA /* Read only after init */ \ > *(__vermagic) /* Kernel version magic */ \ > @@ -439,6 +442,7 @@ > ALIGN_FUNCTION(); \ > *(.text.hot SECTION_TEXT) \ > *(SORT(SECTION_RNG_ALL(SECTION_TEXT))) \ > + *(SORT(SECTION_TBL_ALL(SECTION_TEXT))) \ > *(.text.fixup .text.unlikely) \ > *(SECTION_REF) \ > MEM_KEEP(init.text) \ > @@ -536,6 +540,7 @@ > #define INIT_DATA \ > *(SECTION_INIT_DATA) \ > *(SORT(SECTION_RNG_ALL(SECTION_INIT_DATA))) \ > + *(SORT(SECTION_TBL_ALL(SECTION_INIT_DATA))) \ > MEM_DISCARD(init.data) \ > KERNEL_CTORS() \ > MCOUNT_REC() \ > @@ -559,6 +564,7 @@ > #define INIT_TEXT \ > *(SECTION_INIT) \ > *(SORT(SECTION_RNG_ALL(SECTION_INIT))) \ > + *(SORT(SECTION_TBL_ALL(SECTION_INIT))) \ > *(.text.startup) \ > MEM_DISCARD(init.text) > > diff --git a/include/linux/tables.h b/include/linux/tables.h > new file mode 100644 > index 000000000000..423827eafb52 > --- /dev/null > +++ b/include/linux/tables.h > @@ -0,0 +1,567 @@ > +#ifndef _LINUX_LINKER_TABLES_H > +#define _LINUX_LINKER_TABLES_H > +/* > + * Linux linker tables > + * > + * Copyright (C) 2016 Luis R. Rodriguez <mcgrof@xxxxxxxxxx> > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of copyleft-next (version 0.3.1 or later) as published > + * at http://copyleft-next.org/. > + */ > +#include <linux/export.h> > +#include <linux/sections.h> > +#include <asm/tables.h> > + > +#ifndef __ASSEMBLY__ > + > +/** > + * DOC: Introduction > + * > + * A linker table is a data structure that is stitched together from items in > + * multiple object files for the purpose of selective placement into standard > + * or architecture specific ELF sections. What section is used is utility > + * specific. Linux has historically implicitly used linker tables, however > they > + * were all built in an adhoc manner which requires linker script > modifications > + * per architecture. The linker table API provides a general facility so that > + * data structures can be stitched together and placed into Linux ELF > sections > + * by only changing C or asm code in an architecture agnostic form. > + * > + * Linker tables help you group together related data and code in an > efficient > + * way. Linker tables can be used to help simplify init sequences, they > + * enable linker build time selective sorting (disabled options get ignored), > + * and can optionally also be used to help you avoid code bit-rot due to > + * overuse of #ifdef. > + */ > + > +/** > + * DOC: Linker table provenance > + * > + * The Linux implementation of linker tables was inspired by the iPXE linker > + * table's solution (iPXE commit 67a10ef000cb7 "[contrib] Add rom-o-matic to > + * contrib "[0]). To see how this code evolved refer to the out of tree > + * userspace linker-table tree [1]. > + * > + * Contrary to iPXE's solution which strives to force compilation of > + * everything using linker tables, Linux's solution allows for developers to > be > + * selective over where one wishes to force compilation, this then is just an > + * optional feature for the Linux linker table solution. The main advantages > + * of using linker-tables then are: > + * > + * - Avoiding modifying architecture linker scripts > + * - Simplifying initialization code > + * - Avoiding the code bit-rot problem > + * > + * [0] git://git.ipxe.org/ipxe.git > + * > + * [1] https://git.kernel.org/cgit/linux/kernel/git/mcgrof/linker-tables.git/ > + */ > + > +/** > + * DOC: Avoids modifying architecture linker scripts > + * > + * Linker tables enable you to avoid modifying architecture linker scripts > + * since it has its has extended each core Linux section with a respective > + * linker table entry in `include/asm-generic/vmlinux.lds.h`. When you add > new > + * linker table entry you aggregate them `into` the existing linker table > core > + * section. > + */ > + > +/** > + * DOC: How linker tables simplify initialization code > + * > + * Traditionally, we would implement features in C code as follows: > + * > + * foo_init(); > + * > + * You'd then have a foo.h which would have:: > + * > + * #ifndef CONFIG_FOO > + * static inline void foo_init(void) { } > + * #endif > + * > + * With linker tables this is no longer necessary as your init routines would > + * be implicit, you'd instead call: > + * > + * call_init_fns(); > + * > + * call_init_fns() would call all functions present in your init table and if > + * and only if foo.o gets linked in, then its initialisation function will be > + * called. > + * > + * The linker script takes care of assembling the tables for us. All of our > + * table sections have names of the format `SECTION_NAME.tbl.NAME.N`. Here > + * `SECTION_NAME` is one of the standard sections in:: > + * > + * include/asm-generic/section-core.h > + * > + * and `NAME` designates the specific use case for the linker table, the > table. > + * `N` is a digit used to help sort entries in the section. `N=` (empty > string) > + * is reserved for the symbol indicating `table start`, and `N=~` is reserved > + * for the symbol indicating `table end`. In order for the call_init_fns() to > + * work behind the scenes the custom linker script would need to define the > + * beginning of the table, the end of the table, and in between it should use > + * ``SORT()`` to give order to the section. Typically this would require > custom > + * linker script modifications however since linker table are already defined > + * in ``include/asm-generic/vmlinux.lds.h`` as documented above each new > linker > + * table definition added in C code folds into the respective core Linux > + * section linker table. > + * > + * This is also done to support all architectures. All that is needed then > is > + * to ensure a respective common linker table entry is added to the shared > + * ``include/asm-generic/vmlinux.lds.h``. There should be a respective:: > + * > + * *(SORT(SECTION_TBL_ALL(SECTION_NAME))) > + * > + * entry for each type of supported section there. If your `SECTION_NAME` > + * is not yet supported, consider adding support for it. > + * > + * Linker tables support ordering entries, it does this using a digit which > + * is eventually added as a postfix to a section entry name, we refer to this > + * as the linker table ``order-level``. If order is not important to your > + * linker table entry you can use the special ``SECTION_ORDER_ANY``. After > + * ``order-level``, the next contributing factor to order is the order of the > + * code in the C file, and the order of the objects in the Makefile. Using an > + * ``order-level`` then should not really be needed in most cases, its use > + * however enables to compartamentalize code into tables where ordering > through > + * C file or through the Makefile would otherwise be very difficult or if one > + * wanted to enable very specific initialization semantics. > + * > + * As an example, suppose that we want to create a "frobnicator" > + * feature framework, and allow for several independent modules to > + * provide frobnicating services. Then we would create a frob.h > + * header file containing e.g.:: > + * > + * struct frobnicator { > + * const char *name; > + * void (*frob) (void); > + * }; > + * > + * DECLARE_LINKTABLE(struct frobnicator, frobnicator_fns); > + * > + * Any module providing frobnicating services would look something > + * like:: > + * > + * #include "frob.h" > + * > + * static void my_frob(void) { > + * ... Do my frobnicating > + * } > + * > + * LINKTABLE_INIT_DATA(frobnicator_fns, all) my_frobnicator = { > + * .name = "my_frob", > + * .frob = my_frob, > + * }; > + * > + * The central frobnicator code, say in frob.c, would use the frobnicating > + * modules as follows:: > + * > + * #include "frob.h" > + * > + * void frob_all(void) { > + * struct frobnicator *f; > + * > + * LINKTABLE_FOR_EACH(f, frobnicator_fns) { > + * pr_info("Calling frobnicator %s\n", frob->name); > + * f->frob(); > + * } > + * } > + */ > + > +/** > + * DOC: Linker table module support > + * > + * Modules can use linker tables, however the linker table definition > + * must be built-in to the kernel. That is, the code that implements > + * ``DEFINE_LINKTABLE*()`` must be built-in, and modular code cannot add > + * more items in to the table, unless ``kernel/module.c`` > find_module_sections() > + * and module-common.lds.S are updated accordingly with a respective > + * module notifier to account for updates. This restriction may be enhanced > + * in the future. > + */ > + > +/** > + * DOC: Linker table helpers > + * > + * These are helpers for linker tables. > + */ > + > +/** > + * LINKTABLE_ADDR_WITHIN - returns true if address is in range > + * > + * @tbl: linker table > + * @addr: address to query for > + * > + * Returns true if the address is part of the linker table. > + */ > +#define LINKTABLE_ADDR_WITHIN(tbl, addr) \ > + (addr >= (unsigned long) LINUX_SECTION_START(tbl) && \ > + addr < (unsigned long) LINUX_SECTION_END(tbl)) > + > +/** > + * DOC: Constructing linker tables > + * > + * Linker tables constructors are used to build an entry into a linker table. > + * Linker table constructors exist for each type of supported section. > + * > + * You have weak and regular type of link table entry constructors. > + */ > + > +/** > + * DOC: Weak linker tables constructors > + * > + * The weak attribute is desirable if you want an entry you can replace at > + * link time. A very special use case for linker tables is the first entry. > + * A weak attribute is used for the first entry to ensure that this entry's > + * address matches the end address of the table when the linker table is > + * emtpy, but will also point to the first real entry of the table once not > + * empty. When the first entry is linked in, it takes place of the first > entry. > + */ > + > +/** > + * LINKTABLE_WEAK - Constructs a weak linker table entry for data > + * > + * @name: linker table name > + * @level: order level > + * > + * Constructs a weak linker table for data. > + */ > +#define LINKTABLE_WEAK(name, level) \ > + __typeof__(VMLINUX_SYMBOL(name)[0]) \ > + __attribute__((used, \ > + weak, \ > + __aligned__(LINUX_SECTION_ALIGNMENT(name)),\ > + section(SECTION_TBL(SECTION_DATA, \ > + name, level)))) > + > +/** > + * LINKTABLE_TEXT_WEAK - Constructs a weak linker table entry for execution > + * > + * @name: linker table name > + * @level: order level > + * > + * Constructs a weak linker table for code execution. These will be > + * read-only. > + */ > +#define LINKTABLE_TEXT_WEAK(name, level) \ > + const __typeof__(VMLINUX_SYMBOL(name)[0]) \ > + __attribute__((used, \ > + weak, \ > + __aligned__(LINUX_SECTION_ALIGNMENT(name)),\ > + section(SECTION_TBL(SECTION_TEXT, \ > + name, level)))) > + > +/** > + * LINKTABLE_RO_WEAK - Constructs a weak read-only linker table entry > + * > + * @name: linker table name > + * @level: order level > + * > + * Constructs a weak linker table which only requires read-only access. > + */ > +#define LINKTABLE_RO_WEAK(name, level) \ > + const __typeof__(VMLINUX_SYMBOL(name)[0]) \ > + __attribute__((used, \ > + weak, \ > + __aligned__(LINUX_SECTION_ALIGNMENT(name)),\ > + section(SECTION_TBL(SECTION_TBL_RO, \ > + name, level)))) > + > +/** > + * LINKTABLE_INIT_WEAK - Constructs a weak linker table entry for init code > + * > + * @name: linker table name > + * @level: order level > + * > + * Constructs a weak linker table for execution. use at init. > + */ > +#define LINKTABLE_INIT_WEAK(name, level) \ > + const __typeof__(VMLINUX_SYMBOL(name)[0]) \ > + __attribute__((used, \ > + weak, \ > + __aligned__(LINUX_SECTION_ALIGNMENT(name)),\ > + section(SECTION_TBL(SECTION_INIT, \ > + name, level)))) > + > +/** > + * LINKTABLE_INIT_DATA_WEAK - Constructs a weak linker table entry for > initdata > + * > + * @name: linker table name > + * @level: order level > + * > + * Constructs a weak linker table for data during init. > + */ > +#define LINKTABLE_INIT_DATA_WEAK(name, level) \ > + __typeof__(VMLINUX_SYMBOL(name)[0]) \ > + __attribute__((used, \ > + weak, \ > + __aligned__(LINUX_SECTION_ALIGNMENT(name)),\ > + section(SECTION_TBL(SECTION_INIT_DATA, \ > + name, level)))) > + > +/** > + * DOC: Regular linker linker table constructors > + * > + * Regular constructors are expected to be used for valid linker table > entries. > + * Valid uses of weak entries other than the beginning and is currently > + * untested but should in theory work. > + */ > + > +/** > + * LINKTABLE - Declares a data linker table entry > + * > + * @name: linker table name > + * @level: order level > + * > + * Declares a data linker table entry. These are read-write. > + */ > +#define LINKTABLE(name, level) \ > + __typeof__(VMLINUX_SYMBOL(name)[0]) \ > + __attribute__((used, \ > + __aligned__(LINUX_SECTION_ALIGNMENT(name)),\ > + section(SECTION_TBL(SECTION_DATA, \ > + name, level)))) > + > +/** > + * LINKTABLE_TEXT - Declares a linker table entry for execution > + * > + * @name: linker table name > + * @level: order level > + * > + * Declares a linker table to be used for execution. > + */ > +#define LINKTABLE_TEXT(name, level) \ > + const __typeof__(VMLINUX_SYMBOL(name)[0]) \ > + __attribute__((used, \ > + __aligned__(LINUX_SECTION_ALIGNMENT(name)),\ > + section(SECTION_TBL(SECTION_TEXT, \ > + name, level)))) > + > +/** > + * LINKTABLE_RO - Declares a read-only linker table entry. > + * > + * @name: linker table name > + * @level: order level > + * > + * Declares a linker table which only requires read-only access. Contrary > + * to LINKTABLE_RO_WEAK() which uses SECTION_RODATA this helper uses the > + * section SECTION_TBL_RO here due to possible toolchains bug on some > + * architectures, for instance the c6x architicture stuffs non-weak data > + * into different sections other than the one intended. > + */ > +#define LINKTABLE_RO(name, level) \ > + const __typeof__(VMLINUX_SYMBOL(name)[0]) \ > + __attribute__((used, \ > + __aligned__(LINUX_SECTION_ALIGNMENT(name)),\ > + section(SECTION_TBL(SECTION_TBL_RO, \ > + name, level)))) > + > +/** > + * LINKTABLE_INIT - Declares a linker table entry to be used on init. > + * > + * @name: linker table name > + * @level: order level > + * > + * Declares a linker table entry for execution use during init. > + */ > +#define LINKTABLE_INIT(name, level) \ > + const __typeof__(VMLINUX_SYMBOL(name)[0]) \ > + __attribute__((used, \ > + __aligned__(LINUX_SECTION_ALIGN_FUNC), \ > + section(SECTION_TBL(SECTION_INIT, \ > + name, level)))) > + > +/** > + * LINKTABLE_INIT_DATA - Declares a linker table entry to be used on init > data. > + * > + * @name: linker table name > + * @level: order level > + * > + * Declares a linker table entry for data during init. > + */ > +#define LINKTABLE_INIT_DATA(name, level) \ > + __typeof__(VMLINUX_SYMBOL(name)[0]) \ > + __attribute__((used, \ > + __aligned__(LINUX_SECTION_ALIGNMENT(name)),\ > + section(SECTION_TBL(SECTION_INIT_DATA, \ > + name, level)))) > + > +/** > + * DOC: Declaring Linker tables > + * > + * Declarers are used to help code access the linker tables. Typically > + * header files for subsystems would declare the linker tables to enable > + * easy access to add new entries, and to iterate over the list of table. > + * There are only two declarers needed given that the section association > + * is done by the definition of the linker table using > ``DEFINE_LINKTABLE*()`` > + * helpers. > + */ > + > + > +/** > + * DECLARE_LINKTABLE - Declares a data linker table entry > + * > + * @type: data type > + * @name: table name > + * > + * Declares a data linker table entry. > + */ > +#define DECLARE_LINKTABLE(type, name) \ > + DECLARE_LINUX_SECTION(type, name) > + > +/** > + * DECLARE_LINKTABLE_RO - Declares a read-only linker table entry > + * > + * @type: data type > + * @name: table name > + * > + * Declares a read-only linker table entry. > + */ > +#define DECLARE_LINKTABLE_RO(type, name) \ > + DECLARE_LINUX_SECTION_RO(type, name) > + > +/** > + * DOC: Defining Linker tables > + * > + * Linker tables are defined in the code that takes ownership over > + * the linker table. This is typically done in the same code that is in > + * charge of iterating over the linker table as well. > + */ > + > +/** > + * DEFINE_LINKTABLE - Defines a linker table for data > + * > + * @type: data type > + * @name: table name > + * > + * Defines a linker table which used for data. > + */ > +#define DEFINE_LINKTABLE(type, name) \ > + DECLARE_LINKTABLE(type, name); \ > + LINKTABLE_WEAK(name,) VMLINUX_SYMBOL(name)[0] = {}; \ > + LINKTABLE(name, ~) VMLINUX_SYMBOL(name##__end)[0] = {} > + > +/** > + * DEFINE_LINKTABLE_TEXT - Declares linker table entry for exectuion > + * > + * @type: data type > + * @name: table name > + * > + * Declares a linker table entry for execution. > + */ > +#define DEFINE_LINKTABLE_TEXT(type, name) \ > + DECLARE_LINKTABLE_RO(type, name); \ > + LINKTABLE_TEXT_WEAK(name,) VMLINUX_SYMBOL(name)[0] = {}; \ > + LINKTABLE_TEXT(name, ~) VMLINUX_SYMBOL(name##__end)[0] = {} > + > +/** > + * DEFINE_LINKTABLE_RO - Defines a read-only linker table > + * > + * @type: data type > + * @name: table name > + * > + * Defines a linker table which we know only requires read-only access. > + */ > +#define DEFINE_LINKTABLE_RO(type, name) > \ > + DECLARE_LINKTABLE_RO(type, name); \ > + LINKTABLE_RO_WEAK(name,) VMLINUX_SYMBOL(name)[0] = {}; \ > + LINKTABLE_RO(name, ~) VMLINUX_SYMBOL(name##__end)[0] = {} > + > +/** > + * DEFINE_LINKTABLE_INIT - Defines an init time linker table for execution > + * > + * @type: data type > + * @name: table name > + * > + * Defines a linker table. If you are adding a new type you should > + * enable ``CONFIG_DEBUG_SECTION_MISMATCH`` and ensure routines that make > + * use of the linker tables get a respective __ref tag. > + */ > +#define DEFINE_LINKTABLE_INIT(type, name) \ > + DECLARE_LINKTABLE(type, name); \ > + LINKTABLE_INIT_WEAK(name,) VMLINUX_SYMBOL(name)[0] = {}; \ > + LINKTABLE_INIT(name, ~) VMLINUX_SYMBOL(name##__end)[0] = {} > + > +/** > + * DEFINE_LINKTABLE_INIT_DATA - Defines an init time linker table for data > + * > + * @type: data type > + * @name: table name > + * > + * Defines a linker table for init data. If you are adding a new type you > + * should enable ``CONFIG_DEBUG_SECTION_MISMATCH`` and ensure routines that > + * make use of the linker tables get a respective __ref tag. > + */ > +#define DEFINE_LINKTABLE_INIT_DATA(type, name) \ > + DECLARE_LINKTABLE(type, name); \ > + LINKTABLE_INIT_DATA_WEAK(name,) VMLINUX_SYMBOL(name)[0] = {}; \ > + LINKTABLE_INIT_DATA(name, ~) VMLINUX_SYMBOL(name##__end)[0] = {} > + > +/** > + * DOC: Iterating over Linker tables > + * > + * To make use of the linker tables you want to be able to iterate over > + * them. This section documents the different iterators available. > + */ > + > +/** > + * LINKTABLE_FOR_EACH - iterate through all entries within a linker table > + * > + * @pointer: entry pointer > + * @tbl: linker table > + * > + * Example usage:: > + * > + * struct frobnicator *frob; > + * > + * LINKTABLE_FOR_EACH(frob, frobnicator_fns) { > + * ... > + * } > + */ > + > +#define LINKTABLE_FOR_EACH(pointer, tbl) \ > + for (pointer = LINUX_SECTION_START(tbl); \ > + pointer < LINUX_SECTION_END(tbl); \ > + pointer++) > + > +/** > + * LINKTABLE_RUN_ALL - iterate and run through all entries on a linker table > + * > + * @tbl: linker table > + * @func: structure name for the function name we want to call. > + * @args...: arguments to pass to func > + * > + * Example usage:: > + * > + * LINKTABLE_RUN_ALL(frobnicator_fns, some_run,); > + */ > +#define LINKTABLE_RUN_ALL(tbl, func, args...) \ > +do { \ > + size_t i; \ > + for (i = 0; i < LINUX_SECTION_SIZE(tbl); i++) \ > + (VMLINUX_SYMBOL(tbl)[i]).func (args); \ > +} while (0) > + > +/** > + * LINKTABLE_RUN_ERR - run each linker table entry func and return error if > any > + * > + * @tbl: linker table > + * @func: structure name for the function name we want to call. > + * @args...: arguments to pass to func > + * > + * Example usage:: > + * > + * unsigned int err = LINKTABLE_RUN_ERR(frobnicator_fns, some_run,); > + */ > +#define LINKTABLE_RUN_ERR(tbl, func, args...) \ > +({ \ > + size_t i; \ > + int err = 0; \ > + for (i = 0; !err && i < LINUX_SECTION_SIZE(tbl); i++) \ > + err = (VMLINUX_SYMBOL(tbl)[i]).func (args); \ > + err; \ > +}) > + > +#endif /* __ASSEMBLY__ */ > + > +#endif /* _LINUX_LINKER_TABLES_H */ > diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean > index 50616ea25131..2b54546237d6 100644 > --- a/scripts/Makefile.clean > +++ b/scripts/Makefile.clean > @@ -36,6 +36,8 @@ subdir-ymn := $(addprefix $(obj)/,$(subdir-ymn)) > # directory > > __clean-files := $(extra-y) $(extra-m) $(extra-) \ > + $(force-obj-y) $(force-obj-m) $(force-obj-) \ > + $(force-lib-y) $(force-lib-m) $(force-lib-) \ > $(always) $(targets) $(clean-files) \ > $(host-progs) \ > $(hostprogs-y) $(hostprogs-m) $(hostprogs-) \ > -- > 2.9.2 > -- Kees Cook Nexus Security _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |