[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v6 01/14] generic-sections: add section core helpers



On Mon, Jan 09, 2017 at 06:58:19AM -0800, Luis R. Rodriguez wrote:
> Linux makes extensive use of custom ELF header sections,
> documentation for these are well scatterred. Unify this

                          is

> documentation in a central place and provide helpers to
> build custom Linux sections.

This patch contains at least three logical changes and needs splitting:

* unify documentation
* adding helpers
* MAINTAINERS addition

Documentation and MAINTAINERS changes should go last in the patchset.

Accordingly, the huuge commit message below should be spread around
those three patches.

> 
> 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.
> 
> v5:
> 
> o Huge documentation revamp based on a careful review of the ELF
>   specifications. Includes documentation now also about usage of
>   two dots (..) when prefixing ELF program specific sections.
> 
> o Replace macros for sections names in favor of just using
>   the section names explicitly in the linker script. This is
>   perhaps more work to grep but this is what folks seem to
>   currently prefer.
> 
> o Fix .text and .rodata documentation to explain memory protection
>   strategies which architectures can embrace upon initialization
>   (documents CONFIG_DEBUG_RODATA and mark_rodata_ro())
> 
> o Skip the 'Linux section ordering' documentation section, we'll instead
>   add this on subsequent patch which will expand on it considerably
> 
> o Dropped tree on MAINTAINERS -- as per discussions with Arnd, hpa and
>   Josh, its easier to just let changes for sections go in through the
>   respective tree that needs the changes.
> 
> o Fix typos on documentation
> 
> o Dropped SECTION_ALL(), __SECTION_CORE(), SECTION_CORE_ALL() macros
>   since we are favoring using explicit section names. These are
>   useless if we are being explicit.
> 
> o Drop LINUX_SECTION_SIZE(), LINUX_SECTION_EMPTY() in favor of having
>   section ranges and linker tables define their own, to avoid confusion
>   and make code more readable.
> 
> o Add __define_initcall() documentation and a small section describing
>   our current initcall levels. This should help also clarify what was
>   meant about keeping backward compatiblity.
> 
> v4:
> 
> o Port to shiny new sphinx documentation format

This looks like a 4th patch ontop of the unifying documentation one.

> 
> 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.

...

> +++ b/Documentation/sections/background.rst
> @@ -0,0 +1,105 @@
> +======================
> +ELF section background
> +======================
> +
> +About
> +=====
> +
> +The purpose of this chapter is to help those not familiar with ELF to brush 
> up
> +the latest ELF specifications in order to help understand how Linux uses and
> +defines its own ELF sections.
> +
> +Standardized ELF
> +================
> +
> +The first publication documenting ELF was UNIX System Laboratories' (USL)
> +*System V Release 4 Application Binary Interface* (`SRV4 ABI`_) 
> specification.
> +Originally ELF was only a small part of the SRV4 ABI, with time however new
> +specifications only put focus on ELF, such was the case of the *TIS Portable
> +Formats Specification version 1.2* (`TIS 1.2`_). As of TIS 1.2, ELF was
> +supplemented with processor specific ELF addendums, available on the *Linux
> +Foundation referenced specification page* (`LF ref page`_). The latest ELF
> +specification is the *System V Application Binary Interface - DRAFT - 24 
> April
> +2001* (`gabi4`_).
> +
> +.. _SRV4 ABI: http://www.sco.com/developers/devspecs/gabi41.pdf
> +.. _TIS 1.2: https://refspecs.linuxbase.org/elf/elf.pdf
> +.. _LF ref page: https://refspecs.linuxbase.org/
> +.. _gabi4: https://refspecs.linuxbase.org/elf/gabi4+/contents.html
> +

A pointer to the wikipedia page would suffice instead of us repeating
ELF history here.

> +ELF views on Linux
> +==================
> +
> +There are two views which can be used for inspecting data in an ELF file, a
> +Linking view, and an Execution view. A Section Header Table enables one to
> +describe an object using the Linking view while a Program Header Table 
> enables
> +one to describe an object using the Execution view. The views are not 
> mutually
> +exclusive. For intance, vmlinux can be viewed under both views, ``readelf -S

s/intance/instance/

> +vmlinux`` for the Linking view, and ``readelf -l vmlinux`` for the Execution
> +view.  In Linux only the vmlinux file will have an Execution view, even 
> modules
> +lack an Execution view given that vmlinux is the only file that describes how
> +the the kernel runs from the start.  All other Linux kernel object files have

s/the //

> +an available Linking view.

s/n available// - "have a Linking view" is fine.

