aboutsummaryrefslogtreecommitdiff
path: root/bl31
diff options
context:
space:
mode:
authorSoby Mathew <soby.mathew@arm.com>2018-10-14 08:09:22 +0100
committerSoby Mathew <soby.mathew@arm.com>2018-10-29 09:54:32 +0000
commit931f7c615643e5d0fb2cbab68e4093c980b0e271 (patch)
treee201012199720fab40e33150fbcb61a0a22e60df /bl31
parent12af5ed4fb146d575463bd304027da5a0e6b4a68 (diff)
downloadtrusted-firmware-a-931f7c615643e5d0fb2cbab68e4093c980b0e271.tar.gz
PIE: Position Independant Executable support for BL31
This patch introduces Position Independant Executable(PIE) support in TF-A. As a initial prototype, only BL31 can support PIE. A trivial dynamic linker is implemented which supports fixing up Global Offset Table(GOT) and Dynamic relocations(.rela.dyn). The fixup_gdt_reloc() helper function implements this linker and this needs to be called early in the boot sequence prior to invoking C functions. The GOT is placed in the RO section of BL31 binary for improved security and the BL31 linker script is modified to export the appropriate symbols required for the dynamic linker. The C compiler always generates PC relative addresses to linker symbols and hence referencing symbols exporting constants are a problem when relocating the binary. Hence the reference to the `__PERCPU_TIMESTAMP_SIZE__` symbol in PMF is removed and is now calculated at runtime based on start and end addresses. Change-Id: I1228583ff92cf432963b7cef052e95d995cca93d Signed-off-by: Soby Mathew <soby.mathew@arm.com>
Diffstat (limited to 'bl31')
-rw-r--r--bl31/aarch64/bl31_entrypoint.S13
-rw-r--r--bl31/bl31.ld.S28
2 files changed, 35 insertions, 6 deletions
diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S
index 3a45e53f4b..7c116a2e0d 100644
--- a/bl31/aarch64/bl31_entrypoint.S
+++ b/bl31/aarch64/bl31_entrypoint.S
@@ -7,6 +7,7 @@
#include <arch.h>
#include <bl_common.h>
#include <el3_common_macros.S>
+#include <platform_def.h>
#include <pmf_asm_macros.S>
#include <runtime_instr.h>
#include <xlat_mmu_helpers.h>
@@ -73,6 +74,18 @@ func bl31_entrypoint
mov x22, 0
mov x23, 0
#endif /* RESET_TO_BL31 */
+
+ /* --------------------------------------------------------------------
+ * If PIE is enabled, fixup the Global descriptor Table and dynamic
+ * relocations
+ * --------------------------------------------------------------------
+ */
+#if ENABLE_PIE
+ mov_imm x0, BL31_BASE
+ mov_imm x1, BL31_LIMIT
+ bl fixup_gdt_reloc
+#endif /* ENABLE_PIE */
+
/* ---------------------------------------------
* Perform platform specific early arch. setup
* ---------------------------------------------
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index 81e7ba3a34..43d0ed440d 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -26,6 +26,8 @@ SECTIONS
ASSERT(. == ALIGN(PAGE_SIZE),
"BL31_BASE address is not aligned on a page boundary.")
+ __BL31_START__ = .;
+
#if SEPARATE_CODE_AND_RODATA
.text . : {
__TEXT_START__ = .;
@@ -63,6 +65,16 @@ SECTIONS
KEEP(*(cpu_ops))
__CPU_OPS_END__ = .;
+ /*
+ * Keep the .got section in the RO section as the it is patched
+ * prior to enabling the MMU and having the .got in RO is better for
+ * security.
+ */
+ . = ALIGN(16);
+ __GOT_START__ = .;
+ *(.got)
+ __GOT_END__ = .;
+
/* Place pubsub sections for events */
. = ALIGN(8);
#include <pubsub_events.h>
@@ -153,6 +165,16 @@ SECTIONS
__DATA_END__ = .;
} >RAM
+ . = ALIGN(16);
+ /*
+ * .rela.dyn needs to come after .data for the read-elf utility to parse
+ * this section correctly.
+ */
+ __RELA_START__ = .;
+ .rela.dyn . : {
+ } >RAM
+ __RELA_END__ = .;
+
#ifdef BL31_PROGBITS_LIMIT
ASSERT(. <= BL31_PROGBITS_LIMIT, "BL31 progbits has exceeded its limit.")
#endif
@@ -265,11 +287,5 @@ SECTIONS
__RW_END__ = .;
__BL31_END__ = .;
- __BSS_SIZE__ = SIZEOF(.bss);
-#if USE_COHERENT_MEM
- __COHERENT_RAM_UNALIGNED_SIZE__ =
- __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
-#endif
-
ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
}