| /* 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(__code_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*) |
| } |
| |
| /* |
| * 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 : { |
| *(.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.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 : { |
| *(.data*) |
| } |
| |
| BootCpuidData : { |
| PROVIDE_HIDDEN(__start_BootCpuidData = .); |
| KEEP(*(BootCpuidData)) |
| PROVIDE_HIDDEN(__stop_BootCpuidData = .); |
| } |
| ASSERT(SIZEOF(BootCpuidData) == 2 * SIZEOF(BootCpuidLeaf), |
| "The BootCpuidLeaf and BootCpuidData sizes should precisely correlate: one holds CPUID leaf information and the other the associated values") |
| |
| /* |
| * 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 = .); |
| |
| *(.bss* .sbss* 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) |