summaryrefslogtreecommitdiffstats
path: root/BaseTools
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2019-11-08 08:58:15 +0100
committerArd Biesheuvel <ard.biesheuvel@linaro.org>2019-11-08 08:58:15 +0100
commitf55c76b301f15d287b58cd86dd59be978dc753a3 (patch)
treeb326f10531e62ed187f20d1f03ff85e591e9bbd9 /BaseTools
parent9e9f0be353d4e28ccbca8f84fc8b2ab1bbe31d5c (diff)
downloadedk2-f55c76b301f15d287b58cd86dd59be978dc753a3.tar.gz
edk2-f55c76b301f15d287b58cd86dd59be978dc753a3.tar.bz2
edk2-f55c76b301f15d287b58cd86dd59be978dc753a3.zip
BaseTools/GenFw AARCH64: disregard ADRP instructions that are patched already
In order to permit the use of compilers that only implement the small code model [which involves the use of ADRP instructions that require 4 KB segment alignment] for generating PE/COFF binaries with a small footprint, we patch ADRP instructions into ADR instructions while doing the ELF to PE/COFF conversion. As it turns out, the linker may be doing the same, but for different reasons: there is a silicon erratum #843419 for ARM Cortex-A53 which affects ADRP instructions appearing at a certain offset in memory, and one of the mitigations for this erratum is to patch them into ADR instructions at link time if the symbol reference is within -/+ 1 MB. However, the LD linker fails to update the static relocation tables, and so we end up with an ADR instruction in the fully linked binary, but with a relocation entry in the RELA section identifying it as an ADRP instruction. Since the linker has already updated the symbol reference, there is no handling needed in GenFw for such instructions, and we can simply treat it as an ordinary ADR. However, since it is guaranteed to be accompanied by an add or load instruction with a LO12 relocation referencing the same symbol, the section offset check we apply to ADR instructions is going to take place anyway, so we can just disregard the ADR instruction entirely. Reported-by: Eugene Cohen <eugene@hp.com> Suggested-by: Eugene Cohen <eugene@hp.com> Tested-by: Eugene Cohen <eugene@hp.com> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org> Acked-by: Liming Gao <liming.gao@intel.com> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Diffstat (limited to 'BaseTools')
-rw-r--r--BaseTools/Source/C/GenFw/Elf64Convert.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/BaseTools/Source/C/GenFw/Elf64Convert.c b/BaseTools/Source/C/GenFw/Elf64Convert.c
index d574300ac4..d623dce1f9 100644
--- a/BaseTools/Source/C/GenFw/Elf64Convert.c
+++ b/BaseTools/Source/C/GenFw/Elf64Convert.c
@@ -1045,6 +1045,19 @@ WriteSections64 (
case R_AARCH64_ADR_PREL_PG_HI21:
//
+ // In order to handle Cortex-A53 erratum #843419, the LD linker may
+ // convert ADRP instructions into ADR instructions, but without
+ // updating the static relocation type, and so we may end up here
+ // while the instruction in question is actually ADR. So let's
+ // just disregard it: the section offset check we apply below to
+ // ADR instructions will trigger for its R_AARCH64_xxx_ABS_LO12_NC
+ // companion instruction as well, so it is safe to omit it here.
+ //
+ if ((*(UINT32 *)Targ & BIT31) == 0) {
+ break;
+ }
+
+ //
// AArch64 PG_H21 relocations are typically paired with ABS_LO12
// relocations, where a PC-relative reference with +/- 4 GB range is
// split into a relative high part and an absolute low part. Since