@@ -14,6 +14,7 @@ Contents:
kernel-documentation
media/index
gpu/index
+ sections/index
Indices and tables
==================
new file mode 100644
@@ -0,0 +1,4 @@
+# -*- coding: utf-8; mode: python -*-
+
+project = 'Linux Kernel ELF sections'
+html_search_language = 'en'
new file mode 100644
@@ -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
new file mode 100644
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
new file mode 100644
@@ -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__ */
@@ -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
@@ -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
new file mode 100644
@@ -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_ */
@@ -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>
@@ -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
new file mode 100644
@@ -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 */