diff options
Diffstat (limited to 'llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp')
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp index e96c5a953ff2..a0f0a489816c 100644 --- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp @@ -16,6 +16,7 @@ #include "AArch64MachineFunctionInfo.h" #include "AArch64InstrInfo.h" #include "AArch64Subtarget.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" @@ -72,6 +73,29 @@ static bool ShouldSignWithBKey(const Function &F, const AArch64Subtarget &STI) { return Key == "b_key"; } +// Determine if we need to treat pointers in GOT as signed (as described in +// https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#appendix-signed-got) +// based on PAuth core info encoded as "aarch64-elf-pauthabi-platform" and +// "aarch64-elf-pauthabi-version" module flags. Currently, only +// AARCH64_PAUTH_PLATFORM_LLVM_LINUX platform supports signed GOT with +// AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_GOT bit in version value set. +static bool hasELFSignedGOTHelper(const Function &F, + const AArch64Subtarget *STI) { + if (!Triple(STI->getTargetTriple()).isOSBinFormatELF()) + return false; + const Module *M = F.getParent(); + const auto *PAP = mdconst::extract_or_null<ConstantInt>( + M->getModuleFlag("aarch64-elf-pauthabi-platform")); + if (!PAP || PAP->getZExtValue() != ELF::AARCH64_PAUTH_PLATFORM_LLVM_LINUX) + return false; + const auto *PAV = mdconst::extract_or_null<ConstantInt>( + M->getModuleFlag("aarch64-elf-pauthabi-version")); + if (!PAV) + return false; + return PAV->getZExtValue() & + (1 << ELF::AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_GOT); +} + AArch64FunctionInfo::AArch64FunctionInfo(const Function &F, const AArch64Subtarget *STI) { // If we already know that the function doesn't have a redzone, set @@ -80,6 +104,7 @@ AArch64FunctionInfo::AArch64FunctionInfo(const Function &F, HasRedZone = false; std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(F); SignWithBKey = ShouldSignWithBKey(F, *STI); + HasELFSignedGOT = hasELFSignedGOTHelper(F, STI); // TODO: skip functions that have no instrumented allocas for optimization IsMTETagged = F.hasFnAttribute(Attribute::SanitizeMemTag); |
