ELF - section to program header mapping - Linux

This is a discussion on ELF - section to program header mapping - Linux ; Hi, How/who decides which sections goes into which Segement and Program header in an elf binary? The reason I ask this the 2.6 and 2.4 kernel have different program header to section mapping! Thanks S ************************************************** *********************** "I've never understood ...

+ Reply to Thread
Results 1 to 9 of 9

Thread: ELF - section to program header mapping

  1. ELF - section to program header mapping

    Hi,

    How/who decides which sections goes into which Segement and
    Program header in an elf binary?

    The reason I ask this the 2.6 and 2.4 kernel have different
    program header to section mapping!

    Thanks
    S
    ************************************************** ***********************
    "I've never understood how God could expect his creatures
    to pick the one true religion by faith - it strikes me as a
    sloppy way to run a universe."
    Robert A. Heinlein
    STRANGER IN A STRANGE LAND
    ************************************************** ***********************

  2. Re: ELF - section to program header mapping

    > How/who decides which sections goes into which Segement and Program
    > header in an elf binary?


    A linker script decides. For instance: arch/i386/kernel/vmlinux.lds ,
    which itself is built from other sources.

    --

  3. Re: ELF - section to program header mapping

    I do not see any PHDRS in linker script vmlinux.lds and more
    over I thought it was fixed and not build from anything else.
    S
    On
    Thu, 2 Nov 2006, John Reiser wrote:

    >> How/who decides which sections goes into which Segement and Program
    >> header in an elf binary?

    >
    > A linker script decides. For instance: arch/i386/kernel/vmlinux.lds ,
    > which itself is built from other sources.
    >
    >


    --
    S
    ************************************************** ***********************
    "I've never understood how God could expect his creatures
    to pick the one true religion by faith - it strikes me as a
    sloppy way to run a universe."
    Robert A. Heinlein
    STRANGER IN A STRANGE LAND
    ************************************************** ***********************

  4. Re: ELF - section to program header mapping

    >>> How/who decides which sections goes into which Segement and Program
    >>> header in an elf binary?


    >> A linker script decides. For instance: arch/i386/kernel/vmlinux.lds ,
    >> which itself is built from other sources.


    > I do not see any PHDRS in linker script vmlinux.lds and more over I
    > thought it was fixed and not build from anything else.


    Please do not "top post". For easiest reading of a technical discussion
    the items should be in cronological order, newest at the bottom.

    Do a complete default build. In directory arch/i386/kernel the
    build puts a file .vmlinux.lds.cmd which tells how vmlinux.lds
    was constructed. Such a file with a leading period and a trailing
    ".cmd" records how each file was built. The linker has defaults
    for some things, including PHDRS. The original question asked
    about assignment of SECTIONS to PHDRS. This is controlled by
    commands such as
    .text : AT(ADDR(.text) - (0xC0000000)) {
    *(.text)
    ...
    }
    where the ".text :" names a PHDR and the "*(.text)" designates
    all the .text SECTIONS.

    --

  5. Re: ELF - section to program header mapping

    >>>> How/who decides which sections goes into which Segement and Program
    >>>> header in an elf binary?

    >
    >>> A linker script decides. For instance: arch/i386/kernel/vmlinux.lds ,
    >>> which itself is built from other sources.

    >
    >> I do not see any PHDRS in linker script vmlinux.lds and more over I
    >> thought it was fixed and not build from anything else.

    >
    > Please do not "top post". For easiest reading of a technical discussion
    > the items should be in cronological order, newest at the bottom.
    >
    > Do a complete default build. In directory arch/i386/kernel the
    > build puts a file .vmlinux.lds.cmd which tells how vmlinux.lds
    > was constructed. Such a file with a leading period and a trailing
    > ".cmd" records how each file was built. The linker has defaults
    > for some things, including PHDRS. The original question asked
    > about assignment of SECTIONS to PHDRS. This is controlled by
    > commands such as
    > .text : AT(ADDR(.text) - (0xC0000000)) {
    > *(.text)
    > ...
    > }
    > where the ".text :" names a PHDR and the "*(.text)" designates
    > all the .text SECTIONS.
    >
    >

    Correct me if I am wrong ...
    ".text:" refers to the section and not PHDRS.
    Program headers let you which sections are grouped in which
    segment.


    --
    S
    ************************************************** ***********************
    "I've never understood how God could expect his creatures
    to pick the one true religion by faith - it strikes me as a
    sloppy way to run a universe."
    Robert A. Heinlein
    STRANGER IN A STRANGE LAND
    ************************************************** ***********************

  6. Re: ELF - section to program header mapping

    Perianayagam Somasundaram wrote:
    >>>>> How/who decides which sections goes into which Segement and Program
    >>>>> header in an elf binary?

    >>
    >>
    >>>> A linker script decides. For instance: arch/i386/kernel/vmlinux.lds ,
    >>>> which itself is built from other sources.

    >>
    >>
    >>> I do not see any PHDRS in linker script vmlinux.lds and more over I
    >>> thought it was fixed and not build from anything else.

    >>
    >>
    >> Please do not "top post". For easiest reading of a technical discussion
    >> the items should be in cronological order, newest at the bottom.
    >>
    >> Do a complete default build. In directory arch/i386/kernel the
    >> build puts a file .vmlinux.lds.cmd which tells how vmlinux.lds
    >> was constructed. Such a file with a leading period and a trailing
    >> ".cmd" records how each file was built. The linker has defaults
    >> for some things, including PHDRS. The original question asked
    >> about assignment of SECTIONS to PHDRS. This is controlled by
    >> commands such as
    >> .text : AT(ADDR(.text) - (0xC0000000)) {
    >> *(.text)
    >> ...
    >> }
    >> where the ".text :" names a PHDR and the "*(.text)" designates
    >> all the .text SECTIONS.
    >>
    >>

    > Correct me if I am wrong ...
    > ".text:" refers to the section and not PHDRS.
    > Program headers let you which sections are grouped in which segment.



    The linker reads sections, combines and changes them suitably
    and writes sections. The mapping and combination operation is
    directed by the linker script.

    The mapping of logical sections to the binary formats and back
    is performed by the binary file format library (BFD library) which
    handles the binary file formats (including ELF) handled by the
    programs in the binutils suite (as, ld, objcopy, objdump ...).

    --

    Tauno Voipio
    tauno voipio (at) iki fi


  7. Re: ELF - section to program header mapping

    Perianayagam Somasundaram wrote:
    > > for some things, including PHDRS. The original question asked
    > > about assignment of SECTIONS to PHDRS. This is controlled by
    > > commands such as
    > > .text : AT(ADDR(.text) - (0xC0000000)) {
    > > *(.text)
    > > ...
    > > }
    > > where the ".text :" names a PHDR and the "*(.text)" designates
    > > all the .text SECTIONS.
    > >
    > >

    > Correct me if I am wrong ...
    > ".text:" refers to the section and not PHDRS.


    That's correct. The section command would have an additional symbol on
    the end, after the closing brace, to match it to a PHDR, for instance
    :foo, which would match it to a PHDR called foo. If no symbol is
    written, the default is :text.

    > Program headers let you which sections are grouped in which
    > segment.


    This selection and grouping is controlled by commands in SECTIONS.
    PHDRS is an extra feature for ELF, which works together with SECTIONS
    to define the headers.

    What decides how the output sections are mapped to ELF headers in the
    a.out file when you do "gcc hello-world.c"? There is no linker script
    being used. The answer is that GNU ld has a default linker script
    within it. A linker script passed as an input file to the linker
    command line does not replace the internal linker script, but augments
    it. Scripts which augment ld's internal linker scripts typically would
    not have a PHDRS section. For instance, GNU libc uses a script for
    defining symbol version information.

    The internal linker script is completely replaced when you use the -T
    option of ld: -T . That script then has to take on the
    full responsibility of doing everything. It would have to have the
    PHDRS.

    So if a project has augmenting linker scripts, you have to consider
    them together with the built-in linker script to understand the total
    effect.

    The kernel needs a linker script not to establish the ELF format, but
    to implement various special requirements. For instance the __initcall
    functions all have to be grouped together into a single section, which
    has to be identified by a starting symbol. Why? So that the kernel can
    implement a straightforward loop which iterates over those functions
    and calls them.


  8. Re: ELF - section to program header mapping


    > Perianayagam Somasundaram wrote:
    >>> for some things, including PHDRS. The original question asked
    >>> about assignment of SECTIONS to PHDRS. This is controlled by
    >>> commands such as
    >>> .text : AT(ADDR(.text) - (0xC0000000)) {
    >>> *(.text)
    >>> ...
    >>> }
    >>> where the ".text :" names a PHDR and the "*(.text)" designates
    >>> all the .text SECTIONS.
    >>>
    >>>

    >> Correct me if I am wrong ...
    >> ".text:" refers to the section and not PHDRS.

    >
    > That's correct. The section command would have an additional symbol on
    > the end, after the closing brace, to match it to a PHDR, for instance
    > :foo, which would match it to a PHDR called foo. If no symbol is
    > written, the default is :text.
    >
    >> Program headers let you which sections are grouped in which
    >> segment.

    >
    > This selection and grouping is controlled by commands in SECTIONS.
    > PHDRS is an extra feature for ELF, which works together with SECTIONS
    > to define the headers.
    >
    > What decides how the output sections are mapped to ELF headers in the
    > a.out file when you do "gcc hello-world.c"? There is no linker script
    > being used. The answer is that GNU ld has a default linker script
    > within it. A linker script passed as an input file to the linker
    > command line does not replace the internal linker script, but augments
    > it. Scripts which augment ld's internal linker scripts typically would
    > not have a PHDRS section. For instance, GNU libc uses a script for
    > defining symbol version information.
    >
    > The internal linker script is completely replaced when you use the -T
    > option of ld: -T . That script then has to take on the
    > full responsibility of doing everything. It would have to have the
    > PHDRS.
    >
    > So if a project has augmenting linker scripts, you have to consider
    > them together with the built-in linker script to understand the total
    > effect.
    >
    > The kernel needs a linker script not to establish the ELF format, but
    > to implement various special requirements. For instance the __initcall
    > functions all have to be grouped together into a single section, which
    > has to be identified by a starting symbol. Why? So that the kernel can
    > implement a straightforward loop which iterates over those functions
    > and calls them.
    >
    >


    I do understand the -T flag and the internal linker script.
    It is clear that the kernel uses the linker script to layout
    objects in the way it deems fit. The kernel compilation process
    overrides the internal linker script by using the -T operation.
    I have been looking through the lds file and I see no hint of
    section to segment mapping.

    Here is the lds script generated for my kernel:
    SECTIONS
    {
    . = (0xC0000000 + 0x100000);
    phys_startup_32 = startup_32 - 0xC0000000;
    /* read-only */
    _text = .; /* Text and read-only data */
    .text : AT(ADDR(.text) - 0xC0000000) {
    *(.text)
    . = ALIGN(8); __sched_text_start = .; *(.sched.text)
    __sched_text_end = .;
    . = ALIGN(8); __lock_text_start = .; *(.spinlock.text)
    __lock_text_end = .;
    . = ALIGN(8); __kprobes_text_start = .; *(.kprobes.text)
    __kprobes_text_end = .;
    *(.fixup)
    *(.gnu.warning)
    } = 0x9090

    _etext = .; /* End of text section */

    . = ALIGN(16); /* Exception table */
    __start___ex_table = .;
    __ex_table : AT(ADDR(__ex_table) - 0xC0000000) { *(__ex_table)
    }
    __stop___ex_table = .;

    . = ALIGN(4096); __start_rodata = .; .rodata : AT(ADDR(.rodata)
    - 0xC0000000) { *(.rodata) *(.rodata.*) *(__vermagic) } .rodata1
    : AT(ADDR(.rodata1) - 0xC0000000) { *(.rodata1) } .pci_fixup :
    AT(ADDR(.pci_fixup) - 0xC0000000) { __start_pci_fixups_early = .;
    *(.pci_fixup_early) __end_pci_fixups_early = .;
    __start_pci_fixups_header = .; *(.pci_fixup_header)
    __end_pci_fixups_header = .; __start_pci_fixups_final = .;
    *(.pci_fixup_final) __end_pci_fixups_final = .;
    __start_pci_fixups_enable = .; *(.pci_fixup_enable)
    __end_pci_fixups_enable = .; } .rio_route : AT(ADDR(.rio_route) -
    0xC0000000) { __start_rio_route_ops = .; *(.rio_route_ops)
    __end_rio_route_ops = .; } __ksymtab : AT(ADDR(__ksymtab) -
    0xC0000000) { __start___ksymtab = .; *(__ksymtab)
    __stop___ksymtab = .; } __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) -
    0xC0000000) { __start___ksymtab_gpl = .; *(__ksymtab_gpl)
    __stop___ksymtab_gpl = .; } __kcrctab : AT(ADDR(__kcrctab) -
    0xC0000000) { __start___kcrctab = .; *(__kcrctab)
    __stop___kcrctab = .; } __kcrctab_gpl : AT(ADDR(__kcrctab_gpl) -
    0xC0000000) { __start___kcrctab_gpl = .; *(__kcrctab_gpl)
    __stop___kcrctab_gpl = .; } __ksymtab_strings :
    AT(ADDR(__ksymtab_strings) - 0xC0000000) { *(__ksymtab_strings) }
    __end_rodata = .; . = ALIGN(4096); __param : AT(ADDR(__param) -
    0xC0000000) { __start___param = .; *(__param) __stop___param = .;
    }

    /* writeable */
    .data : AT(ADDR(.data) - 0xC0000000) { /* Data */
    *(.data)
    CONSTRUCTORS
    }

    . = ALIGN(4096);
    __nosave_begin = .;
    .data_nosave : AT(ADDR(.data_nosave) - 0xC0000000) {
    *(.data.nosave) }
    . = ALIGN(4096);
    __nosave_end = .;

    . = ALIGN(4096);
    .data.page_aligned : AT(ADDR(.data.page_aligned) - 0xC0000000)
    {
    *(.data.idt)
    }

    . = ALIGN(32);
    .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) -
    0xC0000000) {
    *(.data.cacheline_aligned)
    }

    /* rarely changed data like cpu maps */
    . = ALIGN(32);
    .data.read_mostly : AT(ADDR(.data.read_mostly) - 0xC0000000) {
    *(.data.read_mostly) }
    _edata = .; /* End of data section */
    }

    I just skipped the end part out because I more interested at the
    point where the sections are split into 2 segments.

    Here is what my program headers and my section to segment
    mappings look like:

    Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
    LOAD 0x001000 0xc0100000 0x00100000 0x24b974 0x24b974 R E 0x1000
    LOAD 0x24d000 0xc034c000 0x0034c000 0x85085 0xc5938 RWE 0x1000
    STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4

    Section to Segment mapping:
    Segment Sections...
    00 .text __ex_table .rodata .pci_fixup __param
    01 .data .data.page_aligned .data.cacheline_aligned
    ..data.read_mostly .data.init_task .init.text .init.data
    ..init.setup .initcall.init .con_initcall.init .altinstructions
    ..altinstr_replacement .exit.text .init.ramfs .bss.page_aligned
    ..bss

    I do understand by default everything falls into text segment.
    There is no indication of anything from .data getting split into
    a different segment.

    S
    ************************************************** ***********************
    "I've never understood how God could expect his creatures
    to pick the one true religion by faith - it strikes me as a
    sloppy way to run a universe."
    Robert A. Heinlein
    STRANGER IN A STRANGE LAND
    ************************************************** ***********************

  9. Re: ELF - section to program header mapping

    Perianayagam Somasundaram wrote:
    > I do understand the -T flag and the internal linker script.


    You can view the internal linker script with ``ld --verbose''. Note
    that, just like the architecture-specific vmlinux.lds files, this
    built-in one does not contain the PHDRS either!

    PHDRS seems to be a special hack that, in a sense, lies outside of the
    normal linker scripting mechanism. It's not part of the built-in linker
    script, but can be overridden by a custom linker script.

    So in other words, if you replace the linker script, the linker still
    knows how to make an ELF header, and assign the sections, which your
    script puts out, to these headers.


+ Reply to Thread