Document linker script.
Explain the linker tricks that aren't immediately obvious and simplify
the range of syntax used to simplify its reading.
Change-Id: I82e843ed959508a6b80d4ed92847a68af77e452a
diff --git a/build/image/image.ld b/build/image/image.ld
index 5f34e48..ba5a626 100644
--- a/build/image/image.ld
+++ b/build/image/image.ld
@@ -1,9 +1,29 @@
+/*
+ * Code will start running at this symbol which is places at the start of the
+ * image.
+ */
ENTRY(entry)
+
+/*
+ * The following would be useful to check that .init code is not called back
+ * into once it has completed but it isn't supported by ld.lld.
+ *
+ * NOCROSSREFS_TO(.init .text)
+ */
+
SECTIONS
{
+ /*
+ * Set the image origin to a platform specific address. The images are
+ * relocatable but some platforms, e.g. QEMU, load to the same address
+ * and it makes debugging easier if the addresses match the symbols.
+ */
. = ORIGIN_ADDRESS;
- _orig_base = ABSOLUTE(.);
+ /*
+ * Collect together the code. This is page aligned so it can be mapped
+ * as executable-only.
+ */
text_begin = .;
.init : {
*(.init.entry)
@@ -14,34 +34,56 @@
}
text_end = .;
+ /*
+ * Collect together read-only data including relocations at the end
+ * which are applied by the entry code. This is page aligned so it can
+ * be mapped as read-only and non-executable.
+ */
. = ALIGN(4096);
rodata_begin = .;
.rodata : {
*(.rodata.*)
}
- .rela : ALIGN(8) {
- rela_begin = .;
- *(.rela .rela*)
- rela_end = .;
+ /* .rela contains Elf64_Rela entries which contain 8-byte fields so
+ * should be 8-byte aligned. */
+ . = ALIGN(8);
+ rela_begin = .;
+ .rela : {
+ *(.rela.*)
}
+ rela_end = .;
rodata_end = .;
+ /*
+ * Collect together the read-write data including .bss at the end which
+ * will be zero'd by the entry code. This is page aligned so it can be
+ * mapped as non-executable.
+ */
. = ALIGN(4096);
data_begin = .;
.data : {
*(.data)
}
-
- /* The entry point code assumes that bss is 16-byte aligned. */
- .bss ALIGN(16) : {
- file_size = ABSOLUTE(. - ORIGIN_ADDRESS);
- bss_begin = .;
- *(.bss COMMON)
- . = ALIGN(16);
- bss_end = .;
+ /* The entry point code assumes that .bss is 16-byte aligned. */
+ . = ALIGN(16);
+ bss_begin = .;
+ .bss : {
+ *(.bss)
+ *(COMMON)
}
+ . = ALIGN(16);
+ bss_end = .;
data_end = .;
+ /*
+ * Make note of some useful values.
+ */
+
+ /* Note the first page not used in the image. */
. = ALIGN(4096);
bin_end = .;
+
+ /* Note the size of the image. This includes everything up to the .bss
+ * as that is initialized to zero by the entry code. */
+ image_size = ABSOLUTE(bss_begin - ORIGIN_ADDRESS);
}
diff --git a/build/toolchain/arch/BUILD.gn b/build/toolchain/arch/BUILD.gn
index b04ed4c..2975cd3 100644
--- a/build/toolchain/arch/BUILD.gn
+++ b/build/toolchain/arch/BUILD.gn
@@ -77,7 +77,7 @@
cc_toolchain(target_name) {
cc = "clang"
cflags = "-target ${invoker.target} -fcolor-diagnostics"
- ld = "ld.lld"
+ ld = "ld.lld --color-diagnostics"
toolchain_args = {
arch_tool_prefix = invoker.arch_tool_prefix
diff --git a/src/arch/aarch64/entry.S b/src/arch/aarch64/entry.S
index 99d97c6..7b9d648 100644
--- a/src/arch/aarch64/entry.S
+++ b/src/arch/aarch64/entry.S
@@ -6,10 +6,11 @@
.section .init.entry, "ax"
.global entry
entry:
+ /* Linux aarch64 image header. */
b 0f
.word 0
- .quad 4096 /* text_offset */
- .quad file_size /* image_size */
+ .quad 0x1000 /* text_offset */
+ .quad image_size /* image_size */
.quad 0 /* flags */
.quad 0 /* res2 */
.quad 0 /* res3 */
@@ -24,7 +25,7 @@
0: adrp x25, entry
add x25, x25, :lo12:entry
- ldr w29, =_orig_base
+ ldr w29, =ORIGIN_ADDRESS
sub x25, x25, x29