linux-arch.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 00/16] linux: generalize sections, ranges and linker tables
@ 2016-08-19 21:32 mcgrof
  2016-08-19 21:32 ` mcgrof
                   ` (11 more replies)
  0 siblings, 12 replies; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: gnomes, linux-ia64, jkosina, benh, ming.lei, linux,
	platform-driver-x86, James.Bottomley, paul.gortmaker, paulus,
	sparclinux, mchehab, linux-arch, markus.heiser, xen-devel,
	msalter, linux-sh, mpe, x86, fontana, linux-arm-kernel,
	catalin.marinas, dvhart, dwmw2, linux-xtensa, pali.rohar,
	keescook, arnd, jani.nikula, will.deacon, rusty, rostedt, acme,
	ak, andriy.shevchenko, mcb30

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

This v4 addresses feedback from the previous v3 series [0], and also
addresses a huge array of additional tests against many architectures
outside of what 0-day provides. As I mentioned in my last v3 series,
0-day had only found one issue with the series, a blackfin architecture
linker issue with the last series. Guenter Rock was kind enough to give
my series a test spin on his test bed and he found quite a bit of other
oddball issues with obscure architectures, and even on x86 with an old
toolchain. After a lot of work and coordinating with a few maintainers
I'm happy to report all issues found so far through all possible testing
I could do are now fixed, this series also addresses all feedback from
the last series, as such this goes submitted as PATCH form.

In addressing fixing this work on a few architectures some of the previous
patches are further simplified. The kprobes port to linker tables is made
much easier now that I've addressed moving out core kprobe declarations
into asm-generic/kprobes.h. Refer to the patch "kprobes: move kprobe
declarations to asm-generic/kprobes.h". This makes for a much cleaner
solution across architectures.

Boris feedback on making the code bit rot feature optional is addressed
by using a new Kconfig symbol for this, CONFIG_BUILD_AVOID_BITROT,
but given Greg's concerns over lack of clarity over what this was all about
I've ripped that functionality out into its own patch with a bit more
extensive documentation and re-wording. See the patch "kbuild: enable option
to force compile force-obj-y and force-lib-y". I hope makes it clear how
linker tables can help with avoiding code bit rot. I've gone with a new
Kconfig symbol CONFIG_BUILD_AVOID_BITROT given CONFIG_COMPILE_TEST is
not available on UML, this feature is desirable on all architectures.

The documentation is revamped, now that the DocBook format is deprecated
I ported the documention into the trendy hipster Sphinx documentation
format.

AT Boris' request I've adapated the userspace linker table application
forintegration into the kernel under tools/ to make it easier to keep
things in sync, however since this requires a bit of changes to some headers
in tools/ I'll submit that separately.

[0] https://lkml.kernel.org/r/1469222687-1600-1-git-send-email-mcgrof@kernel.org

If you'd like this in git-form, you can get it on the 20160819-linker-table-v4
branch of my linux-next tree on kernel.org, this also includes the series of
the linker table userspace sandbox:

https://git.kernel.org/cgit/linux/kernel/git/mcgrof/linux-next.git/log/?h=20160819-linker-table-v4

Please let me know if there are any concerns or questions.

Luis R. Rodriguez (16):
  x86: remove LTO_REFERENCE_INITCALL()
  dell-smo8800: include uaccess.h
  scripts/module-common.lds: enable generation
  generic-sections: add section core helpers
  xtensa: skip adding literal when SORT() is used
  ranges.h: add helpers to build and identify Linux section ranges
  tables.h: add linker table support
  kbuild: enable option to force compile force-obj-y and force-lib-y
  firmware/Makefile: force recompilation if makefile changes
  firmware: port built-in section to linker table
  jump_label: move guard #endif down where it belongs
  jump_label: port __jump_table to linker tables
  dynamic_debug: port to use linker tables
  kprobes: move kprobe declarations to asm-generic/kprobes.h
  kprobes: port .kprobes.text to section range
  kprobes: port blacklist kprobes to linker table

 .gitignore                                         |   2 +
 Documentation/index.rst                            |   1 +
 Documentation/kbuild/makefiles.txt                 |  36 ++
 Documentation/sections/conf.py                     |   4 +
 Documentation/sections/index.rst                   |  13 +
 Documentation/sections/linker-tables.rst           | 202 +++++++
 Documentation/sections/ranges.rst                  |  49 ++
 Documentation/sections/section-core.rst            | 153 +++++
 MAINTAINERS                                        |  37 ++
 Makefile                                           |   6 +-
 arch/alpha/include/asm/Kbuild                      |   4 +
 arch/arc/include/asm/Kbuild                        |   3 +
 arch/arc/include/asm/kprobes.h                     |   6 +-
 arch/arc/kernel/vmlinux.lds.S                      |   1 -
 arch/arm/include/asm/Kbuild                        |   3 +
 arch/arm/include/asm/jump_label.h                  |   6 +-
 arch/arm/include/asm/kprobes.h                     |   4 +
 arch/arm/kernel/entry-armv.S                       |   3 +-
 arch/arm/kernel/vmlinux-xip.lds.S                  |   1 -
 arch/arm/kernel/vmlinux.lds.S                      |   1 -
 arch/arm/probes/decode.h                           |   1 +
 arch/arm64/include/asm/Kbuild                      |   3 +
 arch/arm64/include/asm/jump_label.h                |   6 +-
 arch/arm64/include/asm/kprobes.h                   |   4 +
 arch/arm64/kernel/armv8_deprecated.c               |   1 +
 arch/arm64/kernel/insn.c                           |   1 +
 arch/arm64/kernel/probes/kprobes.c                 |   4 +-
 arch/arm64/kernel/vmlinux.lds.S                    |   1 -
 arch/avr32/include/asm/Kbuild                      |   3 +
 arch/avr32/include/asm/kprobes.h                   |   4 +
 arch/avr32/kernel/entry-avr32b.S                   |  13 +-
 arch/avr32/kernel/vmlinux.lds.S                    |   1 -
 arch/blackfin/include/asm/Kbuild                   |   4 +
 arch/blackfin/kernel/vmlinux.lds.S                 |   1 -
 arch/c6x/include/asm/Kbuild                        |   3 +
 arch/c6x/include/asm/tables.h                      |  26 +
 arch/c6x/kernel/vmlinux.lds.S                      |   1 -
 arch/cris/include/asm/Kbuild                       |   4 +
 arch/frv/include/asm/Kbuild                        |   4 +
 arch/h8300/include/asm/Kbuild                      |   4 +
 arch/hexagon/include/asm/Kbuild                    |   4 +
 arch/hexagon/kernel/vmlinux.lds.S                  |   1 -
 arch/ia64/include/asm/Kbuild                       |   3 +
 arch/ia64/include/asm/kprobes.h                    |   7 +-
 arch/ia64/kernel/jprobes.S                         |   3 +-
 arch/ia64/kernel/vmlinux.lds.S                     |   1 -
 arch/ia64/lib/flush.S                              |   6 +-
 arch/m32r/include/asm/Kbuild                       |   4 +
 arch/m68k/include/asm/Kbuild                       |   4 +
 arch/metag/include/asm/Kbuild                      |   4 +
 arch/metag/kernel/vmlinux.lds.S                    |   1 -
 arch/microblaze/include/asm/Kbuild                 |   4 +
 arch/microblaze/kernel/vmlinux.lds.S               |   1 -
 arch/mips/include/asm/Kbuild                       |   3 +
 arch/mips/include/asm/jump_label.h                 |   6 +-
 arch/mips/include/asm/kprobes.h                    |   6 +-
 arch/mips/kernel/vmlinux.lds.S                     |   1 -
 arch/mn10300/include/asm/Kbuild                    |   3 +
 arch/mn10300/include/asm/kprobes.h                 |   4 +
 arch/mn10300/kernel/vmlinux.lds.S                  |   1 -
 arch/nios2/include/asm/Kbuild                      |   4 +
 arch/nios2/kernel/vmlinux.lds.S                    |   1 -
 arch/openrisc/include/asm/Kbuild                   |   4 +
 arch/openrisc/kernel/vmlinux.lds.S                 |   1 -
 arch/parisc/include/asm/Kbuild                     |   4 +
 arch/parisc/kernel/vmlinux.lds.S                   |   1 -
 arch/powerpc/include/asm/Kbuild                    |   3 +
 arch/powerpc/include/asm/jump_label.h              |   8 +-
 arch/powerpc/include/asm/kprobes.h                 |   6 +
 arch/powerpc/include/asm/ppc_asm.h                 |   7 +-
 arch/powerpc/kernel/vmlinux.lds.S                  |   1 -
 arch/s390/include/asm/Kbuild                       |   3 +
 arch/s390/include/asm/jump_label.h                 |   6 +-
 arch/s390/include/asm/kprobes.h                    |   4 +
 arch/s390/kernel/entry.S                           |   5 +-
 arch/s390/kernel/kprobes.c                         |   6 +-
 arch/s390/kernel/mcount.S                          |   3 +-
 arch/s390/kernel/vmlinux.lds.S                     |   1 -
 arch/score/include/asm/Kbuild                      |   4 +
 arch/score/kernel/vmlinux.lds.S                    |   1 -
 arch/sh/include/asm/Kbuild                         |   3 +
 arch/sh/include/asm/kprobes.h                      |   2 +
 arch/sh/kernel/vmlinux.lds.S                       |   1 -
 arch/sparc/include/asm/Kbuild                      |   3 +
 arch/sparc/include/asm/jump_label.h                |   6 +-
 arch/sparc/include/asm/kprobes.h                   |   5 +
 arch/sparc/kernel/vmlinux.lds.S                    |   1 -
 arch/sparc/mm/ultra.S                              |   3 +-
 arch/tile/include/asm/Kbuild                       |   3 +
 arch/tile/include/asm/kprobes.h                    |   6 +-
 arch/tile/kernel/vmlinux.lds.S                     |   1 -
 arch/um/include/asm/Kbuild                         |   4 +
 arch/unicore32/include/asm/Kbuild                  |   3 +
 arch/unicore32/include/asm/section-core.h          |  19 +
 arch/x86/include/asm/Kbuild                        |   3 +
 arch/x86/include/asm/jump_label.h                  |  10 +-
 arch/x86/include/asm/kprobes.h                     |   6 +
 arch/x86/kernel/cpu/microcode/core.c               |   8 +-
 arch/x86/kernel/kprobes/core.c                     |  11 +-
 arch/x86/kernel/vmlinux.lds.S                      |   1 -
 arch/x86/tools/relocs.c                            |   4 +
 arch/xtensa/include/asm/Kbuild                     |   4 +
 arch/xtensa/kernel/Makefile                        |   8 +-
 drivers/base/firmware_class.c                      |  12 +-
 drivers/platform/x86/dell-smo8800.c                |   1 +
 firmware/Makefile                                  |   6 +-
 include/asm-generic/kprobes.h                      |  26 +
 include/asm-generic/ranges.h                       | 103 ++++
 include/asm-generic/section-core.h                 | 341 +++++++++++
 include/asm-generic/sections.h                     |   4 +-
 include/asm-generic/tables.h                       |  50 ++
 include/asm-generic/vmlinux.lds.h                  |  73 +--
 include/linux/compiler.h                           |   8 -
 include/linux/dynamic_debug.h                      |   5 +-
 include/linux/init.h                               |  20 +-
 include/linux/jump_label.h                         |   8 +-
 include/linux/kprobes.h                            |  24 +-
 include/linux/ranges.h                             | 128 +++++
 include/linux/sections.h                           | 111 ++++
 include/linux/tables.h                             | 638 +++++++++++++++++++++
 init/Kconfig                                       |  22 +
 kernel/jump_label.c                                |  17 +-
 kernel/kprobes.c                                   |  17 +-
 lib/dynamic_debug.c                                |  13 +-
 scripts/Makefile.build                             |   7 +-
 scripts/Makefile.clean                             |   2 +
 scripts/Makefile.lib                               |  11 +
 scripts/Makefile.modpost                           |   2 +-
 scripts/mod/modpost.c                              |   2 +-
 scripts/{module-common.lds => module-common.lds.S} |   6 +
 scripts/recordmcount.c                             |   2 +-
 scripts/recordmcount.pl                            |   2 +-
 tools/objtool/special.c                            |   2 +-
 133 files changed, 2328 insertions(+), 214 deletions(-)
 create mode 100644 Documentation/sections/conf.py
 create mode 100644 Documentation/sections/index.rst
 create mode 100644 Documentation/sections/linker-tables.rst
 create mode 100644 Documentation/sections/ranges.rst
 create mode 100644 Documentation/sections/section-core.rst
 create mode 100644 arch/c6x/include/asm/tables.h
 create mode 100644 arch/unicore32/include/asm/section-core.h
 create mode 100644 include/asm-generic/kprobes.h
 create mode 100644 include/asm-generic/ranges.h
 create mode 100644 include/asm-generic/section-core.h
 create mode 100644 include/asm-generic/tables.h
 create mode 100644 include/linux/ranges.h
 create mode 100644 include/linux/sections.h
 create mode 100644 include/linux/tables.h
 rename scripts/{module-common.lds => module-common.lds.S} (80%)

-- 
2.9.2


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH v4 00/16] linux: generalize sections, ranges and linker tables
  2016-08-19 21:32 [PATCH v4 00/16] linux: generalize sections, ranges and linker tables mcgrof
@ 2016-08-19 21:32 ` mcgrof
  2016-08-19 21:32 ` [PATCH v4 01/16] x86: remove LTO_REFERENCE_INITCALL() mcgrof
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: x86, luto, keescook, torvalds, gregkh, rusty, gnomes, alan,
	dwmw2, arnd, ming.lei, linux-arch, benh, ananth, pebolle,
	fontana, david.vrabel, konrad.wilk, mcb30, jgross,
	andrew.cooper3, andriy.shevchenko, paul.gortmaker, xen-devel, ak,
	pali.rohar, dvhart, platform-driver-x86, mmarek, linux, jkosina,
	korea.drzix, linux-kbuild, tony.luck, akpm, linux-ia64,
	linux-arm-kernel, linux-sh, sparclinux, catalin.marinas,
	will.deacon, rostedt, jani.nikula, mchehab, markus.heiser, acme,
	jolsa, msalter, chris, jcmvbkbc, linux-xtensa, paulus, mpe,
	James.Bottomley, Luis R. Rodriguez

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

This v4 addresses feedback from the previous v3 series [0], and also
addresses a huge array of additional tests against many architectures
outside of what 0-day provides. As I mentioned in my last v3 series,
0-day had only found one issue with the series, a blackfin architecture
linker issue with the last series. Guenter Rock was kind enough to give
my series a test spin on his test bed and he found quite a bit of other
oddball issues with obscure architectures, and even on x86 with an old
toolchain. After a lot of work and coordinating with a few maintainers
I'm happy to report all issues found so far through all possible testing
I could do are now fixed, this series also addresses all feedback from
the last series, as such this goes submitted as PATCH form.

In addressing fixing this work on a few architectures some of the previous
patches are further simplified. The kprobes port to linker tables is made
much easier now that I've addressed moving out core kprobe declarations
into asm-generic/kprobes.h. Refer to the patch "kprobes: move kprobe
declarations to asm-generic/kprobes.h". This makes for a much cleaner
solution across architectures.

Boris feedback on making the code bit rot feature optional is addressed
by using a new Kconfig symbol for this, CONFIG_BUILD_AVOID_BITROT,
but given Greg's concerns over lack of clarity over what this was all about
I've ripped that functionality out into its own patch with a bit more
extensive documentation and re-wording. See the patch "kbuild: enable option
to force compile force-obj-y and force-lib-y". I hope makes it clear how
linker tables can help with avoiding code bit rot. I've gone with a new
Kconfig symbol CONFIG_BUILD_AVOID_BITROT given CONFIG_COMPILE_TEST is
not available on UML, this feature is desirable on all architectures.

The documentation is revamped, now that the DocBook format is deprecated
I ported the documention into the trendy hipster Sphinx documentation
format.

AT Boris' request I've adapated the userspace linker table application
forintegration into the kernel under tools/ to make it easier to keep
things in sync, however since this requires a bit of changes to some headers
in tools/ I'll submit that separately.

[0] https://lkml.kernel.org/r/1469222687-1600-1-git-send-email-mcgrof@kernel.org

If you'd like this in git-form, you can get it on the 20160819-linker-table-v4
branch of my linux-next tree on kernel.org, this also includes the series of
the linker table userspace sandbox:

https://git.kernel.org/cgit/linux/kernel/git/mcgrof/linux-next.git/log/?h=20160819-linker-table-v4

Please let me know if there are any concerns or questions.

Luis R. Rodriguez (16):
  x86: remove LTO_REFERENCE_INITCALL()
  dell-smo8800: include uaccess.h
  scripts/module-common.lds: enable generation
  generic-sections: add section core helpers
  xtensa: skip adding literal when SORT() is used
  ranges.h: add helpers to build and identify Linux section ranges
  tables.h: add linker table support
  kbuild: enable option to force compile force-obj-y and force-lib-y
  firmware/Makefile: force recompilation if makefile changes
  firmware: port built-in section to linker table
  jump_label: move guard #endif down where it belongs
  jump_label: port __jump_table to linker tables
  dynamic_debug: port to use linker tables
  kprobes: move kprobe declarations to asm-generic/kprobes.h
  kprobes: port .kprobes.text to section range
  kprobes: port blacklist kprobes to linker table

 .gitignore                                         |   2 +
 Documentation/index.rst                            |   1 +
 Documentation/kbuild/makefiles.txt                 |  36 ++
 Documentation/sections/conf.py                     |   4 +
 Documentation/sections/index.rst                   |  13 +
 Documentation/sections/linker-tables.rst           | 202 +++++++
 Documentation/sections/ranges.rst                  |  49 ++
 Documentation/sections/section-core.rst            | 153 +++++
 MAINTAINERS                                        |  37 ++
 Makefile                                           |   6 +-
 arch/alpha/include/asm/Kbuild                      |   4 +
 arch/arc/include/asm/Kbuild                        |   3 +
 arch/arc/include/asm/kprobes.h                     |   6 +-
 arch/arc/kernel/vmlinux.lds.S                      |   1 -
 arch/arm/include/asm/Kbuild                        |   3 +
 arch/arm/include/asm/jump_label.h                  |   6 +-
 arch/arm/include/asm/kprobes.h                     |   4 +
 arch/arm/kernel/entry-armv.S                       |   3 +-
 arch/arm/kernel/vmlinux-xip.lds.S                  |   1 -
 arch/arm/kernel/vmlinux.lds.S                      |   1 -
 arch/arm/probes/decode.h                           |   1 +
 arch/arm64/include/asm/Kbuild                      |   3 +
 arch/arm64/include/asm/jump_label.h                |   6 +-
 arch/arm64/include/asm/kprobes.h                   |   4 +
 arch/arm64/kernel/armv8_deprecated.c               |   1 +
 arch/arm64/kernel/insn.c                           |   1 +
 arch/arm64/kernel/probes/kprobes.c                 |   4 +-
 arch/arm64/kernel/vmlinux.lds.S                    |   1 -
 arch/avr32/include/asm/Kbuild                      |   3 +
 arch/avr32/include/asm/kprobes.h                   |   4 +
 arch/avr32/kernel/entry-avr32b.S                   |  13 +-
 arch/avr32/kernel/vmlinux.lds.S                    |   1 -
 arch/blackfin/include/asm/Kbuild                   |   4 +
 arch/blackfin/kernel/vmlinux.lds.S                 |   1 -
 arch/c6x/include/asm/Kbuild                        |   3 +
 arch/c6x/include/asm/tables.h                      |  26 +
 arch/c6x/kernel/vmlinux.lds.S                      |   1 -
 arch/cris/include/asm/Kbuild                       |   4 +
 arch/frv/include/asm/Kbuild                        |   4 +
 arch/h8300/include/asm/Kbuild                      |   4 +
 arch/hexagon/include/asm/Kbuild                    |   4 +
 arch/hexagon/kernel/vmlinux.lds.S                  |   1 -
 arch/ia64/include/asm/Kbuild                       |   3 +
 arch/ia64/include/asm/kprobes.h                    |   7 +-
 arch/ia64/kernel/jprobes.S                         |   3 +-
 arch/ia64/kernel/vmlinux.lds.S                     |   1 -
 arch/ia64/lib/flush.S                              |   6 +-
 arch/m32r/include/asm/Kbuild                       |   4 +
 arch/m68k/include/asm/Kbuild                       |   4 +
 arch/metag/include/asm/Kbuild                      |   4 +
 arch/metag/kernel/vmlinux.lds.S                    |   1 -
 arch/microblaze/include/asm/Kbuild                 |   4 +
 arch/microblaze/kernel/vmlinux.lds.S               |   1 -
 arch/mips/include/asm/Kbuild                       |   3 +
 arch/mips/include/asm/jump_label.h                 |   6 +-
 arch/mips/include/asm/kprobes.h                    |   6 +-
 arch/mips/kernel/vmlinux.lds.S                     |   1 -
 arch/mn10300/include/asm/Kbuild                    |   3 +
 arch/mn10300/include/asm/kprobes.h                 |   4 +
 arch/mn10300/kernel/vmlinux.lds.S                  |   1 -
 arch/nios2/include/asm/Kbuild                      |   4 +
 arch/nios2/kernel/vmlinux.lds.S                    |   1 -
 arch/openrisc/include/asm/Kbuild                   |   4 +
 arch/openrisc/kernel/vmlinux.lds.S                 |   1 -
 arch/parisc/include/asm/Kbuild                     |   4 +
 arch/parisc/kernel/vmlinux.lds.S                   |   1 -
 arch/powerpc/include/asm/Kbuild                    |   3 +
 arch/powerpc/include/asm/jump_label.h              |   8 +-
 arch/powerpc/include/asm/kprobes.h                 |   6 +
 arch/powerpc/include/asm/ppc_asm.h                 |   7 +-
 arch/powerpc/kernel/vmlinux.lds.S                  |   1 -
 arch/s390/include/asm/Kbuild                       |   3 +
 arch/s390/include/asm/jump_label.h                 |   6 +-
 arch/s390/include/asm/kprobes.h                    |   4 +
 arch/s390/kernel/entry.S                           |   5 +-
 arch/s390/kernel/kprobes.c                         |   6 +-
 arch/s390/kernel/mcount.S                          |   3 +-
 arch/s390/kernel/vmlinux.lds.S                     |   1 -
 arch/score/include/asm/Kbuild                      |   4 +
 arch/score/kernel/vmlinux.lds.S                    |   1 -
 arch/sh/include/asm/Kbuild                         |   3 +
 arch/sh/include/asm/kprobes.h                      |   2 +
 arch/sh/kernel/vmlinux.lds.S                       |   1 -
 arch/sparc/include/asm/Kbuild                      |   3 +
 arch/sparc/include/asm/jump_label.h                |   6 +-
 arch/sparc/include/asm/kprobes.h                   |   5 +
 arch/sparc/kernel/vmlinux.lds.S                    |   1 -
 arch/sparc/mm/ultra.S                              |   3 +-
 arch/tile/include/asm/Kbuild                       |   3 +
 arch/tile/include/asm/kprobes.h                    |   6 +-
 arch/tile/kernel/vmlinux.lds.S                     |   1 -
 arch/um/include/asm/Kbuild                         |   4 +
 arch/unicore32/include/asm/Kbuild                  |   3 +
 arch/unicore32/include/asm/section-core.h          |  19 +
 arch/x86/include/asm/Kbuild                        |   3 +
 arch/x86/include/asm/jump_label.h                  |  10 +-
 arch/x86/include/asm/kprobes.h                     |   6 +
 arch/x86/kernel/cpu/microcode/core.c               |   8 +-
 arch/x86/kernel/kprobes/core.c                     |  11 +-
 arch/x86/kernel/vmlinux.lds.S                      |   1 -
 arch/x86/tools/relocs.c                            |   4 +
 arch/xtensa/include/asm/Kbuild                     |   4 +
 arch/xtensa/kernel/Makefile                        |   8 +-
 drivers/base/firmware_class.c                      |  12 +-
 drivers/platform/x86/dell-smo8800.c                |   1 +
 firmware/Makefile                                  |   6 +-
 include/asm-generic/kprobes.h                      |  26 +
 include/asm-generic/ranges.h                       | 103 ++++
 include/asm-generic/section-core.h                 | 341 +++++++++++
 include/asm-generic/sections.h                     |   4 +-
 include/asm-generic/tables.h                       |  50 ++
 include/asm-generic/vmlinux.lds.h                  |  73 +--
 include/linux/compiler.h                           |   8 -
 include/linux/dynamic_debug.h                      |   5 +-
 include/linux/init.h                               |  20 +-
 include/linux/jump_label.h                         |   8 +-
 include/linux/kprobes.h                            |  24 +-
 include/linux/ranges.h                             | 128 +++++
 include/linux/sections.h                           | 111 ++++
 include/linux/tables.h                             | 638 +++++++++++++++++++++
 init/Kconfig                                       |  22 +
 kernel/jump_label.c                                |  17 +-
 kernel/kprobes.c                                   |  17 +-
 lib/dynamic_debug.c                                |  13 +-
 scripts/Makefile.build                             |   7 +-
 scripts/Makefile.clean                             |   2 +
 scripts/Makefile.lib                               |  11 +
 scripts/Makefile.modpost                           |   2 +-
 scripts/mod/modpost.c                              |   2 +-
 scripts/{module-common.lds => module-common.lds.S} |   6 +
 scripts/recordmcount.c                             |   2 +-
 scripts/recordmcount.pl                            |   2 +-
 tools/objtool/special.c                            |   2 +-
 133 files changed, 2328 insertions(+), 214 deletions(-)
 create mode 100644 Documentation/sections/conf.py
 create mode 100644 Documentation/sections/index.rst
 create mode 100644 Documentation/sections/linker-tables.rst
 create mode 100644 Documentation/sections/ranges.rst
 create mode 100644 Documentation/sections/section-core.rst
 create mode 100644 arch/c6x/include/asm/tables.h
 create mode 100644 arch/unicore32/include/asm/section-core.h
 create mode 100644 include/asm-generic/kprobes.h
 create mode 100644 include/asm-generic/ranges.h
 create mode 100644 include/asm-generic/section-core.h
 create mode 100644 include/asm-generic/tables.h
 create mode 100644 include/linux/ranges.h
 create mode 100644 include/linux/sections.h
 create mode 100644 include/linux/tables.h
 rename scripts/{module-common.lds => module-common.lds.S} (80%)

-- 
2.9.2


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH v4 01/16] x86: remove LTO_REFERENCE_INITCALL()
  2016-08-19 21:32 [PATCH v4 00/16] linux: generalize sections, ranges and linker tables mcgrof
  2016-08-19 21:32 ` mcgrof
@ 2016-08-19 21:32 ` mcgrof
  2016-08-19 21:32   ` mcgrof
  2016-08-19 21:32 ` [PATCH v4 02/16] dell-smo8800: include uaccess.h mcgrof
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: gnomes, linux-ia64, jkosina, benh, ming.lei, linux,
	platform-driver-x86, James.Bottomley, paul.gortmaker, paulus,
	sparclinux, mchehab, linux-arch, markus.heiser, xen-devel,
	msalter, linux-sh, mpe, x86, fontana, linux-arm-kernel,
	catalin.marinas, dvhart, dwmw2, linux-xtensa, pali.rohar,
	keescook, arnd, jani.nikula, will.deacon, rusty, rostedt, acme,
	ak, andriy.shevchenko, mcb30

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

The setup for LTO never made it upstream, and although this has
some users, this is now really old stuff for a gcc 4.7 LTO problem.
We know that at least LTO_REFERENCE_INITCALL() work around can
be removed if LTO is not supported on v4.7 anymore.

As per Andi the DISABLE_LTO and LTO_CFLAGS are still neeeded though.

v3: added to this series, removing LTO_REFERENCE_INITCALL()
    justifies that other future similar macros do not need
    a respective LTO_REFERENCE_INITCALL() on them therefore
    simplifying new code.

Acked-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 include/linux/init.h | 20 +-------------------
 1 file changed, 1 insertion(+), 19 deletions(-)

diff --git a/include/linux/init.h b/include/linux/init.h
index 1e5c131d5c9a..aa662ad80d9c 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -151,23 +151,6 @@ extern bool initcall_debug;
 
 #ifndef __ASSEMBLY__
 
-#ifdef CONFIG_LTO
-/* Work around a LTO gcc problem: when there is no reference to a variable
- * in a module it will be moved to the end of the program. This causes
- * reordering of initcalls which the kernel does not like.
- * Add a dummy reference function to avoid this. The function is
- * deleted by the linker.
- */
-#define LTO_REFERENCE_INITCALL(x) \
-	; /* yes this is needed */			\
-	static __used __exit void *reference_##x(void)	\
-	{						\
-		return &x;				\
-	}
-#else
-#define LTO_REFERENCE_INITCALL(x)
-#endif
-
 /* initcalls are now grouped by functionality into separate 
  * subsections. Ordering inside the subsections is determined
  * by link order. 
@@ -180,8 +163,7 @@ extern bool initcall_debug;
 
 #define __define_initcall(fn, id) \
 	static initcall_t __initcall_##fn##id __used \
-	__attribute__((__section__(".initcall" #id ".init"))) = fn; \
-	LTO_REFERENCE_INITCALL(__initcall_##fn##id)
+	__attribute__((__section__(".initcall" #id ".init"))) = fn;
 
 /*
  * Early initcalls run before initializing SMP.
-- 
2.9.2


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 01/16] x86: remove LTO_REFERENCE_INITCALL()
  2016-08-19 21:32 ` [PATCH v4 01/16] x86: remove LTO_REFERENCE_INITCALL() mcgrof
@ 2016-08-19 21:32   ` mcgrof
  0 siblings, 0 replies; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: x86, luto, keescook, torvalds, gregkh, rusty, gnomes, alan,
	dwmw2, arnd, ming.lei, linux-arch, benh, ananth, pebolle,
	fontana, david.vrabel, konrad.wilk, mcb30, jgross,
	andrew.cooper3, andriy.shevchenko, paul.gortmaker, xen-devel, ak,
	pali.rohar, dvhart, platform-driver-x86, mmarek, linux, jkosina,
	korea.drzix, linux-kbuild, tony.luck, akpm, linux-ia64,
	linux-arm-kernel, linux-sh, sparclinux, catalin.marinas,
	will.deacon, rostedt, jani.nikula, mchehab, markus.heiser, acme,
	jolsa, msalter, chris, jcmvbkbc, linux-xtensa, paulus, mpe,
	James.Bottomley, Luis R. Rodriguez

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

The setup for LTO never made it upstream, and although this has
some users, this is now really old stuff for a gcc 4.7 LTO problem.
We know that at least LTO_REFERENCE_INITCALL() work around can
be removed if LTO is not supported on v4.7 anymore.

As per Andi the DISABLE_LTO and LTO_CFLAGS are still neeeded though.

v3: added to this series, removing LTO_REFERENCE_INITCALL()
    justifies that other future similar macros do not need
    a respective LTO_REFERENCE_INITCALL() on them therefore
    simplifying new code.

Acked-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 include/linux/init.h | 20 +-------------------
 1 file changed, 1 insertion(+), 19 deletions(-)

diff --git a/include/linux/init.h b/include/linux/init.h
index 1e5c131d5c9a..aa662ad80d9c 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -151,23 +151,6 @@ extern bool initcall_debug;
 
 #ifndef __ASSEMBLY__
 
-#ifdef CONFIG_LTO
-/* Work around a LTO gcc problem: when there is no reference to a variable
- * in a module it will be moved to the end of the program. This causes
- * reordering of initcalls which the kernel does not like.
- * Add a dummy reference function to avoid this. The function is
- * deleted by the linker.
- */
-#define LTO_REFERENCE_INITCALL(x) \
-	; /* yes this is needed */			\
-	static __used __exit void *reference_##x(void)	\
-	{						\
-		return &x;				\
-	}
-#else
-#define LTO_REFERENCE_INITCALL(x)
-#endif
-
 /* initcalls are now grouped by functionality into separate 
  * subsections. Ordering inside the subsections is determined
  * by link order. 
@@ -180,8 +163,7 @@ extern bool initcall_debug;
 
 #define __define_initcall(fn, id) \
 	static initcall_t __initcall_##fn##id __used \
-	__attribute__((__section__(".initcall" #id ".init"))) = fn; \
-	LTO_REFERENCE_INITCALL(__initcall_##fn##id)
+	__attribute__((__section__(".initcall" #id ".init"))) = fn;
 
 /*
  * Early initcalls run before initializing SMP.
-- 
2.9.2


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 02/16] dell-smo8800: include uaccess.h
  2016-08-19 21:32 [PATCH v4 00/16] linux: generalize sections, ranges and linker tables mcgrof
  2016-08-19 21:32 ` mcgrof
  2016-08-19 21:32 ` [PATCH v4 01/16] x86: remove LTO_REFERENCE_INITCALL() mcgrof
@ 2016-08-19 21:32 ` mcgrof
  2016-08-19 21:32   ` mcgrof
  2016-08-19 21:32 ` [PATCH v4 03/16] scripts/module-common.lds: enable generation mcgrof
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: gnomes, linux-ia64, jkosina, benh, ming.lei, linux,
	platform-driver-x86, James.Bottomley, paul.gortmaker, paulus,
	sparclinux, mchehab, linux-arch, markus.heiser, xen-devel,
	msalter, linux-sh, mpe, x86, fontana, linux-arm-kernel,
	catalin.marinas, dvhart, dwmw2, linux-xtensa, pali.rohar,
	keescook, arnd, jani.nikula, will.deacon, rusty, rostedt, acme,
	ak, andriy.shevchenko, mcb30

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

sections.h is currently included and it provides dell-smo8800
with what it needs, an upcoming change will decouple uaccess.h
from sections.h. This driver needs to explicitly require uaccess.h
before this change.

v3: new to this series -- needed due to collateral of the split of
    old linker tables from tables.h into 3 files: sections.h, ranges.h
    and tables.h

Reviewed-by: Pali Rohár <pali.rohar@gmail.com>
Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 drivers/platform/x86/dell-smo8800.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/platform/x86/dell-smo8800.c b/drivers/platform/x86/dell-smo8800.c
index 0aec4fd4c48e..37e646034ef8 100644
--- a/drivers/platform/x86/dell-smo8800.c
+++ b/drivers/platform/x86/dell-smo8800.c
@@ -24,6 +24,7 @@
 #include <linux/acpi.h>
 #include <linux/interrupt.h>
 #include <linux/miscdevice.h>
+#include <linux/uaccess.h>
 
 struct smo8800_device {
 	u32 irq;                     /* acpi device irq */
-- 
2.9.2


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 02/16] dell-smo8800: include uaccess.h
  2016-08-19 21:32 ` [PATCH v4 02/16] dell-smo8800: include uaccess.h mcgrof
@ 2016-08-19 21:32   ` mcgrof
  0 siblings, 0 replies; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: x86, luto, keescook, torvalds, gregkh, rusty, gnomes, alan,
	dwmw2, arnd, ming.lei, linux-arch, benh, ananth, pebolle,
	fontana, david.vrabel, konrad.wilk, mcb30, jgross,
	andrew.cooper3, andriy.shevchenko, paul.gortmaker, xen-devel, ak,
	pali.rohar, dvhart, platform-driver-x86, mmarek, linux, jkosina,
	korea.drzix, linux-kbuild, tony.luck, akpm, linux-ia64,
	linux-arm-kernel, linux-sh, sparclinux, catalin.marinas,
	will.deacon, rostedt, jani.nikula, mchehab, markus.heiser, acme,
	jolsa, msalter, chris, jcmvbkbc, linux-xtensa, paulus, mpe,
	James.Bottomley, Luis R. Rodriguez

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

sections.h is currently included and it provides dell-smo8800
with what it needs, an upcoming change will decouple uaccess.h
from sections.h. This driver needs to explicitly require uaccess.h
before this change.

v3: new to this series -- needed due to collateral of the split of
    old linker tables from tables.h into 3 files: sections.h, ranges.h
    and tables.h

Reviewed-by: Pali Rohár <pali.rohar@gmail.com>
Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 drivers/platform/x86/dell-smo8800.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/platform/x86/dell-smo8800.c b/drivers/platform/x86/dell-smo8800.c
index 0aec4fd4c48e..37e646034ef8 100644
--- a/drivers/platform/x86/dell-smo8800.c
+++ b/drivers/platform/x86/dell-smo8800.c
@@ -24,6 +24,7 @@
 #include <linux/acpi.h>
 #include <linux/interrupt.h>
 #include <linux/miscdevice.h>
+#include <linux/uaccess.h>
 
 struct smo8800_device {
 	u32 irq;                     /* acpi device irq */
-- 
2.9.2


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 03/16] scripts/module-common.lds: enable generation
  2016-08-19 21:32 [PATCH v4 00/16] linux: generalize sections, ranges and linker tables mcgrof
                   ` (2 preceding siblings ...)
  2016-08-19 21:32 ` [PATCH v4 02/16] dell-smo8800: include uaccess.h mcgrof
@ 2016-08-19 21:32 ` mcgrof
  2016-08-19 21:32   ` mcgrof
  2016-08-19 21:32 ` [PATCH v4 04/16] generic-sections: add section core helpers mcgrof
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: gnomes, linux-ia64, jkosina, benh, ming.lei, linux,
	platform-driver-x86, James.Bottomley, paul.gortmaker, paulus,
	sparclinux, mchehab, linux-arch, markus.heiser, xen-devel,
	msalter, linux-sh, mpe, x86, fontana, linux-arm-kernel,
	catalin.marinas, dvhart, dwmw2, linux-xtensa, pali.rohar,
	keescook, arnd, jani.nikula, will.deacon, rusty, rostedt, acme,
	ak, andriy.shevchenko, mcb30

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

scripts/module-common.lds is currently pretty static, in the
future this may change and we will want access to kernel macros
to help expands certain areas. To get access to use macros we
need to generate module-common.lds from module-common.lds.S, for
now though only enable the generation. We'll later expand on this
as needed.

Since this file is now generated add it to .gitignore.

v4: add file to MAINTAINERS
v3: new to this series

Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 .gitignore                                         | 2 ++
 MAINTAINERS                                        | 1 +
 Makefile                                           | 6 +++++-
 scripts/Makefile.modpost                           | 2 +-
 scripts/{module-common.lds => module-common.lds.S} | 0
 5 files changed, 9 insertions(+), 2 deletions(-)
 rename scripts/{module-common.lds => module-common.lds.S} (100%)

diff --git a/.gitignore b/.gitignore
index c2ed4ecb0acd..0f0702054fdb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -114,3 +114,5 @@ all.config
 
 # Kdevelop4
 *.kdev4
+
+scripts/module-common.lds
diff --git a/MAINTAINERS b/MAINTAINERS
index d635ab047f3a..5aec01883020 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7887,6 +7887,7 @@ M:	Rusty Russell <rusty@rustcorp.com.au>
 S:	Maintained
 F:	include/linux/module.h
 F:	kernel/module.c
+F:	scripts/module-common.lds.S
 
 MOTION EYE VAIO PICTUREBOOK CAMERA DRIVER
 W:	http://popies.net/meye/
diff --git a/Makefile b/Makefile
index 5c18baad7218..b3e5ea78d582 100644
--- a/Makefile
+++ b/Makefile
@@ -408,6 +408,10 @@ KBUILD_AFLAGS_MODULE  := -DMODULE
 KBUILD_CFLAGS_MODULE  := -DMODULE
 KBUILD_LDFLAGS_MODULE := -T $(srctree)/scripts/module-common.lds
 
+$(srctree)/scripts/module-common.lds: $(srctree)/scripts/module-common.lds.S
+	$(Q)$(CC) $(CFLAGS) $(INCLUDES) $(LINUXINCLUDE) -E -P \
+		-D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $<
+
 # Read KERNELRELEASE from include/config/kernel.release (if it exists)
 KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
 KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)
@@ -1174,7 +1178,7 @@ all: modules
 # using awk while concatenating to the final file.
 
 PHONY += modules
-modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin
+modules: $(srctree)/scripts/module-common.lds $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin
 	$(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order
 	@$(kecho) '  Building modules, stage 2.';
 	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 1366a94b6c39..2d8aff7735d6 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -121,7 +121,7 @@ quiet_cmd_ld_ko_o = LD [M]  $@
                              $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
                              -o $@ $(filter-out FORCE,$^)
 
-$(modules): %.ko :%.o %.mod.o FORCE
+$(modules): %.ko : $(srctree)/scripts/module-common.lds %.o %.mod.o FORCE
 	$(call if_changed,ld_ko_o)
 
 targets += $(modules)
diff --git a/scripts/module-common.lds b/scripts/module-common.lds.S
similarity index 100%
rename from scripts/module-common.lds
rename to scripts/module-common.lds.S
-- 
2.9.2


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 03/16] scripts/module-common.lds: enable generation
  2016-08-19 21:32 ` [PATCH v4 03/16] scripts/module-common.lds: enable generation mcgrof
@ 2016-08-19 21:32   ` mcgrof
  0 siblings, 0 replies; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: x86, luto, keescook, torvalds, gregkh, rusty, gnomes, alan,
	dwmw2, arnd, ming.lei, linux-arch, benh, ananth, pebolle,
	fontana, david.vrabel, konrad.wilk, mcb30, jgross,
	andrew.cooper3, andriy.shevchenko, paul.gortmaker, xen-devel, ak,
	pali.rohar, dvhart, platform-driver-x86, mmarek, linux, jkosina,
	korea.drzix, linux-kbuild, tony.luck, akpm, linux-ia64,
	linux-arm-kernel, linux-sh, sparclinux, catalin.marinas,
	will.deacon, rostedt, jani.nikula, mchehab, markus.heiser, acme,
	jolsa, msalter, chris, jcmvbkbc, linux-xtensa, paulus, mpe,
	James.Bottomley, Luis R. Rodriguez

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

scripts/module-common.lds is currently pretty static, in the
future this may change and we will want access to kernel macros
to help expands certain areas. To get access to use macros we
need to generate module-common.lds from module-common.lds.S, for
now though only enable the generation. We'll later expand on this
as needed.

Since this file is now generated add it to .gitignore.

v4: add file to MAINTAINERS
v3: new to this series

Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 .gitignore                                         | 2 ++
 MAINTAINERS                                        | 1 +
 Makefile                                           | 6 +++++-
 scripts/Makefile.modpost                           | 2 +-
 scripts/{module-common.lds => module-common.lds.S} | 0
 5 files changed, 9 insertions(+), 2 deletions(-)
 rename scripts/{module-common.lds => module-common.lds.S} (100%)

diff --git a/.gitignore b/.gitignore
index c2ed4ecb0acd..0f0702054fdb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -114,3 +114,5 @@ all.config
 
 # Kdevelop4
 *.kdev4
+
+scripts/module-common.lds
diff --git a/MAINTAINERS b/MAINTAINERS
index d635ab047f3a..5aec01883020 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7887,6 +7887,7 @@ M:	Rusty Russell <rusty@rustcorp.com.au>
 S:	Maintained
 F:	include/linux/module.h
 F:	kernel/module.c
+F:	scripts/module-common.lds.S
 
 MOTION EYE VAIO PICTUREBOOK CAMERA DRIVER
 W:	http://popies.net/meye/
diff --git a/Makefile b/Makefile
index 5c18baad7218..b3e5ea78d582 100644
--- a/Makefile
+++ b/Makefile
@@ -408,6 +408,10 @@ KBUILD_AFLAGS_MODULE  := -DMODULE
 KBUILD_CFLAGS_MODULE  := -DMODULE
 KBUILD_LDFLAGS_MODULE := -T $(srctree)/scripts/module-common.lds
 
+$(srctree)/scripts/module-common.lds: $(srctree)/scripts/module-common.lds.S
+	$(Q)$(CC) $(CFLAGS) $(INCLUDES) $(LINUXINCLUDE) -E -P \
+		-D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $<
+
 # Read KERNELRELEASE from include/config/kernel.release (if it exists)
 KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
 KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)
@@ -1174,7 +1178,7 @@ all: modules
 # using awk while concatenating to the final file.
 
 PHONY += modules
-modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin
+modules: $(srctree)/scripts/module-common.lds $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin
 	$(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order
 	@$(kecho) '  Building modules, stage 2.';
 	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 1366a94b6c39..2d8aff7735d6 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -121,7 +121,7 @@ quiet_cmd_ld_ko_o = LD [M]  $@
                              $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
                              -o $@ $(filter-out FORCE,$^)
 
-$(modules): %.ko :%.o %.mod.o FORCE
+$(modules): %.ko : $(srctree)/scripts/module-common.lds %.o %.mod.o FORCE
 	$(call if_changed,ld_ko_o)
 
 targets += $(modules)
diff --git a/scripts/module-common.lds b/scripts/module-common.lds.S
similarity index 100%
rename from scripts/module-common.lds
rename to scripts/module-common.lds.S
-- 
2.9.2


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 04/16] generic-sections: add section core helpers
  2016-08-19 21:32 [PATCH v4 00/16] linux: generalize sections, ranges and linker tables mcgrof
                   ` (3 preceding siblings ...)
  2016-08-19 21:32 ` [PATCH v4 03/16] scripts/module-common.lds: enable generation mcgrof
@ 2016-08-19 21:32 ` mcgrof
  2016-08-19 21:32   ` mcgrof
  2016-08-19 21:47   ` Kees Cook
  2016-08-19 21:32 ` [PATCH v4 05/16] xtensa: skip adding literal when SORT() is used mcgrof
                   ` (6 subsequent siblings)
  11 siblings, 2 replies; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: gnomes, linux-ia64, jkosina, benh, ming.lei, linux,
	platform-driver-x86, James.Bottomley, paul.gortmaker, paulus,
	sparclinux, mchehab, linux-arch, markus.heiser, xen-devel,
	msalter, linux-sh, mpe, x86, fontana, linux-arm-kernel,
	catalin.marinas, dvhart, dwmw2, linux-xtensa, pali.rohar,
	keescook, arnd, jani.nikula, will.deacon, rusty, rostedt, acme,
	ak, andriy.shevchenko, mcb30

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

Linux makes extensive use of custom ELF header sections,
documentation for these are well scatterred. Unify this
documentation in a central place and provide helpers to
build custom Linux sections.

This also generalizes sections code to enable avoiding
modifying the linker scripts when we want to add new
custom Linux sections. In order to make this generally
useful we need to ensure all architectures can make use of
core section helpers but that they can also override should
this be needed. Instead of relying on section.h this adds
a sections-core.h since this will be targetted to be safe
to be used on asm code, linker scripts and C code.

v4:

o Port to shiny new sphinx documentation format

o fix a unicore32 build, turns out this actually fixes unicore32
  defconfig builds which were failing for a long while. unicore32
  does not seem to grok well the type passed on a section declaration,
  this ignores it.

o Use VMLINUX_SYMBOL() in more user symbols (extern C code), not doing
  this was causing final linker issues with blackfin -- this is
  a CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX=y architecture. The other one
  being metatag. metatag is not supported on 0-day so I cannot confirm
  compilation there.

o Added SECTION_CORE() for C code, used later by __LINUX_RANGE()

o Since SECTION_CORE() is defined for linker script and C code, share
  the same helper and just use a __stringify() for the C code as is done
  for the other C helpers.

o move generic sections to asm-generic/section-core.h instead.
  PowerPC compilation blows up if asm/jump_labels.h gets
  section.h included, fixing this is not in any way easy.
  The list of issues are endless. Moving new data to a new
  simple file resolves this.

o since things are now in asm-generic/section-core.h the
  guard changes on asm-generic/sections.h and each architecture
  sections.h are no longer needed

o Give generic sections some maintainer love, that change is
  Acked-by Arnd Bergmann, Josh and hpa.

o A few checkpatch.pl style fixes

o As suggested by James Hogan use generic-y to copy generic
  header files on architectures that do not have a sections.h
  instead of writing a simple file only to include the generic one.

v3:

o add missing sections.h for architectures that did not
  have it

o move generic sections to asm-generic/sections.h

o add generic asm helpers section_type(), section_type_asmtype(),
  push_section_type() -- these helpers enable easy use for
  for later declaring and using of custom linux sections using
  more standard APIs in both C code, asm code (C asm calls, or
  asm files), enabling future standardized section types to
  be more immediately accessible to asm code, not just C code.
  Note for ASM_CMD_SEP we use by default "\n", architectures needed
  to override can do so on their own sections.h prior to inclusion
  of asm-generic/sections.h

Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 Documentation/index.rst                   |   1 +
 Documentation/sections/conf.py            |   4 +
 Documentation/sections/index.rst          |  11 +
 Documentation/sections/section-core.rst   | 153 ++++++++++++++
 MAINTAINERS                               |  14 ++
 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/Kbuild               |   1 +
 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/section-core.h |  19 ++
 arch/x86/include/asm/Kbuild               |   1 +
 arch/xtensa/include/asm/Kbuild            |   1 +
 include/asm-generic/section-core.h        | 341 ++++++++++++++++++++++++++++++
 include/asm-generic/sections.h            |   2 +
 include/asm-generic/vmlinux.lds.h         |  27 +--
 include/linux/sections.h                  | 111 ++++++++++
 40 files changed, 700 insertions(+), 13 deletions(-)
 create mode 100644 Documentation/sections/conf.py
 create mode 100644 Documentation/sections/index.rst
 create mode 100644 Documentation/sections/section-core.rst
 create mode 100644 arch/unicore32/include/asm/section-core.h
 create mode 100644 include/asm-generic/section-core.h
 create mode 100644 include/linux/sections.h

diff --git a/Documentation/index.rst b/Documentation/index.rst
index a15f81855b39..10c9b867e326 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -14,6 +14,7 @@ Contents:
    kernel-documentation
    media/index
    gpu/index
+   sections/index
 
 Indices and tables
 ==================
diff --git a/Documentation/sections/conf.py b/Documentation/sections/conf.py
new file mode 100644
index 000000000000..faa1c57595e1
--- /dev/null
+++ b/Documentation/sections/conf.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8; mode: python -*-
+
+project = 'Linux Kernel ELF sections'
+html_search_language = 'en'
diff --git a/Documentation/sections/index.rst b/Documentation/sections/index.rst
new file mode 100644
index 000000000000..d411e9b22eb3
--- /dev/null
+++ b/Documentation/sections/index.rst
@@ -0,0 +1,11 @@
+=========================
+Linux Kernel ELF sections
+=========================
+
+This book documents the Linux kernel's use of ELF sections, as well as helpers
+used throughout the kernel to help declare and define them.
+
+.. toctree::
+   :maxdepth: 4
+
+   section-core
diff --git a/Documentation/sections/section-core.rst b/Documentation/sections/section-core.rst
new file mode 100644
index 000000000000..ecf4228bc4f8
--- /dev/null
+++ b/Documentation/sections/section-core.rst
@@ -0,0 +1,153 @@
+==============================
+Core Linux kernel ELF sections
+==============================
+
+About
+=====
+
+This book documents the different standard and custom ELF sections used
+on the Linux kernel, which we refer to as the ``core Linux sections``. We
+start off by documenting the standard ELF sections used by Linux and move
+on to the basic custom ELF sections, followed by a set of helpers. Each
+section documented describes the goal of the section, and addresses
+concurrency considerations when applicable.
+
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: Custom linker script
+
+Standard ELF section use in Linux
+=================================
+
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: Standard ELF section use in Linux
+
+SECTION_RODATA
+--------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_RODATA
+
+SECTION_RODATA
+--------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_TEXT
+
+SECTION_DATA
+------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_DATA
+
+Linux .init\* sections
+======================
+
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: Linux init sections
+
+SECTION_INIT_DATA
+-----------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_INIT_DATA
+
+SECTION_INIT_RODATA
+-------------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_INIT_RODATA
+
+SECTION_INIT_CALL
+-----------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_INIT_CALL
+
+Linux .exit\* sections
+======================
+
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: Linux exit sections
+
+SECTION_EXIT
+------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_EXIT
+
+SECTION_EXIT_DATA
+-----------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_EXIT_DATA
+
+SECTION_EXIT_CALL
+-----------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_EXIT_CALL
+
+Linux .ref\* sections
+=====================
+
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: Linux references to init sections
+
+SECTION_REF
+-----------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_REF
+
+SECTION_REF_DATA
+----------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_REF_DATA
+
+SECTION_REF_RODATA
+------------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_REF_RODATA
+
+Linux section ordering
+======================
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: Linux section ordering
+
+SECTION_ORDER_ANY
+-----------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_ORDER_ANY
+
+Generic Linux kernel section helpers
+====================================
+
+Introduction
+-------------
+.. kernel-doc:: include/linux/sections.h
+   :doc: Introduction
+
+LINUX_SECTION_ALIGNMENT
+-----------------------
+.. kernel-doc:: include/linux/sections.h
+   :functions: LINUX_SECTION_ALIGNMENT
+
+LINUX_SECTION_SIZE
+------------------
+.. kernel-doc:: include/linux/sections.h
+   :functions: LINUX_SECTION_SIZE
+
+LINUX_SECTION_EMPTY
+-------------------
+.. kernel-doc:: include/linux/sections.h
+   :functions: LINUX_SECTION_EMPTY
+
+LINUX_SECTION_START
+-------------------
+.. kernel-doc:: include/linux/sections.h
+   :functions: LINUX_SECTION_START
+
+LINUX_SECTION_END
+-----------------
+.. kernel-doc:: include/linux/sections.h
+   :functions: LINUX_SECTION_END
+
+DECLARE_LINUX_SECTION
+---------------------
+.. kernel-doc:: include/linux/sections.h
+   :functions: DECLARE_LINUX_SECTION
+
+DECLARE_LINUX_SECTION_RO
+------------------------
+.. kernel-doc:: include/linux/sections.h
+   :functions: DECLARE_LINUX_SECTION_RO
diff --git a/MAINTAINERS b/MAINTAINERS
index 5aec01883020..689c12075842 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5217,6 +5217,20 @@ S:	Supported
 F:	drivers/base/power/domain*.c
 F:	include/linux/pm_domain.h
 
+GENERIC SECTIONS
+M:	"Luis R. Rodriguez" <mcgrof@kernel.org>
+M:	Josh Poimboeuf <jpoimboe@redhat.com>
+M:	"H. Peter Anvin" <hpa@zytor.com>
+L:	linux-arch@vger.kernel.org
+L:	linux-kernel@vger.kernel.org
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux.git for-arnd
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux-next.git for-arnd
+S:	Supported
+F:	include/asm-generic/section-core.h
+F:	include/asm-generic/sections.h
+F:	include/asm-generic/vmlinux.lds.h
+F:	Documentation/sections/section-core.rst
+
 GENERIC UIO DRIVER FOR PCI DEVICES
 M:	"Michael S. Tsirkin" <mst@redhat.com>
 L:	kvm@vger.kernel.org
diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild
index bf8475ce85ee..5422827f1585 100644
--- a/arch/alpha/include/asm/Kbuild
+++ b/arch/alpha/include/asm/Kbuild
@@ -10,3 +10,4 @@ generic-y += mm-arch-hooks.h
 generic-y += preempt.h
 generic-y += sections.h
 generic-y += trace_clock.h
+generic-y += section-core.h
diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild
index 0b10ef2a4372..9a0929576de1 100644
--- a/arch/arc/include/asm/Kbuild
+++ b/arch/arc/include/asm/Kbuild
@@ -50,3 +50,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
index 0745538b26d3..47923635be16 100644
--- a/arch/arm/include/asm/Kbuild
+++ b/arch/arm/include/asm/Kbuild
@@ -39,3 +39,4 @@ generic-y += termios.h
 generic-y += timex.h
 generic-y += trace_clock.h
 generic-y += unaligned.h
+generic-y += section-core.h
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index f43d2c44c765..42d00806e4fb 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -52,3 +52,4 @@ generic-y += unaligned.h
 generic-y += user.h
 generic-y += vga.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/avr32/include/asm/Kbuild b/arch/avr32/include/asm/Kbuild
index 241b9b9729d8..f2c3b656a0e7 100644
--- a/arch/avr32/include/asm/Kbuild
+++ b/arch/avr32/include/asm/Kbuild
@@ -22,3 +22,4 @@ generic-y += trace_clock.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/blackfin/include/asm/Kbuild b/arch/blackfin/include/asm/Kbuild
index 91d49c0a3118..7de674411bed 100644
--- a/arch/blackfin/include/asm/Kbuild
+++ b/arch/blackfin/include/asm/Kbuild
@@ -48,3 +48,4 @@ generic-y += unaligned.h
 generic-y += user.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild
index 64465e7e2245..38127ce747be 100644
--- a/arch/c6x/include/asm/Kbuild
+++ b/arch/c6x/include/asm/Kbuild
@@ -62,3 +62,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild
index 1778805f6380..385cd88a9d9e 100644
--- a/arch/cris/include/asm/Kbuild
+++ b/arch/cris/include/asm/Kbuild
@@ -45,3 +45,4 @@ generic-y += types.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/frv/include/asm/Kbuild b/arch/frv/include/asm/Kbuild
index 1fa084cf1a43..46d7c599d9b8 100644
--- a/arch/frv/include/asm/Kbuild
+++ b/arch/frv/include/asm/Kbuild
@@ -8,3 +8,4 @@ generic-y += mm-arch-hooks.h
 generic-y += preempt.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
+generic-y += section-core.h
diff --git a/arch/h8300/include/asm/Kbuild b/arch/h8300/include/asm/Kbuild
index 373cb23301e3..1ec04ec1c82b 100644
--- a/arch/h8300/include/asm/Kbuild
+++ b/arch/h8300/include/asm/Kbuild
@@ -75,3 +75,4 @@ generic-y += unaligned.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild
index db8ddabc6bd2..37d7bfae7619 100644
--- a/arch/hexagon/include/asm/Kbuild
+++ b/arch/hexagon/include/asm/Kbuild
@@ -60,3 +60,4 @@ generic-y += unaligned.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild
index 502a91d8dbbd..672c6d5da18c 100644
--- a/arch/ia64/include/asm/Kbuild
+++ b/arch/ia64/include/asm/Kbuild
@@ -9,3 +9,4 @@ generic-y += preempt.h
 generic-y += trace_clock.h
 generic-y += vtime.h
 generic-y += word-at-a-time.h
+generic-y += section-core.h
diff --git a/arch/m32r/include/asm/Kbuild b/arch/m32r/include/asm/Kbuild
index 860e440611c9..6111e1523750 100644
--- a/arch/m32r/include/asm/Kbuild
+++ b/arch/m32r/include/asm/Kbuild
@@ -11,3 +11,4 @@ generic-y += preempt.h
 generic-y += sections.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
+generic-y += section-core.h
diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild
index eb85bd9c6180..eef72c464c9b 100644
--- a/arch/m68k/include/asm/Kbuild
+++ b/arch/m68k/include/asm/Kbuild
@@ -35,3 +35,4 @@ generic-y += trace_clock.h
 generic-y += types.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/metag/include/asm/Kbuild b/arch/metag/include/asm/Kbuild
index 29acb89daaaa..50ebd5a30d16 100644
--- a/arch/metag/include/asm/Kbuild
+++ b/arch/metag/include/asm/Kbuild
@@ -56,3 +56,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild
index b0ae88c9fed9..c6c2cf6edc98 100644
--- a/arch/microblaze/include/asm/Kbuild
+++ b/arch/microblaze/include/asm/Kbuild
@@ -11,3 +11,4 @@ generic-y += preempt.h
 generic-y += syscalls.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
+generic-y += section-core.h
diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild
index 9740066cc631..12f7c5984c03 100644
--- a/arch/mips/include/asm/Kbuild
+++ b/arch/mips/include/asm/Kbuild
@@ -20,3 +20,4 @@ generic-y += trace_clock.h
 generic-y += user.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/mn10300/include/asm/Kbuild b/arch/mn10300/include/asm/Kbuild
index 1c8dd0f5cd5d..f8145bc85835 100644
--- a/arch/mn10300/include/asm/Kbuild
+++ b/arch/mn10300/include/asm/Kbuild
@@ -10,3 +10,4 @@ generic-y += preempt.h
 generic-y += sections.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
+generic-y += section-core.h
diff --git a/arch/nios2/include/asm/Kbuild b/arch/nios2/include/asm/Kbuild
index d63330e88379..c9c7cb82b00f 100644
--- a/arch/nios2/include/asm/Kbuild
+++ b/arch/nios2/include/asm/Kbuild
@@ -63,3 +63,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild
index 2832f031fb11..86175e701869 100644
--- a/arch/openrisc/include/asm/Kbuild
+++ b/arch/openrisc/include/asm/Kbuild
@@ -71,3 +71,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild
index f9b3a81aefcd..6f43f33f0e0f 100644
--- a/arch/parisc/include/asm/Kbuild
+++ b/arch/parisc/include/asm/Kbuild
@@ -29,3 +29,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild
index ab9f4e0ed4cf..b49fab7bab2f 100644
--- a/arch/powerpc/include/asm/Kbuild
+++ b/arch/powerpc/include/asm/Kbuild
@@ -7,3 +7,4 @@ generic-y += mcs_spinlock.h
 generic-y += preempt.h
 generic-y += rwsem.h
 generic-y += vtime.h
+generic-y += section-core.h
diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild
index 20f196b82a6e..89e74b59f32d 100644
--- a/arch/s390/include/asm/Kbuild
+++ b/arch/s390/include/asm/Kbuild
@@ -8,3 +8,4 @@ generic-y += mm-arch-hooks.h
 generic-y += preempt.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
+generic-y += section-core.h
diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild
index a05218ff3fe4..f089a264cd38 100644
--- a/arch/score/include/asm/Kbuild
+++ b/arch/score/include/asm/Kbuild
@@ -14,3 +14,4 @@ generic-y += trace_clock.h
 generic-y += xor.h
 generic-y += serial.h
 generic-y += word-at-a-time.h
+generic-y += section-core.h
diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild
index 751c3373a92c..7b0356dca562 100644
--- a/arch/sh/include/asm/Kbuild
+++ b/arch/sh/include/asm/Kbuild
@@ -39,3 +39,4 @@ generic-y += termios.h
 generic-y += trace_clock.h
 generic-y += ucontext.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild
index cfc918067f80..d51b84d6b4b7 100644
--- a/arch/sparc/include/asm/Kbuild
+++ b/arch/sparc/include/asm/Kbuild
@@ -22,3 +22,4 @@ generic-y += serial.h
 generic-y += trace_clock.h
 generic-y += types.h
 generic-y += word-at-a-time.h
+generic-y += section-core.h
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild
index ba35c41c71ff..7b8a652e43ae 100644
--- a/arch/tile/include/asm/Kbuild
+++ b/arch/tile/include/asm/Kbuild
@@ -41,3 +41,4 @@ generic-y += termios.h
 generic-y += trace_clock.h
 generic-y += types.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild
index 904f3ebf4220..e9849834d55e 100644
--- a/arch/um/include/asm/Kbuild
+++ b/arch/um/include/asm/Kbuild
@@ -27,3 +27,4 @@ generic-y += topology.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/unicore32/include/asm/section-core.h b/arch/unicore32/include/asm/section-core.h
new file mode 100644
index 000000000000..ebffeed8835d
--- /dev/null
+++ b/arch/unicore32/include/asm/section-core.h
@@ -0,0 +1,19 @@
+#ifndef __UNICORE_SECTION_CORE_ASM_H__
+#define __UNICORE_SECTION_CORE_ASM_H__
+/*
+ * Copyright (C) 2016 Luis R. Rodriguez <mcgrof@kernel.org>
+ *
+ * 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/.
+ */
+
+/* Unicore32 has known to not work properly with the type set, so ignore it */
+
+#define __set_section_core_type(___section, ___core, ___name,		\
+				___level, ___flags, ___type)		\
+	.section ___section.___core.___name.___level, ___flags
+
+#include <asm-generic/section-core.h>
+
+#endif /* __UNICORE_SECTION_CORE_ASM_H__ */
diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild
index 2cfed174e3c9..f6914a57bc16 100644
--- a/arch/x86/include/asm/Kbuild
+++ b/arch/x86/include/asm/Kbuild
@@ -16,3 +16,4 @@ generic-y += dma-contiguous.h
 generic-y += early_ioremap.h
 generic-y += mcs_spinlock.h
 generic-y += mm-arch-hooks.h
+generic-y += section-core.h
diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild
index 28cf4c5d65ef..81ca6816bd72 100644
--- a/arch/xtensa/include/asm/Kbuild
+++ b/arch/xtensa/include/asm/Kbuild
@@ -31,3 +31,4 @@ generic-y += topology.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/include/asm-generic/section-core.h b/include/asm-generic/section-core.h
new file mode 100644
index 000000000000..2ab57e2c4117
--- /dev/null
+++ b/include/asm-generic/section-core.h
@@ -0,0 +1,341 @@
+#ifndef _ASM_GENERIC_SECTION_CORE_H_
+#define _ASM_GENERIC_SECTION_CORE_H_
+/*
+ * Linux section core definitions
+ *
+ * Copyright (C) 2016 Luis R. Rodriguez <mcgrof@kernel.org>
+ *
+ * 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/.
+ */
+
+/**
+ * DOC: Custom linker script
+ *
+ * The Linux vmlinux binary uses a custom linker script on each architecture
+ * which it uses to strategically place standard ELF sections and also adds
+ * custom specialized ELF sections. Each architecture defines its own custom
+ * linker defined in arch/$(ARCH)/kernel/vmlinux.lds.S -- these in turn
+ * include and use definitions in include/asm-generic/vmlinux.lds.h as well
+ * as some helpers documented in this chaper.
+ */
+
+/**
+ * DOC: Standard ELF section use in Linux
+ *
+ * Linux makes use of the standard ELF sections, this sections documents
+ * these.
+ */
+
+/**
+ * DOC: SECTION_RODATA
+ *
+ * Macro name for code which must be protected from write access, read only
+ * data.
+ */
+#define SECTION_RODATA			.rodata
+
+/**
+ * DOC: SECTION_TEXT
+ *
+ * Macro name used to annotate code (functions) used during regular
+ * kernel run time. This is combined with `SECTION_RODATA`, only this
+ * section also allows for execution.
+ *
+ */
+#define SECTION_TEXT			.text
+
+/**
+ * DOC: SECTION_DATA
+ *
+ * Macro name for read-write data.
+ */
+#define SECTION_DATA			.data
+
+/**
+ * DOC: Linux init sections
+ *
+ * These sections are used for code and data structures used during boot or
+ * module initialization. On architectures that support it (x86, x86_64), all
+ * this code is freed up by the kernel right before the fist userspace init
+ * process is called when built-in to the kernel, and if modular it is freed
+ * after module initialization. Since the code is freed so early, in theory
+ * there should be no races against freeing this code with other CPUs. Init
+ * section code and data structures should never be exported with
+ * EXPORT_SYMBOL*() as the code will quickly become unavailable to the kernel
+ * after bootup.
+ */
+
+/**
+ * DOC: SECTION_INIT
+ *
+ * Macro name used to annotate code (functions) used only during boot or driver
+ * initialization.
+ *
+ */
+#define SECTION_INIT			.init.text
+
+/**
+ * DOC: SECTION_INIT_DATA
+ *
+ * Macro name used to annotate data structures used only during boot or driver
+ * initialization.
+ */
+#define SECTION_INIT_DATA		.init.data
+
+/**
+ * DOC: SECTION_INIT_RODATA
+ *
+ * Macro name used to annotate read-only code (functions) used only during boot
+ * or driver initialization.
+ */
+#define SECTION_INIT_RODATA		.init.rodata
+
+/**
+ * DOC: SECTION_INIT_CALL
+ *
+ * Special macro name used to annotate subsystem init call. These calls are
+ * are now grouped by functionality into separate subsections. Ordering inside
+ * the subsections is determined by link order.
+ */
+#define SECTION_INIT_CALL		.initcall
+
+/**
+ * DOC: Linux exit sections
+ *
+ * These sections are used to declare a functions and data structures which
+ * are only required on exit, the function or data structure will be dropped
+ * if the code declaring this section is not compiled as a module on
+ * architectures that support this (x86, x86_64). There is no special case
+ * handling for this code when built-in to the kernel.
+ */
+
+/**
+ * DOC: SECTION_EXIT
+ *
+ * Macro name used to annotate code (functions) used only during module
+ * unload.
+ */
+#define SECTION_EXIT			.exit.text
+
+/**
+ * DOC: SECTION_EXIT_DATA
+ *
+ * Macro name used to annotate data structures used only during module
+ * unload.
+ */
+#define SECTION_EXIT_DATA		.exit.data
+
+/**
+ * DOC: SECTION_EXIT_CALL
+ *
+ * Special macro name used to annotate an exit exit routine, order
+ * is important and maintained by link order.
+ */
+#define SECTION_EXIT_CALL		.exitcall.exit
+
+/**
+ * DOC: Linux references to init sections
+ *
+ * These sections are used to teach modpost to not warn about possible
+ * misuses of init section code from other sections. If you use this
+ * your use case should document why you are certain such use of init
+ * sectioned code is valid. For more details refer to ``include/linux/init.h``
+ * ``__ref``, ``__refdata``, and ``__refconst`` documentation.
+ */
+
+/**
+ * DOC: SECTION_REF
+ *
+ * Macro name used to annotate that code (functions) declared with this section
+ * has been vetteed as valid for its reference or use of other code (functions)
+ * or data structures which are part of the init sections.
+ */
+#define SECTION_REF			.ref.text
+
+/**
+ * DOC: SECTION_REF_DATA
+ *
+ * Macro name used to annotate data structures declared with this section have
+ * been vetteed for its reference or use of other code (functions) or data
+ * structures part of the init sections.
+ */
+#define SECTION_REF_DATA		.ref.data
+
+/**
+ * DOC: SECTION_REF_RODATA
+ *
+ * Macro name used to annotate const code (functions) const data structures
+ * which has been vetteed for its reference or use of other code (functions)
+ * or data structures part of the init sections.
+ */
+#define SECTION_REF_RODATA		.ref.rodata
+
+/**
+ * DOC: Linux section ordering
+ *
+ * Linux may use binutils linker-script 'SORT()' on sections to sort Linux
+ * sections. Linux has used 'SORT()' in ``include/asm-generic/vmlinux.lds.h``
+ * for years.
+ */
+
+/**
+ * DOC: SECTION_ORDER_ANY
+ *
+ * Macro name which can be used as helper to annotate custom section
+ * ordering at link time is not relevant for specific sections.
+ */
+#define SECTION_ORDER_ANY	any
+
+/*
+ * These section _ALL() helpers are for use on linker scripts and helpers
+ */
+#define SECTION_ALL(__section)						\
+	__section##.*
+
+#define __SECTION_CORE(__section, __core, __name, __level)		\
+	__section.__core.__name.__level
+
+#define SECTION_CORE_ALL(__section, __core)				\
+	__section##.##__core##.*
+
+/* Can be used on foo.S for instance */
+#ifndef __set_section_core_type
+# define __set_section_core_type(___section, ___core, ___name,		\
+				 ___level, ___flags, ___type)		\
+	.section ___section.___core.___name.___level, ___flags, ___type
+#endif
+
+#ifndef __set_section_core
+# define __set_section_core(___section, ___core, ___name, ___level, ___flags) \
+	.section ___section.___core.___name.___level, ___flags
+#endif
+
+#ifndef __push_section_core
+# define __push_section_core(__section, __core, __name, __level, __flags) \
+	.pushsection __section.__core.__name.__level, __flags
+#endif
+
+#ifdef __KERNEL__
+#include <linux/stringify.h>
+#endif
+
+#if defined(__ASSEMBLER__) || defined(__ASSEMBLY__)
+
+# ifdef LINKER_SCRIPT
+
+#  ifndef SECTION_CORE
+#   define SECTION_CORE(__section, __core, __name, __level)		\
+	__SECTION_CORE(__section,__core,__name,__level)
+#  endif
+
+# else
+
+#  ifndef SECTION_CORE
+#   define SECTION_CORE(__section, __core, __name, __level)		\
+	push_section_core(__section, __core, __name, __level,)
+#  endif
+
+#  ifndef push_section_core
+#   define push_section_core(__section, __core, __name, __level, __flags) \
+	 __push_section_core(__section, __core, __name,			  \
+			     __level, __stringify(__flags))
+#  endif
+
+#  ifndef set_section_core
+#   define set_section_core(__section, __core, __name,			\
+			    __level, __flags)				\
+	__set_section_core(__section, __core, __name,			\
+			   __level, __stringify(__flags))
+#  endif
+
+#  ifndef set_section_core_type
+#   define set_section_core_type(__section, __core, __name,		\
+				 __level, __flags, __type)		\
+	__set_section_core_type(__section, __core, __name, __level,	\
+				__stringify(__flags), __type)
+#  endif
+
+# endif /* LINKER_SCRIPT */
+#else /* defined(__ASSEMBLER__) || defined(__ASSEMBLY__) */
+
+# ifndef SECTION_CORE
+#  define SECTION_CORE(__section, __core, __name, __level)		\
+	__stringify(__SECTION_CORE(__section,__core,__name,__level))
+# endif
+
+/*
+ * As per gcc's documentation a common asm separator is a new line followed
+ * by tab [0], it however seems possible to also just use a newline as its
+ * the most commonly empirically observed semantic and folks seem to agree
+ * this even works on S390. In case your architecture disagrees you may
+ * override this and define your own and keep the rest of the macros.
+ *
+ * [0] https://gcc.gnu.org/onlinedocs/gcc/Basic-Asm.html#Basic-Asm
+ */
+# ifndef ASM_CMD_SEP
+#  define ASM_CMD_SEP	"\n"
+# endif
+
+# ifndef set_section_core
+#  define set_section_core(__section, __core, __name, __level, __flags)	\
+	__stringify(__set_section_core_type(__section, __core, __name,	\
+					    __level, __stringify(__flags))) \
+	ASM_CMD_SEP
+# endif
+
+/*
+ * Some architectures (arm, and avr32 are two examples on kprobes) seem
+ * currently explicitly specify the type [0] -- this can be any of the
+ * optional constants on ELF:
+ *
+ * @progbits - section contains data
+ * @nobits - section does not contain data (i.e., section only occupies space)
+ * @note - section contains data which is used by things other than the program
+ * @init_array - section contains an array of pointers to init functions
+ * @fini_array - section contains an array of pointers to finish functions
+ * @preinit_array - section contains an array of pointers to pre-init functions
+ *
+ * ARM requires % instead of @.
+ *
+ * At least as per nasm (x86/x86_64 only), in the absence of qualifiers the
+ * defaults are as follows:
+ *
+ * section .text    progbits  alloc   exec    nowrite  align=16
+ * section .rodata  progbits  alloc   noexec  nowrite  align=4
+ * section .lrodata progbits  alloc   noexec  nowrite  align=4
+ * section .data    progbits  alloc   noexec  write    align=4
+ * section .ldata   progbits  alloc   noexec  write    align=4
+ * section .bss     nobits    alloc   noexec  write    align=4
+ * section .lbss    nobits    alloc   noexec  write    align=4
+ * section .tdata   progbits  alloc   noexec  write    align=4    tls
+ * section .tbss    nobits    alloc   noexec  write    align=4    tls
+ * section .comment progbits  noalloc noexec  nowrite  align=1
+ * section other    progbits  alloc   noexec  nowrite  align=1
+ *
+ * gas should have sensible defaults for architectures...
+ *
+ * [0] http://www.nasm.us/doc/nasmdoc7.html
+ */
+# ifndef set_section_core_type
+#  define set_section_core_type(__section, __core, __name, __level,	\
+				__flags, __type)			\
+	__stringify(__set_section_core_type(__section, __core,		\
+					    __name, __level,		\
+					    __stringify(__flags),	\
+					    __type))			\
+	ASM_CMD_SEP
+# endif
+
+# ifndef push_section_core
+#  define push_section_core(__section, __core, __name,			\
+			    __level, __flags)				\
+	__stringify(__push_section_core(__section, __core,		\
+					__name,	__level,		\
+					__stringify(__flags)))		\
+	ASM_CMD_SEP
+# endif
+
+#endif /* defined(__ASSEMBLER__) || defined(__ASSEMBLY__) */
+#endif /* _ASM_GENERIC_SECTION_CORE_H_ */
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index af0254c09424..298252df3c81 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -1,6 +1,8 @@
 #ifndef _ASM_GENERIC_SECTIONS_H_
 #define _ASM_GENERIC_SECTIONS_H_
 
+#include <asm/section-core.h>
+
 /* References to section boundaries */
 
 #include <linux/compiler.h>
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 24563970ff7b..731087276a32 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -55,6 +55,7 @@
 #endif
 
 #include <linux/export.h>
+#include <asm/section-core.h>
 
 /* Align . to a 8 byte boundary equals to maximum function alignment. */
 #define ALIGN_FUNCTION()  . = ALIGN(8)
@@ -198,8 +199,8 @@
 
 /* .data section */
 #define DATA_DATA							\
-	*(.data)							\
-	*(.ref.data)							\
+	*(SECTION_DATA)							\
+	*(SECTION_REF_DATA)						\
 	*(.data..shared_aligned) /* percpu related */			\
 	MEM_KEEP(init.data)						\
 	MEM_KEEP(exit.data)						\
@@ -262,9 +263,9 @@
  */
 #define RO_DATA_SECTION(align)						\
 	. = ALIGN((align));						\
-	.rodata           : AT(ADDR(.rodata) - LOAD_OFFSET) {		\
+	SECTION_RODATA    : AT(ADDR(SECTION_RODATA) - LOAD_OFFSET) {	\
 		VMLINUX_SYMBOL(__start_rodata) = .;			\
-		*(.rodata) *(.rodata.*)					\
+		*(SECTION_RODATA) *(SECTION_ALL(SECTION_RODATA))	\
 		RO_AFTER_INIT_DATA	/* Read only after init */	\
 		*(__vermagic)		/* Kernel version magic */	\
 		. = ALIGN(8);						\
@@ -394,7 +395,7 @@
 									\
 	/* __*init sections */						\
 	__init_rodata : AT(ADDR(__init_rodata) - LOAD_OFFSET) {		\
-		*(.ref.rodata)						\
+		*(SECTION_REF_RODATA)					\
 		MEM_KEEP(init.rodata)					\
 		MEM_KEEP(exit.rodata)					\
 	}								\
@@ -432,8 +433,8 @@
  * during second ld run in second ld pass when generating System.map */
 #define TEXT_TEXT							\
 		ALIGN_FUNCTION();					\
-		*(.text.hot .text .text.fixup .text.unlikely)		\
-		*(.ref.text)						\
+		*(.text.hot SECTION_TEXT .text.fixup .text.unlikely)	\
+		*(SECTION_REF)						\
 	MEM_KEEP(init.text)						\
 	MEM_KEEP(exit.text)						\
 
@@ -527,11 +528,11 @@
 
 /* init and exit section handling */
 #define INIT_DATA							\
-	*(.init.data)							\
+	*(SECTION_INIT_DATA)						\
 	MEM_DISCARD(init.data)						\
 	KERNEL_CTORS()							\
 	MCOUNT_REC()							\
-	*(.init.rodata)							\
+	*(SECTION_INIT_RODATA)						\
 	FTRACE_EVENTS()							\
 	TRACE_SYSCALLS()						\
 	KPROBE_BLACKLIST()						\
@@ -549,24 +550,24 @@
 	EARLYCON_TABLE()
 
 #define INIT_TEXT							\
-	*(.init.text)							\
+	*(SECTION_INIT)							\
 	*(.text.startup)						\
 	MEM_DISCARD(init.text)
 
 #define EXIT_DATA							\
-	*(.exit.data)							\
+	*(SECTION_EXIT_DATA)						\
 	*(.fini_array)							\
 	*(.dtors)							\
 	MEM_DISCARD(exit.data)						\
 	MEM_DISCARD(exit.rodata)
 
 #define EXIT_TEXT							\
-	*(.exit.text)							\
+	*(SECTION_EXIT)							\
 	*(.text.exit)							\
 	MEM_DISCARD(exit.text)
 
 #define EXIT_CALL							\
-	*(.exitcall.exit)
+	*(SECTION_EXIT_CALL)
 
 /*
  * bss (Block Started by Symbol) - uninitialized data
diff --git a/include/linux/sections.h b/include/linux/sections.h
new file mode 100644
index 000000000000..f21c6ee88ded
--- /dev/null
+++ b/include/linux/sections.h
@@ -0,0 +1,111 @@
+#ifndef _LINUX_SECTIONS_H
+#define _LINUX_SECTIONS_H
+/*
+ * Linux de-facto sections
+ *
+ * Copyright (C) 2016 Luis R. Rodriguez <mcgrof@kernel.org>
+ *
+ * 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>
+#include <linux/export.h>
+
+#ifndef __ASSEMBLY__
+
+/**
+ * DOC: Introduction
+ *
+ * Linux defines a set of common helpers which can be used to against its use
+ * of standard or custom Linux sections, this section is dedicated to these
+ * helpers.
+ */
+
+/**
+ * LINUX_SECTION_ALIGNMENT - get section alignment
+ *
+ * @name: section name
+ *
+ * Gives you the alignment for the section.
+ */
+#define LINUX_SECTION_ALIGNMENT(name)	__alignof__(*VMLINUX_SYMBOL(name))
+
+/**
+ * LINUX_SECTION_SIZE - get number of entries in the section
+ *
+ * @name: section name
+ *
+ * This gives you the number of entries in the section.
+ * Example usage:
+ *
+ *   unsigned int num_frobs = LINUX_SECTION_SIZE(frobnicator_fns);
+ */
+#define LINUX_SECTION_SIZE(name)					\
+	((VMLINUX_SYMBOL(name##__end)) - (VMLINUX_SYMBOL(name)))
+
+/**
+ * LINUX_SECTION_EMPTY - check if section has no entries
+ *
+ * @name: section name
+ *
+ * Returns true if section is emtpy.
+ *
+ *   bool is_empty = LINUX_SECTION_EMPTY(frobnicator_fns);
+ */
+#define LINUX_SECTION_EMPTY(name)	(LINUX_SECTION_SIZE(name) == 0)
+
+/**
+ * LINUX_SECTION_START - get address of start of section
+ *
+ * @name: section name
+ *
+ * This gives you the start address of the section.
+ * This should give you the address of the first entry.
+ *
+ */
+#define LINUX_SECTION_START(name)	VMLINUX_SYMBOL(name)
+
+/**
+ * LINUX_SECTION_END - get address of end of the section
+ *
+ * @name: section name
+ *
+ * This gives you the end address of the section.
+ * This should give you the address of the end of the
+ * section. This will match the start address if the
+ * section is empty.
+ */
+#define LINUX_SECTION_END(name)	VMLINUX_SYMBOL(name##__end)
+
+/**
+ * DECLARE_LINUX_SECTION - Declares a custom Linux section
+ *
+ * @type: type of custom Linux section
+ * @name: custom section name
+ *
+ * Declares a read-write custom Linux section
+ */
+#define DECLARE_LINUX_SECTION(type, name)				\
+	 extern type VMLINUX_SYMBOL(name)[], \
+		     VMLINUX_SYMBOL(name##__end)[]
+
+/**
+ * DECLARE_LINUX_SECTION_RO - Declares a read-only custom Linux section
+ *
+ * @type: type of custom Linux section
+ * @name: custom section name
+ *
+ * Declares a read-only custom Linux section
+ */
+#define DECLARE_LINUX_SECTION_RO(type, name)				\
+	 extern const type VMLINUX_SYMBOL(name)[],			\
+			   VMLINUX_SYMBOL(name##__end)[]
+
+#define __SECTION_TYPE(section, type, name, level)			\
+	#section "." #type "." #name "." #level
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _LINUX_SECTIONS_H */
-- 
2.9.2


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 04/16] generic-sections: add section core helpers
  2016-08-19 21:32 ` [PATCH v4 04/16] generic-sections: add section core helpers mcgrof
@ 2016-08-19 21:32   ` mcgrof
  2016-08-19 21:47   ` Kees Cook
  1 sibling, 0 replies; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: x86, luto, keescook, torvalds, gregkh, rusty, gnomes, alan,
	dwmw2, arnd, ming.lei, linux-arch, benh, ananth, pebolle,
	fontana, david.vrabel, konrad.wilk, mcb30, jgross,
	andrew.cooper3, andriy.shevchenko, paul.gortmaker, xen-devel, ak,
	pali.rohar, dvhart, platform-driver-x86, mmarek, linux, jkosina,
	korea.drzix, linux-kbuild, tony.luck, akpm, linux-ia64,
	linux-arm-kernel, linux-sh, sparclinux, catalin.marinas,
	will.deacon, rostedt, jani.nikula, mchehab, markus.heiser, acme,
	jolsa, msalter, chris, jcmvbkbc, linux-xtensa, paulus, mpe,
	James.Bottomley, Luis R. Rodriguez

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

Linux makes extensive use of custom ELF header sections,
documentation for these are well scatterred. Unify this
documentation in a central place and provide helpers to
build custom Linux sections.

This also generalizes sections code to enable avoiding
modifying the linker scripts when we want to add new
custom Linux sections. In order to make this generally
useful we need to ensure all architectures can make use of
core section helpers but that they can also override should
this be needed. Instead of relying on section.h this adds
a sections-core.h since this will be targetted to be safe
to be used on asm code, linker scripts and C code.

v4:

o Port to shiny new sphinx documentation format

o fix a unicore32 build, turns out this actually fixes unicore32
  defconfig builds which were failing for a long while. unicore32
  does not seem to grok well the type passed on a section declaration,
  this ignores it.

o Use VMLINUX_SYMBOL() in more user symbols (extern C code), not doing
  this was causing final linker issues with blackfin -- this is
  a CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX=y architecture. The other one
  being metatag. metatag is not supported on 0-day so I cannot confirm
  compilation there.

o Added SECTION_CORE() for C code, used later by __LINUX_RANGE()

o Since SECTION_CORE() is defined for linker script and C code, share
  the same helper and just use a __stringify() for the C code as is done
  for the other C helpers.

o move generic sections to asm-generic/section-core.h instead.
  PowerPC compilation blows up if asm/jump_labels.h gets
  section.h included, fixing this is not in any way easy.
  The list of issues are endless. Moving new data to a new
  simple file resolves this.

o since things are now in asm-generic/section-core.h the
  guard changes on asm-generic/sections.h and each architecture
  sections.h are no longer needed

o Give generic sections some maintainer love, that change is
  Acked-by Arnd Bergmann, Josh and hpa.

o A few checkpatch.pl style fixes

o As suggested by James Hogan use generic-y to copy generic
  header files on architectures that do not have a sections.h
  instead of writing a simple file only to include the generic one.

v3:

o add missing sections.h for architectures that did not
  have it

o move generic sections to asm-generic/sections.h

o add generic asm helpers section_type(), section_type_asmtype(),
  push_section_type() -- these helpers enable easy use for
  for later declaring and using of custom linux sections using
  more standard APIs in both C code, asm code (C asm calls, or
  asm files), enabling future standardized section types to
  be more immediately accessible to asm code, not just C code.
  Note for ASM_CMD_SEP we use by default "\n", architectures needed
  to override can do so on their own sections.h prior to inclusion
  of asm-generic/sections.h

Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 Documentation/index.rst                   |   1 +
 Documentation/sections/conf.py            |   4 +
 Documentation/sections/index.rst          |  11 +
 Documentation/sections/section-core.rst   | 153 ++++++++++++++
 MAINTAINERS                               |  14 ++
 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/Kbuild               |   1 +
 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/section-core.h |  19 ++
 arch/x86/include/asm/Kbuild               |   1 +
 arch/xtensa/include/asm/Kbuild            |   1 +
 include/asm-generic/section-core.h        | 341 ++++++++++++++++++++++++++++++
 include/asm-generic/sections.h            |   2 +
 include/asm-generic/vmlinux.lds.h         |  27 +--
 include/linux/sections.h                  | 111 ++++++++++
 40 files changed, 700 insertions(+), 13 deletions(-)
 create mode 100644 Documentation/sections/conf.py
 create mode 100644 Documentation/sections/index.rst
 create mode 100644 Documentation/sections/section-core.rst
 create mode 100644 arch/unicore32/include/asm/section-core.h
 create mode 100644 include/asm-generic/section-core.h
 create mode 100644 include/linux/sections.h

diff --git a/Documentation/index.rst b/Documentation/index.rst
index a15f81855b39..10c9b867e326 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -14,6 +14,7 @@ Contents:
    kernel-documentation
    media/index
    gpu/index
+   sections/index
 
 Indices and tables
 ==================
diff --git a/Documentation/sections/conf.py b/Documentation/sections/conf.py
new file mode 100644
index 000000000000..faa1c57595e1
--- /dev/null
+++ b/Documentation/sections/conf.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8; mode: python -*-
+
+project = 'Linux Kernel ELF sections'
+html_search_language = 'en'
diff --git a/Documentation/sections/index.rst b/Documentation/sections/index.rst
new file mode 100644
index 000000000000..d411e9b22eb3
--- /dev/null
+++ b/Documentation/sections/index.rst
@@ -0,0 +1,11 @@
+=========================
+Linux Kernel ELF sections
+=========================
+
+This book documents the Linux kernel's use of ELF sections, as well as helpers
+used throughout the kernel to help declare and define them.
+
+.. toctree::
+   :maxdepth: 4
+
+   section-core
diff --git a/Documentation/sections/section-core.rst b/Documentation/sections/section-core.rst
new file mode 100644
index 000000000000..ecf4228bc4f8
--- /dev/null
+++ b/Documentation/sections/section-core.rst
@@ -0,0 +1,153 @@
+==============================
+Core Linux kernel ELF sections
+==============================
+
+About
+=====
+
+This book documents the different standard and custom ELF sections used
+on the Linux kernel, which we refer to as the ``core Linux sections``. We
+start off by documenting the standard ELF sections used by Linux and move
+on to the basic custom ELF sections, followed by a set of helpers. Each
+section documented describes the goal of the section, and addresses
+concurrency considerations when applicable.
+
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: Custom linker script
+
+Standard ELF section use in Linux
+=================================
+
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: Standard ELF section use in Linux
+
+SECTION_RODATA
+--------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_RODATA
+
+SECTION_RODATA
+--------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_TEXT
+
+SECTION_DATA
+------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_DATA
+
+Linux .init\* sections
+======================
+
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: Linux init sections
+
+SECTION_INIT_DATA
+-----------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_INIT_DATA
+
+SECTION_INIT_RODATA
+-------------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_INIT_RODATA
+
+SECTION_INIT_CALL
+-----------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_INIT_CALL
+
+Linux .exit\* sections
+======================
+
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: Linux exit sections
+
+SECTION_EXIT
+------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_EXIT
+
+SECTION_EXIT_DATA
+-----------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_EXIT_DATA
+
+SECTION_EXIT_CALL
+-----------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_EXIT_CALL
+
+Linux .ref\* sections
+=====================
+
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: Linux references to init sections
+
+SECTION_REF
+-----------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_REF
+
+SECTION_REF_DATA
+----------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_REF_DATA
+
+SECTION_REF_RODATA
+------------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_REF_RODATA
+
+Linux section ordering
+======================
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: Linux section ordering
+
+SECTION_ORDER_ANY
+-----------------
+.. kernel-doc:: include/asm-generic/section-core.h
+   :doc: SECTION_ORDER_ANY
+
+Generic Linux kernel section helpers
+====================================
+
+Introduction
+-------------
+.. kernel-doc:: include/linux/sections.h
+   :doc: Introduction
+
+LINUX_SECTION_ALIGNMENT
+-----------------------
+.. kernel-doc:: include/linux/sections.h
+   :functions: LINUX_SECTION_ALIGNMENT
+
+LINUX_SECTION_SIZE
+------------------
+.. kernel-doc:: include/linux/sections.h
+   :functions: LINUX_SECTION_SIZE
+
+LINUX_SECTION_EMPTY
+-------------------
+.. kernel-doc:: include/linux/sections.h
+   :functions: LINUX_SECTION_EMPTY
+
+LINUX_SECTION_START
+-------------------
+.. kernel-doc:: include/linux/sections.h
+   :functions: LINUX_SECTION_START
+
+LINUX_SECTION_END
+-----------------
+.. kernel-doc:: include/linux/sections.h
+   :functions: LINUX_SECTION_END
+
+DECLARE_LINUX_SECTION
+---------------------
+.. kernel-doc:: include/linux/sections.h
+   :functions: DECLARE_LINUX_SECTION
+
+DECLARE_LINUX_SECTION_RO
+------------------------
+.. kernel-doc:: include/linux/sections.h
+   :functions: DECLARE_LINUX_SECTION_RO
diff --git a/MAINTAINERS b/MAINTAINERS
index 5aec01883020..689c12075842 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5217,6 +5217,20 @@ S:	Supported
 F:	drivers/base/power/domain*.c
 F:	include/linux/pm_domain.h
 
+GENERIC SECTIONS
+M:	"Luis R. Rodriguez" <mcgrof@kernel.org>
+M:	Josh Poimboeuf <jpoimboe@redhat.com>
+M:	"H. Peter Anvin" <hpa@zytor.com>
+L:	linux-arch@vger.kernel.org
+L:	linux-kernel@vger.kernel.org
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux.git for-arnd
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux-next.git for-arnd
+S:	Supported
+F:	include/asm-generic/section-core.h
+F:	include/asm-generic/sections.h
+F:	include/asm-generic/vmlinux.lds.h
+F:	Documentation/sections/section-core.rst
+
 GENERIC UIO DRIVER FOR PCI DEVICES
 M:	"Michael S. Tsirkin" <mst@redhat.com>
 L:	kvm@vger.kernel.org
diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild
index bf8475ce85ee..5422827f1585 100644
--- a/arch/alpha/include/asm/Kbuild
+++ b/arch/alpha/include/asm/Kbuild
@@ -10,3 +10,4 @@ generic-y += mm-arch-hooks.h
 generic-y += preempt.h
 generic-y += sections.h
 generic-y += trace_clock.h
+generic-y += section-core.h
diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild
index 0b10ef2a4372..9a0929576de1 100644
--- a/arch/arc/include/asm/Kbuild
+++ b/arch/arc/include/asm/Kbuild
@@ -50,3 +50,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
index 0745538b26d3..47923635be16 100644
--- a/arch/arm/include/asm/Kbuild
+++ b/arch/arm/include/asm/Kbuild
@@ -39,3 +39,4 @@ generic-y += termios.h
 generic-y += timex.h
 generic-y += trace_clock.h
 generic-y += unaligned.h
+generic-y += section-core.h
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index f43d2c44c765..42d00806e4fb 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -52,3 +52,4 @@ generic-y += unaligned.h
 generic-y += user.h
 generic-y += vga.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/avr32/include/asm/Kbuild b/arch/avr32/include/asm/Kbuild
index 241b9b9729d8..f2c3b656a0e7 100644
--- a/arch/avr32/include/asm/Kbuild
+++ b/arch/avr32/include/asm/Kbuild
@@ -22,3 +22,4 @@ generic-y += trace_clock.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/blackfin/include/asm/Kbuild b/arch/blackfin/include/asm/Kbuild
index 91d49c0a3118..7de674411bed 100644
--- a/arch/blackfin/include/asm/Kbuild
+++ b/arch/blackfin/include/asm/Kbuild
@@ -48,3 +48,4 @@ generic-y += unaligned.h
 generic-y += user.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild
index 64465e7e2245..38127ce747be 100644
--- a/arch/c6x/include/asm/Kbuild
+++ b/arch/c6x/include/asm/Kbuild
@@ -62,3 +62,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild
index 1778805f6380..385cd88a9d9e 100644
--- a/arch/cris/include/asm/Kbuild
+++ b/arch/cris/include/asm/Kbuild
@@ -45,3 +45,4 @@ generic-y += types.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/frv/include/asm/Kbuild b/arch/frv/include/asm/Kbuild
index 1fa084cf1a43..46d7c599d9b8 100644
--- a/arch/frv/include/asm/Kbuild
+++ b/arch/frv/include/asm/Kbuild
@@ -8,3 +8,4 @@ generic-y += mm-arch-hooks.h
 generic-y += preempt.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
+generic-y += section-core.h
diff --git a/arch/h8300/include/asm/Kbuild b/arch/h8300/include/asm/Kbuild
index 373cb23301e3..1ec04ec1c82b 100644
--- a/arch/h8300/include/asm/Kbuild
+++ b/arch/h8300/include/asm/Kbuild
@@ -75,3 +75,4 @@ generic-y += unaligned.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild
index db8ddabc6bd2..37d7bfae7619 100644
--- a/arch/hexagon/include/asm/Kbuild
+++ b/arch/hexagon/include/asm/Kbuild
@@ -60,3 +60,4 @@ generic-y += unaligned.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild
index 502a91d8dbbd..672c6d5da18c 100644
--- a/arch/ia64/include/asm/Kbuild
+++ b/arch/ia64/include/asm/Kbuild
@@ -9,3 +9,4 @@ generic-y += preempt.h
 generic-y += trace_clock.h
 generic-y += vtime.h
 generic-y += word-at-a-time.h
+generic-y += section-core.h
diff --git a/arch/m32r/include/asm/Kbuild b/arch/m32r/include/asm/Kbuild
index 860e440611c9..6111e1523750 100644
--- a/arch/m32r/include/asm/Kbuild
+++ b/arch/m32r/include/asm/Kbuild
@@ -11,3 +11,4 @@ generic-y += preempt.h
 generic-y += sections.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
+generic-y += section-core.h
diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild
index eb85bd9c6180..eef72c464c9b 100644
--- a/arch/m68k/include/asm/Kbuild
+++ b/arch/m68k/include/asm/Kbuild
@@ -35,3 +35,4 @@ generic-y += trace_clock.h
 generic-y += types.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/metag/include/asm/Kbuild b/arch/metag/include/asm/Kbuild
index 29acb89daaaa..50ebd5a30d16 100644
--- a/arch/metag/include/asm/Kbuild
+++ b/arch/metag/include/asm/Kbuild
@@ -56,3 +56,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild
index b0ae88c9fed9..c6c2cf6edc98 100644
--- a/arch/microblaze/include/asm/Kbuild
+++ b/arch/microblaze/include/asm/Kbuild
@@ -11,3 +11,4 @@ generic-y += preempt.h
 generic-y += syscalls.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
+generic-y += section-core.h
diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild
index 9740066cc631..12f7c5984c03 100644
--- a/arch/mips/include/asm/Kbuild
+++ b/arch/mips/include/asm/Kbuild
@@ -20,3 +20,4 @@ generic-y += trace_clock.h
 generic-y += user.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/mn10300/include/asm/Kbuild b/arch/mn10300/include/asm/Kbuild
index 1c8dd0f5cd5d..f8145bc85835 100644
--- a/arch/mn10300/include/asm/Kbuild
+++ b/arch/mn10300/include/asm/Kbuild
@@ -10,3 +10,4 @@ generic-y += preempt.h
 generic-y += sections.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
+generic-y += section-core.h
diff --git a/arch/nios2/include/asm/Kbuild b/arch/nios2/include/asm/Kbuild
index d63330e88379..c9c7cb82b00f 100644
--- a/arch/nios2/include/asm/Kbuild
+++ b/arch/nios2/include/asm/Kbuild
@@ -63,3 +63,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild
index 2832f031fb11..86175e701869 100644
--- a/arch/openrisc/include/asm/Kbuild
+++ b/arch/openrisc/include/asm/Kbuild
@@ -71,3 +71,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild
index f9b3a81aefcd..6f43f33f0e0f 100644
--- a/arch/parisc/include/asm/Kbuild
+++ b/arch/parisc/include/asm/Kbuild
@@ -29,3 +29,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild
index ab9f4e0ed4cf..b49fab7bab2f 100644
--- a/arch/powerpc/include/asm/Kbuild
+++ b/arch/powerpc/include/asm/Kbuild
@@ -7,3 +7,4 @@ generic-y += mcs_spinlock.h
 generic-y += preempt.h
 generic-y += rwsem.h
 generic-y += vtime.h
+generic-y += section-core.h
diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild
index 20f196b82a6e..89e74b59f32d 100644
--- a/arch/s390/include/asm/Kbuild
+++ b/arch/s390/include/asm/Kbuild
@@ -8,3 +8,4 @@ generic-y += mm-arch-hooks.h
 generic-y += preempt.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
+generic-y += section-core.h
diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild
index a05218ff3fe4..f089a264cd38 100644
--- a/arch/score/include/asm/Kbuild
+++ b/arch/score/include/asm/Kbuild
@@ -14,3 +14,4 @@ generic-y += trace_clock.h
 generic-y += xor.h
 generic-y += serial.h
 generic-y += word-at-a-time.h
+generic-y += section-core.h
diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild
index 751c3373a92c..7b0356dca562 100644
--- a/arch/sh/include/asm/Kbuild
+++ b/arch/sh/include/asm/Kbuild
@@ -39,3 +39,4 @@ generic-y += termios.h
 generic-y += trace_clock.h
 generic-y += ucontext.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild
index cfc918067f80..d51b84d6b4b7 100644
--- a/arch/sparc/include/asm/Kbuild
+++ b/arch/sparc/include/asm/Kbuild
@@ -22,3 +22,4 @@ generic-y += serial.h
 generic-y += trace_clock.h
 generic-y += types.h
 generic-y += word-at-a-time.h
+generic-y += section-core.h
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild
index ba35c41c71ff..7b8a652e43ae 100644
--- a/arch/tile/include/asm/Kbuild
+++ b/arch/tile/include/asm/Kbuild
@@ -41,3 +41,4 @@ generic-y += termios.h
 generic-y += trace_clock.h
 generic-y += types.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild
index 904f3ebf4220..e9849834d55e 100644
--- a/arch/um/include/asm/Kbuild
+++ b/arch/um/include/asm/Kbuild
@@ -27,3 +27,4 @@ generic-y += topology.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/arch/unicore32/include/asm/section-core.h b/arch/unicore32/include/asm/section-core.h
new file mode 100644
index 000000000000..ebffeed8835d
--- /dev/null
+++ b/arch/unicore32/include/asm/section-core.h
@@ -0,0 +1,19 @@
+#ifndef __UNICORE_SECTION_CORE_ASM_H__
+#define __UNICORE_SECTION_CORE_ASM_H__
+/*
+ * Copyright (C) 2016 Luis R. Rodriguez <mcgrof@kernel.org>
+ *
+ * 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/.
+ */
+
+/* Unicore32 has known to not work properly with the type set, so ignore it */
+
+#define __set_section_core_type(___section, ___core, ___name,		\
+				___level, ___flags, ___type)		\
+	.section ___section.___core.___name.___level, ___flags
+
+#include <asm-generic/section-core.h>
+
+#endif /* __UNICORE_SECTION_CORE_ASM_H__ */
diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild
index 2cfed174e3c9..f6914a57bc16 100644
--- a/arch/x86/include/asm/Kbuild
+++ b/arch/x86/include/asm/Kbuild
@@ -16,3 +16,4 @@ generic-y += dma-contiguous.h
 generic-y += early_ioremap.h
 generic-y += mcs_spinlock.h
 generic-y += mm-arch-hooks.h
+generic-y += section-core.h
diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild
index 28cf4c5d65ef..81ca6816bd72 100644
--- a/arch/xtensa/include/asm/Kbuild
+++ b/arch/xtensa/include/asm/Kbuild
@@ -31,3 +31,4 @@ generic-y += topology.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += section-core.h
diff --git a/include/asm-generic/section-core.h b/include/asm-generic/section-core.h
new file mode 100644
index 000000000000..2ab57e2c4117
--- /dev/null
+++ b/include/asm-generic/section-core.h
@@ -0,0 +1,341 @@
+#ifndef _ASM_GENERIC_SECTION_CORE_H_
+#define _ASM_GENERIC_SECTION_CORE_H_
+/*
+ * Linux section core definitions
+ *
+ * Copyright (C) 2016 Luis R. Rodriguez <mcgrof@kernel.org>
+ *
+ * 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/.
+ */
+
+/**
+ * DOC: Custom linker script
+ *
+ * The Linux vmlinux binary uses a custom linker script on each architecture
+ * which it uses to strategically place standard ELF sections and also adds
+ * custom specialized ELF sections. Each architecture defines its own custom
+ * linker defined in arch/$(ARCH)/kernel/vmlinux.lds.S -- these in turn
+ * include and use definitions in include/asm-generic/vmlinux.lds.h as well
+ * as some helpers documented in this chaper.
+ */
+
+/**
+ * DOC: Standard ELF section use in Linux
+ *
+ * Linux makes use of the standard ELF sections, this sections documents
+ * these.
+ */
+
+/**
+ * DOC: SECTION_RODATA
+ *
+ * Macro name for code which must be protected from write access, read only
+ * data.
+ */
+#define SECTION_RODATA			.rodata
+
+/**
+ * DOC: SECTION_TEXT
+ *
+ * Macro name used to annotate code (functions) used during regular
+ * kernel run time. This is combined with `SECTION_RODATA`, only this
+ * section also allows for execution.
+ *
+ */
+#define SECTION_TEXT			.text
+
+/**
+ * DOC: SECTION_DATA
+ *
+ * Macro name for read-write data.
+ */
+#define SECTION_DATA			.data
+
+/**
+ * DOC: Linux init sections
+ *
+ * These sections are used for code and data structures used during boot or
+ * module initialization. On architectures that support it (x86, x86_64), all
+ * this code is freed up by the kernel right before the fist userspace init
+ * process is called when built-in to the kernel, and if modular it is freed
+ * after module initialization. Since the code is freed so early, in theory
+ * there should be no races against freeing this code with other CPUs. Init
+ * section code and data structures should never be exported with
+ * EXPORT_SYMBOL*() as the code will quickly become unavailable to the kernel
+ * after bootup.
+ */
+
+/**
+ * DOC: SECTION_INIT
+ *
+ * Macro name used to annotate code (functions) used only during boot or driver
+ * initialization.
+ *
+ */
+#define SECTION_INIT			.init.text
+
+/**
+ * DOC: SECTION_INIT_DATA
+ *
+ * Macro name used to annotate data structures used only during boot or driver
+ * initialization.
+ */
+#define SECTION_INIT_DATA		.init.data
+
+/**
+ * DOC: SECTION_INIT_RODATA
+ *
+ * Macro name used to annotate read-only code (functions) used only during boot
+ * or driver initialization.
+ */
+#define SECTION_INIT_RODATA		.init.rodata
+
+/**
+ * DOC: SECTION_INIT_CALL
+ *
+ * Special macro name used to annotate subsystem init call. These calls are
+ * are now grouped by functionality into separate subsections. Ordering inside
+ * the subsections is determined by link order.
+ */
+#define SECTION_INIT_CALL		.initcall
+
+/**
+ * DOC: Linux exit sections
+ *
+ * These sections are used to declare a functions and data structures which
+ * are only required on exit, the function or data structure will be dropped
+ * if the code declaring this section is not compiled as a module on
+ * architectures that support this (x86, x86_64). There is no special case
+ * handling for this code when built-in to the kernel.
+ */
+
+/**
+ * DOC: SECTION_EXIT
+ *
+ * Macro name used to annotate code (functions) used only during module
+ * unload.
+ */
+#define SECTION_EXIT			.exit.text
+
+/**
+ * DOC: SECTION_EXIT_DATA
+ *
+ * Macro name used to annotate data structures used only during module
+ * unload.
+ */
+#define SECTION_EXIT_DATA		.exit.data
+
+/**
+ * DOC: SECTION_EXIT_CALL
+ *
+ * Special macro name used to annotate an exit exit routine, order
+ * is important and maintained by link order.
+ */
+#define SECTION_EXIT_CALL		.exitcall.exit
+
+/**
+ * DOC: Linux references to init sections
+ *
+ * These sections are used to teach modpost to not warn about possible
+ * misuses of init section code from other sections. If you use this
+ * your use case should document why you are certain such use of init
+ * sectioned code is valid. For more details refer to ``include/linux/init.h``
+ * ``__ref``, ``__refdata``, and ``__refconst`` documentation.
+ */
+
+/**
+ * DOC: SECTION_REF
+ *
+ * Macro name used to annotate that code (functions) declared with this section
+ * has been vetteed as valid for its reference or use of other code (functions)
+ * or data structures which are part of the init sections.
+ */
+#define SECTION_REF			.ref.text
+
+/**
+ * DOC: SECTION_REF_DATA
+ *
+ * Macro name used to annotate data structures declared with this section have
+ * been vetteed for its reference or use of other code (functions) or data
+ * structures part of the init sections.
+ */
+#define SECTION_REF_DATA		.ref.data
+
+/**
+ * DOC: SECTION_REF_RODATA
+ *
+ * Macro name used to annotate const code (functions) const data structures
+ * which has been vetteed for its reference or use of other code (functions)
+ * or data structures part of the init sections.
+ */
+#define SECTION_REF_RODATA		.ref.rodata
+
+/**
+ * DOC: Linux section ordering
+ *
+ * Linux may use binutils linker-script 'SORT()' on sections to sort Linux
+ * sections. Linux has used 'SORT()' in ``include/asm-generic/vmlinux.lds.h``
+ * for years.
+ */
+
+/**
+ * DOC: SECTION_ORDER_ANY
+ *
+ * Macro name which can be used as helper to annotate custom section
+ * ordering at link time is not relevant for specific sections.
+ */
+#define SECTION_ORDER_ANY	any
+
+/*
+ * These section _ALL() helpers are for use on linker scripts and helpers
+ */
+#define SECTION_ALL(__section)						\
+	__section##.*
+
+#define __SECTION_CORE(__section, __core, __name, __level)		\
+	__section.__core.__name.__level
+
+#define SECTION_CORE_ALL(__section, __core)				\
+	__section##.##__core##.*
+
+/* Can be used on foo.S for instance */
+#ifndef __set_section_core_type
+# define __set_section_core_type(___section, ___core, ___name,		\
+				 ___level, ___flags, ___type)		\
+	.section ___section.___core.___name.___level, ___flags, ___type
+#endif
+
+#ifndef __set_section_core
+# define __set_section_core(___section, ___core, ___name, ___level, ___flags) \
+	.section ___section.___core.___name.___level, ___flags
+#endif
+
+#ifndef __push_section_core
+# define __push_section_core(__section, __core, __name, __level, __flags) \
+	.pushsection __section.__core.__name.__level, __flags
+#endif
+
+#ifdef __KERNEL__
+#include <linux/stringify.h>
+#endif
+
+#if defined(__ASSEMBLER__) || defined(__ASSEMBLY__)
+
+# ifdef LINKER_SCRIPT
+
+#  ifndef SECTION_CORE
+#   define SECTION_CORE(__section, __core, __name, __level)		\
+	__SECTION_CORE(__section,__core,__name,__level)
+#  endif
+
+# else
+
+#  ifndef SECTION_CORE
+#   define SECTION_CORE(__section, __core, __name, __level)		\
+	push_section_core(__section, __core, __name, __level,)
+#  endif
+
+#  ifndef push_section_core
+#   define push_section_core(__section, __core, __name, __level, __flags) \
+	 __push_section_core(__section, __core, __name,			  \
+			     __level, __stringify(__flags))
+#  endif
+
+#  ifndef set_section_core
+#   define set_section_core(__section, __core, __name,			\
+			    __level, __flags)				\
+	__set_section_core(__section, __core, __name,			\
+			   __level, __stringify(__flags))
+#  endif
+
+#  ifndef set_section_core_type
+#   define set_section_core_type(__section, __core, __name,		\
+				 __level, __flags, __type)		\
+	__set_section_core_type(__section, __core, __name, __level,	\
+				__stringify(__flags), __type)
+#  endif
+
+# endif /* LINKER_SCRIPT */
+#else /* defined(__ASSEMBLER__) || defined(__ASSEMBLY__) */
+
+# ifndef SECTION_CORE
+#  define SECTION_CORE(__section, __core, __name, __level)		\
+	__stringify(__SECTION_CORE(__section,__core,__name,__level))
+# endif
+
+/*
+ * As per gcc's documentation a common asm separator is a new line followed
+ * by tab [0], it however seems possible to also just use a newline as its
+ * the most commonly empirically observed semantic and folks seem to agree
+ * this even works on S390. In case your architecture disagrees you may
+ * override this and define your own and keep the rest of the macros.
+ *
+ * [0] https://gcc.gnu.org/onlinedocs/gcc/Basic-Asm.html#Basic-Asm
+ */
+# ifndef ASM_CMD_SEP
+#  define ASM_CMD_SEP	"\n"
+# endif
+
+# ifndef set_section_core
+#  define set_section_core(__section, __core, __name, __level, __flags)	\
+	__stringify(__set_section_core_type(__section, __core, __name,	\
+					    __level, __stringify(__flags))) \
+	ASM_CMD_SEP
+# endif
+
+/*
+ * Some architectures (arm, and avr32 are two examples on kprobes) seem
+ * currently explicitly specify the type [0] -- this can be any of the
+ * optional constants on ELF:
+ *
+ * @progbits - section contains data
+ * @nobits - section does not contain data (i.e., section only occupies space)
+ * @note - section contains data which is used by things other than the program
+ * @init_array - section contains an array of pointers to init functions
+ * @fini_array - section contains an array of pointers to finish functions
+ * @preinit_array - section contains an array of pointers to pre-init functions
+ *
+ * ARM requires % instead of @.
+ *
+ * At least as per nasm (x86/x86_64 only), in the absence of qualifiers the
+ * defaults are as follows:
+ *
+ * section .text    progbits  alloc   exec    nowrite  align=16
+ * section .rodata  progbits  alloc   noexec  nowrite  align=4
+ * section .lrodata progbits  alloc   noexec  nowrite  align=4
+ * section .data    progbits  alloc   noexec  write    align=4
+ * section .ldata   progbits  alloc   noexec  write    align=4
+ * section .bss     nobits    alloc   noexec  write    align=4
+ * section .lbss    nobits    alloc   noexec  write    align=4
+ * section .tdata   progbits  alloc   noexec  write    align=4    tls
+ * section .tbss    nobits    alloc   noexec  write    align=4    tls
+ * section .comment progbits  noalloc noexec  nowrite  align=1
+ * section other    progbits  alloc   noexec  nowrite  align=1
+ *
+ * gas should have sensible defaults for architectures...
+ *
+ * [0] http://www.nasm.us/doc/nasmdoc7.html
+ */
+# ifndef set_section_core_type
+#  define set_section_core_type(__section, __core, __name, __level,	\
+				__flags, __type)			\
+	__stringify(__set_section_core_type(__section, __core,		\
+					    __name, __level,		\
+					    __stringify(__flags),	\
+					    __type))			\
+	ASM_CMD_SEP
+# endif
+
+# ifndef push_section_core
+#  define push_section_core(__section, __core, __name,			\
+			    __level, __flags)				\
+	__stringify(__push_section_core(__section, __core,		\
+					__name,	__level,		\
+					__stringify(__flags)))		\
+	ASM_CMD_SEP
+# endif
+
+#endif /* defined(__ASSEMBLER__) || defined(__ASSEMBLY__) */
+#endif /* _ASM_GENERIC_SECTION_CORE_H_ */
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index af0254c09424..298252df3c81 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -1,6 +1,8 @@
 #ifndef _ASM_GENERIC_SECTIONS_H_
 #define _ASM_GENERIC_SECTIONS_H_
 
+#include <asm/section-core.h>
+
 /* References to section boundaries */
 
 #include <linux/compiler.h>
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 24563970ff7b..731087276a32 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -55,6 +55,7 @@
 #endif
 
 #include <linux/export.h>
+#include <asm/section-core.h>
 
 /* Align . to a 8 byte boundary equals to maximum function alignment. */
 #define ALIGN_FUNCTION()  . = ALIGN(8)
@@ -198,8 +199,8 @@
 
 /* .data section */
 #define DATA_DATA							\
-	*(.data)							\
-	*(.ref.data)							\
+	*(SECTION_DATA)							\
+	*(SECTION_REF_DATA)						\
 	*(.data..shared_aligned) /* percpu related */			\
 	MEM_KEEP(init.data)						\
 	MEM_KEEP(exit.data)						\
@@ -262,9 +263,9 @@
  */
 #define RO_DATA_SECTION(align)						\
 	. = ALIGN((align));						\
-	.rodata           : AT(ADDR(.rodata) - LOAD_OFFSET) {		\
+	SECTION_RODATA    : AT(ADDR(SECTION_RODATA) - LOAD_OFFSET) {	\
 		VMLINUX_SYMBOL(__start_rodata) = .;			\
-		*(.rodata) *(.rodata.*)					\
+		*(SECTION_RODATA) *(SECTION_ALL(SECTION_RODATA))	\
 		RO_AFTER_INIT_DATA	/* Read only after init */	\
 		*(__vermagic)		/* Kernel version magic */	\
 		. = ALIGN(8);						\
@@ -394,7 +395,7 @@
 									\
 	/* __*init sections */						\
 	__init_rodata : AT(ADDR(__init_rodata) - LOAD_OFFSET) {		\
-		*(.ref.rodata)						\
+		*(SECTION_REF_RODATA)					\
 		MEM_KEEP(init.rodata)					\
 		MEM_KEEP(exit.rodata)					\
 	}								\
@@ -432,8 +433,8 @@
  * during second ld run in second ld pass when generating System.map */
 #define TEXT_TEXT							\
 		ALIGN_FUNCTION();					\
-		*(.text.hot .text .text.fixup .text.unlikely)		\
-		*(.ref.text)						\
+		*(.text.hot SECTION_TEXT .text.fixup .text.unlikely)	\
+		*(SECTION_REF)						\
 	MEM_KEEP(init.text)						\
 	MEM_KEEP(exit.text)						\
 
@@ -527,11 +528,11 @@
 
 /* init and exit section handling */
 #define INIT_DATA							\
-	*(.init.data)							\
+	*(SECTION_INIT_DATA)						\
 	MEM_DISCARD(init.data)						\
 	KERNEL_CTORS()							\
 	MCOUNT_REC()							\
-	*(.init.rodata)							\
+	*(SECTION_INIT_RODATA)						\
 	FTRACE_EVENTS()							\
 	TRACE_SYSCALLS()						\
 	KPROBE_BLACKLIST()						\
@@ -549,24 +550,24 @@
 	EARLYCON_TABLE()
 
 #define INIT_TEXT							\
-	*(.init.text)							\
+	*(SECTION_INIT)							\
 	*(.text.startup)						\
 	MEM_DISCARD(init.text)
 
 #define EXIT_DATA							\
-	*(.exit.data)							\
+	*(SECTION_EXIT_DATA)						\
 	*(.fini_array)							\
 	*(.dtors)							\
 	MEM_DISCARD(exit.data)						\
 	MEM_DISCARD(exit.rodata)
 
 #define EXIT_TEXT							\
-	*(.exit.text)							\
+	*(SECTION_EXIT)							\
 	*(.text.exit)							\
 	MEM_DISCARD(exit.text)
 
 #define EXIT_CALL							\
-	*(.exitcall.exit)
+	*(SECTION_EXIT_CALL)
 
 /*
  * bss (Block Started by Symbol) - uninitialized data
diff --git a/include/linux/sections.h b/include/linux/sections.h
new file mode 100644
index 000000000000..f21c6ee88ded
--- /dev/null
+++ b/include/linux/sections.h
@@ -0,0 +1,111 @@
+#ifndef _LINUX_SECTIONS_H
+#define _LINUX_SECTIONS_H
+/*
+ * Linux de-facto sections
+ *
+ * Copyright (C) 2016 Luis R. Rodriguez <mcgrof@kernel.org>
+ *
+ * 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>
+#include <linux/export.h>
+
+#ifndef __ASSEMBLY__
+
+/**
+ * DOC: Introduction
+ *
+ * Linux defines a set of common helpers which can be used to against its use
+ * of standard or custom Linux sections, this section is dedicated to these
+ * helpers.
+ */
+
+/**
+ * LINUX_SECTION_ALIGNMENT - get section alignment
+ *
+ * @name: section name
+ *
+ * Gives you the alignment for the section.
+ */
+#define LINUX_SECTION_ALIGNMENT(name)	__alignof__(*VMLINUX_SYMBOL(name))
+
+/**
+ * LINUX_SECTION_SIZE - get number of entries in the section
+ *
+ * @name: section name
+ *
+ * This gives you the number of entries in the section.
+ * Example usage:
+ *
+ *   unsigned int num_frobs = LINUX_SECTION_SIZE(frobnicator_fns);
+ */
+#define LINUX_SECTION_SIZE(name)					\
+	((VMLINUX_SYMBOL(name##__end)) - (VMLINUX_SYMBOL(name)))
+
+/**
+ * LINUX_SECTION_EMPTY - check if section has no entries
+ *
+ * @name: section name
+ *
+ * Returns true if section is emtpy.
+ *
+ *   bool is_empty = LINUX_SECTION_EMPTY(frobnicator_fns);
+ */
+#define LINUX_SECTION_EMPTY(name)	(LINUX_SECTION_SIZE(name) == 0)
+
+/**
+ * LINUX_SECTION_START - get address of start of section
+ *
+ * @name: section name
+ *
+ * This gives you the start address of the section.
+ * This should give you the address of the first entry.
+ *
+ */
+#define LINUX_SECTION_START(name)	VMLINUX_SYMBOL(name)
+
+/**
+ * LINUX_SECTION_END - get address of end of the section
+ *
+ * @name: section name
+ *
+ * This gives you the end address of the section.
+ * This should give you the address of the end of the
+ * section. This will match the start address if the
+ * section is empty.
+ */
+#define LINUX_SECTION_END(name)	VMLINUX_SYMBOL(name##__end)
+
+/**
+ * DECLARE_LINUX_SECTION - Declares a custom Linux section
+ *
+ * @type: type of custom Linux section
+ * @name: custom section name
+ *
+ * Declares a read-write custom Linux section
+ */
+#define DECLARE_LINUX_SECTION(type, name)				\
+	 extern type VMLINUX_SYMBOL(name)[], \
+		     VMLINUX_SYMBOL(name##__end)[]
+
+/**
+ * DECLARE_LINUX_SECTION_RO - Declares a read-only custom Linux section
+ *
+ * @type: type of custom Linux section
+ * @name: custom section name
+ *
+ * Declares a read-only custom Linux section
+ */
+#define DECLARE_LINUX_SECTION_RO(type, name)				\
+	 extern const type VMLINUX_SYMBOL(name)[],			\
+			   VMLINUX_SYMBOL(name##__end)[]
+
+#define __SECTION_TYPE(section, type, name, level)			\
+	#section "." #type "." #name "." #level
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _LINUX_SECTIONS_H */
-- 
2.9.2


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 05/16] xtensa: skip adding literal when SORT() is used
  2016-08-19 21:32 [PATCH v4 00/16] linux: generalize sections, ranges and linker tables mcgrof
                   ` (4 preceding siblings ...)
  2016-08-19 21:32 ` [PATCH v4 04/16] generic-sections: add section core helpers mcgrof
@ 2016-08-19 21:32 ` mcgrof
  2016-08-19 21:32   ` mcgrof
  2016-08-19 21:32 ` [PATCH v4 06/16] ranges.h: add helpers to build and identify Linux section ranges mcgrof
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: gnomes, linux-ia64, jkosina, benh, ming.lei, linux,
	platform-driver-x86, James.Bottomley, paul.gortmaker, paulus,
	sparclinux, mchehab, linux-arch, markus.heiser, xen-devel,
	msalter, linux-sh, mpe, x86, fontana, linux-arm-kernel,
	catalin.marinas, dvhart, dwmw2, linux-xtensa, pali.rohar,
	keescook, arnd, jani.nikula, will.deacon, rusty, rostedt, acme,
	ak, andriy.shevchenko, mcb30

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

When SORT(foo.*) is used the current sed replacements add
SORT(foo.literal foo.*), this breaks linking. Avoid adding
literals for SORT globs, if needed, these need to be added
manually.

Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 arch/xtensa/kernel/Makefile | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile
index c31f5d5afc7d..8180850ed147 100644
--- a/arch/xtensa/kernel/Makefile
+++ b/arch/xtensa/kernel/Makefile
@@ -29,10 +29,10 @@ AFLAGS_mxhead.o += -mtext-section-literals
 #
 # Replicate rules in scripts/Makefile.build
 
-sed-y = -e ':a; s/\*(\([^)]*\)\.text\.unlikely/*(\1.literal.unlikely .{text}.unlikely/; ta; ' \
-	-e ':b; s/\*(\([^)]*\)\.text\(\.[a-z]*\)/*(\1.{text}\2.literal .{text}\2/; tb; ' \
-	-e ':c; s/\*(\([^)]*\)\(\.[a-z]*it\|\.ref\)\.text/*(\1\2.literal \2.{text}/; tc; ' \
-	-e ':d; s/\*(\([^)]\+ \|\)\.text/*(\1.literal .{text}/; td; ' \
+sed-y = -e ':a; s/\*(\([^)SORT]*\)\.text\.unlikely/*(\1.literal.unlikely .{text}.unlikely/; ta; ' \
+	-e ':b; s/\*(\([^)SORT]*\)\.text\(\.[a-z]*\)/*(\1.{text}\2.literal .{text}\2/; tb; ' \
+	-e ':c; s/\*(\([^SORT)]*\)\(\.[a-z]*it\|\.ref\)\.text/*(\1\2.literal \2.{text}/; tc; ' \
+	-e ':d; s/\*(\([^SORT)]\+ \|\)\.text/*(\1.literal .{text}/; td; ' \
 	-e 's/\.{text}/.text/g'
 
 quiet_cmd__cpp_lds_S = LDS     $@
-- 
2.9.2


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 05/16] xtensa: skip adding literal when SORT() is used
  2016-08-19 21:32 ` [PATCH v4 05/16] xtensa: skip adding literal when SORT() is used mcgrof
@ 2016-08-19 21:32   ` mcgrof
  0 siblings, 0 replies; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: x86, luto, keescook, torvalds, gregkh, rusty, gnomes, alan,
	dwmw2, arnd, ming.lei, linux-arch, benh, ananth, pebolle,
	fontana, david.vrabel, konrad.wilk, mcb30, jgross,
	andrew.cooper3, andriy.shevchenko, paul.gortmaker, xen-devel, ak,
	pali.rohar, dvhart, platform-driver-x86, mmarek, linux, jkosina,
	korea.drzix, linux-kbuild, tony.luck, akpm, linux-ia64,
	linux-arm-kernel, linux-sh, sparclinux, catalin.marinas,
	will.deacon, rostedt, jani.nikula, mchehab, markus.heiser, acme,
	jolsa, msalter, chris, jcmvbkbc, linux-xtensa, paulus, mpe,
	James.Bottomley, Luis R. Rodriguez

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

When SORT(foo.*) is used the current sed replacements add
SORT(foo.literal foo.*), this breaks linking. Avoid adding
literals for SORT globs, if needed, these need to be added
manually.

Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 arch/xtensa/kernel/Makefile | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile
index c31f5d5afc7d..8180850ed147 100644
--- a/arch/xtensa/kernel/Makefile
+++ b/arch/xtensa/kernel/Makefile
@@ -29,10 +29,10 @@ AFLAGS_mxhead.o += -mtext-section-literals
 #
 # Replicate rules in scripts/Makefile.build
 
-sed-y = -e ':a; s/\*(\([^)]*\)\.text\.unlikely/*(\1.literal.unlikely .{text}.unlikely/; ta; ' \
-	-e ':b; s/\*(\([^)]*\)\.text\(\.[a-z]*\)/*(\1.{text}\2.literal .{text}\2/; tb; ' \
-	-e ':c; s/\*(\([^)]*\)\(\.[a-z]*it\|\.ref\)\.text/*(\1\2.literal \2.{text}/; tc; ' \
-	-e ':d; s/\*(\([^)]\+ \|\)\.text/*(\1.literal .{text}/; td; ' \
+sed-y = -e ':a; s/\*(\([^)SORT]*\)\.text\.unlikely/*(\1.literal.unlikely .{text}.unlikely/; ta; ' \
+	-e ':b; s/\*(\([^)SORT]*\)\.text\(\.[a-z]*\)/*(\1.{text}\2.literal .{text}\2/; tb; ' \
+	-e ':c; s/\*(\([^SORT)]*\)\(\.[a-z]*it\|\.ref\)\.text/*(\1\2.literal \2.{text}/; tc; ' \
+	-e ':d; s/\*(\([^SORT)]\+ \|\)\.text/*(\1.literal .{text}/; td; ' \
 	-e 's/\.{text}/.text/g'
 
 quiet_cmd__cpp_lds_S = LDS     $@
-- 
2.9.2


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 06/16] ranges.h: add helpers to build and identify Linux section ranges
  2016-08-19 21:32 [PATCH v4 00/16] linux: generalize sections, ranges and linker tables mcgrof
                   ` (5 preceding siblings ...)
  2016-08-19 21:32 ` [PATCH v4 05/16] xtensa: skip adding literal when SORT() is used mcgrof
@ 2016-08-19 21:32 ` mcgrof
  2016-08-19 21:32   ` mcgrof
  2016-08-19 21:55   ` Kees Cook
  2016-08-19 21:32 ` [PATCH v4 07/16] tables.h: add linker table support mcgrof
                   ` (4 subsequent siblings)
  11 siblings, 2 replies; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: gnomes, linux-ia64, jkosina, benh, ming.lei, linux,
	platform-driver-x86, James.Bottomley, paul.gortmaker, paulus,
	sparclinux, mchehab, linux-arch, markus.heiser, xen-devel,
	msalter, linux-sh, mpe, x86, fontana, linux-arm-kernel,
	catalin.marinas, dvhart, dwmw2, linux-xtensa, pali.rohar,
	keescook, arnd, jani.nikula, will.deacon, rusty, rostedt, acme,
	ak, andriy.shevchenko, mcb30

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

Section ranges are on one of the types of custom sections
types used in Linux. This provides a series of helpers for
defining them and using them. Most importantly this also
enables us to avoid modifying the linker script when we
add a new section range.

It turns out a lot of custom sections are actually section ranges,
and these are typically spelled out in their architecture specific
asm/sections.h file -- we anable architectures to override what asm
is used for section ranges but start by default trusting the
asm-generic version all around.

v4:

o tons of documentation love
o fix arch/x86/tools/relocs.c typo - which caused compilation issues
  on old toolchains
o port to new shiny sphinx documentation
o sprinkle a few more needed VMLINUX_SYMBOL() - fixes
  compilation on blackfin
o name changes as suggested 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
- rebrand DECLARE_SECTION_RNG() as DEFINE_SECTION_RANGE() - this is
  the asm version of the respective C version, this will have a
  userspace C demo added later.
o move __LINUX_RANGE() and __LINUX_RANGE_ORDER() - fixes builds
  on sparc
o adds section ranges to linker script
o rename SECTION_RANGE_ALL()
o use default alignment, fixes builds on powerpc and arm for both
  __LINUX_RANGE() and __LINUX_RANGE_ORDER()
o expand documentation to document modules support
o add maintainers
o use generic-y

v3: new in this series, uses copyleft-next

Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 Documentation/sections/index.rst   |   1 +
 Documentation/sections/ranges.rst  |  49 ++++++++++++++
 MAINTAINERS                        |  10 +++
 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/Kbuild        |   1 +
 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       |  89 ++++++++++++++++++++++++++
 include/asm-generic/vmlinux.lds.h  |  12 +++-
 include/linux/ranges.h             | 128 +++++++++++++++++++++++++++++++++++++
 38 files changed, 320 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/sections/ranges.rst
 create mode 100644 include/asm-generic/ranges.h
 create mode 100644 include/linux/ranges.h

diff --git a/Documentation/sections/index.rst b/Documentation/sections/index.rst
index d411e9b22eb3..6dd93ddd5dbe 100644
--- a/Documentation/sections/index.rst
+++ b/Documentation/sections/index.rst
@@ -9,3 +9,4 @@ used throughout the kernel to help declare and define them.
    :maxdepth: 4
 
    section-core
+   ranges
diff --git a/Documentation/sections/ranges.rst b/Documentation/sections/ranges.rst
new file mode 100644
index 000000000000..1293dcb3ab38
--- /dev/null
+++ b/Documentation/sections/ranges.rst
@@ -0,0 +1,49 @@
+====================
+Linux section ranges
+====================
+
+This documents Linux' use of section ranges, how you can use
+them and how they work.
+
+About section ranges
+====================
+
+Introduction
+------------
+.. kernel-doc:: include/linux/ranges.h
+   :doc: Introduction
+
+Section range module support
+----------------------------
+.. kernel-doc:: include/linux/ranges.h
+   :doc: Section range module support
+
+Section range helpers
+=====================
+.. kernel-doc:: include/linux/ranges.h
+   :doc: Section range helpers
+
+DECLARE_SECTION_RANGE
+---------------------
+.. kernel-doc:: include/linux/ranges.h
+   :functions: DECLARE_SECTION_RANGE
+
+DEFINE_SECTION_RANGE
+--------------------
+.. kernel-doc:: include/linux/ranges.h
+   :functions: DEFINE_SECTION_RANGE
+
+SECTION_ADDR_IN_RANGE
+---------------------
+.. kernel-doc:: include/linux/ranges.h
+   :functions: SECTION_ADDR_IN_RANGE
+
+__LINUX_RANGE
+-------------
+.. kernel-doc:: include/asm-generic/ranges.h
+   :functions: __LINUX_RANGE
+
+__LINUX_RANGE_ORDER
+-------------------
+.. kernel-doc:: include/asm-generic/ranges.h
+   :functions: __LINUX_RANGE_ORDER
diff --git a/MAINTAINERS b/MAINTAINERS
index 689c12075842..1a217751aa8a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5217,6 +5217,16 @@ S:	Supported
 F:	drivers/base/power/domain*.c
 F:	include/linux/pm_domain.h
 
+GENERIC SECTION RANGES
+M:	"Luis R. Rodriguez" <mcgrof@kernel.org>
+M:	"H. Peter Anvin" <hpa@zytor.com>
+L:	linux-arch@vger.kernel.org
+L:	linux-kernel@vger.kernel.org
+S:	Supported
+F:	include/asm-generic/ranges.h
+F:	include/linux/ranges.h
+F:	Documentation/sections/ranges.rst
+
 GENERIC SECTIONS
 M:	"Luis R. Rodriguez" <mcgrof@kernel.org>
 M:	Josh Poimboeuf <jpoimboe@redhat.com>
diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild
index 5422827f1585..e44c896b91c4 100644
--- a/arch/alpha/include/asm/Kbuild
+++ b/arch/alpha/include/asm/Kbuild
@@ -11,3 +11,4 @@ generic-y += preempt.h
 generic-y += sections.h
 generic-y += trace_clock.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild
index 9a0929576de1..e5295413fdf8 100644
--- a/arch/arc/include/asm/Kbuild
+++ b/arch/arc/include/asm/Kbuild
@@ -51,3 +51,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
index 47923635be16..8e52300e1eed 100644
--- a/arch/arm/include/asm/Kbuild
+++ b/arch/arm/include/asm/Kbuild
@@ -40,3 +40,4 @@ generic-y += timex.h
 generic-y += trace_clock.h
 generic-y += unaligned.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index 42d00806e4fb..5ff184574976 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -53,3 +53,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/avr32/include/asm/Kbuild b/arch/avr32/include/asm/Kbuild
index f2c3b656a0e7..edc176348d7c 100644
--- a/arch/avr32/include/asm/Kbuild
+++ b/arch/avr32/include/asm/Kbuild
@@ -23,3 +23,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/blackfin/include/asm/Kbuild b/arch/blackfin/include/asm/Kbuild
index 7de674411bed..35b7752e65c0 100644
--- a/arch/blackfin/include/asm/Kbuild
+++ b/arch/blackfin/include/asm/Kbuild
@@ -49,3 +49,4 @@ generic-y += user.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild
index 38127ce747be..cede2a950fbf 100644
--- a/arch/c6x/include/asm/Kbuild
+++ b/arch/c6x/include/asm/Kbuild
@@ -63,3 +63,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild
index 385cd88a9d9e..fb8bb4112773 100644
--- a/arch/cris/include/asm/Kbuild
+++ b/arch/cris/include/asm/Kbuild
@@ -46,3 +46,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/frv/include/asm/Kbuild b/arch/frv/include/asm/Kbuild
index 46d7c599d9b8..5191fec655d7 100644
--- a/arch/frv/include/asm/Kbuild
+++ b/arch/frv/include/asm/Kbuild
@@ -9,3 +9,4 @@ generic-y += preempt.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/h8300/include/asm/Kbuild b/arch/h8300/include/asm/Kbuild
index 1ec04ec1c82b..7929a992566c 100644
--- a/arch/h8300/include/asm/Kbuild
+++ b/arch/h8300/include/asm/Kbuild
@@ -76,3 +76,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild
index 37d7bfae7619..af17ee334788 100644
--- a/arch/hexagon/include/asm/Kbuild
+++ b/arch/hexagon/include/asm/Kbuild
@@ -61,3 +61,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild
index 672c6d5da18c..d8f226b35a0a 100644
--- a/arch/ia64/include/asm/Kbuild
+++ b/arch/ia64/include/asm/Kbuild
@@ -10,3 +10,4 @@ generic-y += trace_clock.h
 generic-y += vtime.h
 generic-y += word-at-a-time.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/m32r/include/asm/Kbuild b/arch/m32r/include/asm/Kbuild
index 6111e1523750..1c6504d29312 100644
--- a/arch/m32r/include/asm/Kbuild
+++ b/arch/m32r/include/asm/Kbuild
@@ -12,3 +12,4 @@ generic-y += sections.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild
index eef72c464c9b..d465f51c2088 100644
--- a/arch/m68k/include/asm/Kbuild
+++ b/arch/m68k/include/asm/Kbuild
@@ -36,3 +36,4 @@ generic-y += types.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/metag/include/asm/Kbuild b/arch/metag/include/asm/Kbuild
index 50ebd5a30d16..c869b1ebd583 100644
--- a/arch/metag/include/asm/Kbuild
+++ b/arch/metag/include/asm/Kbuild
@@ -57,3 +57,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild
index c6c2cf6edc98..63c083a1f8da 100644
--- a/arch/microblaze/include/asm/Kbuild
+++ b/arch/microblaze/include/asm/Kbuild
@@ -12,3 +12,4 @@ generic-y += syscalls.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild
index 12f7c5984c03..ed225600c8a4 100644
--- a/arch/mips/include/asm/Kbuild
+++ b/arch/mips/include/asm/Kbuild
@@ -21,3 +21,4 @@ generic-y += user.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/mn10300/include/asm/Kbuild b/arch/mn10300/include/asm/Kbuild
index f8145bc85835..656af7b69940 100644
--- a/arch/mn10300/include/asm/Kbuild
+++ b/arch/mn10300/include/asm/Kbuild
@@ -11,3 +11,4 @@ generic-y += sections.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/nios2/include/asm/Kbuild b/arch/nios2/include/asm/Kbuild
index c9c7cb82b00f..c55880659d67 100644
--- a/arch/nios2/include/asm/Kbuild
+++ b/arch/nios2/include/asm/Kbuild
@@ -64,3 +64,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild
index 86175e701869..7d6a704b808c 100644
--- a/arch/openrisc/include/asm/Kbuild
+++ b/arch/openrisc/include/asm/Kbuild
@@ -72,3 +72,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild
index 6f43f33f0e0f..1a263a7158e2 100644
--- a/arch/parisc/include/asm/Kbuild
+++ b/arch/parisc/include/asm/Kbuild
@@ -30,3 +30,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild
index b49fab7bab2f..065c6e84fb67 100644
--- a/arch/powerpc/include/asm/Kbuild
+++ b/arch/powerpc/include/asm/Kbuild
@@ -8,3 +8,4 @@ generic-y += preempt.h
 generic-y += rwsem.h
 generic-y += vtime.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild
index 89e74b59f32d..3e8b95927cb5 100644
--- a/arch/s390/include/asm/Kbuild
+++ b/arch/s390/include/asm/Kbuild
@@ -9,3 +9,4 @@ generic-y += preempt.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild
index f089a264cd38..f0cdb2cbca4d 100644
--- a/arch/score/include/asm/Kbuild
+++ b/arch/score/include/asm/Kbuild
@@ -15,3 +15,4 @@ generic-y += xor.h
 generic-y += serial.h
 generic-y += word-at-a-time.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild
index 7b0356dca562..c9bb7932a3d1 100644
--- a/arch/sh/include/asm/Kbuild
+++ b/arch/sh/include/asm/Kbuild
@@ -40,3 +40,4 @@ generic-y += trace_clock.h
 generic-y += ucontext.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild
index d51b84d6b4b7..79664d10e63b 100644
--- a/arch/sparc/include/asm/Kbuild
+++ b/arch/sparc/include/asm/Kbuild
@@ -23,3 +23,4 @@ generic-y += trace_clock.h
 generic-y += types.h
 generic-y += word-at-a-time.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild
index 7b8a652e43ae..951fa4be571d 100644
--- a/arch/tile/include/asm/Kbuild
+++ b/arch/tile/include/asm/Kbuild
@@ -42,3 +42,4 @@ generic-y += trace_clock.h
 generic-y += types.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild
index e9849834d55e..99be54949b99 100644
--- a/arch/um/include/asm/Kbuild
+++ b/arch/um/include/asm/Kbuild
@@ -28,3 +28,4 @@ generic-y += trace_clock.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild
index 256c45b3ae34..6c35905fe371 100644
--- a/arch/unicore32/include/asm/Kbuild
+++ b/arch/unicore32/include/asm/Kbuild
@@ -64,3 +64,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += ranges.h
diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild
index f6914a57bc16..f790756fdb48 100644
--- a/arch/x86/include/asm/Kbuild
+++ b/arch/x86/include/asm/Kbuild
@@ -17,3 +17,4 @@ generic-y += early_ioremap.h
 generic-y += mcs_spinlock.h
 generic-y += mm-arch-hooks.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
index 0c2fae8d929d..c215db049920 100644
--- a/arch/x86/tools/relocs.c
+++ b/arch/x86/tools/relocs.c
@@ -68,6 +68,8 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = {
 	"__end_rodata|"
 	"__initramfs_start|"
 	"(jiffies|jiffies_64)|"
+	".rodata.rng.*|"
+	".init.text.rng.*|"
 #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 81ca6816bd72..221b6b652500 100644
--- a/arch/xtensa/include/asm/Kbuild
+++ b/arch/xtensa/include/asm/Kbuild
@@ -32,3 +32,4 @@ generic-y += trace_clock.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/include/asm-generic/ranges.h b/include/asm-generic/ranges.h
new file mode 100644
index 000000000000..74cd941aa2f8
--- /dev/null
+++ b/include/asm-generic/ranges.h
@@ -0,0 +1,89 @@
+#ifndef _ASM_GENERIC_RANGES_H_
+#define _ASM_GENERIC_RANGES_H_
+/*
+ * Copyright (C) 2016 Luis R. Rodriguez <mcgrof@kernel.org>
+ *
+ * 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_RNG(section, name)					\
+	SECTION_CORE(section, rng, name,				\
+		     SECTION_ORDER_ANY)
+
+#define SECTION_RNG_LEVEL(section, name, level)				\
+	SECTION_CORE(section, rng, name, level)
+
+#define SECTION_RNG_ALL(section)					\
+	SECTION_CORE_ALL(section,rng)
+
+#ifndef set_section_rng
+# define set_section_rng(section, name, flags)				\
+	 set_section_core(section, rng, name,				\
+			  SECTION_ORDER_ANY, flags)
+#endif
+
+#ifndef set_section_rng_type
+# define set_section_rng_type(section, name, flags, type)		\
+	 set_section_core_type(section, rng, name,			\
+			       SECTION_ORDER_ANY, flags, type)
+#endif
+
+#ifndef set_section_rng_level
+# define set_section_rng_level(section, name, level, flags)		\
+	 set_section_core(section, rng, name, level, flags)
+#endif
+
+#ifndef push_section_rng
+# define push_section_rng(section, name, flags)				\
+	 push_section_core(section, rng, name,				\
+			   SECTION_ORDER_ANY, flags)
+#endif
+
+#ifndef push_section_rng_level
+# define push_section_rng_level(section, name, level, flags)		\
+	 push_section_core(section, rng, name,				\
+			   level, flags)
+#endif
+
+#ifndef __ASSEMBLY__
+/**
+ * __LINUX_RANGE - short hand association into a section range
+ *
+ * @section: ELF section name to place section range into
+ * @name: section range name
+ *
+ * This helper can be used by subsystems to define their own subsystem
+ * specific helpers to easily associate a piece of code being defined to a
+ * section range.
+ */
+#define __LINUX_RANGE(section, name)					\
+	__attribute__((__section__(SECTION_RNG(section, name))))
+
+/**
+ * __LINUX_RANGE_ORDER - short hand association into a section range of order
+ *
+ * @section: ELF section name to place section range into
+ * @name: section range name
+ * @level: order level, a number. The order level gets tucked into the
+ *	section as a postfix string. Order levels are sorted using
+ * 	binutils SORT(), the number is sorted as a string, as such be
+ * 	sure to fill with zeroes any empty digits. For instance if you are
+ * 	using 3 levels of digits for order levels, use 001 for the first entry,
+ * 	0002 for the second, 999 for the last entry. You can use however many
+ * 	digits you need.
+ *
+ * This helper can be used by subsystems to define their own subsystem specific
+ * helpers to easily associate a piece of code being defined to a section range
+ * with an associated specific order level. The order level provides the
+ * ability for explicit user ordering of code. Sorting takes place at link
+ * time, after compilation.
+ */
+#define __LINUX_RANGE_ORDER(section, name, level)			\
+	__attribute__((__section__(SECTION_RNG_LEVEL(section, name, level))))
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_GENERIC_RANGES_H_ */
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 731087276a32..ad843555e6a4 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -56,6 +56,7 @@
 
 #include <linux/export.h>
 #include <asm/section-core.h>
+#include <asm/ranges.h>
 
 /* Align . to a 8 byte boundary equals to maximum function alignment. */
 #define ALIGN_FUNCTION()  . = ALIGN(8)
@@ -200,6 +201,7 @@
 /* .data section */
 #define DATA_DATA							\
 	*(SECTION_DATA)							\
+	*(SORT(SECTION_RNG_ALL(SECTION_DATA)))				\
 	*(SECTION_REF_DATA)						\
 	*(.data..shared_aligned) /* percpu related */			\
 	MEM_KEEP(init.data)						\
@@ -265,7 +267,9 @@
 	. = ALIGN((align));						\
 	SECTION_RODATA    : AT(ADDR(SECTION_RODATA) - LOAD_OFFSET) {	\
 		VMLINUX_SYMBOL(__start_rodata) = .;			\
-		*(SECTION_RODATA) *(SECTION_ALL(SECTION_RODATA))	\
+		*(SECTION_RODATA)					\
+		*(SORT(SECTION_RNG_ALL(SECTION_RODATA)))		\
+		*(SECTION_ALL(SECTION_RODATA))				\
 		RO_AFTER_INIT_DATA	/* Read only after init */	\
 		*(__vermagic)		/* Kernel version magic */	\
 		. = ALIGN(8);						\
@@ -433,7 +437,9 @@
  * during second ld run in second ld pass when generating System.map */
 #define TEXT_TEXT							\
 		ALIGN_FUNCTION();					\
-		*(.text.hot SECTION_TEXT .text.fixup .text.unlikely)	\
+		*(.text.hot SECTION_TEXT)				\
+		*(SORT(SECTION_RNG_ALL(SECTION_TEXT)))			\
+		*(.text.fixup .text.unlikely)				\
 		*(SECTION_REF)						\
 	MEM_KEEP(init.text)						\
 	MEM_KEEP(exit.text)						\
@@ -529,6 +535,7 @@
 /* init and exit section handling */
 #define INIT_DATA							\
 	*(SECTION_INIT_DATA)						\
+	*(SORT(SECTION_RNG_ALL(SECTION_INIT_DATA)))			\
 	MEM_DISCARD(init.data)						\
 	KERNEL_CTORS()							\
 	MCOUNT_REC()							\
@@ -551,6 +558,7 @@
 
 #define INIT_TEXT							\
 	*(SECTION_INIT)							\
+	*(SORT(SECTION_RNG_ALL(SECTION_INIT)))				\
 	*(.text.startup)						\
 	MEM_DISCARD(init.text)
 
diff --git a/include/linux/ranges.h b/include/linux/ranges.h
new file mode 100644
index 000000000000..30b2182bd484
--- /dev/null
+++ b/include/linux/ranges.h
@@ -0,0 +1,128 @@
+#ifndef _LINUX_RANGES_H
+#define _LINUX_RANGES_H
+/*
+ * Linux section ranges
+ *
+ * Copyright (C) 2016 Luis R. Rodriguez <mcgrof@kernel.org>
+ *
+ * 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/sections.h>
+#include <asm/ranges.h>
+
+#ifndef __ASSEMBLY__
+
+/**
+ * DOC: Introduction
+ *
+ * A section ranges consists of explicitly annotated series executable code
+ * stitched together for the purpose of selective placement into standard or
+ * architecture specific ELF sections. What ELF section is used is utility
+ * specific. Linux has historically implicitly used section ranges, however
+ * they were all built in an adhoc manner and typically required linker script
+ * modifications per architecture. The section range API allows adding new
+ * bundles of stiched executable code into custom ELF sections by only
+ * modifying C or asm code in an architecture agnostic form.
+ *
+ * This documents the set of helpers available to declare, and define section
+ * ranges and associate each section range to a specific Linux ELF section.
+ */
+
+/**
+ * DOC: Section range module support
+ *
+ * Modules can use section ranges, however the section range definition must be
+ * built-in to the kernel. That is, the code that implements
+ * DEFINE_SECTION_RANGE() must be built-in, and modular code cannot add more
+ * items in to the section range (with __LINUX_RANGE() or
+ * __LINUX_RANGE_ORDER()), 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: Section range helpers
+ *
+ * These are helpers for section ranges.
+ */
+
+/**
+ * DECLARE_SECTION_RANGE - Declares a section range
+ *
+ * @name: section range name
+ *
+ * Declares a section range to help code access the range. Typically if
+ * a subsystems needs code to have direct access to the section range the
+ * subsystem's header file would declare the section range. Care should be
+ * taken to only declare the section range in a header file if access to it
+ * is truly needed outside of the code defining it. You typically would
+ * rather instead provide helpers which access the section range with special
+ * code on behalf of the caller.
+ */
+#define DECLARE_SECTION_RANGE(name)					\
+	DECLARE_LINUX_SECTION_RO(char, name)
+
+/**
+ * __SECTION_RANGE_BEGIN - Constructs the beginning of a section range
+ *
+ * @name: section range name
+ * @__section: ELF section to place section range into
+ *
+ * Constructs the beginning of a section range. You will typically not need
+ * to use this directly.
+ */
+#define __SECTION_RANGE_BEGIN(name, __section)				\
+	const __typeof__(VMLINUX_SYMBOL(name)[0])			\
+	      __attribute__((used,					\
+			     weak,					\
+			     __aligned__(LINUX_SECTION_ALIGNMENT(name)),\
+			     section(SECTION_RNG_LEVEL(__section, name,))))
+
+/**
+ * __SECTION_RANGE_END - Constructs the end of a section range
+ *
+ * @name: section range name
+ * @__section: ELF section to place section range into
+ *
+ * Constructs the end of a section range. You will typically not need
+ * to use this directly.
+ */
+#define __SECTION_RANGE_END(name, __section)				\
+	const __typeof__(VMLINUX_SYMBOL(name)[0])			\
+	      __attribute__((used,					\
+			     __aligned__(LINUX_SECTION_ALIGNMENT(name)),\
+			     section(SECTION_RNG_LEVEL(__section, name, ~))))
+
+/**
+ * DEFINE_SECTION_RANGE - Defines a section range
+ *
+ * @name: section range name
+ * @section: ELF section name to place section range into
+ *
+ * Defines a section range, used for executable code. Section ranges are
+ * defined in the code that takes ownership and makes use of the section
+ * range.
+ */
+#define DEFINE_SECTION_RANGE(name, section)				\
+	DECLARE_LINUX_SECTION_RO(char, name);				\
+	__SECTION_RANGE_BEGIN(name, section) VMLINUX_SYMBOL(name)[0] = {};\
+	__SECTION_RANGE_END(name, section) VMLINUX_SYMBOL(name##__end)[0] = {}
+
+/**
+ * SECTION_ADDR_IN_RANGE - returns true if address is in range
+ *
+ * @name: section range name
+ * @addr: address to query for
+ *
+ * Returns true if the address is in the section range.
+ */
+#define SECTION_ADDR_IN_RANGE(name, addr)				\
+	 (addr >= (unsigned long) LINUX_SECTION_START(name) &&		\
+	  addr <  (unsigned long) LINUX_SECTION_END(name))
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _LINUX_RANGES_H */
-- 
2.9.2


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 06/16] ranges.h: add helpers to build and identify Linux section ranges
  2016-08-19 21:32 ` [PATCH v4 06/16] ranges.h: add helpers to build and identify Linux section ranges mcgrof
@ 2016-08-19 21:32   ` mcgrof
  2016-08-19 21:55   ` Kees Cook
  1 sibling, 0 replies; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: x86, luto, keescook, torvalds, gregkh, rusty, gnomes, alan,
	dwmw2, arnd, ming.lei, linux-arch, benh, ananth, pebolle,
	fontana, david.vrabel, konrad.wilk, mcb30, jgross,
	andrew.cooper3, andriy.shevchenko, paul.gortmaker, xen-devel, ak,
	pali.rohar, dvhart, platform-driver-x86, mmarek, linux, jkosina,
	korea.drzix, linux-kbuild, tony.luck, akpm, linux-ia64,
	linux-arm-kernel, linux-sh, sparclinux, catalin.marinas,
	will.deacon, rostedt, jani.nikula, mchehab, markus.heiser, acme,
	jolsa, msalter, chris, jcmvbkbc, linux-xtensa, paulus, mpe,
	James.Bottomley, Luis R. Rodriguez

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

Section ranges are on one of the types of custom sections
types used in Linux. This provides a series of helpers for
defining them and using them. Most importantly this also
enables us to avoid modifying the linker script when we
add a new section range.

It turns out a lot of custom sections are actually section ranges,
and these are typically spelled out in their architecture specific
asm/sections.h file -- we anable architectures to override what asm
is used for section ranges but start by default trusting the
asm-generic version all around.

v4:

o tons of documentation love
o fix arch/x86/tools/relocs.c typo - which caused compilation issues
  on old toolchains
o port to new shiny sphinx documentation
o sprinkle a few more needed VMLINUX_SYMBOL() - fixes
  compilation on blackfin
o name changes as suggested 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
- rebrand DECLARE_SECTION_RNG() as DEFINE_SECTION_RANGE() - this is
  the asm version of the respective C version, this will have a
  userspace C demo added later.
o move __LINUX_RANGE() and __LINUX_RANGE_ORDER() - fixes builds
  on sparc
o adds section ranges to linker script
o rename SECTION_RANGE_ALL()
o use default alignment, fixes builds on powerpc and arm for both
  __LINUX_RANGE() and __LINUX_RANGE_ORDER()
o expand documentation to document modules support
o add maintainers
o use generic-y

v3: new in this series, uses copyleft-next

Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 Documentation/sections/index.rst   |   1 +
 Documentation/sections/ranges.rst  |  49 ++++++++++++++
 MAINTAINERS                        |  10 +++
 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/Kbuild        |   1 +
 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       |  89 ++++++++++++++++++++++++++
 include/asm-generic/vmlinux.lds.h  |  12 +++-
 include/linux/ranges.h             | 128 +++++++++++++++++++++++++++++++++++++
 38 files changed, 320 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/sections/ranges.rst
 create mode 100644 include/asm-generic/ranges.h
 create mode 100644 include/linux/ranges.h

diff --git a/Documentation/sections/index.rst b/Documentation/sections/index.rst
index d411e9b22eb3..6dd93ddd5dbe 100644
--- a/Documentation/sections/index.rst
+++ b/Documentation/sections/index.rst
@@ -9,3 +9,4 @@ used throughout the kernel to help declare and define them.
    :maxdepth: 4
 
    section-core
+   ranges
diff --git a/Documentation/sections/ranges.rst b/Documentation/sections/ranges.rst
new file mode 100644
index 000000000000..1293dcb3ab38
--- /dev/null
+++ b/Documentation/sections/ranges.rst
@@ -0,0 +1,49 @@
+====================
+Linux section ranges
+====================
+
+This documents Linux' use of section ranges, how you can use
+them and how they work.
+
+About section ranges
+====================
+
+Introduction
+------------
+.. kernel-doc:: include/linux/ranges.h
+   :doc: Introduction
+
+Section range module support
+----------------------------
+.. kernel-doc:: include/linux/ranges.h
+   :doc: Section range module support
+
+Section range helpers
+=====================
+.. kernel-doc:: include/linux/ranges.h
+   :doc: Section range helpers
+
+DECLARE_SECTION_RANGE
+---------------------
+.. kernel-doc:: include/linux/ranges.h
+   :functions: DECLARE_SECTION_RANGE
+
+DEFINE_SECTION_RANGE
+--------------------
+.. kernel-doc:: include/linux/ranges.h
+   :functions: DEFINE_SECTION_RANGE
+
+SECTION_ADDR_IN_RANGE
+---------------------
+.. kernel-doc:: include/linux/ranges.h
+   :functions: SECTION_ADDR_IN_RANGE
+
+__LINUX_RANGE
+-------------
+.. kernel-doc:: include/asm-generic/ranges.h
+   :functions: __LINUX_RANGE
+
+__LINUX_RANGE_ORDER
+-------------------
+.. kernel-doc:: include/asm-generic/ranges.h
+   :functions: __LINUX_RANGE_ORDER
diff --git a/MAINTAINERS b/MAINTAINERS
index 689c12075842..1a217751aa8a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5217,6 +5217,16 @@ S:	Supported
 F:	drivers/base/power/domain*.c
 F:	include/linux/pm_domain.h
 
+GENERIC SECTION RANGES
+M:	"Luis R. Rodriguez" <mcgrof@kernel.org>
+M:	"H. Peter Anvin" <hpa@zytor.com>
+L:	linux-arch@vger.kernel.org
+L:	linux-kernel@vger.kernel.org
+S:	Supported
+F:	include/asm-generic/ranges.h
+F:	include/linux/ranges.h
+F:	Documentation/sections/ranges.rst
+
 GENERIC SECTIONS
 M:	"Luis R. Rodriguez" <mcgrof@kernel.org>
 M:	Josh Poimboeuf <jpoimboe@redhat.com>
diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild
index 5422827f1585..e44c896b91c4 100644
--- a/arch/alpha/include/asm/Kbuild
+++ b/arch/alpha/include/asm/Kbuild
@@ -11,3 +11,4 @@ generic-y += preempt.h
 generic-y += sections.h
 generic-y += trace_clock.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild
index 9a0929576de1..e5295413fdf8 100644
--- a/arch/arc/include/asm/Kbuild
+++ b/arch/arc/include/asm/Kbuild
@@ -51,3 +51,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
index 47923635be16..8e52300e1eed 100644
--- a/arch/arm/include/asm/Kbuild
+++ b/arch/arm/include/asm/Kbuild
@@ -40,3 +40,4 @@ generic-y += timex.h
 generic-y += trace_clock.h
 generic-y += unaligned.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index 42d00806e4fb..5ff184574976 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -53,3 +53,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/avr32/include/asm/Kbuild b/arch/avr32/include/asm/Kbuild
index f2c3b656a0e7..edc176348d7c 100644
--- a/arch/avr32/include/asm/Kbuild
+++ b/arch/avr32/include/asm/Kbuild
@@ -23,3 +23,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/blackfin/include/asm/Kbuild b/arch/blackfin/include/asm/Kbuild
index 7de674411bed..35b7752e65c0 100644
--- a/arch/blackfin/include/asm/Kbuild
+++ b/arch/blackfin/include/asm/Kbuild
@@ -49,3 +49,4 @@ generic-y += user.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild
index 38127ce747be..cede2a950fbf 100644
--- a/arch/c6x/include/asm/Kbuild
+++ b/arch/c6x/include/asm/Kbuild
@@ -63,3 +63,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild
index 385cd88a9d9e..fb8bb4112773 100644
--- a/arch/cris/include/asm/Kbuild
+++ b/arch/cris/include/asm/Kbuild
@@ -46,3 +46,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/frv/include/asm/Kbuild b/arch/frv/include/asm/Kbuild
index 46d7c599d9b8..5191fec655d7 100644
--- a/arch/frv/include/asm/Kbuild
+++ b/arch/frv/include/asm/Kbuild
@@ -9,3 +9,4 @@ generic-y += preempt.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/h8300/include/asm/Kbuild b/arch/h8300/include/asm/Kbuild
index 1ec04ec1c82b..7929a992566c 100644
--- a/arch/h8300/include/asm/Kbuild
+++ b/arch/h8300/include/asm/Kbuild
@@ -76,3 +76,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild
index 37d7bfae7619..af17ee334788 100644
--- a/arch/hexagon/include/asm/Kbuild
+++ b/arch/hexagon/include/asm/Kbuild
@@ -61,3 +61,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild
index 672c6d5da18c..d8f226b35a0a 100644
--- a/arch/ia64/include/asm/Kbuild
+++ b/arch/ia64/include/asm/Kbuild
@@ -10,3 +10,4 @@ generic-y += trace_clock.h
 generic-y += vtime.h
 generic-y += word-at-a-time.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/m32r/include/asm/Kbuild b/arch/m32r/include/asm/Kbuild
index 6111e1523750..1c6504d29312 100644
--- a/arch/m32r/include/asm/Kbuild
+++ b/arch/m32r/include/asm/Kbuild
@@ -12,3 +12,4 @@ generic-y += sections.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild
index eef72c464c9b..d465f51c2088 100644
--- a/arch/m68k/include/asm/Kbuild
+++ b/arch/m68k/include/asm/Kbuild
@@ -36,3 +36,4 @@ generic-y += types.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/metag/include/asm/Kbuild b/arch/metag/include/asm/Kbuild
index 50ebd5a30d16..c869b1ebd583 100644
--- a/arch/metag/include/asm/Kbuild
+++ b/arch/metag/include/asm/Kbuild
@@ -57,3 +57,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild
index c6c2cf6edc98..63c083a1f8da 100644
--- a/arch/microblaze/include/asm/Kbuild
+++ b/arch/microblaze/include/asm/Kbuild
@@ -12,3 +12,4 @@ generic-y += syscalls.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild
index 12f7c5984c03..ed225600c8a4 100644
--- a/arch/mips/include/asm/Kbuild
+++ b/arch/mips/include/asm/Kbuild
@@ -21,3 +21,4 @@ generic-y += user.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/mn10300/include/asm/Kbuild b/arch/mn10300/include/asm/Kbuild
index f8145bc85835..656af7b69940 100644
--- a/arch/mn10300/include/asm/Kbuild
+++ b/arch/mn10300/include/asm/Kbuild
@@ -11,3 +11,4 @@ generic-y += sections.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/nios2/include/asm/Kbuild b/arch/nios2/include/asm/Kbuild
index c9c7cb82b00f..c55880659d67 100644
--- a/arch/nios2/include/asm/Kbuild
+++ b/arch/nios2/include/asm/Kbuild
@@ -64,3 +64,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild
index 86175e701869..7d6a704b808c 100644
--- a/arch/openrisc/include/asm/Kbuild
+++ b/arch/openrisc/include/asm/Kbuild
@@ -72,3 +72,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild
index 6f43f33f0e0f..1a263a7158e2 100644
--- a/arch/parisc/include/asm/Kbuild
+++ b/arch/parisc/include/asm/Kbuild
@@ -30,3 +30,4 @@ generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild
index b49fab7bab2f..065c6e84fb67 100644
--- a/arch/powerpc/include/asm/Kbuild
+++ b/arch/powerpc/include/asm/Kbuild
@@ -8,3 +8,4 @@ generic-y += preempt.h
 generic-y += rwsem.h
 generic-y += vtime.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild
index 89e74b59f32d..3e8b95927cb5 100644
--- a/arch/s390/include/asm/Kbuild
+++ b/arch/s390/include/asm/Kbuild
@@ -9,3 +9,4 @@ generic-y += preempt.h
 generic-y += trace_clock.h
 generic-y += word-at-a-time.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild
index f089a264cd38..f0cdb2cbca4d 100644
--- a/arch/score/include/asm/Kbuild
+++ b/arch/score/include/asm/Kbuild
@@ -15,3 +15,4 @@ generic-y += xor.h
 generic-y += serial.h
 generic-y += word-at-a-time.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild
index 7b0356dca562..c9bb7932a3d1 100644
--- a/arch/sh/include/asm/Kbuild
+++ b/arch/sh/include/asm/Kbuild
@@ -40,3 +40,4 @@ generic-y += trace_clock.h
 generic-y += ucontext.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild
index d51b84d6b4b7..79664d10e63b 100644
--- a/arch/sparc/include/asm/Kbuild
+++ b/arch/sparc/include/asm/Kbuild
@@ -23,3 +23,4 @@ generic-y += trace_clock.h
 generic-y += types.h
 generic-y += word-at-a-time.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild
index 7b8a652e43ae..951fa4be571d 100644
--- a/arch/tile/include/asm/Kbuild
+++ b/arch/tile/include/asm/Kbuild
@@ -42,3 +42,4 @@ generic-y += trace_clock.h
 generic-y += types.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild
index e9849834d55e..99be54949b99 100644
--- a/arch/um/include/asm/Kbuild
+++ b/arch/um/include/asm/Kbuild
@@ -28,3 +28,4 @@ generic-y += trace_clock.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild
index 256c45b3ae34..6c35905fe371 100644
--- a/arch/unicore32/include/asm/Kbuild
+++ b/arch/unicore32/include/asm/Kbuild
@@ -64,3 +64,4 @@ generic-y += user.h
 generic-y += vga.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
+generic-y += ranges.h
diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild
index f6914a57bc16..f790756fdb48 100644
--- a/arch/x86/include/asm/Kbuild
+++ b/arch/x86/include/asm/Kbuild
@@ -17,3 +17,4 @@ generic-y += early_ioremap.h
 generic-y += mcs_spinlock.h
 generic-y += mm-arch-hooks.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
index 0c2fae8d929d..c215db049920 100644
--- a/arch/x86/tools/relocs.c
+++ b/arch/x86/tools/relocs.c
@@ -68,6 +68,8 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = {
 	"__end_rodata|"
 	"__initramfs_start|"
 	"(jiffies|jiffies_64)|"
+	".rodata.rng.*|"
+	".init.text.rng.*|"
 #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 81ca6816bd72..221b6b652500 100644
--- a/arch/xtensa/include/asm/Kbuild
+++ b/arch/xtensa/include/asm/Kbuild
@@ -32,3 +32,4 @@ generic-y += trace_clock.h
 generic-y += word-at-a-time.h
 generic-y += xor.h
 generic-y += section-core.h
+generic-y += ranges.h
diff --git a/include/asm-generic/ranges.h b/include/asm-generic/ranges.h
new file mode 100644
index 000000000000..74cd941aa2f8
--- /dev/null
+++ b/include/asm-generic/ranges.h
@@ -0,0 +1,89 @@
+#ifndef _ASM_GENERIC_RANGES_H_
+#define _ASM_GENERIC_RANGES_H_
+/*
+ * Copyright (C) 2016 Luis R. Rodriguez <mcgrof@kernel.org>
+ *
+ * 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_RNG(section, name)					\
+	SECTION_CORE(section, rng, name,				\
+		     SECTION_ORDER_ANY)
+
+#define SECTION_RNG_LEVEL(section, name, level)				\
+	SECTION_CORE(section, rng, name, level)
+
+#define SECTION_RNG_ALL(section)					\
+	SECTION_CORE_ALL(section,rng)
+
+#ifndef set_section_rng
+# define set_section_rng(section, name, flags)				\
+	 set_section_core(section, rng, name,				\
+			  SECTION_ORDER_ANY, flags)
+#endif
+
+#ifndef set_section_rng_type
+# define set_section_rng_type(section, name, flags, type)		\
+	 set_section_core_type(section, rng, name,			\
+			       SECTION_ORDER_ANY, flags, type)
+#endif
+
+#ifndef set_section_rng_level
+# define set_section_rng_level(section, name, level, flags)		\
+	 set_section_core(section, rng, name, level, flags)
+#endif
+
+#ifndef push_section_rng
+# define push_section_rng(section, name, flags)				\
+	 push_section_core(section, rng, name,				\
+			   SECTION_ORDER_ANY, flags)
+#endif
+
+#ifndef push_section_rng_level
+# define push_section_rng_level(section, name, level, flags)		\
+	 push_section_core(section, rng, name,				\
+			   level, flags)
+#endif
+
+#ifndef __ASSEMBLY__
+/**
+ * __LINUX_RANGE - short hand association into a section range
+ *
+ * @section: ELF section name to place section range into
+ * @name: section range name
+ *
+ * This helper can be used by subsystems to define their own subsystem
+ * specific helpers to easily associate a piece of code being defined to a
+ * section range.
+ */
+#define __LINUX_RANGE(section, name)					\
+	__attribute__((__section__(SECTION_RNG(section, name))))
+
+/**
+ * __LINUX_RANGE_ORDER - short hand association into a section range of order
+ *
+ * @section: ELF section name to place section range into
+ * @name: section range name
+ * @level: order level, a number. The order level gets tucked into the
+ *	section as a postfix string. Order levels are sorted using
+ * 	binutils SORT(), the number is sorted as a string, as such be
+ * 	sure to fill with zeroes any empty digits. For instance if you are
+ * 	using 3 levels of digits for order levels, use 001 for the first entry,
+ * 	0002 for the second, 999 for the last entry. You can use however many
+ * 	digits you need.
+ *
+ * This helper can be used by subsystems to define their own subsystem specific
+ * helpers to easily associate a piece of code being defined to a section range
+ * with an associated specific order level. The order level provides the
+ * ability for explicit user ordering of code. Sorting takes place at link
+ * time, after compilation.
+ */
+#define __LINUX_RANGE_ORDER(section, name, level)			\
+	__attribute__((__section__(SECTION_RNG_LEVEL(section, name, level))))
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_GENERIC_RANGES_H_ */
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 731087276a32..ad843555e6a4 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -56,6 +56,7 @@
 
 #include <linux/export.h>
 #include <asm/section-core.h>
+#include <asm/ranges.h>
 
 /* Align . to a 8 byte boundary equals to maximum function alignment. */
 #define ALIGN_FUNCTION()  . = ALIGN(8)
@@ -200,6 +201,7 @@
 /* .data section */
 #define DATA_DATA							\
 	*(SECTION_DATA)							\
+	*(SORT(SECTION_RNG_ALL(SECTION_DATA)))				\
 	*(SECTION_REF_DATA)						\
 	*(.data..shared_aligned) /* percpu related */			\
 	MEM_KEEP(init.data)						\
@@ -265,7 +267,9 @@
 	. = ALIGN((align));						\
 	SECTION_RODATA    : AT(ADDR(SECTION_RODATA) - LOAD_OFFSET) {	\
 		VMLINUX_SYMBOL(__start_rodata) = .;			\
-		*(SECTION_RODATA) *(SECTION_ALL(SECTION_RODATA))	\
+		*(SECTION_RODATA)					\
+		*(SORT(SECTION_RNG_ALL(SECTION_RODATA)))		\
+		*(SECTION_ALL(SECTION_RODATA))				\
 		RO_AFTER_INIT_DATA	/* Read only after init */	\
 		*(__vermagic)		/* Kernel version magic */	\
 		. = ALIGN(8);						\
@@ -433,7 +437,9 @@
  * during second ld run in second ld pass when generating System.map */
 #define TEXT_TEXT							\
 		ALIGN_FUNCTION();					\
-		*(.text.hot SECTION_TEXT .text.fixup .text.unlikely)	\
+		*(.text.hot SECTION_TEXT)				\
+		*(SORT(SECTION_RNG_ALL(SECTION_TEXT)))			\
+		*(.text.fixup .text.unlikely)				\
 		*(SECTION_REF)						\
 	MEM_KEEP(init.text)						\
 	MEM_KEEP(exit.text)						\
@@ -529,6 +535,7 @@
 /* init and exit section handling */
 #define INIT_DATA							\
 	*(SECTION_INIT_DATA)						\
+	*(SORT(SECTION_RNG_ALL(SECTION_INIT_DATA)))			\
 	MEM_DISCARD(init.data)						\
 	KERNEL_CTORS()							\
 	MCOUNT_REC()							\
@@ -551,6 +558,7 @@
 
 #define INIT_TEXT							\
 	*(SECTION_INIT)							\
+	*(SORT(SECTION_RNG_ALL(SECTION_INIT)))				\
 	*(.text.startup)						\
 	MEM_DISCARD(init.text)
 
diff --git a/include/linux/ranges.h b/include/linux/ranges.h
new file mode 100644
index 000000000000..30b2182bd484
--- /dev/null
+++ b/include/linux/ranges.h
@@ -0,0 +1,128 @@
+#ifndef _LINUX_RANGES_H
+#define _LINUX_RANGES_H
+/*
+ * Linux section ranges
+ *
+ * Copyright (C) 2016 Luis R. Rodriguez <mcgrof@kernel.org>
+ *
+ * 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/sections.h>
+#include <asm/ranges.h>
+
+#ifndef __ASSEMBLY__
+
+/**
+ * DOC: Introduction
+ *
+ * A section ranges consists of explicitly annotated series executable code
+ * stitched together for the purpose of selective placement into standard or
+ * architecture specific ELF sections. What ELF section is used is utility
+ * specific. Linux has historically implicitly used section ranges, however
+ * they were all built in an adhoc manner and typically required linker script
+ * modifications per architecture. The section range API allows adding new
+ * bundles of stiched executable code into custom ELF sections by only
+ * modifying C or asm code in an architecture agnostic form.
+ *
+ * This documents the set of helpers available to declare, and define section
+ * ranges and associate each section range to a specific Linux ELF section.
+ */
+
+/**
+ * DOC: Section range module support
+ *
+ * Modules can use section ranges, however the section range definition must be
+ * built-in to the kernel. That is, the code that implements
+ * DEFINE_SECTION_RANGE() must be built-in, and modular code cannot add more
+ * items in to the section range (with __LINUX_RANGE() or
+ * __LINUX_RANGE_ORDER()), 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: Section range helpers
+ *
+ * These are helpers for section ranges.
+ */
+
+/**
+ * DECLARE_SECTION_RANGE - Declares a section range
+ *
+ * @name: section range name
+ *
+ * Declares a section range to help code access the range. Typically if
+ * a subsystems needs code to have direct access to the section range the
+ * subsystem's header file would declare the section range. Care should be
+ * taken to only declare the section range in a header file if access to it
+ * is truly needed outside of the code defining it. You typically would
+ * rather instead provide helpers which access the section range with special
+ * code on behalf of the caller.
+ */
+#define DECLARE_SECTION_RANGE(name)					\
+	DECLARE_LINUX_SECTION_RO(char, name)
+
+/**
+ * __SECTION_RANGE_BEGIN - Constructs the beginning of a section range
+ *
+ * @name: section range name
+ * @__section: ELF section to place section range into
+ *
+ * Constructs the beginning of a section range. You will typically not need
+ * to use this directly.
+ */
+#define __SECTION_RANGE_BEGIN(name, __section)				\
+	const __typeof__(VMLINUX_SYMBOL(name)[0])			\
+	      __attribute__((used,					\
+			     weak,					\
+			     __aligned__(LINUX_SECTION_ALIGNMENT(name)),\
+			     section(SECTION_RNG_LEVEL(__section, name,))))
+
+/**
+ * __SECTION_RANGE_END - Constructs the end of a section range
+ *
+ * @name: section range name
+ * @__section: ELF section to place section range into
+ *
+ * Constructs the end of a section range. You will typically not need
+ * to use this directly.
+ */
+#define __SECTION_RANGE_END(name, __section)				\
+	const __typeof__(VMLINUX_SYMBOL(name)[0])			\
+	      __attribute__((used,					\
+			     __aligned__(LINUX_SECTION_ALIGNMENT(name)),\
+			     section(SECTION_RNG_LEVEL(__section, name, ~))))
+
+/**
+ * DEFINE_SECTION_RANGE - Defines a section range
+ *
+ * @name: section range name
+ * @section: ELF section name to place section range into
+ *
+ * Defines a section range, used for executable code. Section ranges are
+ * defined in the code that takes ownership and makes use of the section
+ * range.
+ */
+#define DEFINE_SECTION_RANGE(name, section)				\
+	DECLARE_LINUX_SECTION_RO(char, name);				\
+	__SECTION_RANGE_BEGIN(name, section) VMLINUX_SYMBOL(name)[0] = {};\
+	__SECTION_RANGE_END(name, section) VMLINUX_SYMBOL(name##__end)[0] = {}
+
+/**
+ * SECTION_ADDR_IN_RANGE - returns true if address is in range
+ *
+ * @name: section range name
+ * @addr: address to query for
+ *
+ * Returns true if the address is in the section range.
+ */
+#define SECTION_ADDR_IN_RANGE(name, addr)				\
+	 (addr >= (unsigned long) LINUX_SECTION_START(name) &&		\
+	  addr <  (unsigned long) LINUX_SECTION_END(name))
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _LINUX_RANGES_H */
-- 
2.9.2


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 07/16] tables.h: add linker table support
  2016-08-19 21:32 [PATCH v4 00/16] linux: generalize sections, ranges and linker tables mcgrof
                   ` (6 preceding siblings ...)
  2016-08-19 21:32 ` [PATCH v4 06/16] ranges.h: add helpers to build and identify Linux section ranges mcgrof
@ 2016-08-19 21:32 ` mcgrof
  2016-08-19 21:32   ` mcgrof
  2016-08-19 22:02   ` Kees Cook
  2016-08-19 21:32 ` [PATCH v4 08/16] kbuild: enable option to force compile force-obj-y and force-lib-y mcgrof
                   ` (3 subsequent siblings)
  11 siblings, 2 replies; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: gnomes, linux-ia64, jkosina, benh, ming.lei, linux,
	platform-driver-x86, James.Bottomley, paul.gortmaker, paulus,
	sparclinux, mchehab, linux-arch, markus.heiser, xen-devel,
	msalter, linux-sh, mpe, x86, fontana, linux-arm-kernel,
	catalin.marinas, dvhart, dwmw2, linux-xtensa, pali.rohar,
	keescook, arnd, jani.nikula, will.deacon, rusty, rostedt, acme,
	ak, andriy.shevchenko, mcb30

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

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@ipxe.org>
Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 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@kernel.org>
+M:	"H. Peter Anvin" <hpa@zytor.com>
+L:	linux-arch@vger.kernel.org
+L:	linux-kernel@vger.kernel.org
+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@ti.com>
 L:	linux-kernel@vger.kernel.org
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@kernel.org>
+ *
+ * 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.
+ *
+ * [0] https://lkml.kernel.org/r/1470798247.3551.94.camel@redhat.com
+ */
+
+#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@kernel.org>
+ *
+ * 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@kernel.org>
+ *
+ * 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


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 07/16] tables.h: add linker table support
  2016-08-19 21:32 ` [PATCH v4 07/16] tables.h: add linker table support mcgrof
@ 2016-08-19 21:32   ` mcgrof
  2016-08-19 22:02   ` Kees Cook
  1 sibling, 0 replies; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: x86, luto, keescook, torvalds, gregkh, rusty, gnomes, alan,
	dwmw2, arnd, ming.lei, linux-arch, benh, ananth, pebolle,
	fontana, david.vrabel, konrad.wilk, mcb30, jgross,
	andrew.cooper3, andriy.shevchenko, paul.gortmaker, xen-devel, ak,
	pali.rohar, dvhart, platform-driver-x86, mmarek, linux, jkosina,
	korea.drzix, linux-kbuild, tony.luck, akpm, linux-ia64,
	linux-arm-kernel, linux-sh, sparclinux, catalin.marinas,
	will.deacon, rostedt, jani.nikula, mchehab, markus.heiser, acme,
	jolsa, msalter, chris, jcmvbkbc, linux-xtensa, paulus, mpe,
	James.Bottomley, Luis R. Rodriguez

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

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@ipxe.org>
Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 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@kernel.org>
+M:	"H. Peter Anvin" <hpa@zytor.com>
+L:	linux-arch@vger.kernel.org
+L:	linux-kernel@vger.kernel.org
+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@ti.com>
 L:	linux-kernel@vger.kernel.org
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@kernel.org>
+ *
+ * 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.
+ *
+ * [0] https://lkml.kernel.org/r/1470798247.3551.94.camel@redhat.com
+ */
+
+#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@kernel.org>
+ *
+ * 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@kernel.org>
+ *
+ * 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


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 08/16] kbuild: enable option to force compile force-obj-y and force-lib-y
  2016-08-19 21:32 [PATCH v4 00/16] linux: generalize sections, ranges and linker tables mcgrof
                   ` (7 preceding siblings ...)
  2016-08-19 21:32 ` [PATCH v4 07/16] tables.h: add linker table support mcgrof
@ 2016-08-19 21:32 ` mcgrof
  2016-08-19 21:32   ` mcgrof
  2016-08-19 22:10   ` Kees Cook
  2016-08-19 21:32 ` [PATCH v4 09/16] firmware/Makefile: force recompilation if makefile changes mcgrof
                   ` (2 subsequent siblings)
  11 siblings, 2 replies; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: gnomes, linux-ia64, jkosina, benh, ming.lei, linux,
	platform-driver-x86, James.Bottomley, paul.gortmaker, paulus,
	sparclinux, mchehab, linux-arch, markus.heiser, xen-devel,
	msalter, linux-sh, mpe, x86, fontana, linux-arm-kernel,
	catalin.marinas, dvhart, dwmw2, linux-xtensa, pali.rohar,
	keescook, arnd, jani.nikula, will.deacon, rusty, rostedt, acme,
	ak, andriy.shevchenko, mcb30

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

Linux provides a rich array of features, enabling each feature
however increases the size of the kernel and there are many
features which users often want disabled. The traditional
solution to this problem is for each feature to have its own
Kconfig symbol, followed by a series of #ifdef statements
in C code and header files, allowing the feature to be compiled
only when desirable. As the variability of Linux increases build
tests can and are often done with random kernel configurations,
allyesconfig, and allmodconfig to help find code issues. This
however doesn't catch all errors and as a consequence code that
is typically not enabled often can suffer from bit-rot over time.

An alternative approach for subsystems, which refer to as the 'build-all
link-selectively philosophy' is to keep the Kconfig symbols, replace
the #ifdef approach by having each feature implemented it its own C file,
and force compilation for all features to avoid the code bit-rot problem.
With this strategy only features that are enabled via Kconfig get
linked into the kernel, so the forced compilation has no size impact
on the kernel. The practice of having each feature implemented in its own
C file is already prevalent in many subsystems, however #ifdefs are still
typically required during feature initialization. For instance in:

  #ifdef CONFIG_FOO
  foo_init();
  #endif

We cannot remove the #ifdef and leave foo_init() as we'd either
need to always enable the feature or add a respective #ifdef in a
foo.h which makes foo_init() do nothing when CONFIG_FOO is disabled.

Linker tables enable lifting the requirement to use of #ifdefs during
initialization. With linker tables initialization sequences can instead
be aggregated into a custom ELF section at link time, during run time
the table can be iterated over and each init sequence enabled can be called.
A feature's init routine is only added to a table when its respective
Kconfig symbols has been enabled and therefore linked in. Linker tables
enable subsystems to completely do away with #ifdefs if one is comfortable
in accepting all subsystem's feature's structural size implications.

Subsystems which want to follow the 'build-all link-selectively
philosophy' still need a way to easily express and annotate that they
wish for all code to always be compiled to help avoid code bit rot,
as such two new targets force-obj-y and force-lib-y are provided to
help with this. Its not fair to require everyone to force compilation
of all features of a subsystem though, so as a compromise, the new
targets only force compilation when CONFIG_BUILD_AVOID_BITROT is
enabled.

Only built-in features are supported at the moment. Module support
is expected to be added after a generic solution to add linker
tables to modules more easily is developed.

v4: this patch was added to this series, it was split off from the
    linker tables addition due to the confusion over the code bit
    rot alternatives that are possible with linker tables.

Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 Documentation/kbuild/makefiles.txt       | 36 ++++++++++++++++
 Documentation/sections/linker-tables.rst | 15 +++++++
 include/linux/tables.h                   | 71 ++++++++++++++++++++++++++++++++
 init/Kconfig                             | 22 ++++++++++
 scripts/Makefile.build                   |  7 ++--
 scripts/Makefile.lib                     | 11 +++++
 6 files changed, 159 insertions(+), 3 deletions(-)

diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt
index 385a5ef41c17..01c260913f5c 100644
--- a/Documentation/kbuild/makefiles.txt
+++ b/Documentation/kbuild/makefiles.txt
@@ -1089,6 +1089,42 @@ When kbuild executes, the following steps are followed (roughly):
 	In this example, extra-y is used to list object files that
 	shall be built, but shall not be linked as part of built-in.o.
 
+    force-obj-y force-lib-y
+
+	When CONFIG_BUILD_AVOID_BITROT is enabled using these targets for your
+	kconfig symbols forces compilation of the associated objects if the
+	kconfig's symbol's dependencies are met, the objects however are only
+	linked into to the kernel if and only if the kconfig symbol was
+	enabled. If CONFIG_BUILD_AVOID_BITROT is disabled the force-obj-y and
+	force-lib-y targets are functionally equilvalent to obj-y and lib-y
+	respectively.
+
+	Using force-obj-y and force-lib-y are part of a code architecture and
+	build philosophy further enabled by linker tables, for more details
+	refer to the documention in include/linux/tables.h, refer to the
+	sections:
+
+		o The code bit-rot problem
+		o The build-all selective-link philosophy
+		o Avoiding the code bit-rot problem with linker tables
+		o Linker table module support
+
+	Modules support is expected to be enhanced in the future, so for now
+	only built-in features are supported.
+
+	Example use:
+
+		force-obj-$(CONFIG_FEATURE_FOO) += foo.o
+
+	An alternative to using force-obj-y, is to use extra-y followed by the
+	respective obj-y:
+
+		extra-y += foo.o
+		obj-$(CONFIG_FEATURE_FOO) += foo.o
+
+	Using force-obj-y and force-lib-y can be used to help annotate the
+	targets follow the 'build-all selective-link philosophy' further
+	enabled by linker tables.
 
 --- 6.7 Commands useful for building a boot image
 
diff --git a/Documentation/sections/linker-tables.rst b/Documentation/sections/linker-tables.rst
index df11c632dca7..e425c5cd36d6 100644
--- a/Documentation/sections/linker-tables.rst
+++ b/Documentation/sections/linker-tables.rst
@@ -30,6 +30,21 @@ How linker tables simplify initialization code
 .. kernel-doc:: include/linux/tables.h
    :doc: How linker tables simplify initialization code
 
+The code bit-rot problem
+------------------------
+.. kernel-doc:: include/linux/tables.h
+   :doc: The code bit-rot problem
+
+The build-all selective-link philosophy
+---------------------------------------
+.. kernel-doc:: include/linux/tables.h
+   :doc: The build-all selective-link philosophy
+
+Avoiding the code bit-rot problem with linker tables
+----------------------------------------------------
+.. kernel-doc:: include/linux/tables.h
+   :doc: Avoiding the code bit-rot problem with linker tables
+
 Using linker tables in Linux
 ============================
 
diff --git a/include/linux/tables.h b/include/linux/tables.h
index 423827eafb52..bf8fae7f9246 100644
--- a/include/linux/tables.h
+++ b/include/linux/tables.h
@@ -169,6 +169,77 @@
  */
 
 /**
+ * DOC: The code bit-rot problem
+ *
+ * Linux provides a rich array of features, enabling each feature
+ * however increases the size of the kernel and there are many
+ * features which users often want disabled. The traditional
+ * solution to this problem is for each feature to have its own
+ * Kconfig symbol, followed by a series of #ifdef statements
+ * in C code and header files, allowing the feature to be compiled
+ * only when desirable. As the variability of Linux increases build
+ * tests can and are often done with random kernel configurations,
+ * allyesconfig, and allmodconfig to help find code issues. This
+ * however doesn't catch all errors and as a consequence code that
+ * is typically not enabled often can suffer from bit-rot over time.
+ */
+
+/**
+ * DOC: The build-all selective-link philosophy
+ *
+ * A code architecture philosophy to help avoid code bit-rot consists
+ * of using Kconfig symbols for each subsystem feature, replace all #ifdefs
+ * by instead having each feature implemented it its own C file, and force
+ * compilation for all features. Only features that are enabled get linked in,
+ * the forced compilation therefore has no size impact on the final result of
+ * the kernel. The practice of having each feature implemented in its own C
+ * file is already prevalent in many subsystems, however #ifdefs are still
+ * typically required during feature initialization. For instance in::
+ *
+ *	#ifdef CONFIG_FOO
+ *	foo_init();
+ *	#endif
+ *
+ * We cannot remove the #ifdef and leave foo_init() as we'd either
+ * need to always enable the feature or add a respective #ifdef in a
+ * foo.h which makes foo_init() do nothing when ``CONFIG_FOO`` is disabled.
+ */
+
+/**
+ * DOC: Avoiding the code bit-rot problem with linker tables
+ *
+ * Linker tables can be used to further help avoid the code bit-rot problem
+ * when embracing the 'build-all selective-link philosophy' by lifting the
+ * requirement to use of #ifdefs during initialization. With linker tables
+ * initialization sequences can be aggregated into a custom ELF section at
+ * link time, during run time the table can be iterated over and each init
+ * sequence enabled can be called. A feature's init routine is only added to a
+ * table when its respective Kconfig symbols has been enabled and therefore
+ * linked in. Linker tables enable subsystems to completely do away with
+ * #ifdefs if one is comfortable in accepting all subsystem's feature's
+ * structural size implications.
+ *
+ * To further help with this the Linux build system supports two special
+ * targets, ``force-obj-y`` and ``force-lib-y``. A subsystem which wants to
+ * follow the 'build-all selective-link philosophy' can use these targets for a
+ * feature's kconfig symbol. Using these targets will always require
+ * compilation of the kconfig's objects if the kconfig symbol's dependencies
+ * are met but only link the objects into the kernel, and therefore enable the
+ * feature, if and only if the kconfig symbol has been enabled.
+ *
+ * Not all users or build systems may want to opt-in to compile all objects
+ * following the 'build-all selective-link philosophy', as such the targets
+ * ``force-obj-y`` and ``force-lib-y`` only force compilation when the kconfig
+ * symbol ``CONFIG_BUILD_AVOID_BITROT`` has been enabled. Disabling this feature
+ * makes ``force-obj-y`` and ``force-lib-y`` functionally equivalent to
+ * ``obj-y`` and ``lib-y`` respectively.
+ *
+ * Example use::
+ *
+ * 	force-obj-$(CONFIG_FEATURE_FOO) += foo.o
+ */
+
+/**
  * DOC: Linker table module support
  *
  * Modules can use linker tables, however the linker table definition
diff --git a/init/Kconfig b/init/Kconfig
index cac3f096050d..ef09e83b9196 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -53,6 +53,28 @@ config CROSS_COMPILE
 	  need to set this unless you want the configured kernel build
 	  directory to select the cross-compiler automatically.
 
+config BUILD_AVOID_BITROT
+	bool "Enable force building of force-obj-y and force-lib-y"
+	default n
+	help
+	  When enabled objects under the force-obj-y and force-lib-y targets
+	  using a Kconfig symbol will be forced to compile if the Kconfig
+	  symbol's dependencies are met but only linked into the kernel if
+	  the Kconfig symbol is enabled. If a Kconfig symbol on a force-obj-y
+	  or force-lib-y target is disabled, it will be compiled but not linked
+	  into the kernel.
+
+	  The force-obj-y and force-lib-y targets can be used by subsystems
+	  which wish to want to follow the 'build-all selective-link philosophy'
+	  documented under include/linux/tables.h.
+
+	  Say Y if you have a decent build machine and would like to help test
+	  building code for more subsystems. Say N if you do you not have a
+	  good build machine or only want to compile what you've enabled for
+	  your kernel.
+
+	  Enabling this option never increases the size of your kernel.
+
 config COMPILE_TEST
 	bool "Compile also drivers which will not load"
 	depends on !UML
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index cd9bf22bb027..cc2c7241d193 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -92,7 +92,8 @@ modorder-target := $(obj)/modules.order
 
 # We keep a list of all modules in $(MODVERDIR)
 
-__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
+__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y) \
+				$(force-obj-y)) \
 	 $(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
 	 $(subdir-ym) $(always)
 	@:
@@ -326,8 +327,8 @@ cmd_as_o_S       = $(CC) $(a_flags) -c -o $@ $<
 $(obj)/%.o: $(src)/%.S $(objtool_obj) FORCE
 	$(call if_changed_rule,as_o_S)
 
-targets += $(real-objs-y) $(real-objs-m) $(lib-y)
-targets += $(extra-y) $(MAKECMDGOALS) $(always)
+targets += $(real-objs-y) $(real-objs-m) $(lib-y) $(force-lib-y)
+targets += $(extra-y) $(force-obj-y) $(MAKECMDGOALS) $(always)
 
 # Linker scripts preprocessor (.lds.S -> .lds)
 # ---------------------------------------------------------------------------
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 0a07f9014944..d1cb0cfdf1bf 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -12,6 +12,15 @@ export KBUILD_SUBDIR_CCFLAGS := $(KBUILD_SUBDIR_CCFLAGS) $(subdir-ccflags-y)
 # Figure out what we need to build from the various variables
 # ===========================================================================
 
+ifeq ($(CONFIG_BUILD_AVOID_BITROT),y)
+extra-y += $(force-obj-) $(force-lib-)
+endif
+
+obj-m += $(force-obj-m)
+obj-y += $(force-obj-y)
+lib-m += $(force-lib-m)
+lib-y += $(force-lib-y)
+
 # When an object is listed to be built compiled-in and modular,
 # only build the compiled-in version
 
@@ -72,6 +81,8 @@ real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)
 # Add subdir path
 
 extra-y		:= $(addprefix $(obj)/,$(extra-y))
+force-obj-y		:= $(addprefix $(obj)/,$(force-obj-y))
+force-obj-m		:= $(addprefix $(obj)/,$(force-obj-m))
 always		:= $(addprefix $(obj)/,$(always))
 targets		:= $(addprefix $(obj)/,$(targets))
 modorder	:= $(addprefix $(obj)/,$(modorder))
-- 
2.9.2


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 08/16] kbuild: enable option to force compile force-obj-y and force-lib-y
  2016-08-19 21:32 ` [PATCH v4 08/16] kbuild: enable option to force compile force-obj-y and force-lib-y mcgrof
@ 2016-08-19 21:32   ` mcgrof
  2016-08-19 22:10   ` Kees Cook
  1 sibling, 0 replies; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: x86, luto, keescook, torvalds, gregkh, rusty, gnomes, alan,
	dwmw2, arnd, ming.lei, linux-arch, benh, ananth, pebolle,
	fontana, david.vrabel, konrad.wilk, mcb30, jgross,
	andrew.cooper3, andriy.shevchenko, paul.gortmaker, xen-devel, ak,
	pali.rohar, dvhart, platform-driver-x86, mmarek, linux, jkosina,
	korea.drzix, linux-kbuild, tony.luck, akpm, linux-ia64,
	linux-arm-kernel, linux-sh, sparclinux, catalin.marinas,
	will.deacon, rostedt, jani.nikula, mchehab, markus.heiser, acme,
	jolsa, msalter, chris, jcmvbkbc, linux-xtensa, paulus, mpe,
	James.Bottomley, Luis R. Rodriguez

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

Linux provides a rich array of features, enabling each feature
however increases the size of the kernel and there are many
features which users often want disabled. The traditional
solution to this problem is for each feature to have its own
Kconfig symbol, followed by a series of #ifdef statements
in C code and header files, allowing the feature to be compiled
only when desirable. As the variability of Linux increases build
tests can and are often done with random kernel configurations,
allyesconfig, and allmodconfig to help find code issues. This
however doesn't catch all errors and as a consequence code that
is typically not enabled often can suffer from bit-rot over time.

An alternative approach for subsystems, which refer to as the 'build-all
link-selectively philosophy' is to keep the Kconfig symbols, replace
the #ifdef approach by having each feature implemented it its own C file,
and force compilation for all features to avoid the code bit-rot problem.
With this strategy only features that are enabled via Kconfig get
linked into the kernel, so the forced compilation has no size impact
on the kernel. The practice of having each feature implemented in its own
C file is already prevalent in many subsystems, however #ifdefs are still
typically required during feature initialization. For instance in:

  #ifdef CONFIG_FOO
  foo_init();
  #endif

We cannot remove the #ifdef and leave foo_init() as we'd either
need to always enable the feature or add a respective #ifdef in a
foo.h which makes foo_init() do nothing when CONFIG_FOO is disabled.

Linker tables enable lifting the requirement to use of #ifdefs during
initialization. With linker tables initialization sequences can instead
be aggregated into a custom ELF section at link time, during run time
the table can be iterated over and each init sequence enabled can be called.
A feature's init routine is only added to a table when its respective
Kconfig symbols has been enabled and therefore linked in. Linker tables
enable subsystems to completely do away with #ifdefs if one is comfortable
in accepting all subsystem's feature's structural size implications.

Subsystems which want to follow the 'build-all link-selectively
philosophy' still need a way to easily express and annotate that they
wish for all code to always be compiled to help avoid code bit rot,
as such two new targets force-obj-y and force-lib-y are provided to
help with this. Its not fair to require everyone to force compilation
of all features of a subsystem though, so as a compromise, the new
targets only force compilation when CONFIG_BUILD_AVOID_BITROT is
enabled.

Only built-in features are supported at the moment. Module support
is expected to be added after a generic solution to add linker
tables to modules more easily is developed.

v4: this patch was added to this series, it was split off from the
    linker tables addition due to the confusion over the code bit
    rot alternatives that are possible with linker tables.

Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 Documentation/kbuild/makefiles.txt       | 36 ++++++++++++++++
 Documentation/sections/linker-tables.rst | 15 +++++++
 include/linux/tables.h                   | 71 ++++++++++++++++++++++++++++++++
 init/Kconfig                             | 22 ++++++++++
 scripts/Makefile.build                   |  7 ++--
 scripts/Makefile.lib                     | 11 +++++
 6 files changed, 159 insertions(+), 3 deletions(-)

diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt
index 385a5ef41c17..01c260913f5c 100644
--- a/Documentation/kbuild/makefiles.txt
+++ b/Documentation/kbuild/makefiles.txt
@@ -1089,6 +1089,42 @@ When kbuild executes, the following steps are followed (roughly):
 	In this example, extra-y is used to list object files that
 	shall be built, but shall not be linked as part of built-in.o.
 
+    force-obj-y force-lib-y
+
+	When CONFIG_BUILD_AVOID_BITROT is enabled using these targets for your
+	kconfig symbols forces compilation of the associated objects if the
+	kconfig's symbol's dependencies are met, the objects however are only
+	linked into to the kernel if and only if the kconfig symbol was
+	enabled. If CONFIG_BUILD_AVOID_BITROT is disabled the force-obj-y and
+	force-lib-y targets are functionally equilvalent to obj-y and lib-y
+	respectively.
+
+	Using force-obj-y and force-lib-y are part of a code architecture and
+	build philosophy further enabled by linker tables, for more details
+	refer to the documention in include/linux/tables.h, refer to the
+	sections:
+
+		o The code bit-rot problem
+		o The build-all selective-link philosophy
+		o Avoiding the code bit-rot problem with linker tables
+		o Linker table module support
+
+	Modules support is expected to be enhanced in the future, so for now
+	only built-in features are supported.
+
+	Example use:
+
+		force-obj-$(CONFIG_FEATURE_FOO) += foo.o
+
+	An alternative to using force-obj-y, is to use extra-y followed by the
+	respective obj-y:
+
+		extra-y += foo.o
+		obj-$(CONFIG_FEATURE_FOO) += foo.o
+
+	Using force-obj-y and force-lib-y can be used to help annotate the
+	targets follow the 'build-all selective-link philosophy' further
+	enabled by linker tables.
 
 --- 6.7 Commands useful for building a boot image
 
diff --git a/Documentation/sections/linker-tables.rst b/Documentation/sections/linker-tables.rst
index df11c632dca7..e425c5cd36d6 100644
--- a/Documentation/sections/linker-tables.rst
+++ b/Documentation/sections/linker-tables.rst
@@ -30,6 +30,21 @@ How linker tables simplify initialization code
 .. kernel-doc:: include/linux/tables.h
    :doc: How linker tables simplify initialization code
 
+The code bit-rot problem
+------------------------
+.. kernel-doc:: include/linux/tables.h
+   :doc: The code bit-rot problem
+
+The build-all selective-link philosophy
+---------------------------------------
+.. kernel-doc:: include/linux/tables.h
+   :doc: The build-all selective-link philosophy
+
+Avoiding the code bit-rot problem with linker tables
+----------------------------------------------------
+.. kernel-doc:: include/linux/tables.h
+   :doc: Avoiding the code bit-rot problem with linker tables
+
 Using linker tables in Linux
 ============================
 
diff --git a/include/linux/tables.h b/include/linux/tables.h
index 423827eafb52..bf8fae7f9246 100644
--- a/include/linux/tables.h
+++ b/include/linux/tables.h
@@ -169,6 +169,77 @@
  */
 
 /**
+ * DOC: The code bit-rot problem
+ *
+ * Linux provides a rich array of features, enabling each feature
+ * however increases the size of the kernel and there are many
+ * features which users often want disabled. The traditional
+ * solution to this problem is for each feature to have its own
+ * Kconfig symbol, followed by a series of #ifdef statements
+ * in C code and header files, allowing the feature to be compiled
+ * only when desirable. As the variability of Linux increases build
+ * tests can and are often done with random kernel configurations,
+ * allyesconfig, and allmodconfig to help find code issues. This
+ * however doesn't catch all errors and as a consequence code that
+ * is typically not enabled often can suffer from bit-rot over time.
+ */
+
+/**
+ * DOC: The build-all selective-link philosophy
+ *
+ * A code architecture philosophy to help avoid code bit-rot consists
+ * of using Kconfig symbols for each subsystem feature, replace all #ifdefs
+ * by instead having each feature implemented it its own C file, and force
+ * compilation for all features. Only features that are enabled get linked in,
+ * the forced compilation therefore has no size impact on the final result of
+ * the kernel. The practice of having each feature implemented in its own C
+ * file is already prevalent in many subsystems, however #ifdefs are still
+ * typically required during feature initialization. For instance in::
+ *
+ *	#ifdef CONFIG_FOO
+ *	foo_init();
+ *	#endif
+ *
+ * We cannot remove the #ifdef and leave foo_init() as we'd either
+ * need to always enable the feature or add a respective #ifdef in a
+ * foo.h which makes foo_init() do nothing when ``CONFIG_FOO`` is disabled.
+ */
+
+/**
+ * DOC: Avoiding the code bit-rot problem with linker tables
+ *
+ * Linker tables can be used to further help avoid the code bit-rot problem
+ * when embracing the 'build-all selective-link philosophy' by lifting the
+ * requirement to use of #ifdefs during initialization. With linker tables
+ * initialization sequences can be aggregated into a custom ELF section at
+ * link time, during run time the table can be iterated over and each init
+ * sequence enabled can be called. A feature's init routine is only added to a
+ * table when its respective Kconfig symbols has been enabled and therefore
+ * linked in. Linker tables enable subsystems to completely do away with
+ * #ifdefs if one is comfortable in accepting all subsystem's feature's
+ * structural size implications.
+ *
+ * To further help with this the Linux build system supports two special
+ * targets, ``force-obj-y`` and ``force-lib-y``. A subsystem which wants to
+ * follow the 'build-all selective-link philosophy' can use these targets for a
+ * feature's kconfig symbol. Using these targets will always require
+ * compilation of the kconfig's objects if the kconfig symbol's dependencies
+ * are met but only link the objects into the kernel, and therefore enable the
+ * feature, if and only if the kconfig symbol has been enabled.
+ *
+ * Not all users or build systems may want to opt-in to compile all objects
+ * following the 'build-all selective-link philosophy', as such the targets
+ * ``force-obj-y`` and ``force-lib-y`` only force compilation when the kconfig
+ * symbol ``CONFIG_BUILD_AVOID_BITROT`` has been enabled. Disabling this feature
+ * makes ``force-obj-y`` and ``force-lib-y`` functionally equivalent to
+ * ``obj-y`` and ``lib-y`` respectively.
+ *
+ * Example use::
+ *
+ * 	force-obj-$(CONFIG_FEATURE_FOO) += foo.o
+ */
+
+/**
  * DOC: Linker table module support
  *
  * Modules can use linker tables, however the linker table definition
diff --git a/init/Kconfig b/init/Kconfig
index cac3f096050d..ef09e83b9196 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -53,6 +53,28 @@ config CROSS_COMPILE
 	  need to set this unless you want the configured kernel build
 	  directory to select the cross-compiler automatically.
 
+config BUILD_AVOID_BITROT
+	bool "Enable force building of force-obj-y and force-lib-y"
+	default n
+	help
+	  When enabled objects under the force-obj-y and force-lib-y targets
+	  using a Kconfig symbol will be forced to compile if the Kconfig
+	  symbol's dependencies are met but only linked into the kernel if
+	  the Kconfig symbol is enabled. If a Kconfig symbol on a force-obj-y
+	  or force-lib-y target is disabled, it will be compiled but not linked
+	  into the kernel.
+
+	  The force-obj-y and force-lib-y targets can be used by subsystems
+	  which wish to want to follow the 'build-all selective-link philosophy'
+	  documented under include/linux/tables.h.
+
+	  Say Y if you have a decent build machine and would like to help test
+	  building code for more subsystems. Say N if you do you not have a
+	  good build machine or only want to compile what you've enabled for
+	  your kernel.
+
+	  Enabling this option never increases the size of your kernel.
+
 config COMPILE_TEST
 	bool "Compile also drivers which will not load"
 	depends on !UML
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index cd9bf22bb027..cc2c7241d193 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -92,7 +92,8 @@ modorder-target := $(obj)/modules.order
 
 # We keep a list of all modules in $(MODVERDIR)
 
-__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
+__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y) \
+				$(force-obj-y)) \
 	 $(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
 	 $(subdir-ym) $(always)
 	@:
@@ -326,8 +327,8 @@ cmd_as_o_S       = $(CC) $(a_flags) -c -o $@ $<
 $(obj)/%.o: $(src)/%.S $(objtool_obj) FORCE
 	$(call if_changed_rule,as_o_S)
 
-targets += $(real-objs-y) $(real-objs-m) $(lib-y)
-targets += $(extra-y) $(MAKECMDGOALS) $(always)
+targets += $(real-objs-y) $(real-objs-m) $(lib-y) $(force-lib-y)
+targets += $(extra-y) $(force-obj-y) $(MAKECMDGOALS) $(always)
 
 # Linker scripts preprocessor (.lds.S -> .lds)
 # ---------------------------------------------------------------------------
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 0a07f9014944..d1cb0cfdf1bf 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -12,6 +12,15 @@ export KBUILD_SUBDIR_CCFLAGS := $(KBUILD_SUBDIR_CCFLAGS) $(subdir-ccflags-y)
 # Figure out what we need to build from the various variables
 # ===========================================================================
 
+ifeq ($(CONFIG_BUILD_AVOID_BITROT),y)
+extra-y += $(force-obj-) $(force-lib-)
+endif
+
+obj-m += $(force-obj-m)
+obj-y += $(force-obj-y)
+lib-m += $(force-lib-m)
+lib-y += $(force-lib-y)
+
 # When an object is listed to be built compiled-in and modular,
 # only build the compiled-in version
 
@@ -72,6 +81,8 @@ real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)
 # Add subdir path
 
 extra-y		:= $(addprefix $(obj)/,$(extra-y))
+force-obj-y		:= $(addprefix $(obj)/,$(force-obj-y))
+force-obj-m		:= $(addprefix $(obj)/,$(force-obj-m))
 always		:= $(addprefix $(obj)/,$(always))
 targets		:= $(addprefix $(obj)/,$(targets))
 modorder	:= $(addprefix $(obj)/,$(modorder))
-- 
2.9.2


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 09/16] firmware/Makefile: force recompilation if makefile changes
  2016-08-19 21:32 [PATCH v4 00/16] linux: generalize sections, ranges and linker tables mcgrof
                   ` (8 preceding siblings ...)
  2016-08-19 21:32 ` [PATCH v4 08/16] kbuild: enable option to force compile force-obj-y and force-lib-y mcgrof
@ 2016-08-19 21:32 ` mcgrof
  2016-08-19 21:32   ` mcgrof
  2016-08-19 21:32 ` [PATCH v4 10/16] firmware: port built-in section to linker table mcgrof
  2016-08-19 22:29 ` [PATCH v4 00/16] linux: generalize sections, ranges and linker tables Kees Cook
  11 siblings, 1 reply; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: gnomes, linux-ia64, jkosina, benh, ming.lei, linux,
	platform-driver-x86, James.Bottomley, paul.gortmaker, paulus,
	sparclinux, mchehab, linux-arch, markus.heiser, xen-devel,
	msalter, linux-sh, mpe, x86, fontana, linux-arm-kernel,
	catalin.marinas, dvhart, dwmw2, linux-xtensa, pali.rohar,
	keescook, arnd, jani.nikula, will.deacon, rusty, rostedt, acme,
	ak, andriy.shevchenko, mcb30

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

If you modify the target asm we currently do not force the
recompilation of the firmware files. The target asm is in
the firmware/Makefile, peg this file as a dependency to
require re-compilation of firmware targets when the asm
changes.

v3: introduced in this series

Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 firmware/Makefile | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/firmware/Makefile b/firmware/Makefile
index e297e1b52636..fa3e81c2a97b 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -176,7 +176,8 @@ quiet_cmd_fwbin = MK_FW   $@
 wordsize_deps := $(wildcard include/config/64bit.h include/config/32bit.h \
 		include/config/ppc32.h include/config/ppc64.h \
 		include/config/superh32.h include/config/superh64.h \
-		include/config/x86_32.h include/config/x86_64.h)
+		include/config/x86_32.h include/config/x86_64.h \
+		firmware/Makefile)
 
 $(patsubst %,$(obj)/%.gen.S, $(fw-shipped-y)): %: $(wordsize_deps)
 	$(call cmd,fwbin,$(patsubst %.gen.S,%,$@))
-- 
2.9.2


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 09/16] firmware/Makefile: force recompilation if makefile changes
  2016-08-19 21:32 ` [PATCH v4 09/16] firmware/Makefile: force recompilation if makefile changes mcgrof
@ 2016-08-19 21:32   ` mcgrof
  0 siblings, 0 replies; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: x86, luto, keescook, torvalds, gregkh, rusty, gnomes, alan,
	dwmw2, arnd, ming.lei, linux-arch, benh, ananth, pebolle,
	fontana, david.vrabel, konrad.wilk, mcb30, jgross,
	andrew.cooper3, andriy.shevchenko, paul.gortmaker, xen-devel, ak,
	pali.rohar, dvhart, platform-driver-x86, mmarek, linux, jkosina,
	korea.drzix, linux-kbuild, tony.luck, akpm, linux-ia64,
	linux-arm-kernel, linux-sh, sparclinux, catalin.marinas,
	will.deacon, rostedt, jani.nikula, mchehab, markus.heiser, acme,
	jolsa, msalter, chris, jcmvbkbc, linux-xtensa, paulus, mpe,
	James.Bottomley, Luis R. Rodriguez

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

If you modify the target asm we currently do not force the
recompilation of the firmware files. The target asm is in
the firmware/Makefile, peg this file as a dependency to
require re-compilation of firmware targets when the asm
changes.

v3: introduced in this series

Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 firmware/Makefile | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/firmware/Makefile b/firmware/Makefile
index e297e1b52636..fa3e81c2a97b 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -176,7 +176,8 @@ quiet_cmd_fwbin = MK_FW   $@
 wordsize_deps := $(wildcard include/config/64bit.h include/config/32bit.h \
 		include/config/ppc32.h include/config/ppc64.h \
 		include/config/superh32.h include/config/superh64.h \
-		include/config/x86_32.h include/config/x86_64.h)
+		include/config/x86_32.h include/config/x86_64.h \
+		firmware/Makefile)
 
 $(patsubst %,$(obj)/%.gen.S, $(fw-shipped-y)): %: $(wordsize_deps)
 	$(call cmd,fwbin,$(patsubst %.gen.S,%,$@))
-- 
2.9.2


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 10/16] firmware: port built-in section to linker table
  2016-08-19 21:32 [PATCH v4 00/16] linux: generalize sections, ranges and linker tables mcgrof
                   ` (9 preceding siblings ...)
  2016-08-19 21:32 ` [PATCH v4 09/16] firmware/Makefile: force recompilation if makefile changes mcgrof
@ 2016-08-19 21:32 ` mcgrof
  2016-08-19 21:32   ` mcgrof
  2016-08-19 22:29 ` [PATCH v4 00/16] linux: generalize sections, ranges and linker tables Kees Cook
  11 siblings, 1 reply; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: gnomes, linux-ia64, jkosina, benh, ming.lei, linux,
	platform-driver-x86, James.Bottomley, paul.gortmaker, paulus,
	sparclinux, Michael Matz, Barry Song, mchehab, linux-arch,
	markus.heiser, xen-devel, msalter, linux-sh, mpe, x86, fontana,
	linux-arm-kernel, catalin.marinas, dvhart, dwmw2, Guenter Roeck,
	linux-xtensa, pali.rohar, Mike Frysinger, keescook, arnd,
	jani.nikula, will.dea

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

This ports built-in firmware to use linker tables,
this replaces the custom section solution with a
generic solution.

This also demos the use of the .rodata (SECTION_RO)
linker tables.

Tested with 0 built-in firmware, 1 and 2 built-in
firmwares successfully.

v4:

o work around c6x toolchain bug by using SECTION_TBL_RO

o fix compilation on blackfin

v3:
o explicitly include tables.h as we no longer include
  tables.h from sections.h

o use new section_tbl_asmtype() helper on firmware/Makefile
  to enable having to unfold things on our own.

v2: introduced this file in this version of the series

Cc: Barry Song <barry.song@analog.com>
Cc: Mike Frysinger <vapier@gentoo.org>
Cc: Steven Miao <realmz6@gmail.com>
Cc: Michael Matz <matz@suse.de>
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 arch/x86/kernel/cpu/microcode/core.c |  8 ++++----
 drivers/base/firmware_class.c        | 12 ++++++------
 firmware/Makefile                    |  3 ++-
 include/asm-generic/vmlinux.lds.h    |  7 -------
 4 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index df04b2d033f6..3e7c08d99601 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -31,6 +31,7 @@
 #include <linux/cpu.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
+#include <linux/tables.h>
 
 #include <asm/microcode_intel.h>
 #include <asm/cpu_device_id.h>
@@ -91,15 +92,14 @@ static bool __init check_loader_disabled_bsp(void)
 	return *res;
 }
 
-extern struct builtin_fw __start_builtin_fw[];
-extern struct builtin_fw __end_builtin_fw[];
+DECLARE_LINKTABLE_RO(struct builtin_fw, builtin_fw);
 
 bool get_builtin_firmware(struct cpio_data *cd, const char *name)
 {
 #ifdef CONFIG_FW_LOADER
-	struct builtin_fw *b_fw;
+	const struct builtin_fw *b_fw;
 
-	for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) {
+	LINKTABLE_FOR_EACH(b_fw, builtin_fw) {
 		if (!strcmp(name, b_fw->name)) {
 			cd->size = b_fw->size;
 			cd->data = b_fw->data;
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 22d1760a4278..8fbf03c3e4c2 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -30,6 +30,7 @@
 #include <linux/syscore_ops.h>
 #include <linux/reboot.h>
 #include <linux/security.h>
+#include <linux/tables.h>
 
 #include <generated/utsrelease.h>
 
@@ -43,15 +44,14 @@ MODULE_LICENSE("GPL");
 
 #ifdef CONFIG_FW_LOADER
 
-extern struct builtin_fw __start_builtin_fw[];
-extern struct builtin_fw __end_builtin_fw[];
+DEFINE_LINKTABLE_RO(struct builtin_fw, builtin_fw);
 
 static bool fw_get_builtin_firmware(struct firmware *fw, const char *name,
 				    void *buf, size_t size)
 {
-	struct builtin_fw *b_fw;
+	const struct builtin_fw *b_fw;
 
-	for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) {
+	LINKTABLE_FOR_EACH(b_fw, builtin_fw) {
 		if (strcmp(name, b_fw->name) == 0) {
 			fw->size = b_fw->size;
 			fw->data = b_fw->data;
@@ -67,9 +67,9 @@ static bool fw_get_builtin_firmware(struct firmware *fw, const char *name,
 
 static bool fw_is_builtin_firmware(const struct firmware *fw)
 {
-	struct builtin_fw *b_fw;
+	const struct builtin_fw *b_fw;
 
-	for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++)
+	LINKTABLE_FOR_EACH(b_fw, builtin_fw)
 		if (fw->data == b_fw->data)
 			return true;
 
diff --git a/firmware/Makefile b/firmware/Makefile
index fa3e81c2a97b..9e701bf4ced2 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -155,6 +155,7 @@ quiet_cmd_fwbin = MK_FW   $@
 		  ASM_ALIGN=$(if $(CONFIG_64BIT),3,2);			     \
 		  PROGBITS=$(if $(CONFIG_ARM),%,@)progbits;		     \
 		  echo "/* Generated by firmware/Makefile */"		> $@;\
+		  echo "\#include <asm/tables.h>"			>>$@;\
 		  echo "    .section .rodata"				>>$@;\
 		  echo "    .p2align $${ASM_ALIGN}"			>>$@;\
 		  echo "_fw_$${FWSTR}_bin:"				>>$@;\
@@ -164,7 +165,7 @@ quiet_cmd_fwbin = MK_FW   $@
 		  echo "    .p2align $${ASM_ALIGN}"			>>$@;\
 		  echo "_fw_$${FWSTR}_name:"				>>$@;\
 		  echo "    .string \"$$FWNAME\""			>>$@;\
-		  echo "    .section .builtin_fw,\"a\",$${PROGBITS}"	>>$@;\
+		  echo "    set_section_tbl_type(SECTION_TBL_RO, builtin_fw, SECTION_ORDER_ANY, a,$${PROGBITS})" >>$@;\
 		  echo "    .p2align $${ASM_ALIGN}"			>>$@;\
 		  echo "    $${ASM_WORD} _fw_$${FWSTR}_name"		>>$@;\
 		  echo "    $${ASM_WORD} _fw_$${FWSTR}_bin"		>>$@;\
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 4b6a3d820883..2413444c048d 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -316,13 +316,6 @@
 		VMLINUX_SYMBOL(__end_pci_fixups_suspend_late) = .;	\
 	}								\
 									\
-	/* Built-in firmware blobs */					\
-	.builtin_fw        : AT(ADDR(.builtin_fw) - LOAD_OFFSET) {	\
-		VMLINUX_SYMBOL(__start_builtin_fw) = .;			\
-		*(.builtin_fw)						\
-		VMLINUX_SYMBOL(__end_builtin_fw) = .;			\
-	}								\
-									\
 	TRACEDATA							\
 									\
 	/* Kernel symbol table: Normal symbols */			\
-- 
2.9.2


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 10/16] firmware: port built-in section to linker table
  2016-08-19 21:32 ` [PATCH v4 10/16] firmware: port built-in section to linker table mcgrof
@ 2016-08-19 21:32   ` mcgrof
  0 siblings, 0 replies; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:32 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: x86, luto, keescook, torvalds, gregkh, rusty, gnomes, alan,
	dwmw2, arnd, ming.lei, linux-arch, benh, ananth, pebolle,
	fontana, david.vrabel, konrad.wilk, mcb30, jgross,
	andrew.cooper3, andriy.shevchenko, paul.gortmaker, xen-devel, ak,
	pali.rohar, dvhart, platform-driver-x86, mmarek, linux, jkosina,
	korea.drzix, linux-kbuild, tony.luck, akpm, linux-ia64,
	linux-arm-kernel, linux-sh, sparclinux, catalin.marinas,
	will.deacon, rostedt, jani.nikula, mchehab, markus.heiser, acme,
	jolsa, msalter, chris, jcmvbkbc, linux-xtensa, paulus, mpe,
	James.Bottomley, Luis R. Rodriguez, Barry Song, Mike Frysinger,
	Michael Matz, Guenter Roeck, Fengguang Wu

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

This ports built-in firmware to use linker tables,
this replaces the custom section solution with a
generic solution.

This also demos the use of the .rodata (SECTION_RO)
linker tables.

Tested with 0 built-in firmware, 1 and 2 built-in
firmwares successfully.

v4:

o work around c6x toolchain bug by using SECTION_TBL_RO

o fix compilation on blackfin

v3:
o explicitly include tables.h as we no longer include
  tables.h from sections.h

o use new section_tbl_asmtype() helper on firmware/Makefile
  to enable having to unfold things on our own.

v2: introduced this file in this version of the series

Cc: Barry Song <barry.song@analog.com>
Cc: Mike Frysinger <vapier@gentoo.org>
Cc: Steven Miao <realmz6@gmail.com>
Cc: Michael Matz <matz@suse.de>
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 arch/x86/kernel/cpu/microcode/core.c |  8 ++++----
 drivers/base/firmware_class.c        | 12 ++++++------
 firmware/Makefile                    |  3 ++-
 include/asm-generic/vmlinux.lds.h    |  7 -------
 4 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index df04b2d033f6..3e7c08d99601 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -31,6 +31,7 @@
 #include <linux/cpu.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
+#include <linux/tables.h>
 
 #include <asm/microcode_intel.h>
 #include <asm/cpu_device_id.h>
@@ -91,15 +92,14 @@ static bool __init check_loader_disabled_bsp(void)
 	return *res;
 }
 
-extern struct builtin_fw __start_builtin_fw[];
-extern struct builtin_fw __end_builtin_fw[];
+DECLARE_LINKTABLE_RO(struct builtin_fw, builtin_fw);
 
 bool get_builtin_firmware(struct cpio_data *cd, const char *name)
 {
 #ifdef CONFIG_FW_LOADER
-	struct builtin_fw *b_fw;
+	const struct builtin_fw *b_fw;
 
-	for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) {
+	LINKTABLE_FOR_EACH(b_fw, builtin_fw) {
 		if (!strcmp(name, b_fw->name)) {
 			cd->size = b_fw->size;
 			cd->data = b_fw->data;
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 22d1760a4278..8fbf03c3e4c2 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -30,6 +30,7 @@
 #include <linux/syscore_ops.h>
 #include <linux/reboot.h>
 #include <linux/security.h>
+#include <linux/tables.h>
 
 #include <generated/utsrelease.h>
 
@@ -43,15 +44,14 @@ MODULE_LICENSE("GPL");
 
 #ifdef CONFIG_FW_LOADER
 
-extern struct builtin_fw __start_builtin_fw[];
-extern struct builtin_fw __end_builtin_fw[];
+DEFINE_LINKTABLE_RO(struct builtin_fw, builtin_fw);
 
 static bool fw_get_builtin_firmware(struct firmware *fw, const char *name,
 				    void *buf, size_t size)
 {
-	struct builtin_fw *b_fw;
+	const struct builtin_fw *b_fw;
 
-	for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) {
+	LINKTABLE_FOR_EACH(b_fw, builtin_fw) {
 		if (strcmp(name, b_fw->name) == 0) {
 			fw->size = b_fw->size;
 			fw->data = b_fw->data;
@@ -67,9 +67,9 @@ static bool fw_get_builtin_firmware(struct firmware *fw, const char *name,
 
 static bool fw_is_builtin_firmware(const struct firmware *fw)
 {
-	struct builtin_fw *b_fw;
+	const struct builtin_fw *b_fw;
 
-	for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++)
+	LINKTABLE_FOR_EACH(b_fw, builtin_fw)
 		if (fw->data == b_fw->data)
 			return true;
 
diff --git a/firmware/Makefile b/firmware/Makefile
index fa3e81c2a97b..9e701bf4ced2 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -155,6 +155,7 @@ quiet_cmd_fwbin = MK_FW   $@
 		  ASM_ALIGN=$(if $(CONFIG_64BIT),3,2);			     \
 		  PROGBITS=$(if $(CONFIG_ARM),%,@)progbits;		     \
 		  echo "/* Generated by firmware/Makefile */"		> $@;\
+		  echo "\#include <asm/tables.h>"			>>$@;\
 		  echo "    .section .rodata"				>>$@;\
 		  echo "    .p2align $${ASM_ALIGN}"			>>$@;\
 		  echo "_fw_$${FWSTR}_bin:"				>>$@;\
@@ -164,7 +165,7 @@ quiet_cmd_fwbin = MK_FW   $@
 		  echo "    .p2align $${ASM_ALIGN}"			>>$@;\
 		  echo "_fw_$${FWSTR}_name:"				>>$@;\
 		  echo "    .string \"$$FWNAME\""			>>$@;\
-		  echo "    .section .builtin_fw,\"a\",$${PROGBITS}"	>>$@;\
+		  echo "    set_section_tbl_type(SECTION_TBL_RO, builtin_fw, SECTION_ORDER_ANY, a,$${PROGBITS})" >>$@;\
 		  echo "    .p2align $${ASM_ALIGN}"			>>$@;\
 		  echo "    $${ASM_WORD} _fw_$${FWSTR}_name"		>>$@;\
 		  echo "    $${ASM_WORD} _fw_$${FWSTR}_bin"		>>$@;\
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 4b6a3d820883..2413444c048d 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -316,13 +316,6 @@
 		VMLINUX_SYMBOL(__end_pci_fixups_suspend_late) = .;	\
 	}								\
 									\
-	/* Built-in firmware blobs */					\
-	.builtin_fw        : AT(ADDR(.builtin_fw) - LOAD_OFFSET) {	\
-		VMLINUX_SYMBOL(__start_builtin_fw) = .;			\
-		*(.builtin_fw)						\
-		VMLINUX_SYMBOL(__end_builtin_fw) = .;			\
-	}								\
-									\
 	TRACEDATA							\
 									\
 	/* Kernel symbol table: Normal symbols */			\
-- 
2.9.2


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 04/16] generic-sections: add section core helpers
  2016-08-19 21:32 ` [PATCH v4 04/16] generic-sections: add section core helpers mcgrof
  2016-08-19 21:32   ` mcgrof
@ 2016-08-19 21:47   ` Kees Cook
  2016-08-22 23:13     ` Luis R. Rodriguez
  1 sibling, 1 reply; 35+ messages in thread
From: Kees Cook @ 2016-08-19 21:47 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: gnomes, linux-ia64, Jiri Kosina, benh, Ming Lei, Heiko Carstens,
	platform-driver-x86, James Bottomley, Paul Gortmaker,
	Paul Mackerras, Michael Ellerman, H. Peter Anvin,
	Masami Hiramatsu, Mauro Carvalho Chehab, linux-arch,
	markus.heiser, sparclinux, xen-devel, Russell King - ARM Linux,
	linux-sh, Will Deacon

On Fri, Aug 19, 2016 at 2:32 PM,  <mcgrof@kernel.org> wrote:
> From: "Luis R. Rodriguez" <mcgrof@kernel.org>
>
> Linux makes extensive use of custom ELF header sections,
> documentation for these are well scatterred. Unify this
> documentation in a central place and provide helpers to
> build custom Linux sections.
>
> This also generalizes sections code to enable avoiding
> modifying the linker scripts when we want to add new
> custom Linux sections. In order to make this generally
> useful we need to ensure all architectures can make use of
> core section helpers but that they can also override should
> this be needed. Instead of relying on section.h this adds
> a sections-core.h since this will be targetted to be safe
> to be used on asm code, linker scripts and C code.
>
> v4:
>
> o Port to shiny new sphinx documentation format
>
> o fix a unicore32 build, turns out this actually fixes unicore32
>   defconfig builds which were failing for a long while. unicore32
>   does not seem to grok well the type passed on a section declaration,
>   this ignores it.
>
> o Use VMLINUX_SYMBOL() in more user symbols (extern C code), not doing
>   this was causing final linker issues with blackfin -- this is
>   a CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX=y architecture. The other one
>   being metatag. metatag is not supported on 0-day so I cannot confirm
>   compilation there.
>
> o Added SECTION_CORE() for C code, used later by __LINUX_RANGE()
>
> o Since SECTION_CORE() is defined for linker script and C code, share
>   the same helper and just use a __stringify() for the C code as is done
>   for the other C helpers.
>
> o move generic sections to asm-generic/section-core.h instead.
>   PowerPC compilation blows up if asm/jump_labels.h gets
>   section.h included, fixing this is not in any way easy.
>   The list of issues are endless. Moving new data to a new
>   simple file resolves this.
>
> o since things are now in asm-generic/section-core.h the
>   guard changes on asm-generic/sections.h and each architecture
>   sections.h are no longer needed
>
> o Give generic sections some maintainer love, that change is
>   Acked-by Arnd Bergmann, Josh and hpa.
>
> o A few checkpatch.pl style fixes
>
> o As suggested by James Hogan use generic-y to copy generic
>   header files on architectures that do not have a sections.h
>   instead of writing a simple file only to include the generic one.
>
> v3:
>
> o add missing sections.h for architectures that did not
>   have it
>
> o move generic sections to asm-generic/sections.h
>
> o add generic asm helpers section_type(), section_type_asmtype(),
>   push_section_type() -- these helpers enable easy use for
>   for later declaring and using of custom linux sections using
>   more standard APIs in both C code, asm code (C asm calls, or
>   asm files), enabling future standardized section types to
>   be more immediately accessible to asm code, not just C code.
>   Note for ASM_CMD_SEP we use by default "\n", architectures needed
>   to override can do so on their own sections.h prior to inclusion
>   of asm-generic/sections.h
>
> Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
> ---
>  Documentation/index.rst                   |   1 +
>  Documentation/sections/conf.py            |   4 +
>  Documentation/sections/index.rst          |  11 +
>  Documentation/sections/section-core.rst   | 153 ++++++++++++++
>  MAINTAINERS                               |  14 ++
>  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/Kbuild               |   1 +
>  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/section-core.h |  19 ++
>  arch/x86/include/asm/Kbuild               |   1 +
>  arch/xtensa/include/asm/Kbuild            |   1 +
>  include/asm-generic/section-core.h        | 341 ++++++++++++++++++++++++++++++
>  include/asm-generic/sections.h            |   2 +
>  include/asm-generic/vmlinux.lds.h         |  27 +--
>  include/linux/sections.h                  | 111 ++++++++++
>  40 files changed, 700 insertions(+), 13 deletions(-)
>  create mode 100644 Documentation/sections/conf.py
>  create mode 100644 Documentation/sections/index.rst
>  create mode 100644 Documentation/sections/section-core.rst
>  create mode 100644 arch/unicore32/include/asm/section-core.h
>  create mode 100644 include/asm-generic/section-core.h
>  create mode 100644 include/linux/sections.h
>
> diff --git a/Documentation/index.rst b/Documentation/index.rst
> index a15f81855b39..10c9b867e326 100644
> --- a/Documentation/index.rst
> +++ b/Documentation/index.rst
> @@ -14,6 +14,7 @@ Contents:
>     kernel-documentation
>     media/index
>     gpu/index
> +   sections/index
>
>  Indices and tables
>  ==================
> diff --git a/Documentation/sections/conf.py b/Documentation/sections/conf.py
> new file mode 100644
> index 000000000000..faa1c57595e1
> --- /dev/null
> +++ b/Documentation/sections/conf.py
> @@ -0,0 +1,4 @@
> +# -*- coding: utf-8; mode: python -*-
> +
> +project = 'Linux Kernel ELF sections'
> +html_search_language = 'en'
> diff --git a/Documentation/sections/index.rst b/Documentation/sections/index.rst
> new file mode 100644
> index 000000000000..d411e9b22eb3
> --- /dev/null
> +++ b/Documentation/sections/index.rst
> @@ -0,0 +1,11 @@
> +=========================
> +Linux Kernel ELF sections
> +=========================
> +
> +This book documents the Linux kernel's use of ELF sections, as well as helpers
> +used throughout the kernel to help declare and define them.
> +
> +.. toctree::
> +   :maxdepth: 4
> +
> +   section-core
> diff --git a/Documentation/sections/section-core.rst b/Documentation/sections/section-core.rst
> new file mode 100644
> index 000000000000..ecf4228bc4f8
> --- /dev/null
> +++ b/Documentation/sections/section-core.rst
> @@ -0,0 +1,153 @@
> +==============================
> +Core Linux kernel ELF sections
> +==============================
> +
> +About
> +=====
> +
> +This book documents the different standard and custom ELF sections used
> +on the Linux kernel, which we refer to as the ``core Linux sections``. We
> +start off by documenting the standard ELF sections used by Linux and move
> +on to the basic custom ELF sections, followed by a set of helpers. Each
> +section documented describes the goal of the section, and addresses
> +concurrency considerations when applicable.
> +
> +.. kernel-doc:: include/asm-generic/section-core.h
> +   :doc: Custom linker script
> +
> +Standard ELF section use in Linux
> +=================================
> +
> +.. kernel-doc:: include/asm-generic/section-core.h
> +   :doc: Standard ELF section use in Linux
> +
> +SECTION_RODATA
> +--------------
> +.. kernel-doc:: include/asm-generic/section-core.h
> +   :doc: SECTION_RODATA
> +
> +SECTION_RODATA

Typo: should this be called SECTION_TEXT instead?

> +--------------
> +.. kernel-doc:: include/asm-generic/section-core.h
> +   :doc: SECTION_TEXT
> +
> +SECTION_DATA
> +------------
> +.. kernel-doc:: include/asm-generic/section-core.h
> +   :doc: SECTION_DATA

Missing from this list are things like the __read_mostly
(".data..read_mostly") and __ro_after_init (".data..ro_after_init")
sections. Should those be included too, or are you only doing the "top
level" sections?

-Kees

-- 
Kees Cook
Nexus Security

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 06/16] ranges.h: add helpers to build and identify Linux section ranges
  2016-08-19 21:32 ` [PATCH v4 06/16] ranges.h: add helpers to build and identify Linux section ranges mcgrof
  2016-08-19 21:32   ` mcgrof
@ 2016-08-19 21:55   ` Kees Cook
  2016-08-22 23:48     ` Luis R. Rodriguez
  1 sibling, 1 reply; 35+ messages in thread
From: Kees Cook @ 2016-08-19 21:55 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: gnomes, linux-ia64, Jiri Kosina, benh, Ming Lei, Heiko Carstens,
	platform-driver-x86, James Bottomley, Paul Gortmaker,
	Paul Mackerras, Michael Ellerman, H. Peter Anvin,
	Masami Hiramatsu, Mauro Carvalho Chehab, linux-arch,
	markus.heiser, sparclinux, xen-devel, Russell King - ARM Linux,
	linux-sh, Will Deacon

On Fri, Aug 19, 2016 at 2:32 PM,  <mcgrof@kernel.org> wrote:
> From: "Luis R. Rodriguez" <mcgrof@kernel.org>
>
> Section ranges are on one of the types of custom sections
> types used in Linux. This provides a series of helpers for
> defining them and using them. Most importantly this also
> enables us to avoid modifying the linker script when we
> add a new section range.
>
> It turns out a lot of custom sections are actually section ranges,
> and these are typically spelled out in their architecture specific
> asm/sections.h file -- we anable architectures to override what asm

Typo: anable -> enable

> is used for section ranges but start by default trusting the
> asm-generic version all around.

Can you explain the addition of the SORT() stuff in this patch? Its
purpose isn't clear to me and doesn't appear to be mentioned in the
commit log.

>
> v4:
>
> o tons of documentation love
> o fix arch/x86/tools/relocs.c typo - which caused compilation issues
>   on old toolchains
> o port to new shiny sphinx documentation
> o sprinkle a few more needed VMLINUX_SYMBOL() - fixes
>   compilation on blackfin
> o name changes as suggested 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
> - rebrand DECLARE_SECTION_RNG() as DEFINE_SECTION_RANGE() - this is
>   the asm version of the respective C version, this will have a
>   userspace C demo added later.
> o move __LINUX_RANGE() and __LINUX_RANGE_ORDER() - fixes builds
>   on sparc
> o adds section ranges to linker script
> o rename SECTION_RANGE_ALL()
> o use default alignment, fixes builds on powerpc and arm for both
>   __LINUX_RANGE() and __LINUX_RANGE_ORDER()
> o expand documentation to document modules support
> o add maintainers
> o use generic-y
>
> v3: new in this series, uses copyleft-next
>
> Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
> ---
>  Documentation/sections/index.rst   |   1 +
>  Documentation/sections/ranges.rst  |  49 ++++++++++++++
>  MAINTAINERS                        |  10 +++
>  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/Kbuild        |   1 +
>  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       |  89 ++++++++++++++++++++++++++
>  include/asm-generic/vmlinux.lds.h  |  12 +++-
>  include/linux/ranges.h             | 128 +++++++++++++++++++++++++++++++++++++
>  38 files changed, 320 insertions(+), 2 deletions(-)
>  create mode 100644 Documentation/sections/ranges.rst
>  create mode 100644 include/asm-generic/ranges.h
>  create mode 100644 include/linux/ranges.h
>
> diff --git a/Documentation/sections/index.rst b/Documentation/sections/index.rst
> index d411e9b22eb3..6dd93ddd5dbe 100644
> --- a/Documentation/sections/index.rst
> +++ b/Documentation/sections/index.rst
> @@ -9,3 +9,4 @@ used throughout the kernel to help declare and define them.
>     :maxdepth: 4
>
>     section-core
> +   ranges
> diff --git a/Documentation/sections/ranges.rst b/Documentation/sections/ranges.rst
> new file mode 100644
> index 000000000000..1293dcb3ab38
> --- /dev/null
> +++ b/Documentation/sections/ranges.rst
> @@ -0,0 +1,49 @@
> +====================
> +Linux section ranges
> +====================
> +
> +This documents Linux' use of section ranges, how you can use
> +them and how they work.
> +
> +About section ranges
> +====================
> +
> +Introduction
> +------------
> +.. kernel-doc:: include/linux/ranges.h
> +   :doc: Introduction
> +
> +Section range module support
> +----------------------------
> +.. kernel-doc:: include/linux/ranges.h
> +   :doc: Section range module support
> +
> +Section range helpers
> +=====================
> +.. kernel-doc:: include/linux/ranges.h
> +   :doc: Section range helpers
> +
> +DECLARE_SECTION_RANGE
> +---------------------
> +.. kernel-doc:: include/linux/ranges.h
> +   :functions: DECLARE_SECTION_RANGE
> +
> +DEFINE_SECTION_RANGE
> +--------------------
> +.. kernel-doc:: include/linux/ranges.h
> +   :functions: DEFINE_SECTION_RANGE
> +
> +SECTION_ADDR_IN_RANGE
> +---------------------
> +.. kernel-doc:: include/linux/ranges.h
> +   :functions: SECTION_ADDR_IN_RANGE
> +
> +__LINUX_RANGE
> +-------------
> +.. kernel-doc:: include/asm-generic/ranges.h
> +   :functions: __LINUX_RANGE
> +
> +__LINUX_RANGE_ORDER
> +-------------------
> +.. kernel-doc:: include/asm-generic/ranges.h
> +   :functions: __LINUX_RANGE_ORDER
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 689c12075842..1a217751aa8a 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -5217,6 +5217,16 @@ S:       Supported
>  F:     drivers/base/power/domain*.c
>  F:     include/linux/pm_domain.h
>
> +GENERIC SECTION RANGES
> +M:     "Luis R. Rodriguez" <mcgrof@kernel.org>
> +M:     "H. Peter Anvin" <hpa@zytor.com>
> +L:     linux-arch@vger.kernel.org
> +L:     linux-kernel@vger.kernel.org
> +S:     Supported
> +F:     include/asm-generic/ranges.h
> +F:     include/linux/ranges.h
> +F:     Documentation/sections/ranges.rst
> +
>  GENERIC SECTIONS
>  M:     "Luis R. Rodriguez" <mcgrof@kernel.org>
>  M:     Josh Poimboeuf <jpoimboe@redhat.com>
> diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild
> index 5422827f1585..e44c896b91c4 100644
> --- a/arch/alpha/include/asm/Kbuild
> +++ b/arch/alpha/include/asm/Kbuild
> @@ -11,3 +11,4 @@ generic-y += preempt.h
>  generic-y += sections.h
>  generic-y += trace_clock.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild
> index 9a0929576de1..e5295413fdf8 100644
> --- a/arch/arc/include/asm/Kbuild
> +++ b/arch/arc/include/asm/Kbuild
> @@ -51,3 +51,4 @@ generic-y += vga.h
>  generic-y += word-at-a-time.h
>  generic-y += xor.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
> index 47923635be16..8e52300e1eed 100644
> --- a/arch/arm/include/asm/Kbuild
> +++ b/arch/arm/include/asm/Kbuild
> @@ -40,3 +40,4 @@ generic-y += timex.h
>  generic-y += trace_clock.h
>  generic-y += unaligned.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
> index 42d00806e4fb..5ff184574976 100644
> --- a/arch/arm64/include/asm/Kbuild
> +++ b/arch/arm64/include/asm/Kbuild
> @@ -53,3 +53,4 @@ generic-y += user.h
>  generic-y += vga.h
>  generic-y += xor.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/avr32/include/asm/Kbuild b/arch/avr32/include/asm/Kbuild
> index f2c3b656a0e7..edc176348d7c 100644
> --- a/arch/avr32/include/asm/Kbuild
> +++ b/arch/avr32/include/asm/Kbuild
> @@ -23,3 +23,4 @@ generic-y += vga.h
>  generic-y += word-at-a-time.h
>  generic-y += xor.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/blackfin/include/asm/Kbuild b/arch/blackfin/include/asm/Kbuild
> index 7de674411bed..35b7752e65c0 100644
> --- a/arch/blackfin/include/asm/Kbuild
> +++ b/arch/blackfin/include/asm/Kbuild
> @@ -49,3 +49,4 @@ generic-y += user.h
>  generic-y += word-at-a-time.h
>  generic-y += xor.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild
> index 38127ce747be..cede2a950fbf 100644
> --- a/arch/c6x/include/asm/Kbuild
> +++ b/arch/c6x/include/asm/Kbuild
> @@ -63,3 +63,4 @@ generic-y += vga.h
>  generic-y += word-at-a-time.h
>  generic-y += xor.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild
> index 385cd88a9d9e..fb8bb4112773 100644
> --- a/arch/cris/include/asm/Kbuild
> +++ b/arch/cris/include/asm/Kbuild
> @@ -46,3 +46,4 @@ generic-y += vga.h
>  generic-y += word-at-a-time.h
>  generic-y += xor.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/frv/include/asm/Kbuild b/arch/frv/include/asm/Kbuild
> index 46d7c599d9b8..5191fec655d7 100644
> --- a/arch/frv/include/asm/Kbuild
> +++ b/arch/frv/include/asm/Kbuild
> @@ -9,3 +9,4 @@ generic-y += preempt.h
>  generic-y += trace_clock.h
>  generic-y += word-at-a-time.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/h8300/include/asm/Kbuild b/arch/h8300/include/asm/Kbuild
> index 1ec04ec1c82b..7929a992566c 100644
> --- a/arch/h8300/include/asm/Kbuild
> +++ b/arch/h8300/include/asm/Kbuild
> @@ -76,3 +76,4 @@ generic-y += vga.h
>  generic-y += word-at-a-time.h
>  generic-y += xor.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild
> index 37d7bfae7619..af17ee334788 100644
> --- a/arch/hexagon/include/asm/Kbuild
> +++ b/arch/hexagon/include/asm/Kbuild
> @@ -61,3 +61,4 @@ generic-y += vga.h
>  generic-y += word-at-a-time.h
>  generic-y += xor.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild
> index 672c6d5da18c..d8f226b35a0a 100644
> --- a/arch/ia64/include/asm/Kbuild
> +++ b/arch/ia64/include/asm/Kbuild
> @@ -10,3 +10,4 @@ generic-y += trace_clock.h
>  generic-y += vtime.h
>  generic-y += word-at-a-time.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/m32r/include/asm/Kbuild b/arch/m32r/include/asm/Kbuild
> index 6111e1523750..1c6504d29312 100644
> --- a/arch/m32r/include/asm/Kbuild
> +++ b/arch/m32r/include/asm/Kbuild
> @@ -12,3 +12,4 @@ generic-y += sections.h
>  generic-y += trace_clock.h
>  generic-y += word-at-a-time.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild
> index eef72c464c9b..d465f51c2088 100644
> --- a/arch/m68k/include/asm/Kbuild
> +++ b/arch/m68k/include/asm/Kbuild
> @@ -36,3 +36,4 @@ generic-y += types.h
>  generic-y += word-at-a-time.h
>  generic-y += xor.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/metag/include/asm/Kbuild b/arch/metag/include/asm/Kbuild
> index 50ebd5a30d16..c869b1ebd583 100644
> --- a/arch/metag/include/asm/Kbuild
> +++ b/arch/metag/include/asm/Kbuild
> @@ -57,3 +57,4 @@ generic-y += vga.h
>  generic-y += word-at-a-time.h
>  generic-y += xor.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild
> index c6c2cf6edc98..63c083a1f8da 100644
> --- a/arch/microblaze/include/asm/Kbuild
> +++ b/arch/microblaze/include/asm/Kbuild
> @@ -12,3 +12,4 @@ generic-y += syscalls.h
>  generic-y += trace_clock.h
>  generic-y += word-at-a-time.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild
> index 12f7c5984c03..ed225600c8a4 100644
> --- a/arch/mips/include/asm/Kbuild
> +++ b/arch/mips/include/asm/Kbuild
> @@ -21,3 +21,4 @@ generic-y += user.h
>  generic-y += word-at-a-time.h
>  generic-y += xor.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/mn10300/include/asm/Kbuild b/arch/mn10300/include/asm/Kbuild
> index f8145bc85835..656af7b69940 100644
> --- a/arch/mn10300/include/asm/Kbuild
> +++ b/arch/mn10300/include/asm/Kbuild
> @@ -11,3 +11,4 @@ generic-y += sections.h
>  generic-y += trace_clock.h
>  generic-y += word-at-a-time.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/nios2/include/asm/Kbuild b/arch/nios2/include/asm/Kbuild
> index c9c7cb82b00f..c55880659d67 100644
> --- a/arch/nios2/include/asm/Kbuild
> +++ b/arch/nios2/include/asm/Kbuild
> @@ -64,3 +64,4 @@ generic-y += vga.h
>  generic-y += word-at-a-time.h
>  generic-y += xor.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild
> index 86175e701869..7d6a704b808c 100644
> --- a/arch/openrisc/include/asm/Kbuild
> +++ b/arch/openrisc/include/asm/Kbuild
> @@ -72,3 +72,4 @@ generic-y += vga.h
>  generic-y += word-at-a-time.h
>  generic-y += xor.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild
> index 6f43f33f0e0f..1a263a7158e2 100644
> --- a/arch/parisc/include/asm/Kbuild
> +++ b/arch/parisc/include/asm/Kbuild
> @@ -30,3 +30,4 @@ generic-y += vga.h
>  generic-y += word-at-a-time.h
>  generic-y += xor.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild
> index b49fab7bab2f..065c6e84fb67 100644
> --- a/arch/powerpc/include/asm/Kbuild
> +++ b/arch/powerpc/include/asm/Kbuild
> @@ -8,3 +8,4 @@ generic-y += preempt.h
>  generic-y += rwsem.h
>  generic-y += vtime.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild
> index 89e74b59f32d..3e8b95927cb5 100644
> --- a/arch/s390/include/asm/Kbuild
> +++ b/arch/s390/include/asm/Kbuild
> @@ -9,3 +9,4 @@ generic-y += preempt.h
>  generic-y += trace_clock.h
>  generic-y += word-at-a-time.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild
> index f089a264cd38..f0cdb2cbca4d 100644
> --- a/arch/score/include/asm/Kbuild
> +++ b/arch/score/include/asm/Kbuild
> @@ -15,3 +15,4 @@ generic-y += xor.h
>  generic-y += serial.h
>  generic-y += word-at-a-time.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild
> index 7b0356dca562..c9bb7932a3d1 100644
> --- a/arch/sh/include/asm/Kbuild
> +++ b/arch/sh/include/asm/Kbuild
> @@ -40,3 +40,4 @@ generic-y += trace_clock.h
>  generic-y += ucontext.h
>  generic-y += xor.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild
> index d51b84d6b4b7..79664d10e63b 100644
> --- a/arch/sparc/include/asm/Kbuild
> +++ b/arch/sparc/include/asm/Kbuild
> @@ -23,3 +23,4 @@ generic-y += trace_clock.h
>  generic-y += types.h
>  generic-y += word-at-a-time.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild
> index 7b8a652e43ae..951fa4be571d 100644
> --- a/arch/tile/include/asm/Kbuild
> +++ b/arch/tile/include/asm/Kbuild
> @@ -42,3 +42,4 @@ generic-y += trace_clock.h
>  generic-y += types.h
>  generic-y += xor.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild
> index e9849834d55e..99be54949b99 100644
> --- a/arch/um/include/asm/Kbuild
> +++ b/arch/um/include/asm/Kbuild
> @@ -28,3 +28,4 @@ generic-y += trace_clock.h
>  generic-y += word-at-a-time.h
>  generic-y += xor.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild
> index 256c45b3ae34..6c35905fe371 100644
> --- a/arch/unicore32/include/asm/Kbuild
> +++ b/arch/unicore32/include/asm/Kbuild
> @@ -64,3 +64,4 @@ generic-y += user.h
>  generic-y += vga.h
>  generic-y += word-at-a-time.h
>  generic-y += xor.h
> +generic-y += ranges.h
> diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild
> index f6914a57bc16..f790756fdb48 100644
> --- a/arch/x86/include/asm/Kbuild
> +++ b/arch/x86/include/asm/Kbuild
> @@ -17,3 +17,4 @@ generic-y += early_ioremap.h
>  generic-y += mcs_spinlock.h
>  generic-y += mm-arch-hooks.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
> index 0c2fae8d929d..c215db049920 100644
> --- a/arch/x86/tools/relocs.c
> +++ b/arch/x86/tools/relocs.c
> @@ -68,6 +68,8 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = {
>         "__end_rodata|"
>         "__initramfs_start|"
>         "(jiffies|jiffies_64)|"
> +       ".rodata.rng.*|"
> +       ".init.text.rng.*|"
>  #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 81ca6816bd72..221b6b652500 100644
> --- a/arch/xtensa/include/asm/Kbuild
> +++ b/arch/xtensa/include/asm/Kbuild
> @@ -32,3 +32,4 @@ generic-y += trace_clock.h
>  generic-y += word-at-a-time.h
>  generic-y += xor.h
>  generic-y += section-core.h
> +generic-y += ranges.h
> diff --git a/include/asm-generic/ranges.h b/include/asm-generic/ranges.h
> new file mode 100644
> index 000000000000..74cd941aa2f8
> --- /dev/null
> +++ b/include/asm-generic/ranges.h
> @@ -0,0 +1,89 @@
> +#ifndef _ASM_GENERIC_RANGES_H_
> +#define _ASM_GENERIC_RANGES_H_
> +/*
> + * Copyright (C) 2016 Luis R. Rodriguez <mcgrof@kernel.org>
> + *
> + * 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_RNG(section, name)                                     \

I would really prefer to avoid shortening "range" to the acronym for
"random number generator". That's very confusing. :P It's only two
letters more...

> +       SECTION_CORE(section, rng, name,                                \
> +                    SECTION_ORDER_ANY)
> +
> +#define SECTION_RNG_LEVEL(section, name, level)                                \
> +       SECTION_CORE(section, rng, name, level)
> +
> +#define SECTION_RNG_ALL(section)                                       \
> +       SECTION_CORE_ALL(section,rng)
> +
> +#ifndef set_section_rng
> +# define set_section_rng(section, name, flags)                         \
> +        set_section_core(section, rng, name,                           \
> +                         SECTION_ORDER_ANY, flags)
> +#endif
> +
> +#ifndef set_section_rng_type
> +# define set_section_rng_type(section, name, flags, type)              \
> +        set_section_core_type(section, rng, name,                      \
> +                              SECTION_ORDER_ANY, flags, type)
> +#endif
> +
> +#ifndef set_section_rng_level
> +# define set_section_rng_level(section, name, level, flags)            \
> +        set_section_core(section, rng, name, level, flags)
> +#endif
> +
> +#ifndef push_section_rng
> +# define push_section_rng(section, name, flags)                                \
> +        push_section_core(section, rng, name,                          \
> +                          SECTION_ORDER_ANY, flags)
> +#endif
> +
> +#ifndef push_section_rng_level
> +# define push_section_rng_level(section, name, level, flags)           \
> +        push_section_core(section, rng, name,                          \
> +                          level, flags)
> +#endif
> +
> +#ifndef __ASSEMBLY__
> +/**
> + * __LINUX_RANGE - short hand association into a section range
> + *
> + * @section: ELF section name to place section range into
> + * @name: section range name
> + *
> + * This helper can be used by subsystems to define their own subsystem
> + * specific helpers to easily associate a piece of code being defined to a
> + * section range.
> + */
> +#define __LINUX_RANGE(section, name)                                   \
> +       __attribute__((__section__(SECTION_RNG(section, name))))
> +
> +/**
> + * __LINUX_RANGE_ORDER - short hand association into a section range of order
> + *
> + * @section: ELF section name to place section range into
> + * @name: section range name
> + * @level: order level, a number. The order level gets tucked into the
> + *     section as a postfix string. Order levels are sorted using
> + *     binutils SORT(), the number is sorted as a string, as such be
> + *     sure to fill with zeroes any empty digits. For instance if you are
> + *     using 3 levels of digits for order levels, use 001 for the first entry,
> + *     0002 for the second, 999 for the last entry. You can use however many
> + *     digits you need.
> + *
> + * This helper can be used by subsystems to define their own subsystem specific
> + * helpers to easily associate a piece of code being defined to a section range
> + * with an associated specific order level. The order level provides the
> + * ability for explicit user ordering of code. Sorting takes place at link
> + * time, after compilation.
> + */
> +#define __LINUX_RANGE_ORDER(section, name, level)                      \
> +       __attribute__((__section__(SECTION_RNG_LEVEL(section, name, level))))
> +
> +#endif /* __ASSEMBLY__ */
> +
> +#endif /* _ASM_GENERIC_RANGES_H_ */
> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> index 731087276a32..ad843555e6a4 100644
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -56,6 +56,7 @@
>
>  #include <linux/export.h>
>  #include <asm/section-core.h>
> +#include <asm/ranges.h>
>
>  /* Align . to a 8 byte boundary equals to maximum function alignment. */
>  #define ALIGN_FUNCTION()  . = ALIGN(8)
> @@ -200,6 +201,7 @@
>  /* .data section */
>  #define DATA_DATA                                                      \
>         *(SECTION_DATA)                                                 \
> +       *(SORT(SECTION_RNG_ALL(SECTION_DATA)))                          \
>         *(SECTION_REF_DATA)                                             \
>         *(.data..shared_aligned) /* percpu related */                   \
>         MEM_KEEP(init.data)                                             \
> @@ -265,7 +267,9 @@
>         . = ALIGN((align));                                             \
>         SECTION_RODATA    : AT(ADDR(SECTION_RODATA) - LOAD_OFFSET) {    \
>                 VMLINUX_SYMBOL(__start_rodata) = .;                     \
> -               *(SECTION_RODATA) *(SECTION_ALL(SECTION_RODATA))        \
> +               *(SECTION_RODATA)                                       \
> +               *(SORT(SECTION_RNG_ALL(SECTION_RODATA)))                \
> +               *(SECTION_ALL(SECTION_RODATA))                          \
>                 RO_AFTER_INIT_DATA      /* Read only after init */      \
>                 *(__vermagic)           /* Kernel version magic */      \
>                 . = ALIGN(8);                                           \
> @@ -433,7 +437,9 @@
>   * during second ld run in second ld pass when generating System.map */
>  #define TEXT_TEXT                                                      \
>                 ALIGN_FUNCTION();                                       \
> -               *(.text.hot SECTION_TEXT .text.fixup .text.unlikely)    \
> +               *(.text.hot SECTION_TEXT)                               \
> +               *(SORT(SECTION_RNG_ALL(SECTION_TEXT)))                  \
> +               *(.text.fixup .text.unlikely)                           \
>                 *(SECTION_REF)                                          \
>         MEM_KEEP(init.text)                                             \
>         MEM_KEEP(exit.text)                                             \
> @@ -529,6 +535,7 @@
>  /* init and exit section handling */
>  #define INIT_DATA                                                      \
>         *(SECTION_INIT_DATA)                                            \
> +       *(SORT(SECTION_RNG_ALL(SECTION_INIT_DATA)))                     \
>         MEM_DISCARD(init.data)                                          \
>         KERNEL_CTORS()                                                  \
>         MCOUNT_REC()                                                    \
> @@ -551,6 +558,7 @@
>
>  #define INIT_TEXT                                                      \
>         *(SECTION_INIT)                                                 \
> +       *(SORT(SECTION_RNG_ALL(SECTION_INIT)))                          \
>         *(.text.startup)                                                \
>         MEM_DISCARD(init.text)
>
> diff --git a/include/linux/ranges.h b/include/linux/ranges.h
> new file mode 100644
> index 000000000000..30b2182bd484
> --- /dev/null
> +++ b/include/linux/ranges.h
> @@ -0,0 +1,128 @@
> +#ifndef _LINUX_RANGES_H
> +#define _LINUX_RANGES_H
> +/*
> + * Linux section ranges
> + *
> + * Copyright (C) 2016 Luis R. Rodriguez <mcgrof@kernel.org>
> + *
> + * 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/sections.h>
> +#include <asm/ranges.h>
> +
> +#ifndef __ASSEMBLY__
> +
> +/**
> + * DOC: Introduction
> + *
> + * A section ranges consists of explicitly annotated series executable code

Typo: ranges -> range

and "series of" instead of "series" I think?

> + * stitched together for the purpose of selective placement into standard or
> + * architecture specific ELF sections. What ELF section is used is utility
> + * specific. Linux has historically implicitly used section ranges, however
> + * they were all built in an adhoc manner and typically required linker script
> + * modifications per architecture. The section range API allows adding new
> + * bundles of stiched executable code into custom ELF sections by only
> + * modifying C or asm code in an architecture agnostic form.
> + *
> + * This documents the set of helpers available to declare, and define section
> + * ranges and associate each section range to a specific Linux ELF section.
> + */
> +
> +/**
> + * DOC: Section range module support
> + *
> + * Modules can use section ranges, however the section range definition must be
> + * built-in to the kernel. That is, the code that implements
> + * DEFINE_SECTION_RANGE() must be built-in, and modular code cannot add more
> + * items in to the section range (with __LINUX_RANGE() or
> + * __LINUX_RANGE_ORDER()), 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: Section range helpers
> + *
> + * These are helpers for section ranges.
> + */
> +
> +/**
> + * DECLARE_SECTION_RANGE - Declares a section range
> + *
> + * @name: section range name
> + *
> + * Declares a section range to help code access the range. Typically if
> + * a subsystems needs code to have direct access to the section range the
> + * subsystem's header file would declare the section range. Care should be
> + * taken to only declare the section range in a header file if access to it
> + * is truly needed outside of the code defining it. You typically would
> + * rather instead provide helpers which access the section range with special
> + * code on behalf of the caller.
> + */
> +#define DECLARE_SECTION_RANGE(name)                                    \
> +       DECLARE_LINUX_SECTION_RO(char, name)
> +
> +/**
> + * __SECTION_RANGE_BEGIN - Constructs the beginning of a section range
> + *
> + * @name: section range name
> + * @__section: ELF section to place section range into
> + *
> + * Constructs the beginning of a section range. You will typically not need
> + * to use this directly.
> + */
> +#define __SECTION_RANGE_BEGIN(name, __section)                         \
> +       const __typeof__(VMLINUX_SYMBOL(name)[0])                       \
> +             __attribute__((used,                                      \
> +                            weak,                                      \
> +                            __aligned__(LINUX_SECTION_ALIGNMENT(name)),\
> +                            section(SECTION_RNG_LEVEL(__section, name,))))
> +
> +/**
> + * __SECTION_RANGE_END - Constructs the end of a section range
> + *
> + * @name: section range name
> + * @__section: ELF section to place section range into
> + *
> + * Constructs the end of a section range. You will typically not need
> + * to use this directly.
> + */
> +#define __SECTION_RANGE_END(name, __section)                           \
> +       const __typeof__(VMLINUX_SYMBOL(name)[0])                       \
> +             __attribute__((used,                                      \
> +                            __aligned__(LINUX_SECTION_ALIGNMENT(name)),\
> +                            section(SECTION_RNG_LEVEL(__section, name, ~))))
> +
> +/**
> + * DEFINE_SECTION_RANGE - Defines a section range
> + *
> + * @name: section range name
> + * @section: ELF section name to place section range into
> + *
> + * Defines a section range, used for executable code. Section ranges are
> + * defined in the code that takes ownership and makes use of the section
> + * range.
> + */
> +#define DEFINE_SECTION_RANGE(name, section)                            \
> +       DECLARE_LINUX_SECTION_RO(char, name);                           \
> +       __SECTION_RANGE_BEGIN(name, section) VMLINUX_SYMBOL(name)[0] = {};\
> +       __SECTION_RANGE_END(name, section) VMLINUX_SYMBOL(name##__end)[0] = {}
> +
> +/**
> + * SECTION_ADDR_IN_RANGE - returns true if address is in range
> + *
> + * @name: section range name
> + * @addr: address to query for
> + *
> + * Returns true if the address is in the section range.
> + */
> +#define SECTION_ADDR_IN_RANGE(name, addr)                              \
> +        (addr >= (unsigned long) LINUX_SECTION_START(name) &&          \
> +         addr <  (unsigned long) LINUX_SECTION_END(name))
> +
> +#endif /* __ASSEMBLY__ */
> +
> +#endif /* _LINUX_RANGES_H */
> --
> 2.9.2
>

-Kees

-- 
Kees Cook
Nexus Security

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 07/16] tables.h: add linker table support
  2016-08-19 21:32 ` [PATCH v4 07/16] tables.h: add linker table support mcgrof
  2016-08-19 21:32   ` mcgrof
@ 2016-08-19 22:02   ` Kees Cook
  2016-08-22 23:53     ` Luis R. Rodriguez
  1 sibling, 1 reply; 35+ messages in thread
From: Kees Cook @ 2016-08-19 22:02 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: gnomes, linux-ia64, Jiri Kosina, benh, Ming Lei, Heiko Carstens,
	platform-driver-x86, James Bottomley, Paul Gortmaker,
	Paul Mackerras, Michael Ellerman, H. Peter Anvin,
	Masami Hiramatsu, Mauro Carvalho Chehab, linux-arch,
	markus.heiser, sparclinux, xen-devel, Russell King - ARM Linux,
	linux-sh, Will Deacon

On Fri, Aug 19, 2016 at 2:32 PM,  <mcgrof@kernel.org> wrote:
> From: "Luis R. Rodriguez" <mcgrof@kernel.org>
>
> 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@ipxe.org>
> Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
> ---
>  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@kernel.org>
> +M:     "H. Peter Anvin" <hpa@zytor.com>
> +L:     linux-arch@vger.kernel.org
> +L:     linux-kernel@vger.kernel.org
> +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@ti.com>
>  L:     linux-kernel@vger.kernel.org
> 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@kernel.org>
> + *
> + * 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@redhat.com
> + */
> +
> +#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@kernel.org>
> + *
> + * 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@kernel.org>
> + *
> + * 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@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 08/16] kbuild: enable option to force compile force-obj-y and force-lib-y
  2016-08-19 21:32 ` [PATCH v4 08/16] kbuild: enable option to force compile force-obj-y and force-lib-y mcgrof
  2016-08-19 21:32   ` mcgrof
@ 2016-08-19 22:10   ` Kees Cook
  2016-08-22 23:59     ` Luis R. Rodriguez
  1 sibling, 1 reply; 35+ messages in thread
From: Kees Cook @ 2016-08-19 22:10 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: gnomes, linux-ia64, Jiri Kosina, benh, Ming Lei, Heiko Carstens,
	platform-driver-x86, James Bottomley, Paul Gortmaker,
	Paul Mackerras, Michael Ellerman, H. Peter Anvin,
	Masami Hiramatsu, Mauro Carvalho Chehab, linux-arch,
	markus.heiser, sparclinux, xen-devel, Russell King - ARM Linux,
	linux-sh, Will Deacon

On Fri, Aug 19, 2016 at 2:32 PM,  <mcgrof@kernel.org> wrote:
> From: "Luis R. Rodriguez" <mcgrof@kernel.org>
>
> Linux provides a rich array of features, enabling each feature
> however increases the size of the kernel and there are many
> features which users often want disabled. The traditional
> solution to this problem is for each feature to have its own
> Kconfig symbol, followed by a series of #ifdef statements
> in C code and header files, allowing the feature to be compiled
> only when desirable. As the variability of Linux increases build
> tests can and are often done with random kernel configurations,
> allyesconfig, and allmodconfig to help find code issues. This
> however doesn't catch all errors and as a consequence code that
> is typically not enabled often can suffer from bit-rot over time.
>
> An alternative approach for subsystems, which refer to as the 'build-all
> link-selectively philosophy' is to keep the Kconfig symbols, replace
> the #ifdef approach by having each feature implemented it its own C file,
> and force compilation for all features to avoid the code bit-rot problem.
> With this strategy only features that are enabled via Kconfig get
> linked into the kernel, so the forced compilation has no size impact
> on the kernel. The practice of having each feature implemented in its own
> C file is already prevalent in many subsystems, however #ifdefs are still
> typically required during feature initialization. For instance in:
>
>   #ifdef CONFIG_FOO
>   foo_init();
>   #endif
>
> We cannot remove the #ifdef and leave foo_init() as we'd either
> need to always enable the feature or add a respective #ifdef in a
> foo.h which makes foo_init() do nothing when CONFIG_FOO is disabled.
>
> Linker tables enable lifting the requirement to use of #ifdefs during
> initialization. With linker tables initialization sequences can instead
> be aggregated into a custom ELF section at link time, during run time
> the table can be iterated over and each init sequence enabled can be called.
> A feature's init routine is only added to a table when its respective
> Kconfig symbols has been enabled and therefore linked in. Linker tables
> enable subsystems to completely do away with #ifdefs if one is comfortable
> in accepting all subsystem's feature's structural size implications.
>
> Subsystems which want to follow the 'build-all link-selectively
> philosophy' still need a way to easily express and annotate that they
> wish for all code to always be compiled to help avoid code bit rot,
> as such two new targets force-obj-y and force-lib-y are provided to
> help with this. Its not fair to require everyone to force compilation
> of all features of a subsystem though, so as a compromise, the new
> targets only force compilation when CONFIG_BUILD_AVOID_BITROT is
> enabled.
>
> Only built-in features are supported at the moment. Module support
> is expected to be added after a generic solution to add linker
> tables to modules more easily is developed.
>
> v4: this patch was added to this series, it was split off from the
>     linker tables addition due to the confusion over the code bit
>     rot alternatives that are possible with linker tables.
>
> Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
> ---
>  Documentation/kbuild/makefiles.txt       | 36 ++++++++++++++++
>  Documentation/sections/linker-tables.rst | 15 +++++++
>  include/linux/tables.h                   | 71 ++++++++++++++++++++++++++++++++
>  init/Kconfig                             | 22 ++++++++++
>  scripts/Makefile.build                   |  7 ++--
>  scripts/Makefile.lib                     | 11 +++++
>  6 files changed, 159 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt
> index 385a5ef41c17..01c260913f5c 100644
> --- a/Documentation/kbuild/makefiles.txt
> +++ b/Documentation/kbuild/makefiles.txt
> @@ -1089,6 +1089,42 @@ When kbuild executes, the following steps are followed (roughly):
>         In this example, extra-y is used to list object files that
>         shall be built, but shall not be linked as part of built-in.o.
>
> +    force-obj-y force-lib-y
> +
> +       When CONFIG_BUILD_AVOID_BITROT is enabled using these targets for your
> +       kconfig symbols forces compilation of the associated objects if the
> +       kconfig's symbol's dependencies are met, the objects however are only
> +       linked into to the kernel if and only if the kconfig symbol was
> +       enabled. If CONFIG_BUILD_AVOID_BITROT is disabled the force-obj-y and
> +       force-lib-y targets are functionally equilvalent to obj-y and lib-y
> +       respectively.
> +
> +       Using force-obj-y and force-lib-y are part of a code architecture and
> +       build philosophy further enabled by linker tables, for more details
> +       refer to the documention in include/linux/tables.h, refer to the
> +       sections:
> +
> +               o The code bit-rot problem
> +               o The build-all selective-link philosophy
> +               o Avoiding the code bit-rot problem with linker tables
> +               o Linker table module support
> +
> +       Modules support is expected to be enhanced in the future, so for now
> +       only built-in features are supported.
> +
> +       Example use:
> +
> +               force-obj-$(CONFIG_FEATURE_FOO) += foo.o
> +
> +       An alternative to using force-obj-y, is to use extra-y followed by the
> +       respective obj-y:
> +
> +               extra-y += foo.o
> +               obj-$(CONFIG_FEATURE_FOO) += foo.o
> +
> +       Using force-obj-y and force-lib-y can be used to help annotate the
> +       targets follow the 'build-all selective-link philosophy' further
> +       enabled by linker tables.
>
>  --- 6.7 Commands useful for building a boot image
>
> diff --git a/Documentation/sections/linker-tables.rst b/Documentation/sections/linker-tables.rst
> index df11c632dca7..e425c5cd36d6 100644
> --- a/Documentation/sections/linker-tables.rst
> +++ b/Documentation/sections/linker-tables.rst
> @@ -30,6 +30,21 @@ How linker tables simplify initialization code
>  .. kernel-doc:: include/linux/tables.h
>     :doc: How linker tables simplify initialization code
>
> +The code bit-rot problem
> +------------------------
> +.. kernel-doc:: include/linux/tables.h
> +   :doc: The code bit-rot problem
> +
> +The build-all selective-link philosophy
> +---------------------------------------
> +.. kernel-doc:: include/linux/tables.h
> +   :doc: The build-all selective-link philosophy
> +
> +Avoiding the code bit-rot problem with linker tables
> +----------------------------------------------------
> +.. kernel-doc:: include/linux/tables.h
> +   :doc: Avoiding the code bit-rot problem with linker tables
> +
>  Using linker tables in Linux
>  ============================
>
> diff --git a/include/linux/tables.h b/include/linux/tables.h
> index 423827eafb52..bf8fae7f9246 100644
> --- a/include/linux/tables.h
> +++ b/include/linux/tables.h
> @@ -169,6 +169,77 @@
>   */
>
>  /**
> + * DOC: The code bit-rot problem
> + *
> + * Linux provides a rich array of features, enabling each feature
> + * however increases the size of the kernel and there are many
> + * features which users often want disabled. The traditional
> + * solution to this problem is for each feature to have its own
> + * Kconfig symbol, followed by a series of #ifdef statements
> + * in C code and header files, allowing the feature to be compiled
> + * only when desirable. As the variability of Linux increases build
> + * tests can and are often done with random kernel configurations,
> + * allyesconfig, and allmodconfig to help find code issues. This
> + * however doesn't catch all errors and as a consequence code that
> + * is typically not enabled often can suffer from bit-rot over time.
> + */
> +
> +/**
> + * DOC: The build-all selective-link philosophy
> + *
> + * A code architecture philosophy to help avoid code bit-rot consists
> + * of using Kconfig symbols for each subsystem feature, replace all #ifdefs
> + * by instead having each feature implemented it its own C file, and force
> + * compilation for all features. Only features that are enabled get linked in,
> + * the forced compilation therefore has no size impact on the final result of
> + * the kernel. The practice of having each feature implemented in its own C
> + * file is already prevalent in many subsystems, however #ifdefs are still
> + * typically required during feature initialization. For instance in::
> + *
> + *     #ifdef CONFIG_FOO
> + *     foo_init();
> + *     #endif
> + *
> + * We cannot remove the #ifdef and leave foo_init() as we'd either
> + * need to always enable the feature or add a respective #ifdef in a
> + * foo.h which makes foo_init() do nothing when ``CONFIG_FOO`` is disabled.
> + */
> +
> +/**
> + * DOC: Avoiding the code bit-rot problem with linker tables
> + *
> + * Linker tables can be used to further help avoid the code bit-rot problem
> + * when embracing the 'build-all selective-link philosophy' by lifting the
> + * requirement to use of #ifdefs during initialization. With linker tables
> + * initialization sequences can be aggregated into a custom ELF section at
> + * link time, during run time the table can be iterated over and each init
> + * sequence enabled can be called. A feature's init routine is only added to a
> + * table when its respective Kconfig symbols has been enabled and therefore
> + * linked in. Linker tables enable subsystems to completely do away with
> + * #ifdefs if one is comfortable in accepting all subsystem's feature's
> + * structural size implications.
> + *
> + * To further help with this the Linux build system supports two special
> + * targets, ``force-obj-y`` and ``force-lib-y``. A subsystem which wants to
> + * follow the 'build-all selective-link philosophy' can use these targets for a
> + * feature's kconfig symbol. Using these targets will always require
> + * compilation of the kconfig's objects if the kconfig symbol's dependencies
> + * are met but only link the objects into the kernel, and therefore enable the
> + * feature, if and only if the kconfig symbol has been enabled.
> + *
> + * Not all users or build systems may want to opt-in to compile all objects
> + * following the 'build-all selective-link philosophy', as such the targets
> + * ``force-obj-y`` and ``force-lib-y`` only force compilation when the kconfig
> + * symbol ``CONFIG_BUILD_AVOID_BITROT`` has been enabled. Disabling this feature
> + * makes ``force-obj-y`` and ``force-lib-y`` functionally equivalent to
> + * ``obj-y`` and ``lib-y`` respectively.
> + *
> + * Example use::
> + *
> + *     force-obj-$(CONFIG_FEATURE_FOO) += foo.o
> + */
> +
> +/**
>   * DOC: Linker table module support
>   *
>   * Modules can use linker tables, however the linker table definition
> diff --git a/init/Kconfig b/init/Kconfig
> index cac3f096050d..ef09e83b9196 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -53,6 +53,28 @@ config CROSS_COMPILE
>           need to set this unless you want the configured kernel build
>           directory to select the cross-compiler automatically.
>
> +config BUILD_AVOID_BITROT
> +       bool "Enable force building of force-obj-y and force-lib-y"

Sorry to continue the bikeshedding on this, but if I encounter
something in a Makefile named "force-obj-y" I would expect it to
always be built, no matter what. But this is not the case: the
"force-" prefix is tied to this CONFIG_BUILD_AVOID_BITROT. This verb
usage is weird, as I'd expect an adjective, like "forceable-obj-y" or
something that describes that it CAN be built even with the CONFIG for
it is missing, etc.

Regardless, I defer to Michal on this, but I'm not a fan of "force"
being used when it's an optional action. :)

-Kees

> +       default n
> +       help
> +         When enabled objects under the force-obj-y and force-lib-y targets
> +         using a Kconfig symbol will be forced to compile if the Kconfig
> +         symbol's dependencies are met but only linked into the kernel if
> +         the Kconfig symbol is enabled. If a Kconfig symbol on a force-obj-y
> +         or force-lib-y target is disabled, it will be compiled but not linked
> +         into the kernel.
> +
> +         The force-obj-y and force-lib-y targets can be used by subsystems
> +         which wish to want to follow the 'build-all selective-link philosophy'
> +         documented under include/linux/tables.h.
> +
> +         Say Y if you have a decent build machine and would like to help test
> +         building code for more subsystems. Say N if you do you not have a
> +         good build machine or only want to compile what you've enabled for
> +         your kernel.
> +
> +         Enabling this option never increases the size of your kernel.
> +
>  config COMPILE_TEST
>         bool "Compile also drivers which will not load"
>         depends on !UML
> diff --git a/scripts/Makefile.build b/scripts/Makefile.build
> index cd9bf22bb027..cc2c7241d193 100644
> --- a/scripts/Makefile.build
> +++ b/scripts/Makefile.build
> @@ -92,7 +92,8 @@ modorder-target := $(obj)/modules.order
>
>  # We keep a list of all modules in $(MODVERDIR)
>
> -__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
> +__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y) \
> +                               $(force-obj-y)) \
>          $(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
>          $(subdir-ym) $(always)
>         @:
> @@ -326,8 +327,8 @@ cmd_as_o_S       = $(CC) $(a_flags) -c -o $@ $<
>  $(obj)/%.o: $(src)/%.S $(objtool_obj) FORCE
>         $(call if_changed_rule,as_o_S)
>
> -targets += $(real-objs-y) $(real-objs-m) $(lib-y)
> -targets += $(extra-y) $(MAKECMDGOALS) $(always)
> +targets += $(real-objs-y) $(real-objs-m) $(lib-y) $(force-lib-y)
> +targets += $(extra-y) $(force-obj-y) $(MAKECMDGOALS) $(always)
>
>  # Linker scripts preprocessor (.lds.S -> .lds)
>  # ---------------------------------------------------------------------------
> diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
> index 0a07f9014944..d1cb0cfdf1bf 100644
> --- a/scripts/Makefile.lib
> +++ b/scripts/Makefile.lib
> @@ -12,6 +12,15 @@ export KBUILD_SUBDIR_CCFLAGS := $(KBUILD_SUBDIR_CCFLAGS) $(subdir-ccflags-y)
>  # Figure out what we need to build from the various variables
>  # ===========================================================================
>
> +ifeq ($(CONFIG_BUILD_AVOID_BITROT),y)
> +extra-y += $(force-obj-) $(force-lib-)
> +endif
> +
> +obj-m += $(force-obj-m)
> +obj-y += $(force-obj-y)
> +lib-m += $(force-lib-m)
> +lib-y += $(force-lib-y)
> +
>  # When an object is listed to be built compiled-in and modular,
>  # only build the compiled-in version
>
> @@ -72,6 +81,8 @@ real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)
>  # Add subdir path
>
>  extra-y                := $(addprefix $(obj)/,$(extra-y))
> +force-obj-y            := $(addprefix $(obj)/,$(force-obj-y))
> +force-obj-m            := $(addprefix $(obj)/,$(force-obj-m))
>  always         := $(addprefix $(obj)/,$(always))
>  targets                := $(addprefix $(obj)/,$(targets))
>  modorder       := $(addprefix $(obj)/,$(modorder))
> --
> 2.9.2
>



-- 
Kees Cook
Nexus Security

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 00/16] linux: generalize sections, ranges and linker tables
  2016-08-19 21:32 [PATCH v4 00/16] linux: generalize sections, ranges and linker tables mcgrof
                   ` (10 preceding siblings ...)
  2016-08-19 21:32 ` [PATCH v4 10/16] firmware: port built-in section to linker table mcgrof
@ 2016-08-19 22:29 ` Kees Cook
  2016-08-22 23:06   ` Luis R. Rodriguez
  11 siblings, 1 reply; 35+ messages in thread
From: Kees Cook @ 2016-08-19 22:29 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: gnomes, linux-ia64, Jiri Kosina, benh, Ming Lei, Heiko Carstens,
	platform-driver-x86, James Bottomley, Paul Gortmaker,
	Paul Mackerras, Michael Ellerman, H. Peter Anvin,
	Masami Hiramatsu, Mauro Carvalho Chehab, linux-arch,
	markus.heiser, sparclinux, xen-devel, Russell King - ARM Linux,
	linux-sh, Will Deacon

On Fri, Aug 19, 2016 at 2:32 PM,  <mcgrof@kernel.org> wrote:
> From: "Luis R. Rodriguez" <mcgrof@kernel.org>
>
> This v4 addresses feedback from the previous v3 series [0], and also
> addresses a huge array of additional tests against many architectures
> outside of what 0-day provides. As I mentioned in my last v3 series,
> 0-day had only found one issue with the series, a blackfin architecture
> linker issue with the last series. Guenter Rock was kind enough to give
> my series a test spin on his test bed and he found quite a bit of other
> oddball issues with obscure architectures, and even on x86 with an old
> toolchain. After a lot of work and coordinating with a few maintainers
> I'm happy to report all issues found so far through all possible testing
> I could do are now fixed, this series also addresses all feedback from
> the last series, as such this goes submitted as PATCH form.
>
> In addressing fixing this work on a few architectures some of the previous
> patches are further simplified. The kprobes port to linker tables is made
> much easier now that I've addressed moving out core kprobe declarations
> into asm-generic/kprobes.h. Refer to the patch "kprobes: move kprobe
> declarations to asm-generic/kprobes.h". This makes for a much cleaner
> solution across architectures.
>
> Boris feedback on making the code bit rot feature optional is addressed
> by using a new Kconfig symbol for this, CONFIG_BUILD_AVOID_BITROT,
> but given Greg's concerns over lack of clarity over what this was all about
> I've ripped that functionality out into its own patch with a bit more
> extensive documentation and re-wording. See the patch "kbuild: enable option
> to force compile force-obj-y and force-lib-y". I hope makes it clear how
> linker tables can help with avoiding code bit rot. I've gone with a new
> Kconfig symbol CONFIG_BUILD_AVOID_BITROT given CONFIG_COMPILE_TEST is
> not available on UML, this feature is desirable on all architectures.
>
> The documentation is revamped, now that the DocBook format is deprecated
> I ported the documention into the trendy hipster Sphinx documentation
> format.
>
> AT Boris' request I've adapated the userspace linker table application
> forintegration into the kernel under tools/ to make it easier to keep
> things in sync, however since this requires a bit of changes to some headers
> in tools/ I'll submit that separately.
>
> [0] https://lkml.kernel.org/r/1469222687-1600-1-git-send-email-mcgrof@kernel.org
>
> If you'd like this in git-form, you can get it on the 20160819-linker-table-v4
> branch of my linux-next tree on kernel.org, this also includes the series of
> the linker table userspace sandbox:
>
> https://git.kernel.org/cgit/linux/kernel/git/mcgrof/linux-next.git/log/?h=20160819-linker-table-v4
>
> Please let me know if there are any concerns or questions.

Thanks for the documentation and examples on this feature; I appreciate it! :)

While it seems like all the section declarations work in this series
is designed for assembler source, I'm curious if I've missed a way to
do this in .c source too. I'd love to avoid doing the crazy thing I'm
currently doing in lkdtm with section markings. Namely, I want to
write a function in .c and have it moved into the .rodata section. The
linkers get very very angry with me and I don't seem to be able to
override the progbits to lose "x". Right now I'm doing an objcopy in
drivers/misc/Makefile:

OBJCOPYFLAGS_lkdtm_rodata_objcopy.o := \
                        --set-section-flags .text=alloc,readonly \
                        --rename-section .text=.rodata
targets += lkdtm_rodata.o lkdtm_rodata_objcopy.o
$(obj)/lkdtm_rodata_objcopy.o: $(obj)/lkdtm_rodata.o FORCE
        $(call if_changed,objcopy)

Thanks!

-Kees

>
> Luis R. Rodriguez (16):
>   x86: remove LTO_REFERENCE_INITCALL()
>   dell-smo8800: include uaccess.h
>   scripts/module-common.lds: enable generation
>   generic-sections: add section core helpers
>   xtensa: skip adding literal when SORT() is used
>   ranges.h: add helpers to build and identify Linux section ranges
>   tables.h: add linker table support
>   kbuild: enable option to force compile force-obj-y and force-lib-y
>   firmware/Makefile: force recompilation if makefile changes
>   firmware: port built-in section to linker table
>   jump_label: move guard #endif down where it belongs
>   jump_label: port __jump_table to linker tables
>   dynamic_debug: port to use linker tables
>   kprobes: move kprobe declarations to asm-generic/kprobes.h
>   kprobes: port .kprobes.text to section range
>   kprobes: port blacklist kprobes to linker table
>
>  .gitignore                                         |   2 +
>  Documentation/index.rst                            |   1 +
>  Documentation/kbuild/makefiles.txt                 |  36 ++
>  Documentation/sections/conf.py                     |   4 +
>  Documentation/sections/index.rst                   |  13 +
>  Documentation/sections/linker-tables.rst           | 202 +++++++
>  Documentation/sections/ranges.rst                  |  49 ++
>  Documentation/sections/section-core.rst            | 153 +++++
>  MAINTAINERS                                        |  37 ++
>  Makefile                                           |   6 +-
>  arch/alpha/include/asm/Kbuild                      |   4 +
>  arch/arc/include/asm/Kbuild                        |   3 +
>  arch/arc/include/asm/kprobes.h                     |   6 +-
>  arch/arc/kernel/vmlinux.lds.S                      |   1 -
>  arch/arm/include/asm/Kbuild                        |   3 +
>  arch/arm/include/asm/jump_label.h                  |   6 +-
>  arch/arm/include/asm/kprobes.h                     |   4 +
>  arch/arm/kernel/entry-armv.S                       |   3 +-
>  arch/arm/kernel/vmlinux-xip.lds.S                  |   1 -
>  arch/arm/kernel/vmlinux.lds.S                      |   1 -
>  arch/arm/probes/decode.h                           |   1 +
>  arch/arm64/include/asm/Kbuild                      |   3 +
>  arch/arm64/include/asm/jump_label.h                |   6 +-
>  arch/arm64/include/asm/kprobes.h                   |   4 +
>  arch/arm64/kernel/armv8_deprecated.c               |   1 +
>  arch/arm64/kernel/insn.c                           |   1 +
>  arch/arm64/kernel/probes/kprobes.c                 |   4 +-
>  arch/arm64/kernel/vmlinux.lds.S                    |   1 -
>  arch/avr32/include/asm/Kbuild                      |   3 +
>  arch/avr32/include/asm/kprobes.h                   |   4 +
>  arch/avr32/kernel/entry-avr32b.S                   |  13 +-
>  arch/avr32/kernel/vmlinux.lds.S                    |   1 -
>  arch/blackfin/include/asm/Kbuild                   |   4 +
>  arch/blackfin/kernel/vmlinux.lds.S                 |   1 -
>  arch/c6x/include/asm/Kbuild                        |   3 +
>  arch/c6x/include/asm/tables.h                      |  26 +
>  arch/c6x/kernel/vmlinux.lds.S                      |   1 -
>  arch/cris/include/asm/Kbuild                       |   4 +
>  arch/frv/include/asm/Kbuild                        |   4 +
>  arch/h8300/include/asm/Kbuild                      |   4 +
>  arch/hexagon/include/asm/Kbuild                    |   4 +
>  arch/hexagon/kernel/vmlinux.lds.S                  |   1 -
>  arch/ia64/include/asm/Kbuild                       |   3 +
>  arch/ia64/include/asm/kprobes.h                    |   7 +-
>  arch/ia64/kernel/jprobes.S                         |   3 +-
>  arch/ia64/kernel/vmlinux.lds.S                     |   1 -
>  arch/ia64/lib/flush.S                              |   6 +-
>  arch/m32r/include/asm/Kbuild                       |   4 +
>  arch/m68k/include/asm/Kbuild                       |   4 +
>  arch/metag/include/asm/Kbuild                      |   4 +
>  arch/metag/kernel/vmlinux.lds.S                    |   1 -
>  arch/microblaze/include/asm/Kbuild                 |   4 +
>  arch/microblaze/kernel/vmlinux.lds.S               |   1 -
>  arch/mips/include/asm/Kbuild                       |   3 +
>  arch/mips/include/asm/jump_label.h                 |   6 +-
>  arch/mips/include/asm/kprobes.h                    |   6 +-
>  arch/mips/kernel/vmlinux.lds.S                     |   1 -
>  arch/mn10300/include/asm/Kbuild                    |   3 +
>  arch/mn10300/include/asm/kprobes.h                 |   4 +
>  arch/mn10300/kernel/vmlinux.lds.S                  |   1 -
>  arch/nios2/include/asm/Kbuild                      |   4 +
>  arch/nios2/kernel/vmlinux.lds.S                    |   1 -
>  arch/openrisc/include/asm/Kbuild                   |   4 +
>  arch/openrisc/kernel/vmlinux.lds.S                 |   1 -
>  arch/parisc/include/asm/Kbuild                     |   4 +
>  arch/parisc/kernel/vmlinux.lds.S                   |   1 -
>  arch/powerpc/include/asm/Kbuild                    |   3 +
>  arch/powerpc/include/asm/jump_label.h              |   8 +-
>  arch/powerpc/include/asm/kprobes.h                 |   6 +
>  arch/powerpc/include/asm/ppc_asm.h                 |   7 +-
>  arch/powerpc/kernel/vmlinux.lds.S                  |   1 -
>  arch/s390/include/asm/Kbuild                       |   3 +
>  arch/s390/include/asm/jump_label.h                 |   6 +-
>  arch/s390/include/asm/kprobes.h                    |   4 +
>  arch/s390/kernel/entry.S                           |   5 +-
>  arch/s390/kernel/kprobes.c                         |   6 +-
>  arch/s390/kernel/mcount.S                          |   3 +-
>  arch/s390/kernel/vmlinux.lds.S                     |   1 -
>  arch/score/include/asm/Kbuild                      |   4 +
>  arch/score/kernel/vmlinux.lds.S                    |   1 -
>  arch/sh/include/asm/Kbuild                         |   3 +
>  arch/sh/include/asm/kprobes.h                      |   2 +
>  arch/sh/kernel/vmlinux.lds.S                       |   1 -
>  arch/sparc/include/asm/Kbuild                      |   3 +
>  arch/sparc/include/asm/jump_label.h                |   6 +-
>  arch/sparc/include/asm/kprobes.h                   |   5 +
>  arch/sparc/kernel/vmlinux.lds.S                    |   1 -
>  arch/sparc/mm/ultra.S                              |   3 +-
>  arch/tile/include/asm/Kbuild                       |   3 +
>  arch/tile/include/asm/kprobes.h                    |   6 +-
>  arch/tile/kernel/vmlinux.lds.S                     |   1 -
>  arch/um/include/asm/Kbuild                         |   4 +
>  arch/unicore32/include/asm/Kbuild                  |   3 +
>  arch/unicore32/include/asm/section-core.h          |  19 +
>  arch/x86/include/asm/Kbuild                        |   3 +
>  arch/x86/include/asm/jump_label.h                  |  10 +-
>  arch/x86/include/asm/kprobes.h                     |   6 +
>  arch/x86/kernel/cpu/microcode/core.c               |   8 +-
>  arch/x86/kernel/kprobes/core.c                     |  11 +-
>  arch/x86/kernel/vmlinux.lds.S                      |   1 -
>  arch/x86/tools/relocs.c                            |   4 +
>  arch/xtensa/include/asm/Kbuild                     |   4 +
>  arch/xtensa/kernel/Makefile                        |   8 +-
>  drivers/base/firmware_class.c                      |  12 +-
>  drivers/platform/x86/dell-smo8800.c                |   1 +
>  firmware/Makefile                                  |   6 +-
>  include/asm-generic/kprobes.h                      |  26 +
>  include/asm-generic/ranges.h                       | 103 ++++
>  include/asm-generic/section-core.h                 | 341 +++++++++++
>  include/asm-generic/sections.h                     |   4 +-
>  include/asm-generic/tables.h                       |  50 ++
>  include/asm-generic/vmlinux.lds.h                  |  73 +--
>  include/linux/compiler.h                           |   8 -
>  include/linux/dynamic_debug.h                      |   5 +-
>  include/linux/init.h                               |  20 +-
>  include/linux/jump_label.h                         |   8 +-
>  include/linux/kprobes.h                            |  24 +-
>  include/linux/ranges.h                             | 128 +++++
>  include/linux/sections.h                           | 111 ++++
>  include/linux/tables.h                             | 638 +++++++++++++++++++++
>  init/Kconfig                                       |  22 +
>  kernel/jump_label.c                                |  17 +-
>  kernel/kprobes.c                                   |  17 +-
>  lib/dynamic_debug.c                                |  13 +-
>  scripts/Makefile.build                             |   7 +-
>  scripts/Makefile.clean                             |   2 +
>  scripts/Makefile.lib                               |  11 +
>  scripts/Makefile.modpost                           |   2 +-
>  scripts/mod/modpost.c                              |   2 +-
>  scripts/{module-common.lds => module-common.lds.S} |   6 +
>  scripts/recordmcount.c                             |   2 +-
>  scripts/recordmcount.pl                            |   2 +-
>  tools/objtool/special.c                            |   2 +-
>  133 files changed, 2328 insertions(+), 214 deletions(-)
>  create mode 100644 Documentation/sections/conf.py
>  create mode 100644 Documentation/sections/index.rst
>  create mode 100644 Documentation/sections/linker-tables.rst
>  create mode 100644 Documentation/sections/ranges.rst
>  create mode 100644 Documentation/sections/section-core.rst
>  create mode 100644 arch/c6x/include/asm/tables.h
>  create mode 100644 arch/unicore32/include/asm/section-core.h
>  create mode 100644 include/asm-generic/kprobes.h
>  create mode 100644 include/asm-generic/ranges.h
>  create mode 100644 include/asm-generic/section-core.h
>  create mode 100644 include/asm-generic/tables.h
>  create mode 100644 include/linux/ranges.h
>  create mode 100644 include/linux/sections.h
>  create mode 100644 include/linux/tables.h
>  rename scripts/{module-common.lds => module-common.lds.S} (80%)
>
> --
> 2.9.2
>



-- 
Kees Cook
Nexus Security

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 00/16] linux: generalize sections, ranges and linker tables
  2016-08-19 22:29 ` [PATCH v4 00/16] linux: generalize sections, ranges and linker tables Kees Cook
@ 2016-08-22 23:06   ` Luis R. Rodriguez
  0 siblings, 0 replies; 35+ messages in thread
From: Luis R. Rodriguez @ 2016-08-22 23:06 UTC (permalink / raw)
  To: Kees Cook
  Cc: gnomes, linux-ia64, Jiri Kosina, benh, Ming Lei, Heiko Carstens,
	platform-driver-x86, James Bottomley, Paul Gortmaker,
	Paul Mackerras, Michael Ellerman, H. Peter Anvin,
	Masami Hiramatsu, Mauro Carvalho Chehab, linux-arch,
	markus.heiser, sparclinux, xen-devel, Russell King - ARM Linux,
	linux-sh, Will Deacon

On Fri, Aug 19, 2016 at 03:29:24PM -0700, Kees Cook wrote:
> On Fri, Aug 19, 2016 at 2:32 PM,  <mcgrof@kernel.org> wrote:
> > From: "Luis R. Rodriguez" <mcgrof@kernel.org>
> >
> > This v4 addresses feedback from the previous v3 series [0], and also
> > addresses a huge array of additional tests against many architectures
> > outside of what 0-day provides. As I mentioned in my last v3 series,
> > 0-day had only found one issue with the series, a blackfin architecture
> > linker issue with the last series. Guenter Rock was kind enough to give
> > my series a test spin on his test bed and he found quite a bit of other
> > oddball issues with obscure architectures, and even on x86 with an old
> > toolchain. After a lot of work and coordinating with a few maintainers
> > I'm happy to report all issues found so far through all possible testing
> > I could do are now fixed, this series also addresses all feedback from
> > the last series, as such this goes submitted as PATCH form.
> >
> > In addressing fixing this work on a few architectures some of the previous
> > patches are further simplified. The kprobes port to linker tables is made
> > much easier now that I've addressed moving out core kprobe declarations
> > into asm-generic/kprobes.h. Refer to the patch "kprobes: move kprobe
> > declarations to asm-generic/kprobes.h". This makes for a much cleaner
> > solution across architectures.
> >
> > Boris feedback on making the code bit rot feature optional is addressed
> > by using a new Kconfig symbol for this, CONFIG_BUILD_AVOID_BITROT,
> > but given Greg's concerns over lack of clarity over what this was all about
> > I've ripped that functionality out into its own patch with a bit more
> > extensive documentation and re-wording. See the patch "kbuild: enable option
> > to force compile force-obj-y and force-lib-y". I hope makes it clear how
> > linker tables can help with avoiding code bit rot. I've gone with a new
> > Kconfig symbol CONFIG_BUILD_AVOID_BITROT given CONFIG_COMPILE_TEST is
> > not available on UML, this feature is desirable on all architectures.
> >
> > The documentation is revamped, now that the DocBook format is deprecated
> > I ported the documention into the trendy hipster Sphinx documentation
> > format.
> >
> > AT Boris' request I've adapated the userspace linker table application
> > forintegration into the kernel under tools/ to make it easier to keep
> > things in sync, however since this requires a bit of changes to some headers
> > in tools/ I'll submit that separately.
> >
> > [0] https://lkml.kernel.org/r/1469222687-1600-1-git-send-email-mcgrof@kernel.org
> >
> > If you'd like this in git-form, you can get it on the 20160819-linker-table-v4
> > branch of my linux-next tree on kernel.org, this also includes the series of
> > the linker table userspace sandbox:
> >
> > https://git.kernel.org/cgit/linux/kernel/git/mcgrof/linux-next.git/log/?h=20160819-linker-table-v4
> >
> > Please let me know if there are any concerns or questions.
> 
> Thanks for the documentation and examples on this feature; I appreciate it! :)
> 
> While it seems like all the section declarations work in this series
> is designed for assembler source, I'm curious if I've missed a way to
> do this in .c source too.

Actually, the whole point to this originally was to provide helpers to
only do this in .c source code -- the fact that there are a few asm helpers
now is an after thought to provide parity of functionality to asm code to do
the exact same thing. The same macros provide the same functionality in
both C and asm code then and if there is some functionality lacking it may
for now just be on the asm side.

So for instance we have DECLARE_SECTION_RANGE() and that exist for C and
asm, but DECLARE_LINKTABLE() is currently only implemented for C code,
when and if we want it we can add it. DECLARE_SECTION_RANGE() has a demo
use in the userspace linker table sandbox.

> I'd love to avoid doing the crazy thing I'm currently doing in lkdtm 
> with section markings. Namely, I want to write a function in .c and have it
> moved into the .rodata section. The linkers get very very angry with me and I
> don't seem to be able to override the progbits to lose "x". Right now I'm
> doing an objcopy in
> drivers/misc/Makefile:
> 
> OBJCOPYFLAGS_lkdtm_rodata_objcopy.o := \
>                         --set-section-flags .text=alloc,readonly \
>                         --rename-section .text=.rodata
> targets += lkdtm_rodata.o lkdtm_rodata_objcopy.o
> $(obj)/lkdtm_rodata_objcopy.o: $(obj)/lkdtm_rodata.o FORCE
>         $(call if_changed,objcopy)
> 
> Thanks!

I'd have to take a closer look but from what you describe indeed this is
something that linker tables and section ranges is supposed to help with -- a
generic API to set sections in an architecture-agnostic way.  If you can
classify your functions with section ranges or linker tables then you should be
set. They flags used is whatever the architecture has decided to use for the
section as per the linker script and where each section falls under. If you
need more special tweaking (see flags in push_section_tbl()) then indeed some
newer APIs might be needed in C, as these flags tweaks are only provided for
asm right now but it'd be good to know if just using the existing APIs with
defaults for the section you needs for C code would not suffice.

If all you have is functions you can stick to section ranges, if these
functions are instead part of a larger data structure you need linker
tables. It sounds like you just have functions, and even if you needed
something outside of what is provided, say the flags, then adding a new
__LINUX_RANGE_FLAGS() could be added easily that also lets you specify
the flags you need.

For an example of section range us kprobes was ported over so we have
for instance:

# define __kprobes      __LINUX_RANGE(SECTION_TEXT, kprobes)

If you had something that needed custom flags you could see if
adding a __LINUX_RANGE_FLAGS() would suffice, but I'd be very
interested to know if the defaults used by the specified section
does not suffice.

Also  your use case seems to require a full file set to a section with specific
attributes. Although first instinct might be to use section ranges, if the
section range accessed some global variable or data structure in the file there
may be an issue, or you'd have to the also peg the data into a section. If this
is done it occurs to me an alternative is to just use a large data structure
to represent the full of functions and data, so to use a linker table that way
the association is done in one full swing with the definition of the table.

This of course is just at a cursory review.

  Luis

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 04/16] generic-sections: add section core helpers
  2016-08-19 21:47   ` Kees Cook
@ 2016-08-22 23:13     ` Luis R. Rodriguez
  0 siblings, 0 replies; 35+ messages in thread
From: Luis R. Rodriguez @ 2016-08-22 23:13 UTC (permalink / raw)
  To: Kees Cook
  Cc: gnomes, linux-ia64, Jiri Kosina, benh, Ming Lei, Heiko Carstens,
	platform-driver-x86, James Bottomley, Paul Gortmaker,
	Paul Mackerras, Michael Ellerman, H. Peter Anvin,
	Masami Hiramatsu, Mauro Carvalho Chehab, linux-arch,
	markus.heiser, sparclinux, xen-devel, Russell King - ARM Linux,
	linux-sh, Will Deacon

On Fri, Aug 19, 2016 at 02:47:48PM -0700, Kees Cook wrote:
> On Fri, Aug 19, 2016 at 2:32 PM,  <mcgrof@kernel.org> wrote:
> > From: "Luis R. Rodriguez" <mcgrof@kernel.org>
> >
> > +SECTION_RODATA
> > +--------------
> > +.. kernel-doc:: include/asm-generic/section-core.h
> > +   :doc: SECTION_RODATA
> > +
> > +SECTION_RODATA
> 
> Typo: should this be called SECTION_TEXT instead?

Fixed thanks.

> > +--------------
> > +.. kernel-doc:: include/asm-generic/section-core.h
> > +   :doc: SECTION_TEXT
> > +
> > +SECTION_DATA
> > +------------
> > +.. kernel-doc:: include/asm-generic/section-core.h
> > +   :doc: SECTION_DATA
> 
> Missing from this list are things like the __read_mostly
> (".data..read_mostly") and __ro_after_init (".data..ro_after_init")
> sections. Should those be included too, or are you only doing the "top
> level" sections?

I'm doing top level right now just to start off and get the
bikeshedding out of the way. We can add more with more time
or as we port more things or as the need arises.

  Luis

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 06/16] ranges.h: add helpers to build and identify Linux section ranges
  2016-08-19 21:55   ` Kees Cook
@ 2016-08-22 23:48     ` Luis R. Rodriguez
  0 siblings, 0 replies; 35+ messages in thread
From: Luis R. Rodriguez @ 2016-08-22 23:48 UTC (permalink / raw)
  To: Kees Cook
  Cc: gnomes, linux-ia64, Jiri Kosina, benh, Ming Lei, Heiko Carstens,
	platform-driver-x86, James Bottomley, Paul Gortmaker,
	Paul Mackerras, Michael Ellerman, H. Peter Anvin,
	Masami Hiramatsu, Mauro Carvalho Chehab, linux-arch,
	markus.heiser, sparclinux, xen-devel, Russell King - ARM Linux,
	linux-sh, Will Deacon

On Fri, Aug 19, 2016 at 02:55:43PM -0700, Kees Cook wrote:
> On Fri, Aug 19, 2016 at 2:32 PM,  <mcgrof@kernel.org> wrote:
> > From: "Luis R. Rodriguez" <mcgrof@kernel.org>
> >
> > Section ranges are on one of the types of custom sections
> > types used in Linux. This provides a series of helpers for
> > defining them and using them. Most importantly this also
> > enables us to avoid modifying the linker script when we
> > add a new section range.
> >
> > It turns out a lot of custom sections are actually section ranges,
> > and these are typically spelled out in their architecture specific
> > asm/sections.h file -- we anable architectures to override what asm
> 
> Typo: anable -> enable

Fixed.

> > is used for section ranges but start by default trusting the
> > asm-generic version all around.
> 
> Can you explain the addition of the SORT() stuff in this patch? Its
> purpose isn't clear to me and doesn't appear to be mentioned in the
> commit log.

Indeed, let me explain and I'll also add this to the commit log.
We need to use SORT() in vmlinux.lds.S for section ranges for two
reasons:

a) By using SORT() and using "any" for cases where order does not
   matter we're able to extend section ranges without modifying the
   linker script. The special annotation used for the "order" for
   the first element of a section range is the empty string (see
   __SECTION_RANGE_BEGIN(), the ending element uses the character
   "~", see __SECTION_RANGE_END(). By default anything added in between
   uses the "any" order, when you use SORT() on this you end up stuffing
   all elements with the "any" order in between, and allowing you to have
   a beginning and end reference -- without modifying the linker script.

b) Although explicit order is typically not required for section ranges
   there is one use case brought to my attention we wanted to support
   where order was desired -- to build synthetic functions. An example
   is provided in asm in tools in the last patch where the linker tables
   sandbox is provided. Refer to tools/linker-tables/drivers/synth/or.S

> > diff --git a/include/asm-generic/ranges.h b/include/asm-generic/ranges.h
> > new file mode 100644
> > index 000000000000..74cd941aa2f8
> > --- /dev/null
> > +++ b/include/asm-generic/ranges.h
> > @@ -0,0 +1,89 @@
> > +#ifndef _ASM_GENERIC_RANGES_H_
> > +#define _ASM_GENERIC_RANGES_H_
> > +/*
> > + * Copyright (C) 2016 Luis R. Rodriguez <mcgrof@kernel.org>
> > + *
> > + * 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_RNG(section, name)                                     \
> 
> I would really prefer to avoid shortening "range" to the acronym for
> "random number generator". That's very confusing. :P It's only two
> letters more...

Speaking of, it'd be great if you could trim your reply to the hunks of
interest :) but yes sure, more bike shedding -- I'm happy to go with that
if that is the consensus.

  Luis

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 07/16] tables.h: add linker table support
  2016-08-19 22:02   ` Kees Cook
@ 2016-08-22 23:53     ` Luis R. Rodriguez
  0 siblings, 0 replies; 35+ messages in thread
From: Luis R. Rodriguez @ 2016-08-22 23:53 UTC (permalink / raw)
  To: Kees Cook
  Cc: gnomes, linux-ia64, Jiri Kosina, benh, Ming Lei, Heiko Carstens,
	platform-driver-x86, James Bottomley, Paul Gortmaker,
	Paul Mackerras, Michael Ellerman, H. Peter Anvin,
	Masami Hiramatsu, Mauro Carvalho Chehab, linux-arch,
	markus.heiser, sparclinux, xen-devel, Russell King - ARM Linux,
	linux-sh, Will Deacon

On Fri, Aug 19, 2016 at 03:02:07PM -0700, Kees Cook wrote:
> On Fri, Aug 19, 2016 at 2:32 PM,  <mcgrof@kernel.org> wrote:
> > 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@kernel.org>
> > + *
> > + * 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

Thanks, fixed.

  Luis

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 08/16] kbuild: enable option to force compile force-obj-y and force-lib-y
  2016-08-19 22:10   ` Kees Cook
@ 2016-08-22 23:59     ` Luis R. Rodriguez
  2016-08-30 20:15       ` Luis R. Rodriguez
  0 siblings, 1 reply; 35+ messages in thread
From: Luis R. Rodriguez @ 2016-08-22 23:59 UTC (permalink / raw)
  To: Kees Cook, Michal Marek
  Cc: gnomes, linux-ia64, Jiri Kosina, benh, Ming Lei, Heiko Carstens,
	platform-driver-x86, James Bottomley, Paul Gortmaker,
	Paul Mackerras, Michael Ellerman, H. Peter Anvin,
	Masami Hiramatsu, Mauro Carvalho Chehab, linux-arch,
	markus.heiser, sparclinux, xen-devel, Russell King - ARM Linux,
	linux-sh, Will Deacon

On Fri, Aug 19, 2016 at 03:10:33PM -0700, Kees Cook wrote:
> On Fri, Aug 19, 2016 at 2:32 PM,  <mcgrof@kernel.org> wrote:
> > diff --git a/init/Kconfig b/init/Kconfig
> > index cac3f096050d..ef09e83b9196 100644
> > --- a/init/Kconfig
> > +++ b/init/Kconfig
> > @@ -53,6 +53,28 @@ config CROSS_COMPILE
> >           need to set this unless you want the configured kernel build
> >           directory to select the cross-compiler automatically.
> >
> > +config BUILD_AVOID_BITROT
> > +       bool "Enable force building of force-obj-y and force-lib-y"
> 
> Sorry to continue the bikeshedding on this, but if I encounter
> something in a Makefile named "force-obj-y" I would expect it to
> always be built, no matter what. But this is not the case: the
> "force-" prefix is tied to this CONFIG_BUILD_AVOID_BITROT. This verb
> usage is weird, as I'd expect an adjective, like "forceable-obj-y" or
> something that describes that it CAN be built even with the CONFIG for
> it is missing, etc.
> 
> Regardless, I defer to Michal on this, but I'm not a fan of "force"
> being used when it's an optional action. :)

Sure, Michal let me know if forceable-obj-y and forceable-lib-y is the
way to go.

  Luis

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH v4 08/16] kbuild: enable option to force compile force-obj-y and force-lib-y
  2016-08-22 23:59     ` Luis R. Rodriguez
@ 2016-08-30 20:15       ` Luis R. Rodriguez
  0 siblings, 0 replies; 35+ messages in thread
From: Luis R. Rodriguez @ 2016-08-30 20:15 UTC (permalink / raw)
  To: Luis R. Rodriguez, Michal Marek
  Cc: gnomes, linux-ia64, Jiri Kosina, benh, Ming Lei, Heiko Carstens,
	platform-driver-x86, James Bottomley, Paul Gortmaker,
	Paul Mackerras, Michael Ellerman, H. Peter Anvin,
	Masami Hiramatsu, Mauro Carvalho Chehab, linux-arch,
	markus.heiser, sparclinux, xen-devel, Russell King - ARM Linux,
	linux-sh, Will Deacon

On Tue, Aug 23, 2016 at 01:59:10AM +0200, Luis R. Rodriguez wrote:
> On Fri, Aug 19, 2016 at 03:10:33PM -0700, Kees Cook wrote:
> > On Fri, Aug 19, 2016 at 2:32 PM,  <mcgrof@kernel.org> wrote:
> > > diff --git a/init/Kconfig b/init/Kconfig
> > > index cac3f096050d..ef09e83b9196 100644
> > > --- a/init/Kconfig
> > > +++ b/init/Kconfig
> > > @@ -53,6 +53,28 @@ config CROSS_COMPILE
> > >           need to set this unless you want the configured kernel build
> > >           directory to select the cross-compiler automatically.
> > >
> > > +config BUILD_AVOID_BITROT
> > > +       bool "Enable force building of force-obj-y and force-lib-y"
> > 
> > Sorry to continue the bikeshedding on this, but if I encounter
> > something in a Makefile named "force-obj-y" I would expect it to
> > always be built, no matter what. But this is not the case: the
> > "force-" prefix is tied to this CONFIG_BUILD_AVOID_BITROT. This verb
> > usage is weird, as I'd expect an adjective, like "forceable-obj-y" or
> > something that describes that it CAN be built even with the CONFIG for
> > it is missing, etc.
> > 
> > Regardless, I defer to Michal on this, but I'm not a fan of "force"
> > being used when it's an optional action. :)
> 
> Sure, Michal let me know if forceable-obj-y and forceable-lib-y is the
> way to go.

Michal? Any preference ? Or how about opt-force-obj ?

  Luis

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH v4 07/16] tables.h: add linker table support
  2016-08-19 21:33 mcgrof
@ 2016-08-19 21:34 ` mcgrof
  2016-08-19 21:34   ` mcgrof
  0 siblings, 1 reply; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:34 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: x86, luto, keescook, torvalds, gregkh, rusty, gnomes, alan,
	dwmw2, arnd, ming.lei, linux-arch, benh, ananth, pebolle,
	fontana, david.vrabel, konrad.wilk, mcb30, jgross,
	andrew.cooper3, andriy.shevchenko, paul.gortmaker, xen-devel, ak,
	pali.rohar, dvhart, platform-driver-x86, mmarek, linux, jkosina,
	korea.drzix, linux-kbuild, ton

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

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@ipxe.org>
Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 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@kernel.org>
+M:	"H. Peter Anvin" <hpa@zytor.com>
+L:	linux-arch@vger.kernel.org
+L:	linux-kernel@vger.kernel.org
+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@ti.com>
 L:	linux-kernel@vger.kernel.org
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@kernel.org>
+ *
+ * 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.
+ *
+ * [0] https://lkml.kernel.org/r/1470798247.3551.94.camel@redhat.com
+ */
+
+#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@kernel.org>
+ *
+ * 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@kernel.org>
+ *
+ * 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

^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH v4 07/16] tables.h: add linker table support
  2016-08-19 21:34 ` [PATCH v4 07/16] tables.h: add linker table support mcgrof
@ 2016-08-19 21:34   ` mcgrof
  0 siblings, 0 replies; 35+ messages in thread
From: mcgrof @ 2016-08-19 21:34 UTC (permalink / raw)
  To: hpa, tglx, mingo, jpoimboe, bp, linux, mhiramat,
	masami.hiramatsu.pt, jbaron, heiko.carstens, ananth,
	anil.s.keshavamurthy, davem, realmz6
  Cc: x86, luto, keescook, torvalds, gregkh, rusty, gnomes, alan,
	dwmw2, arnd, ming.lei, linux-arch, benh, ananth, pebolle,
	fontana, david.vrabel, konrad.wilk, mcb30, jgross,
	andrew.cooper3, andriy.shevchenko, paul.gortmaker, xen-devel, ak,
	pali.rohar, dvhart, platform-driver-x86, mmarek, linux, jkosina,
	korea.drzix, linux-kbuild, tony.luck, akpm, linux-ia64,
	linux-arm-kernel, linux-sh, sparclinux, catalin.marinas,
	will.deacon, rostedt, jani.nikula, mchehab, markus.heiser, acme,
	jolsa, msalter, chris, jcmvbkbc, linux-xtensa, paulus, mpe,
	James.Bottomley, Luis R. Rodriguez

From: "Luis R. Rodriguez" <mcgrof@kernel.org>

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@ipxe.org>
Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
---
 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@kernel.org>
+M:	"H. Peter Anvin" <hpa@zytor.com>
+L:	linux-arch@vger.kernel.org
+L:	linux-kernel@vger.kernel.org
+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@ti.com>
 L:	linux-kernel@vger.kernel.org
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@kernel.org>
+ *
+ * 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.
+ *
+ * [0] https://lkml.kernel.org/r/1470798247.3551.94.camel@redhat.com
+ */
+
+#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@kernel.org>
+ *
+ * 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@kernel.org>
+ *
+ * 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


^ permalink raw reply related	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2016-08-30 20:15 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-19 21:32 [PATCH v4 00/16] linux: generalize sections, ranges and linker tables mcgrof
2016-08-19 21:32 ` mcgrof
2016-08-19 21:32 ` [PATCH v4 01/16] x86: remove LTO_REFERENCE_INITCALL() mcgrof
2016-08-19 21:32   ` mcgrof
2016-08-19 21:32 ` [PATCH v4 02/16] dell-smo8800: include uaccess.h mcgrof
2016-08-19 21:32   ` mcgrof
2016-08-19 21:32 ` [PATCH v4 03/16] scripts/module-common.lds: enable generation mcgrof
2016-08-19 21:32   ` mcgrof
2016-08-19 21:32 ` [PATCH v4 04/16] generic-sections: add section core helpers mcgrof
2016-08-19 21:32   ` mcgrof
2016-08-19 21:47   ` Kees Cook
2016-08-22 23:13     ` Luis R. Rodriguez
2016-08-19 21:32 ` [PATCH v4 05/16] xtensa: skip adding literal when SORT() is used mcgrof
2016-08-19 21:32   ` mcgrof
2016-08-19 21:32 ` [PATCH v4 06/16] ranges.h: add helpers to build and identify Linux section ranges mcgrof
2016-08-19 21:32   ` mcgrof
2016-08-19 21:55   ` Kees Cook
2016-08-22 23:48     ` Luis R. Rodriguez
2016-08-19 21:32 ` [PATCH v4 07/16] tables.h: add linker table support mcgrof
2016-08-19 21:32   ` mcgrof
2016-08-19 22:02   ` Kees Cook
2016-08-22 23:53     ` Luis R. Rodriguez
2016-08-19 21:32 ` [PATCH v4 08/16] kbuild: enable option to force compile force-obj-y and force-lib-y mcgrof
2016-08-19 21:32   ` mcgrof
2016-08-19 22:10   ` Kees Cook
2016-08-22 23:59     ` Luis R. Rodriguez
2016-08-30 20:15       ` Luis R. Rodriguez
2016-08-19 21:32 ` [PATCH v4 09/16] firmware/Makefile: force recompilation if makefile changes mcgrof
2016-08-19 21:32   ` mcgrof
2016-08-19 21:32 ` [PATCH v4 10/16] firmware: port built-in section to linker table mcgrof
2016-08-19 21:32   ` mcgrof
2016-08-19 22:29 ` [PATCH v4 00/16] linux: generalize sections, ranges and linker tables Kees Cook
2016-08-22 23:06   ` Luis R. Rodriguez
2016-08-19 21:33 mcgrof
2016-08-19 21:34 ` [PATCH v4 07/16] tables.h: add linker table support mcgrof
2016-08-19 21:34   ` mcgrof

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).