> +
> +Under the Linking view, the Section Header Table describes all available
> +sections. The Section Header Table is an array of ELF section header data
> +structures. If on a 32-bit system this is ``struct elf32_shd``, if on a 
> 64-bit
> +this is ``struct elf64_shdr``.

"If on ... if on" doesn't work as a sentence.

> Sections are only visible on object files that

s/on/in/

> +have a Linking view, since all Linux kernel files have Linking view, all 
> kernel
> +objects have ELF sections.

Btw, that last sentence is kinda funny and not really needed. Or do you
wanna say that everything-code is in a section?

> +
> +Limitations on ELF sections

ELF sections limitations

> +===========================
> +
> +We provide a summary on the limitations of ELF sections.

Kill that sentence.

> Refer to the public
> +ELF specifications for details. Note that 64-bit limitations may depend
> +on processor specific section attributes to be used, refer to your processsor

"processsor" - the 's' button stuck? :-)

> +specification if unsure.

Better yet, kill that whole paragraph.

> +
> +Its worth ellaborating on the limitations on the name of an ELF section:

"elaborating"

> +ELF section names are stored as strings as per the ELF specification, and
> +as can be expected, these don't have explicit limitations. The implicit
> +limitation then depends on the size of an ELF object file and ELF section.
> +
> +If using really large kernels or objects with large amounts of sections one
> +would still need to be sure that ELF loader in charge of loading the Linux
> +kernel is properly updated to handle coping with the latest ELF extensions.
> +
> +   .. flat-table:: Limitations on ELF Sections
> +
> +      * - Section attribute
> +        - 32-bit
> +        - 64-bit
> +
> +      * - ELF section name
> +        - Size of an ELF section
> +        - Size of an ELF section
> +
> +      * - Size of an ELF section
> +        - 4 GiB
> +        - 16 EiB
> +
> +      * - Max number of sections in an object file
> +        - 4 GiEntries (4294967296)
> +        - 16 EiEntries (18446744073709551616)
> +
> +Program specific ELF sections

Program-specific

> +=============================
> +
> +The ELF specification allows for a section type to be specified as
> +*Program specific section*, defined as ``SHT_PROGBITS``. This sections type

                                                                 section

> +enables programs to customize sections for their own use. In assembly this
                                                                        ^
                                                                        is

> +specified ``@progbits`` on most architectures, on ARM this is ``%progbits``.
             ^            ^

             with the     flag                          s/this is/it is called/

> +
> +``SHT_PROGBITS`` is used by Linux for defining and using Linux ELF sections.
> +
> +Special ELF Sections
> +====================
> +
> +The ELF specification defines *Special ELF Sections* on chapter 4 (`gabi4
> +ch4`_). These are defined as sections which hold program and control
> +information. Of these sections, a few have the section type as
> +``SHT_PROGBITS``. This enables Linux to *further customize* use of the 
> section
> +beyond what the ELF specification suggests.
> +
> +.. _gabi4 ch4: 
> https://refspecs.linuxbase.org/elf/gabi4+/ch4.sheader.html#special_sections
> 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..f37511ef05e7
> --- /dev/null
> +++ b/Documentation/sections/index.rst
> @@ -0,0 +1,17 @@
> +=========================
> +Linux Kernel ELF sections
> +=========================
> +
> +This book documents the different ELF sections used on the Linux kernel.

                                                        in

> +We start off by providing references to how ELF was standardized, references
> +to the standards on ELF sections, review limitations of ELF sections, and
> +finally how Linux uses ELF sections in the Linux kernel. Certain important
> +Linux ELF sections are documented carefully: we describe the goal of the
> +ELF section, and address concurrency considerations when applicable. A few
> +common a set of Linux helpers for ELF sections are also documented.

s/few common a //

> +
> +.. toctree::
> +   :maxdepth: 4
> +
> +   background
> +   section-core

...

> diff --git a/arch/unicore32/include/asm/section-core.h 
> b/arch/unicore32/include/asm/section-core.h
> new file mode 100644
> index 000000000000..0b9c68429a1a
> --- /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@xxxxxxxxxx>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of copyleft-next (version 0.3.1 or later) as published
> + * at http://copyleft-next.org/.

Isn't all kernel code GPLv2?

