Use -ffunction-sections and --gc-sections.

This removes dormant code from the final image binary.

Change-Id: I85449d3b4bc1bebe829bcc4dec30a871febe7ed1
diff --git a/build/BUILD.gn b/build/BUILD.gn
index b8ec9fc..ce69ec2 100644
--- a/build/BUILD.gn
+++ b/build/BUILD.gn
@@ -44,6 +44,7 @@
       "-fno-builtin",
       "-ffreestanding",
       "-fpic",
+      "-ffunction-sections",
     ]
 
     if (!use_gcc) {
@@ -70,6 +71,9 @@
 }
 
 config("executable_ldconfig") {
-  ldflags = [
-  ]
+  if (current_toolchain == arch_toolchain) {
+    ldflags = [
+      "--gc-sections"
+    ]
+  }
 }
diff --git a/build/image/image.ld b/build/image/image.ld
index c7f3c60..5f34e48 100644
--- a/build/image/image.ld
+++ b/build/image/image.ld
@@ -7,14 +7,18 @@
 	text_begin = .;
 	.init : {
 		*(.init.entry)
-		*(.init.image)
+		*(.init.*)
 	}
-	.text : { *(.text) }
+	.text : {
+		*(.text.*)
+	}
 	text_end = .;
 
 	. = ALIGN(4096);
 	rodata_begin = .;
