/* Copyright 2020 The Fuchsia Authors
 *
 * Use of this source code is governed by a MIT-style
 * license that can be found in the LICENSE file or at
 * https://opensource.org/licenses/MIT
 */

SECTIONS {
  /*
   * A phys executable is purely position-independent so its link address
   * doesn't really matter to it--it only affects the debug file, not the
   * load image.  Using zero simplifies the arithmetic when debugging.
   *
   * It's all a single contiguous segment that is both writable and
   * executable, since no MMU protections are enabled.
   *
   * This layout is also used for fixed-position x86-32 boot shims.
   * The legacy x86-64 ZBI boot protocol is also fixed-position.
   * PHYS_LOAD_ADDRESS is always set via -defsym, either to the
   * fixed position or to 0 for the relocatable case.
   */
  . = PHYS_LOAD_ADDRESS;
  PROVIDE_HIDDEN(__executable_start = .);

  /*
   * This overrides the definition from //src/lib/elfldltl/self-base.ld
   * to make elfldltl::Self<>:LoadBias() work (on non-x86) when __ehdr_start
   * is not available.
   */
  HIDDEN(elfldltl.kBase = PHYS_LOAD_ADDRESS);

  /*
   * The contents of this section differ for different kinds of "phys" target
   * environments, but it's always the thing that has to appear first in the
   * load image (in place of where e.g. ELF headers would be found in a normal
   * executable's load image).  For ZBI executables, it's the ZBI headers to
   * make the load image itself a ZBI file and it's immediately followed by
   * more ZBI format headers synthesized in zbi-header.ld (which see).
   */
  .boot.header : {
    KEEP(*(.boot.header))
  } :load

  .text : {
    *(.text*) *(.stext*)
  }

  /*
   * PLT entry sections.
   *
   * The compiler and linker should never generate PLT entries since all
   * symbols have hidden visibility.
   */
  .plt : { *(.plt) }
  ASSERT(SIZEOF(.plt) == 0, "unexpected '.plt' entries")
  .plt.got : { *(.plt.got) }
  ASSERT(SIZEOF(.plt.got) == 0, "unexpected '.plt.got' entries")

  .note.gnu.build-id : {
    PROVIDE_HIDDEN(__start_note_gnu_build_id = .);
    *(.note.gnu.build-id)
    PROVIDE_HIDDEN(__stop_note_gnu_build_id = .);
  } :load :note

  /*
   * Code compiled for kernels should generate .debug_frame, not .eh_frame.
   * We don't want to clutter the runtime image with this data, since it's
   * not used at runtime.  However, GCC currently generates .eh_frame even
   * given -fno-unwind-tables.  Also, the 32-bit x86 build can use outcalls
   * to libclang_rt.builtins (libgcc) functions, which will have been
   * compiled with .eh_frame generation.  So just discard all that data here.
   * Unfortunately this may let us overlook some regression where other code
   * is emitting .eh_frame rather than .debug_frame in the future.
   */
  /DISCARD/ : {
    *(.eh_frame)
  }

  .rodata : {
    *(.srodata*) *(.rodata*)

    /*
     * Provide the link-time load address, required for relocation calculations.
     *
     * The C expression `_DYNAMIC - _GLOBAL_OFFSET_TABLE_[0]` should
     * theoretically give us this, but LLD doesn't always provide
     * a _GLOBAL_OFFSET_TABLE_ on ARM64.
     */
    . = ALIGN(8);
    PROVIDE_HIDDEN(kLinkTimeLoadAddress = .);
    QUAD(PHYS_LOAD_ADDRESS);
  } :load

  BootCpuidLeaf : {
    PROVIDE_HIDDEN(__start_BootCpuidLeaf = .);
    KEEP(*(BootCpuidLeaf))
    PROVIDE_HIDDEN(__stop_BootCpuidLeaf = .);
  }

  /*
   * Dynamic linking metadata.
   *
   * These are generated by the linker when linking with "-pie".
   */
  .dynamic : { *(.dynamic) } :load :dynamic
  .rela.dyn : { *(.rela.*) } :load
  .rel.dyn : { *(.rel.*) }
  .relr.auth.dyn : { *(.relr.auth.*) }
  ASSERT(SIZEOF(.relr.auth.dyn) == 0, ".relr.auth.dyn is not supported")
  .relr.dyn : { *(.relr.*) }
  .gnu.hash : { *(.gnu.hash) }
  .dynsym : { *(.dynsym) }
  .dynstr : { *(.dynstr) }

  /*
   * Instrumentation data.  Orphans placement can put this in weird places,
   * so place it explicitly.  This is a read-only section.
   */
  __llvm_prf_names : { *(__llvm_prf_names) }

  .preinit_array : {
    KEEP(*(.preinit_array))
  }
  ASSERT(SIZEOF(.preinit_array) == 0, "no static constructors allowed")

  .init_array : {
    KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*)))
    KEEP(*(SORT_BY_INIT_PRIORITY(.ctors.*)))
    KEEP(*(.init_array))
  }
  ASSERT(SIZEOF(.init_array) == 0, "no static constructors allowed")

  /*
   * Global offset table entries.
   *
   * We theoretically don't want/need any GOT entries, but BFD LD inserts
   * an entry to _DYNAMIC into ".got", as required by the ABI, and three empty
   * ".got.plt" entries on some architectures (required by their respective
   * ABIs).
   *
   * We assert that we have at most 4 × 64-bit entries.
   */
  .got : { *(.got.plt) *(.got) }
  ASSERT(SIZEOF(.got) <= 4 * 8, ".got should contain only ABI-required entries.")

  /*
   * Instrumentation data.  Orphans placement can put this in weird places,
   * so place it explicitly.  This is a RELRO section.
   */
  __llvm_prf_data : { *(__llvm_prf_data) }

  .data : { *(.sdata*) *(.data*) }

  /*
   * Instrumentation data.  Orphans placement can put this in weird places,
   * so place it explicitly.  This is a writable section.
   * TODO(mcgrathr): This is not a bss (NOBITS) section though it probably
   * ought to be.  Move this down into the bss segment if that changes.
   */
  __llvm_prf_cnts : { *(__llvm_prf_cnts) }

  /*
   * Any writable orphan sections will be placed here.  The separate clause
   * `SECTIONS ... INSERT BEFORE .bss` in phys-end.ld will attach after the
   * orphans and before .bss.  Note that the linker invocation must use the
   * switches `-T phys-end.ld -T phys.ld`, *in that order* for BFD ld to work.
   */

  .bss : {
    /*
     * Despite the name, _edata really represents the start of bss rather than
     * the end of data.  Putting it here gives it the alignment of the output
     * .bss section so the start.S code can rely on its alignment.
     */
    PROVIDE_HIDDEN(_edata = .);

    *(.sbss*) *(.bss* COMMON)

    /*
     * The start.S code relies on the alignment of the end of .bss as well.
     * This implicitly ensures the alignment of the start of the section
     * is at least this much.
     */
    . = ALIGN(16);
    PROVIDE_HIDDEN(_end = .);
  }

  /*
   * This is the amount of memory past the load image that should be
   * reserved by the boot loader.  In a ZBI executable, it goes into
   * the zbi_kernel_t::reserve_memory_size field.
   */
  PROVIDE_HIDDEN(PHYS_RESERVE_MEMORY_SIZE = _end - PHYS_LOAD_END);
}

PHDRS {
  load PT_LOAD FLAGS(7);        /* PF_R|PF_W|PF_X */
  note PT_NOTE FLAGS(4);        /* PF_R */
  dynamic PT_DYNAMIC FLAGS(4);  /* PF_R */
}

/*
 * This has no real effect since the ELF headers aren't used at runtime.
 * But it makes e_entry in the debug file match the entry point address.
 */
ENTRY(_start)
