BL2_AT_EL3: add PIE support

This implementation simply mimics that of BL31.

I did not implement the ENABLE_PIE support for BL2_IN_XIP_MEM=1 case.
It would make the linker script a bit uglier.

Change-Id: If3215abd99f2758dfb232e44b50320d04eba808b
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
diff --git a/Makefile b/Makefile
index 89653b7..0193c29 100644
--- a/Makefile
+++ b/Makefile
@@ -464,6 +464,12 @@
 endif
 
 ifeq ($(ENABLE_PIE),1)
+ifeq ($(BL2_AT_EL3),1)
+ifneq ($(BL2_IN_XIP_MEM),1)
+	BL2_CFLAGS	+=	-fpie
+	BL2_LDFLAGS	+=	$(PIE_LDFLAGS)
+endif
+endif
 	BL31_CFLAGS	+=	-fpie
 	BL31_LDFLAGS	+=	$(PIE_LDFLAGS)
 endif
diff --git a/bl2/aarch64/bl2_el3_entrypoint.S b/bl2/aarch64/bl2_el3_entrypoint.S
index 2ca6acf..4eab39c 100644
--- a/bl2/aarch64/bl2_el3_entrypoint.S
+++ b/bl2/aarch64/bl2_el3_entrypoint.S
@@ -4,6 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <platform_def.h>
+
 #include <arch.h>
 #include <asm_macros.S>
 #include <common/bl_common.h>
@@ -13,6 +15,12 @@
 	.globl	bl2_el3_run_image
 	.globl	bl2_run_next_image
 
+#if BL2_IN_XIP_MEM
+#define FIXUP_SIZE	0
+#else
+#define FIXUP_SIZE	((BL2_LIMIT) - (BL2_BASE))
+#endif
+
 func bl2_entrypoint
 	/* Save arguments x0-x3 from previous Boot loader */
 	mov	x20, x0
@@ -27,7 +35,7 @@
 		_init_memory=1                                  \
 		_init_c_runtime=1                               \
 		_exception_vectors=bl2_el3_exceptions		\
-		_pie_fixup_size=0
+		_pie_fixup_size=FIXUP_SIZE
 
 	/* ---------------------------------------------
 	 * Restore parameters of boot rom
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
index dc398eb..b6570ee 100644
--- a/bl2/bl2_el3.ld.S
+++ b/bl2/bl2_el3.ld.S
@@ -69,6 +69,16 @@
         KEEP(*(cpu_ops))
         __CPU_OPS_END__ = .;
 
+        /*
+         * Keep the .got section in the RO section as it is patched
+         * prior to enabling the MMU and having the .got in RO is better for
+         * security. GOT is a table of addresses so ensure 8-byte alignment.
+         */
+        . = ALIGN(8);
+        __GOT_START__ = .;
+        *(.got)
+        __GOT_END__ = .;
+
         . = ALIGN(PAGE_SIZE);
         __RODATA_END__ = .;
     } >ROM
@@ -100,6 +110,16 @@
         KEEP(*(.img_parser_lib_descs))
         __PARSER_LIB_DESCS_END__ = .;
 
+        /*
+         * Keep the .got section in the RO section as it is patched
+         * prior to enabling the MMU and having the .got in RO is better for
+         * security. GOT is a table of addresses so ensure 8-byte alignment.
+         */
+        . = ALIGN(8);
+        __GOT_START__ = .;
+        *(.got)
+        __GOT_END__ = .;
+
         *(.vectors)
         __RO_END_UNALIGNED__ = .;
         /*
@@ -139,6 +159,17 @@
         __DATA_RAM_END__ = .;
     } >RAM AT>ROM
 
+    /*
+     * .rela.dyn needs to come after .data for the read-elf utility to parse
+     * this section correctly. Ensure 8-byte alignment so that the fields of
+     * RELA data structure are aligned.
+     */
+    . = ALIGN(8);
+    __RELA_START__ = .;
+    .rela.dyn . : {
+    } >RAM
+    __RELA_END__ = .;
+
     stacks (NOLOAD) : {
         __STACKS_START__ = .;
         *(tzfw_normal_stacks)
@@ -195,6 +226,10 @@
     __RW_END__ = .;
     __BL2_END__ = .;
 
+    /DISCARD/ : {
+        *(.dynsym .dynstr .hash .gnu.hash)
+    }
+
 #if BL2_IN_XIP_MEM
     __BL2_RAM_START__ = ADDR(.data);
     __BL2_RAM_END__ = .;
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index d7bb044..cac7e31 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -213,7 +213,7 @@
 
 -  ``ENABLE_PIE``: Boolean option to enable Position Independent Executable(PIE)
    support within generic code in TF-A. This option is currently only supported
-   in BL31. Default is 0.
+   in BL2_AT_EL3 and BL31. Default is 0.
 
 -  ``ENABLE_PMF``: Boolean option to enable support for optional Performance
    Measurement Framework(PMF). Default is 0.