[llvm] f65a21a - [PAC][ELF][AArch64] Support signed personality function pointer (#119361)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Dec 15 23:24:15 PST 2024
Author: Daniil Kovalev
Date: 2024-12-16T10:24:09+03:00
New Revision: f65a21a4ecc2e712c700c59842b6b9a1d2a9a060
URL: https://github.com/llvm/llvm-project/commit/f65a21a4ecc2e712c700c59842b6b9a1d2a9a060
DIFF: https://github.com/llvm/llvm-project/commit/f65a21a4ecc2e712c700c59842b6b9a1d2a9a060.diff
LOG: [PAC][ELF][AArch64] Support signed personality function pointer (#119361)
Re-apply #113148 after revert in #119331
If function pointer signing is enabled, sign personality function
pointer stored in `.DW.ref.__gxx_personality_v0` section with IA key,
0x7EAD = `ptrauth_string_discriminator("personality")` constant
discriminator and address diversity enabled.
Added:
llvm/test/CodeGen/AArch64/ptrauth-sign-personality.ll
Modified:
clang/lib/CodeGen/CodeGenModule.cpp
clang/test/CodeGen/ptrauth-module-flags.c
llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h
llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
llvm/include/llvm/Target/TargetLoweringObjectFile.h
llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
llvm/lib/CodeGen/MachineModuleInfoImpls.cpp
llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
llvm/lib/Target/AArch64/AArch64TargetObjectFile.h
llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
llvm/lib/Target/TargetLoweringObjectFile.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index d3d5c0743a520b..841fb1ced9a02b 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1218,6 +1218,9 @@ void CodeGenModule::Release() {
getModule().addModuleFlag(llvm::Module::Min, "ptrauth-elf-got", 1);
if (getTriple().isOSLinux()) {
+ if (LangOpts.PointerAuthCalls)
+ getModule().addModuleFlag(llvm::Module::Min, "ptrauth-sign-personality",
+ 1);
assert(getTriple().isOSBinFormatELF());
using namespace llvm::ELF;
uint64_t PAuthABIVersion =
diff --git a/clang/test/CodeGen/ptrauth-module-flags.c b/clang/test/CodeGen/ptrauth-module-flags.c
index 5a7e9a7c2a36fe..e441d52cb7c62b 100644
--- a/clang/test/CodeGen/ptrauth-module-flags.c
+++ b/clang/test/CodeGen/ptrauth-module-flags.c
@@ -1,8 +1,13 @@
// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=OFF
// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-elf-got -emit-llvm %s -o - | FileCheck %s --check-prefix=ELFGOT
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -emit-llvm %s -o - | FileCheck %s --check-prefix=PERSONALITY
// ELFGOT: !llvm.module.flags = !{
// ELFGOT-SAME: !1
// ELFGOT: !1 = !{i32 8, !"ptrauth-elf-got", i32 1}
+// PERSONALITY: !llvm.module.flags = !{
+// PERSONALITY-SAME: !1
+// PERSONALITY: !1 = !{i32 8, !"ptrauth-sign-personality", i32 1}
+
// OFF-NOT: "ptrauth-
diff --git a/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h b/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h
index c1ae3d2d966df5..f7a028625ee3c8 100644
--- a/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h
+++ b/llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h
@@ -83,10 +83,14 @@ class MachineModuleInfoELF : public MachineModuleInfoImpl {
/// extern_weak symbols.
DenseMap<MCSymbol *, const MCExpr *> AuthPtrStubs;
+ /// HasSignedPersonality is true if the corresponding IR module has the
+ /// "ptrauth-sign-personality" flag set to 1.
+ bool HasSignedPersonality = false;
+
virtual void anchor(); // Out of line virtual method.
public:
- MachineModuleInfoELF(const MachineModuleInfo &) {}
+ MachineModuleInfoELF(const MachineModuleInfo &);
StubValueTy &getGVStubEntry(MCSymbol *Sym) {
assert(Sym && "Key cannot be null");
@@ -105,6 +109,8 @@ class MachineModuleInfoELF : public MachineModuleInfoImpl {
ExprStubListTy getAuthGVStubList() {
return getSortedExprStubs(AuthPtrStubs);
}
+
+ bool hasSignedPersonality() const { return HasSignedPersonality; }
};
/// MachineModuleInfoCOFF - This is a MachineModuleInfoImpl implementation
diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index 8eef45ce565deb..a2a9e5d499e527 100644
--- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -52,7 +52,13 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
void emitModuleMetadata(MCStreamer &Streamer, Module &M) const override;
void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &DL,
- const MCSymbol *Sym) const override;
+ const MCSymbol *Sym,
+ const MachineModuleInfo *MMI) const override;
+
+ virtual void emitPersonalityValueImpl(MCStreamer &Streamer,
+ const DataLayout &DL,
+ const MCSymbol *Sym,
+ const MachineModuleInfo *MMI) const;
/// Given a constant with the SectionKind, return a section that it should be
/// placed in.
diff --git a/llvm/include/llvm/Target/TargetLoweringObjectFile.h b/llvm/include/llvm/Target/TargetLoweringObjectFile.h
index 0c09cfe684783b..4864ba843f4886 100644
--- a/llvm/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/llvm/include/llvm/Target/TargetLoweringObjectFile.h
@@ -82,7 +82,8 @@ class TargetLoweringObjectFile : public MCObjectFileInfo {
virtual void Initialize(MCContext &ctx, const TargetMachine &TM);
virtual void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &TM,
- const MCSymbol *Sym) const;
+ const MCSymbol *Sym,
+ const MachineModuleInfo *MMI) const;
/// Emit the module-level metadata that the platform cares about.
virtual void emitModuleMetadata(MCStreamer &Streamer, Module &M) const {}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
index 087ee02a7f2b35..4fac4bbc98477d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
@@ -50,7 +50,8 @@ void DwarfCFIException::endModule() {
// Emit indirect reference table for all used personality functions
for (const GlobalValue *Personality : Personalities) {
MCSymbol *Sym = Asm->getSymbol(Personality);
- TLOF.emitPersonalityValue(*Asm->OutStreamer, Asm->getDataLayout(), Sym);
+ TLOF.emitPersonalityValue(*Asm->OutStreamer, Asm->getDataLayout(), Sym,
+ Asm->MMI);
}
Personalities.clear();
}
diff --git a/llvm/lib/CodeGen/MachineModuleInfoImpls.cpp b/llvm/lib/CodeGen/MachineModuleInfoImpls.cpp
index 956317510dc736..5c5f4b6738bb9c 100644
--- a/llvm/lib/CodeGen/MachineModuleInfoImpls.cpp
+++ b/llvm/lib/CodeGen/MachineModuleInfoImpls.cpp
@@ -14,6 +14,8 @@
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Module.h"
#include "llvm/MC/MCSymbol.h"
using namespace llvm;
@@ -59,3 +61,10 @@ MachineModuleInfoImpl::ExprStubListTy MachineModuleInfoImpl::getSortedExprStubs(
ExprStubs.clear();
return List;
}
+
+MachineModuleInfoELF::MachineModuleInfoELF(const MachineModuleInfo &MMI) {
+ const Module *M = MMI.getModule();
+ const auto *Flag = mdconst::extract_or_null<ConstantInt>(
+ M->getModuleFlag("ptrauth-sign-personality"));
+ HasSignedPersonality = Flag && Flag->getZExtValue() == 1;
+}
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index ce50a3c19ffe04..be243c0e74e9db 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -413,7 +413,8 @@ MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol(
}
void TargetLoweringObjectFileELF::emitPersonalityValue(
- MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym) const {
+ MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym,
+ const MachineModuleInfo *MMI) const {
SmallString<64> NameData("DW.ref.");
NameData += Sym->getName();
MCSymbolELF *Label =
@@ -431,7 +432,13 @@ void TargetLoweringObjectFileELF::emitPersonalityValue(
Streamer.emitELFSize(Label, E);
Streamer.emitLabel(Label);
- Streamer.emitSymbolValue(Sym, Size);
+ emitPersonalityValueImpl(Streamer, DL, Sym, MMI);
+}
+
+void TargetLoweringObjectFileELF::emitPersonalityValueImpl(
+ MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym,
+ const MachineModuleInfo *MMI) const {
+ Streamer.emitSymbolValue(Sym, DL.getPointerSize());
}
const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference(
diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
index 54de42a094f340..8729fd4b802c8e 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
@@ -9,6 +9,7 @@
#include "AArch64TargetObjectFile.h"
#include "AArch64TargetMachine.h"
#include "MCTargetDesc/AArch64MCExpr.h"
+#include "MCTargetDesc/AArch64TargetStreamer.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/IR/Mangler.h"
@@ -28,6 +29,21 @@ void AArch64_ELFTargetObjectFile::Initialize(MCContext &Ctx,
SupportDebugThreadLocalLocation = false;
}
+void AArch64_ELFTargetObjectFile::emitPersonalityValueImpl(
+ MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym,
+ const MachineModuleInfo *MMI) const {
+ if (!MMI->getObjFileInfo<MachineModuleInfoELF>().hasSignedPersonality()) {
+ TargetLoweringObjectFileELF::emitPersonalityValueImpl(Streamer, DL, Sym,
+ MMI);
+ return;
+ }
+ auto *TS = static_cast<AArch64TargetStreamer *>(Streamer.getTargetStreamer());
+ // The value is ptrauth_string_discriminator("personality")
+ constexpr uint16_t Discriminator = 0x7EAD;
+ TS->emitAuthValue(MCSymbolRefExpr::create(Sym, getContext()), Discriminator,
+ AArch64PACKey::IA, /*HasAddressDiversity=*/true);
+}
+
const MCExpr *AArch64_ELFTargetObjectFile::getIndirectSymViaGOTPCRel(
const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV,
int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const {
diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h
index 2ef8bda2988d47..0c822ac84f200c 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h
+++ b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h
@@ -35,6 +35,10 @@ class AArch64_ELFTargetObjectFile : public TargetLoweringObjectFileELF {
MachineModuleInfo *MMI, const MCSymbol *RawSym,
AArch64PACKey::ID Key,
uint16_t Discriminator) const;
+
+ void emitPersonalityValueImpl(MCStreamer &Streamer, const DataLayout &DL,
+ const MCSymbol *Sym,
+ const MachineModuleInfo *MMI) const override;
};
/// AArch64_MachoTargetObjectFile - This TLOF implementation is used for Darwin.
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
index dc5383ce941ed9..7bd89c9e29a728 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
@@ -35,6 +35,16 @@ AArch64TargetStreamer::AArch64TargetStreamer(MCStreamer &S)
AArch64TargetStreamer::~AArch64TargetStreamer() = default;
+void AArch64TargetStreamer::emitAuthValue(const MCExpr *Expr,
+ uint16_t Discriminator,
+ AArch64PACKey::ID Key,
+ bool HasAddressDiversity) {
+ Streamer.emitValueImpl(AArch64AuthMCExpr::create(Expr, Discriminator, Key,
+ HasAddressDiversity,
+ Streamer.getContext()),
+ 8);
+}
+
// The constant pool handling is shared by all AArch64TargetStreamer
// implementations.
const MCExpr *AArch64TargetStreamer::addConstantPoolEntry(const MCExpr *Expr,
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
index ac441ae3b603ff..1c0f5d848c00c6 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64TARGETSTREAMER_H
#define LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64TARGETSTREAMER_H
+#include "AArch64MCExpr.h"
#include "llvm/MC/MCStreamer.h"
namespace {
@@ -38,6 +39,11 @@ class AArch64TargetStreamer : public MCTargetStreamer {
void emitNoteSection(unsigned Flags, uint64_t PAuthABIPlatform = -1,
uint64_t PAuthABIVersion = -1);
+ /// Callback used to emit AUTH expressions (e.g. signed
+ /// personality function pointer).
+ void emitAuthValue(const MCExpr *Expr, uint16_t Discriminator,
+ AArch64PACKey::ID Key, bool HasAddressDiversity);
+
/// Callback used to implement the .inst directive.
virtual void emitInst(uint32_t Inst);
diff --git a/llvm/lib/Target/TargetLoweringObjectFile.cpp b/llvm/lib/Target/TargetLoweringObjectFile.cpp
index 7d9b926f4c42b6..4fe9d13d062265 100644
--- a/llvm/lib/Target/TargetLoweringObjectFile.cpp
+++ b/llvm/lib/Target/TargetLoweringObjectFile.cpp
@@ -141,10 +141,9 @@ MCSymbol *TargetLoweringObjectFile::getCFIPersonalitySymbol(
return TM.getSymbol(GV);
}
-void TargetLoweringObjectFile::emitPersonalityValue(MCStreamer &Streamer,
- const DataLayout &,
- const MCSymbol *Sym) const {
-}
+void TargetLoweringObjectFile::emitPersonalityValue(
+ MCStreamer &Streamer, const DataLayout &, const MCSymbol *Sym,
+ const MachineModuleInfo *MMI) const {}
void TargetLoweringObjectFile::emitCGProfileMetadata(MCStreamer &Streamer,
Module &M) const {
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-sign-personality.ll b/llvm/test/CodeGen/AArch64/ptrauth-sign-personality.ll
new file mode 100644
index 00000000000000..ef0e203b55ee2d
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/ptrauth-sign-personality.ll
@@ -0,0 +1,73 @@
+; RUN: rm -rf %t && split-file %s %t && cd %t
+; RUN: cat common.ll authflag.ll > auth.ll
+; RUN: cat common.ll noauthflag.ll > noauth1.ll
+; RUN: cat common.ll > noauth2.ll
+
+; RUN: llc -mtriple=aarch64-linux -filetype=asm auth.ll -o - | \
+; RUN: FileCheck --check-prefix=AUTH-ASM %s
+; RUN: llc -mtriple=aarch64-linux -filetype=obj auth.ll -o - | \
+; RUN: llvm-readelf -r -x .data.DW.ref.__gxx_personality_v0 - | \
+; RUN: FileCheck --check-prefix=AUTH-RELOC %s
+
+; AUTH-ASM: DW.ref.__gxx_personality_v0:
+; AUTH-ASM-NEXT: .xword __gxx_personality_v0 at AUTH(ia,32429,addr)
+
+; AUTH-RELOC: Relocation section '.rela.data.DW.ref.__gxx_personality_v0' at offset 0x2a0 contains 1 entries:
+; AUTH-RELOC-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend
+; AUTH-RELOC-NEXT: 0000000000000000 0000000f00000244 R_AARCH64_AUTH_ABS64 0000000000000000 __gxx_personality_v0 + 0
+
+; AUTH-RELOC: Hex dump of section '.data.DW.ref.__gxx_personality_v0':
+; AUTH-RELOC-NEXT: 0x00000000 00000000 ad7e0080
+; ^^^^ 0x7EAD = discriminator
+; ^^ 0b10000000: bit 63 = 1 -> address diversity enabled, bits 61:60 = 0b00 -> key is IA
+
+; RUN: llc -mtriple=aarch64-linux -filetype=asm noauth1.ll -o - | \
+; RUN: FileCheck --check-prefix=NOAUTH-ASM %s
+; RUN: llc -mtriple=aarch64-linux -filetype=obj noauth1.ll -o - | \
+; RUN: llvm-readelf -r -x .data.DW.ref.__gxx_personality_v0 - | \
+; RUN: FileCheck --check-prefix=NOAUTH-RELOC %s
+
+; RUN: llc -mtriple=aarch64-linux -filetype=asm noauth2.ll -o - | \
+; RUN: FileCheck --check-prefix=NOAUTH-ASM %s
+; RUN: llc -mtriple=aarch64-linux -filetype=obj noauth2.ll -o - | \
+; RUN: llvm-readelf -r -x .data.DW.ref.__gxx_personality_v0 - | \
+; RUN: FileCheck --check-prefix=NOAUTH-RELOC %s
+
+; NOAUTH-ASM: DW.ref.__gxx_personality_v0:
+; NOAUTH-ASM-NEXT: .xword __gxx_personality_v0{{$}}
+
+; NOAUTH-RELOC: Relocation section '.rela.data.DW.ref.__gxx_personality_v0' at offset 0x2a0 contains 1 entries:
+; NOAUTH-RELOC-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend
+; NOAUTH-RELOC-NEXT: 0000000000000000 0000000f00000101 R_AARCH64_ABS64 0000000000000000 __gxx_personality_v0 + 0
+
+; NOAUTH-RELOC: Hex dump of section '.data.DW.ref.__gxx_personality_v0':
+; NOAUTH-RELOC-NEXT: 0x00000000 00000000 00000000
+
+;--- common.ll
+ at _ZTISt9exception = external constant ptr
+
+define i32 @main() personality ptr @__gxx_personality_v0 {
+entry:
+ invoke void @foo() to label %cont unwind label %lpad
+
+lpad:
+ %0 = landingpad { ptr, i32 }
+ catch ptr null
+ catch ptr @_ZTISt9exception
+ ret i32 0
+
+cont:
+ ret i32 0
+}
+
+declare i32 @__gxx_personality_v0(...)
+
+declare void @foo()
+
+;--- authflag.ll
+!llvm.module.flags = !{!0}
+!0 = !{i32 8, !"ptrauth-sign-personality", i32 1}
+
+;--- noauthflag.ll
+!llvm.module.flags = !{!0}
+!0 = !{i32 8, !"ptrauth-sign-personality", i32 0}
More information about the llvm-commits
mailing list