> + */
> +
> +/* 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 2b892e2313a9..af975f21eeee 100644
> --- a/arch/x86/include/asm/Kbuild
> +++ b/arch/x86/include/asm/Kbuild
> @@ -12,3 +12,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 b7fbaa56b51a..7879c31e66a7 100644
> --- a/arch/xtensa/include/asm/Kbuild
> +++ b/arch/xtensa/include/asm/Kbuild
> @@ -32,3 +32,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..bb16befc4251
> --- /dev/null
> +++ b/include/asm-generic/section-core.h
> @@ -0,0 +1,307 @@
> +#ifndef _ASM_GENERIC_SECTION_CORE_H_
> +#define _ASM_GENERIC_SECTION_CORE_H_
> +/*
> + * Linux section core definitions
> + *
> + * Copyright (C) 2016 Luis R. Rodriguez <mcgrof@xxxxxxxxxx>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of copyleft-next (version 0.3.1 or later) as published
> + * at http://copyleft-next.org/.

Ditto.

> + */
> +
> +/**
> + * DOC: Linux ELF program specific sections
> + *
> + * Linux makes extensive use of ``SHT_PROGBITS`` to both extend use and 
> definition
                                                             
^^^^^^^^^^^^^^^^^^^^^^^^

                                                             needs rewording

> of *Special ELF Sections* (`gabi4 ch4`_) and to define its own
> + * sections. This chaper is dedicated to documenting Linux program specific

"chapter"

Please spellcheck the whole patchset before next submission.

> + * sections and helpers available to make use of these easier to implement 
> and
> + * use.

Huh, come again? This sentence is funny.

> + *
> + * .. _gabi4 ch4: 
> https://refspecs.linuxbase.org/elf/gabi4+/ch4.sheader.html#special_sections
> + */
> +
> +/**
> + * DOC: Linux linker script
> + *
> + * Linux uses a custom linker script to build the vmlinux binary, it uses it 
> to
> + * strategically place and define Linux ELF sections.  Each architecture 
> needs
> + * to implement its own linker script, it is expected to reside in

                              ... script which is expected ...

> + * ``arch/$(ARCH)/kernel/vmlinux.lds.S``.  Architecture Linux linker scripts 
> in
> + * turn include and use definitions from 
> ``include/asm-generic/vmlinux.lds.h``,
> + * as well as some helpers documented in this chapter.
> + *
> + * In assembly it is common practice to use dots (``.``) in labels to avoid
> + * clashes with C symbols. Similarly, a dot (``.``) can be part of a section
> + * name but not a C symbol. Historically then, two dots are used (``..``)
> + * have been used in linker scripts when adding program specific sections

are used .. have been used?

> + * when there are concerns to avoid clashes with compiler generated sections.

This last sentence needs simplifying.

> + */
> +
> +/**
> + * DOC: Memory protection
> + *
> + * Linux allows architectures which support memory protection features to
> + * take advantage of them by letting architectures define and enable
> + * ``CONFIG_DEBUG_RODATA`` and implement a mark_rodata_ro() call.

Simplify: "Architectures with memory protection features can define and
enable CONFIG_DEBUG_RODATA... "

> + * mark_rodata_ro() can be used for instance to mark specific sections as
                                  , for instance, 


> + * read-only or non-executable.
> + *
> + * Linux typically follows a convention to have the .rodata ELF section 
> follow
> + * after the .text ELF section, it does this to help architectures which
                                 . It does this...

> + * support memory protection to mark both .text and .rodata as read-only in
> + * one shot.
> + *
> + * For more details refer to mark_rodata_ro().
> + */
> +
> +/**
> + * DOC: .rodata
> + *
> + * ELF section used for data which must be protected from write access.
> + */
> +
> +/**
> + * DOC: .text
> + *
> + * ELF section name used for code (functions) used during regular
> + * kernel run time.
> + */
> +
> +/**
> + * DOC: .data
> + *
> + * ELF section used for read-write 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: .init.text
> + *
> + * ELF section for code (functions) used only during boot or driver
> + * initialization.
> + *
> + */
> +
> +/**
> + * DOC: .init.data
> + *
> + * ELF section used for data structures used only during boot or driver
> + * initialization.
> + */
> +
> +/**
> + * DOC: .init.rodata
> + *
> + * ELF section used for read-only code (functions) used only during boot
> + * or driver initialization.
> + */
> +
> +/**
> + * DOC: .initcall
> + *
> + * ELF section used for subsystem init calls. There are init levels
> + * representing different functionality in the kernel. For more details
> + * refer to __define_initcall().
> + */
> +
> +/**
> + * DOC: Linux exit sections
> + *
> + * These sections are used to declare a functions and data structures which

s/a //

> + * 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: .exit.text
> + *
> + * ELF section used to for code (functions) used only during module unload.
> + */
> +
> +/**
> + * DOC: .exit.data
> + *
> + * ELF section used to for data structures used only during module
> + * unload.
> + */
> +
> +/**
> + * DOC: .exitcall.exit
> + *
> + * ELF section used for exit routines, order is important and maintained by
> + * link order.
> + */
> +
> +/**
> + * 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: .ref.text
> + *
> + * ELF section used to annotate code (functions) which has been vetteed as

vetted?

> + * valid for its reference or use of other code (functions) or data 
> structures
> + * which are part of the init sections.
> + */
> +
> +/**
> + * DOC: .ref.data
> + *
> + * ELF section used for data structures which have been vetteed for its

ditto.

> + * reference or use of other code (functions) or data structures part of the
> + * init sections.
> + */
> +
> +/**
> + * DOC: .ref.rodata
> + *
> + * ELF section used to annotate const code (functions) const data structures
> + * which has been vetteed for its reference or use of other code (functions)

ditto.

> + * or data structures part of the init sections.
> + */
> +
> +/* Can be used on foo.S for instance */