-	.rodata : { *(.rodata) }
+	.rodata : {
+		*(.rodata.*)
+	}
 	.rela : ALIGN(8) {
 		rela_begin = .;
 		*(.rela .rela*)
@@ -24,7 +28,9 @@
 
 	. = ALIGN(4096);
 	data_begin = .;
-	.data : { *(.data) }
+	.data : {
+		*(.data)
+	}
 
 	/* The entry point code assumes that bss is 16-byte aligned. */
 	.bss ALIGN(16) : {
diff --git a/src/arch/aarch64/BUILD.gn b/src/arch/aarch64/BUILD.gn
index 1db1e37..93d887d 100644
--- a/src/arch/aarch64/BUILD.gn
+++ b/src/arch/aarch64/BUILD.gn
@@ -5,6 +5,7 @@
 source_set("aarch64") {
   sources = [
     "exceptions.S",
+    "cpu_entry.S",
     "hypervisor_entry.S",
     "smc.S",
   ]
diff --git a/src/arch/aarch64/cpu_entry.S b/src/arch/aarch64/cpu_entry.S
new file mode 100644
index 0000000..39e1378
--- /dev/null
+++ b/src/arch/aarch64/cpu_entry.S
@@ -0,0 +1,32 @@
+#include "offsets.h"
+
+.section .text.cpu_entry, "ax"
+.globl cpu_entry
+cpu_entry:
+	/* Disable interrupts. */
+	msr DAIFSet, #0xf
+
+	/* Save pointer to CPU struct for later reference. */
+	msr tpidr_el2, x0
+
+	/* Use SPx (instead of SP0). */
+	msr spsel, #1
+
+	/* Prepare the stack. */
+	ldr x30, [x0, #CPU_STACK_BOTTOM]
+	mov sp, x30
+
+	/* Configure exception handlers. */
+	adrp x30, vector_table_el2
+	add x30, x30, :lo12:vector_table_el2
+	msr vbar_el2, x30
+
+	/* Call into C code. */
+	bl cpu_main
+
+	/* Run the vcpu returned by cpu_main. */
+	bl vcpu_restore_all_and_run
+
+	/* Loop forever waiting for interrupts. */
+0:	wfi
+	b 0b
diff --git a/src/arch/aarch64/entry.S b/src/arch/aarch64/entry.S
index 3cf7463..99d97c6 100644
--- a/src/arch/aarch64/entry.S
+++ b/src/arch/aarch64/entry.S
@@ -1,10 +1,9 @@
-.section .init.entry, "ax"
-
 /**
  * This is a generic entry point for an image. It carries out the operations
  * required to prepare the loaded image to be run. Specifically, it performs
  * relocations and zeroing of the bss section using registers x25 and above.
  */
+.section .init.entry, "ax"
 .global entry
 entry:
 	b 0f
diff --git a/src/arch/aarch64/exceptions.S b/src/arch/aarch64/exceptions.S
index a143361..4da8997 100644
--- a/src/arch/aarch64/exceptions.S
+++ b/src/arch/aarch64/exceptions.S
@@ -1,8 +1,7 @@
 #include "offsets.h"
 
-.text
-
 .balign 0x800
+.section .text.vector_table_el2, "ax"
 .global vector_table_el2
 vector_table_el2:
 	/* sync_cur_sp0 */
diff --git a/src/arch/aarch64/hypervisor_entry.S b/src/arch/aarch64/hypervisor_entry.S
index 07747bd..9b7d095 100644
--- a/src/arch/aarch64/hypervisor_entry.S
+++ b/src/arch/aarch64/hypervisor_entry.S
@@ -1,7 +1,4 @@
-#include "offsets.h"
-
-.section .init.image, "ax"
-
+.section .init.image_entry, "ax"
 .global image_entry
 image_entry:
 	/* Save the FDT to a global variable. */
@@ -13,32 +10,5 @@
 	adrp x0, cpus
 	add x0, x0, :lo12:cpus
 
-.globl cpu_entry
-cpu_entry:
-	/* Disable interrupts. */
-	msr DAIFSet, #0xf
+	b cpu_entry
 
-	/* Save pointer to CPU struct for later reference. */
-	msr tpidr_el2, x0
-
-	/* Use SPx (instead of SP0). */
-	msr spsel, #1
-
-	/* Prepare the stack. */
-	ldr x30, [x0, #CPU_STACK_BOTTOM]
-	mov sp, x30
-
-	/* Configure exception handlers. */
-	adrp x30, vector_table_el2
-	add x30, x30, :lo12:vector_table_el2
-	msr vbar_el2, x30
-
-	/* Call into C code. */
-	bl cpu_main
-
-	/* Run the vcpu returned by cpu_main. */
-	bl vcpu_restore_all_and_run
-
-	/* Loop forever waiting for interrupts. */
-0:	wfi
-	b 0b
diff --git a/src/arch/aarch64/smc.S b/src/arch/aarch64/smc.S
index 8c817c9..ceec68b 100644
--- a/src/arch/aarch64/smc.S
+++ b/src/arch/aarch64/smc.S
@@ -1,5 +1,4 @@
-.text
-
+.section .text.smc, "ax"
 .globl smc
 smc:
 	smc #0
diff --git a/src/arch/aarch64/vm/BUILD.gn b/src/arch/aarch64/vm/BUILD.gn
index 53ed1de..aa5c7dc 100644
--- a/src/arch/aarch64/vm/BUILD.gn
+++ b/src/arch/aarch64/vm/BUILD.gn
@@ -1,5 +1,12 @@
 # These components are only used by VMs for aarch64 specific actions.
 
+# Implements image_entry for a simple VM kernel.
+source_set("vm_entry") {
+  sources = [
+    "vm_entry.S",
+  ]
+}
+
 # Make a call to the hypervisor from a VM.
 source_set("hf_call") {
   sources = [
diff --git a/src/arch/aarch64/vm/hf_call.S b/src/arch/aarch64/vm/hf_call.S
index 07743ca..538bc27 100644
--- a/src/arch/aarch64/vm/hf_call.S
+++ b/src/arch/aarch64/vm/hf_call.S
@@ -1,5 +1,4 @@
-.text
-
+.section .text.hf_call, "ax"
 .global hf_call
 hf_call:
 	hvc #0
diff --git a/test/vm/vm_entry.S b/src/arch/aarch64/vm/vm_entry.S
similarity index 87%
rename from test/vm/vm_entry.S
rename to src/arch/aarch64/vm/vm_entry.S
index 61c9a20..6db2526 100644
--- a/test/vm/vm_entry.S
+++ b/src/arch/aarch64/vm/vm_entry.S
@@ -1,5 +1,4 @@
-.section .init.image, "ax"
-
+.section .init.image_entry, "ax"
 .global image_entry
 image_entry:
 	/* Prepare the stack. */
diff --git a/test/vm/BUILD.gn b/test/vm/BUILD.gn
index fb05a32..dd1825e 100644
--- a/test/vm/BUILD.gn
+++ b/test/vm/BUILD.gn
@@ -2,7 +2,7 @@
 
 source_set("hf_test_vm") {
   sources = [
-    "vm_entry.S",
+    "hf_test.h",
   ]
 
   deps = [
@@ -11,5 +11,6 @@
     "//src/arch/${arch}:entry",
     "//src/arch/${arch}/vm:hf_call",
     "//src/arch/${arch}/vm:shutdown",
+    "//src/arch/${arch}/vm:vm_entry",
   ]
 }