[PATCH kvm-unit-tests 2/2] arm64: compile relocatable

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Support R_AARCH64_RELATIVE relocations allowing unit tests to be
loaded at different addresses. We also take the opportunity to
spruce up flat.lds and to stop pointless stack usage in start.

Signed-off-by: Andrew Jones <drjones@xxxxxxxxxx>
---
 arm/Makefile.arm64 |  6 +++++-
 arm/cstart64.S     | 52 +++++++++++++++++++++++++++++++++++-----------
 arm/flat.lds       | 42 +++++++++++++++++++++++++------------
 3 files changed, 74 insertions(+), 26 deletions(-)

diff --git a/arm/Makefile.arm64 b/arm/Makefile.arm64
index 782d4faa5cdc..38a8a5da0fb8 100644
--- a/arm/Makefile.arm64
+++ b/arm/Makefile.arm64
@@ -6,9 +6,13 @@
 bits = 64
 ldarch = elf64-littleaarch64
 
-arch_LDFLAGS = -Ttext=40080000
+arch_LDFLAGS = -pie -n
 
 define arch_elf_check =
+	$(if $(shell ! $(OBJDUMP) -R $(1) >&/dev/null && echo "nok"),
+		$(error $(shell $(OBJDUMP) -R $(1) 2>&1)))
+	$(if $(shell $(OBJDUMP) -R $(1) | grep R_ | grep -v R_AARCH64_RELATIVE),
+		$(error $(1) has unsupported reloc types))
 endef
 
 cstart.o = $(TEST_DIR)/cstart64.o
diff --git a/arm/cstart64.S b/arm/cstart64.S
index cbb4fb65683d..b0e8baa1a23a 100644
--- a/arm/cstart64.S
+++ b/arm/cstart64.S
@@ -15,30 +15,58 @@
 
 .section .init
 
+/*
+ * Bootloader params are in x0-x3. See kernel doc
+ * Documentation/arm64/booting.txt
+ */
 .globl start
 start:
+	/* get our base address */
+	adrp	x4, start
+	add     x4, x4, :lo12:start
+
 	/*
-	 * bootloader params are in x0-x3
-	 * The physical address of the dtb is in x0, x1-x3 are reserved
-	 * See the kernel doc Documentation/arm64/booting.txt
+	 * Update all R_AARCH64_RELATIVE relocations using the table
+	 * of Elf64_Rela entries between reloc_start/end. The build
+	 * will not emit other relocation types.
+	 *
+	 * struct Elf64_Rela {
+	 * 	uint64_t r_offset;
+	 * 	uint64_t r_info;
+	 * 	int64_t  r_addend;
+	 * }
 	 */
+	adrp	x5, reloc_start
+	add     x5, x5, :lo12:reloc_start
+	adrp	x6, reloc_end
+	add     x6, x6, :lo12:reloc_end
+1:
+	cmp	x5, x6
+	b.hs	1f
+	ldr	x7, [x5]			// r_offset
+	ldr	x8, [x5, #16]			// r_addend
+	add	x8, x8, x4			// val = base + r_addend
+	str	x8, [x4, x7]			// base[r_offset] = val
+	add	x5, x5, #24
+	b	1b
+
+1:
+	/* set up stack */
 	mov	x4, #1
 	msr	spsel, x4
 	isb
 	adrp    x4, stackptr
 	add     sp, x4, :lo12:stackptr
-	stp	x0, x1, [sp, #-16]!
 
-	/* Enable FP/ASIMD */
-	mov	x0, #(3 << 20)
-	msr	cpacr_el1, x0
+	/* enable FP/ASIMD */
+	mov	x4, #(3 << 20)
+	msr	cpacr_el1, x4
 
 	/* set up exception handling */
 	bl	exceptions_init
 
 	/* complete setup */
-	ldp	x0, x1, [sp], #16
-	bl	setup
+	bl	setup				// x0 is the addr of the dtb
 	bl	get_mmu_off
 	cbnz	x0, 1f
 	bl	setup_vm
@@ -56,9 +84,9 @@ start:
 	b	halt
 
 exceptions_init:
-	adrp	x0, vector_table
-	add	x0, x0, :lo12:vector_table
-	msr	vbar_el1, x0
+	adrp	x4, vector_table
+	add	x4, x4, :lo12:vector_table
+	msr	vbar_el1, x4
 	isb
 	ret
 
diff --git a/arm/flat.lds b/arm/flat.lds
index efdf5d7109ff..25f8d03cba87 100644
--- a/arm/flat.lds
+++ b/arm/flat.lds
@@ -3,25 +3,41 @@ SECTIONS
 {
     .text : { *(.init) *(.text) *(.text.*) }
     . = ALIGN(64K);
-    etext = .;
-    .data : {
-        *(.data)
-    }
-    . = ALIGN(16);
-    .rodata : { *(.rodata) }
-    . = ALIGN(16);
-    .bss : { *(.bss) }
-    . = ALIGN(64K);
-    edata = .;
-    . += 64K;
+    PROVIDE(etext = .);
+
+    PROVIDE(reloc_start = .);
+    .rela.dyn : { *(.rela.dyn) }
+    PROVIDE(reloc_end = .);
+    .dynsym   : { *(.dynsym) }
+    .dynstr   : { *(.dynstr) }
+    .hash     : { *(.hash) }
+    .gnu.hash : { *(.gnu.hash) }
+    .got      : { *(.got) *(.got.plt) }
+    .eh_frame : { *(.eh_frame) }
+
+    .rodata   : { *(.rodata*) }
+    .data     : { *(.data) }
+    .bss      : { *(.bss) }
     . = ALIGN(64K);
+    PROVIDE(edata = .);
+
     /*
      * stack depth is 16K for arm and PAGE_SIZE for arm64, see THREAD_SIZE
      * sp must be 16 byte aligned for arm64, and 8 byte aligned for arm
      * sp must always be strictly less than the true stacktop
      */
-    stackptr = . - 16;
-    stacktop = .;
+    . += 64K;
+    . = ALIGN(64K);
+    PROVIDE(stackptr = . - 16);
+    PROVIDE(stacktop = .);
+
+    /DISCARD/ : {
+        *(.note*)
+        *(.interp)
+        *(.debug*)
+        *(.comment)
+        *(.dynamic)
+    }
 }
 
 ENTRY(start)
-- 
2.17.1




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux