/* Copyright 2016 The Fuchsia Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/*
 * This is a linker script for producing a DSO (shared library) image
 * that is entirely read-only and trivial to map in without using a
 * proper ELF loader.  It has two segments: read-only starting at the
 * beginning of the file, and executable code page-aligned and marked
 * by the (hidden) symbols CODE_START and CODE_END.
 *
 * Ideally this could be accomplished without an explicit linker
 * script.  The linker would need an option to make the .dynamic
 * section (aka PT_DYNAMIC segment) read-only rather than read-write;
 * in fact that could be the default for Zircon/Fuchsia or for
 * anything using a dynamic linker like musl's that doesn't try to
 * write into the .dynamic section at runtime (for -shared that is;
 * for -pie and dynamically-linked executables there is the DT_DEBUG
 * question).  The linker would need a second option to entirely
 * segregate code from rodata (and from non-loaded parts of the file),
 * and page-align the code segment (and pad the end to a page
 * boundary); in fact that could be the default for any system that
 * wants to minimize what can go into pages mapped with execute
 * permission, which is a worthwhile trade-off of security mitigation
 * over tiny amounts of wasted space in the ELF file.  Beyond that,
 * the linker should not generate the .got* or .plt* sections at all
 * when there are no relocs being generated, but today's linkers still
 * do; since some of those sections are writable, they cause the
 * creation of a writable PT_LOAD segment by normal linker logic.
 */

SECTIONS {
    . = 0 + SIZEOF_HEADERS;

    /*
     * This should be defined automatically by the linker.
     * But LLD fails to do so in the presence of a linker script.
     * So define it explicitly.
     * TODO(mcgrathr): If http://bugs.llvm.org/show_bug.cgi?id=32367
     * is ever fixed, remove this.
     */
    PROVIDE_HIDDEN(__ehdr_start = . - SIZEOF_HEADERS);

    /*
     * Match the non-allocated Gold version note specially, so
     * it doesn't go into the allocated .note section below.
     * With BFD ld, the .note clause could use:
     *     INPUT_SECTION_FLAGS(SHF_ALLOC) *(.note*)
     * so as not to match any non-allocated note sections generically.
     * But gold and lld do not support the INPUT_SECTION_FLAGS keyword.
     */
    .note.gnu.gold-version : { *(.note.gnu.gold-version) }

    .note : {
        *(.note*)
    } :rodata :note
    .dynamic : {
        *(.dynamic)
    } :rodata :dynamic
    .hash : {
        *(.hash)
    } :rodata
    .gnu.hash : { *(.gnu.hash) }
    .dynsym : { *(.dynsym) }
    .dynstr : { *(.dynstr) }

    .rodata : {
        *(.rodata .rodata.* .gnu.linkonce.r.*)
    } :rodata
    .rodata1 : { *(.rodata1) }
    .eh_frame_hdr : {
        *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*)
    } :rodata :eh_frame_hdr
    .eh_frame : {
        KEEP(*(.eh_frame))
        *(.eh_frame.*)
    } :rodata
    .gcc_except_table : { *(.gcc_except_table*) }
    .gnu_extab : { *(.gnu_extab*) }

    /*
     * We'd like to discard these linker-generated sections with /DISCARD/
     * (or convince the linker not to generate them at all).
     * But the linker doesn't know how to do that.
     */
    .got : { *(.got*) }
    .plt : { *(.plt*) }

    /*
     * This section will only exist if there were some dynamic relocation
     * sections generated by the linker.  If this happens, the code is
     * broken (it uses PC-sensitive static initializers or suchlike).
     */
    .norelocs : { *(.rel*) }
    ASSERT(SIZEOF(.norelocs) == 0,
           "rodso code must avoid dynamic relocations!")

    /*
     * Likewise, this will only exist if there was some writable data.
     */
    .nodata : { *(.data*) *(.sdata*) *(.bss*) *(.sbss*) }
    ASSERT(SIZEOF(.nodata) == 0,
           "rodso code must avoid writable data sections!")

    . = ALIGN(CONSTANT(MAXPAGESIZE));

    .text : {
        *(.text.unlikely .text.*_unlikely .text.unlikely.*)
        *(.text.exit .text.exit.*)
        *(.text.startup .text.startup.*)
        *(.text.hot .text.hot.*)
        *(.text .stub .text.* .gnu.linkonce.t.*)
        *(.init .init.* .fini .fini.*)
        *(.gnu.warning)
        *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)

        PROVIDE_HIDDEN(_end = .);

        /*
         * Pad out the code segment to a page boundary, so that there
         * is only nop or zero padding visible in the memory image
         * rather than seeing non-loaded portions of the ELF file
         * (.shstrtab, section headers, .symtab if not stripped, etc.).
         */
        . = ALIGN(CONSTANT(MAXPAGESIZE));
    } :code
}

PHDRS {
    rodata PT_LOAD FLAGS(4) FILEHDR PHDRS;
    code PT_LOAD FLAGS(5);
    dynamic PT_DYNAMIC FLAGS(4);
    note PT_NOTE;
    eh_frame_hdr PT_GNU_EH_FRAME;
}
