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