What does that comment mean?

> +#ifndef __set_section_core_type
> +# define __set_section_core_type(___section, ___core, ___name,               
> \
> +                              ___level, ___flags, ___type)           \
> +     .section ___section..___core.___name.___level, ___flags, ___type

Are you sure we need 4 levels of hierarchy?

If so, we should document what all those section, core, name and level
mean and how the whole sections hierarchy is supposed to look like.

> +#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__)
> +
> +# ifndef LINKER_SCRIPT
> +
> +#  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__) */
> +
> +/*
> + * 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

                . It, however, seems ...

> + * 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 4df64a1fc09e..b145ae8d9cbe 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 0968d13b3885..483f60c451f9 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)
> diff --git a/include/linux/init.h b/include/linux/init.h
> index 885c3e6d0f9d..116e3262332a 100644
> --- a/include/linux/init.h
> +++ b/include/linux/init.h
> @@ -130,6 +130,24 @@ int __init init_rootfs(void);
>  extern bool rodata_enabled;
>  #endif
>  #ifdef CONFIG_DEBUG_RODATA
> +/**
> + * mark_rodata_ro - implemement memory protection for ELF sections
> + *
> + * Architectures which support memory protection define a kernel 
> configuration
> + * entry for CONFIG_DEBUG_RODATA,

That's just too many words for nothing. You can just as well say:

"Architectures which support memory protection enable CONFIG_DEBUG_RODATA and
implement mark_rodata_ro()."

> enable it in and implement mark_rodata_ro().
> + * mark_rodata_ro() should strive to adjust the .rodata and .text ELF 
> sections
> + * with read-only memory protection to prevent modifications of these 
> sections

"mark_rodata_ro() marks .rodata and .text section read-only..."

Simple.

> + * after bootup. It can also try to use memory protection to prevent 
> execution
> + * on the .rodata ELF section.
> + *
> + * In order to help architectures set both .text and .rodata as read-only 
> with
> + * memory protections in one shot Linux has typically followed the convention
> + * to have the .rodata ELF section follow the .text ELF section on the 
> vmlinux

                                                                   in

> + * linker script.
> + *
> + * Linux calls mark_rodata_ro() after freeing .init code and prior to calling
> + * the first init userspace process.

"first init userspace process" either say "prior to calling init" or
"prior to calling the first userspace process" but both is jambalayed
into something confusing.

> + */
>  void mark_rodata_ro(void);
>  #endif
>  
> @@ -140,25 +158,70 @@ extern bool initcall_debug;
>  #endif
>    
>  #ifndef MODULE
> +/**
> + * DOC: Initcall levels
> + *
> + * When Linux boots the kernel do_initcalls() iterates over each Linux

When Linux boots the kernel?!? You're joking, right?

Just do "During boot, do_initcalls() ..."

> + * initialization level ID and calls all routines embedded on each level ID.
> + * Prior to v2.5.2.3 Linux had only one init level onto which all init
> + * functions folded onto using __initcall(). After v2.5.2.4 Linux split up
> + * initcalls into 7 separate initcall subsection levels, each level 
> describing
> + * different functionality part of the kernel (commit `9d6ba121b7e17085`_
> + * (v2.5.2.3 -> v2.5.2.4)). In order to remain backward compatible 
> __initcall()
> + * calls were left mapped to device_initcall().

And why do we need all that git archeology here?

> + * Each init level consists of a dedicated ELF section, init functions are
> + * associated to an init level by linking it into the respective level's
                 with

> + * ELF section.
> + *
> + * Lower order init levels run prior to higher order init levels. Ordering
> + * inside each initcall level is determined by respective link order.

Those last two sentences are enough.

> + *
> + * .. _9d6ba121b7e17085: 
> https://git.kernel.org/cgit/linux/kernel/git/history/history.git/commit/?id=9d6ba121b7e17085c95139233686b27a4d4c650e

That's one ugly footnote. Also, the git commit id suffices, you don't
need the URL.

> + */
>  
>  #ifndef __ASSEMBLY__
>  
> -/*
> - * initcalls are now grouped by functionality into separate
> - * subsections. Ordering inside the subsections is determined
> - * by link order. 
> - * For backwards compatibility, initcall() puts the call in 
> - * the device init subsection.
> +/**
> + * __define_initcall - wrapper for definiting init levels
                       ()

also s/definiting/defining/

Also, this is not what __define_initcall() does. It is not defining init levels.

>   *
> - * The `id' arg to __define_initcall() is needed so that multiple initcalls
> - * can point at the same handler without causing duplicate-symbol build 
> errors.
> + * @fn: init routine
> + * @id: init level
>   *
> - * Initcalls are run by placing pointers in initcall sections that the
> - * kernel iterates at runtime. The linker can do dead code / data elimination
> - * and remove that completely, so the initcall sections have to be marked
> - * as KEEP() in the linker script.
> + * Defines a kernel initialization level. A respective linker script entry
> + * is required to ensure the init level is accounted for and to ensure 
> symbols
> + * exist for iterating over all functions in the init level. A init level
                                                                An

> + * represents a series of functionality in the kernel.

That sounds yucky.

An init level is a bunch of functions which are called after init_level
- 1 and before init_level + 1.

> + *
> + * Ordering within an initialization level is determined by link order, so
> + * for instance if a Makefile had::
> + *
> + *   obj-y += foo.o
> + *   obj-y += bar.o
> + *
> + * And foo.c::
> + *
> + *   subsys_initcall(foo_init);
> + *
> + * And bar.c had::
> + *
> + *   subsys_initcall(bar_init);
> + *
> + * foo_init() would be called prior to bar_init().
> + *
> + * Note that @id in __define_initcall() also enables multiple initcalls
> + * to be created using the same handler for different init levels without
> + * causing duplicate-symbol build errors.
> + *
> + * Initcalls are run by placing start symbols to initcall levels inside ELF
> + * sections, the kernel in turn uses these symbols to iterate over each init
> + * level at runtime with do_initcall_level(). The end of each init level is
> + * marked by the subsequent's symbol's start address until we reach the 
> symbol
> + * ``__initcall_end``.

Needlessly complex, simplify.

> The linker can do dead code / data elimination and each
> + * init level start symbol could be removed completely in this process, to
                                                                         . To   
<-- new sentence

> + * avoid this each init level start symbols must be marked as 'KEEP()' in the
> + * linker script to avoid any linker optimization heuristic on initcalls.
>   */
> -
>  #define __define_initcall(fn, id) \
>       static initcall_t __initcall_##fn##id __used \
>       __attribute__((__section__(".initcall" #id ".init"))) = fn;
> diff --git a/include/linux/sections.h b/include/linux/sections.h
> new file mode 100644
> index 000000000000..6771c727bcd1
> --- /dev/null
> +++ b/include/linux/sections.h
> @@ -0,0 +1,87 @@
> +#ifndef _LINUX_SECTIONS_H
> +#define _LINUX_SECTIONS_H
> +/*
> + * Linux de-facto sections

Useless.

> + *
> + * Copyright (C) 2016 Luis R. Rodriguez <mcgrof@xxxxxxxxxx>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of copyleft-next (version 0.3.1 or later) as published
> + * at http://copyleft-next.org/.
> + */
> +
> +#include <asm/section-core.h>
> +#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

this section is talking about sections, that's too much.

> + * 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))

Eeww, too long and it is a getter but doesn't have "GET" in its name.

How about GET_SECTION_ALIGN() ?

And what's with the "LINUX_" prefix - that's like useless use of screen
real estate.

> +
> +/**
> + * LINUX_SECTION_START - get address of start of section

GET_SECTION_START()     -  get address of section start

> + *
> + * @name: section name
> + *
> + * This gives you the start address of the section.
> + * This should give you the address of the first entry.

Huh?

> + *
> + */
> +#define LINUX_SECTION_START(name)    VMLINUX_SYMBOL(name)

Ditto.

> +
> +/**
> + * 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

DECLARE_SECTION() is perfectly fine IMO.

> + *
> + * @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

DECLARE_SECTION_RO()

> + *
> + * @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_CORE(section, core, name, level)                   \
> +     #section ".." #core "." #name "." #level
> +
> +#endif /* __ASSEMBLY__ */
> +
> +#endif /* _LINUX_SECTIONS_H */
> -- 

-- 
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.

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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.