/* 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.gnu.build-id : {
        *(.note.gnu.build-id)
    } :rodata :note
    .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;
    stack PT_GNU_STACK FLAGS(6);  /* RW- */
}
