audk/BaseTools/Source/C
Jake Garver 5d533bbc27 BaseTools/GenFw: Correct offset when relocating an ADR
When converting ELF to PE/COFF for the AArch64 target, we may encounter
an R_AARCH64_ADR_GOT_PAGE relocation that refers to an ADR instruction
instead of an ADRP instruction. This can happen when the toolchain is
working around Cortex-A53 erratum #843419.  If that's the case, be sure
to calculate the offset appropriately.

This resolves an issue experienced when building a StandaloneMm image
(which is built with -fpie) with stack protection enabled on GCC
compiled with "--enable-fix-cortex-a53-843419". In this case, the linker
may convert an ADRP instruction appearing at an offset of 0xff8 or 0xffc
modulo 4KiB into an ADR instruction, but will leave the original
R_AARCH64_ADR_GOT_PAGE relocation in place. (This is not a bug in the
linker, given that there is no other relocation type that it could
reasonably convert it into)

In this scenario, the following code is being generated by the
toolchain:

    # Load to set the stack canary
    2ffc:	10028020 	adr	x0, 8000 <mErrorString+0x1bc>
    3008:	f940d400 	ldr	x0, [x0, #424]

    # Load to check the stack canary
    30cc:	b0000020 	adrp	x0, 8000 <mErrorString+0x1bc>
    30d0:	f940d400 	ldr	x0, [x0, #424]

GenFw rewrote that to:

    # Load to set the stack canary
    2ffc:	10000480 	adr	x0, 0x308c
    3008:	912ec000 	add	x0, x0, #0xbb0

    # Load to check the stack canary
    30cc:	f0000460 	adrp	x0, 0x92000
    30d0:	912ec000 	add	x0, x0, #0xbb0

Note that we're now setting the stack canary from the wrong address,
resulting in an erroneous stack fault.

After this fix, the offset will be calculated correctly for an ADR and
the stack canary is set correctly. Note that there is a corner case
where this may cause the conversion to fail: if the original GOT entry
is just within -/+ 1 MiB of the reference, but the actual variable it
refers to is not, the resulting offset cannot be represented by the
immediate offset field in a ADR instruction. Given that this issue only
affects PIE executables, which are rare and usually tiny, this is
unlikely to cause problems in practice.

Ref: https://edk2.groups.io/g/devel/topic/102202314

[ardb: expand commit log, add reference]

Signed-off-by: Jake Garver <jake@nvidia.com>
Reviewed-by: Rebecca Cran <rebecca@bsdio.com>
2023-12-21 10:08:47 +00:00
..
BrotliCompress BaseTools: Update brotli submodule 2022-02-15 02:13:32 +00:00
Common BaseTools: switch from EFI_IMAGE_MACHINE_* to IMAGE_FILE_MACHINE_* 2023-06-01 10:53:35 +00:00
DevicePath BaseTools: Allow users to build with clang using CC=clang CXX=clang++ 2023-04-05 15:44:48 +00:00
EfiRom BaseTools: remove duplicate includes: IndustryStandard/*.h 2023-06-01 10:53:35 +00:00
GenCrc32 BaseTools: Replace BSD License with BSD+Patent License 2019-04-09 09:10:20 -07:00
GenFfs BaseTools: fix gcc12 warning 2022-03-28 00:51:30 +00:00
GenFv BaseTools: Remove logic to create AP waking vector in GenFv 2023-09-18 02:39:25 +00:00
GenFw BaseTools/GenFw: Correct offset when relocating an ADR 2023-12-21 10:08:47 +00:00
GenSec BaseTools: Fix wrong type of arguments to formatting functions 2022-11-09 14:53:10 +00:00
Include BaseTools: remove duplicate includes: IndustryStandard/*.h 2023-06-01 10:53:35 +00:00
LzmaCompress BaseTools: Allow users to specify compiler to use with make CC= CXX= 2023-04-05 15:44:48 +00:00
Makefiles BaseTools: remove duplicate includes: IndustryStandard/Acpi*.h 2023-06-01 10:53:35 +00:00
PyEfiCompressor BaseTools: Replace BSD License with BSD+Patent License 2019-04-09 09:10:20 -07:00
TianoCompress BaseTools: Replace BSD License with BSD+Patent License 2019-04-09 09:10:20 -07:00
VfrCompile BaseTools: Update antlr makefile to use cc by default 2023-04-06 01:32:09 +00:00
VolInfo BaseTools/VolInfo: Update file and section type strings 2022-10-02 05:34:38 +00:00
GNUmakefile BaseTools: Add LoongArch64 binding. 2022-10-14 02:16:33 +00:00
Makefile BaseTools: Convert Split tool to python 2021-01-21 10:19:09 +00:00