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