-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[PAC][ELF][AArch64] Support signed personality function pointer #119361
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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.
@MaskRay Regarding your comment #113148 (comment):
Maybe I got your intention wrong, but it looks like that following this approach will complicate things. Since
So, I've reverted the changes from b4ca8b1. Also, I added tests ensuring that w/o the module flag set, we do not sign personality. |
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-codegen Author: Daniil Kovalev (kovdan01) ChangesRe-apply #113148 after revert in #119331 If function pointer signing is enabled, sign personality function pointer stored in Full diff: https://github.com/llvm/llvm-project/pull/119361.diff 14 Files Affected:
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..0d8c30883d6dcf 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,13 @@ 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"));
+ if (Flag && Flag->getZExtValue() == 1)
+ HasSignedPersonality = true;
+ else
+ HasSignedPersonality = false;
+}
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index ce50a3c19ffe04..d5342b5d3651f1 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,6 +432,13 @@ void TargetLoweringObjectFileELF::emitPersonalityValue(
Streamer.emitELFSize(Label, E);
Streamer.emitLabel(Label);
+ emitPersonalityValueImpl(Streamer, DL, Sym, MMI);
+}
+
+void TargetLoweringObjectFileELF::emitPersonalityValueImpl(
+ MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym,
+ const MachineModuleInfo *MMI) const {
+ unsigned Size = DL.getPointerSize();
Streamer.emitSymbolValue(Sym, Size);
}
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@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
+@_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}
|
@llvm/pr-subscribers-debuginfo Author: Daniil Kovalev (kovdan01) ChangesRe-apply #113148 after revert in #119331 If function pointer signing is enabled, sign personality function pointer stored in Full diff: https://github.com/llvm/llvm-project/pull/119361.diff 14 Files Affected:
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..0d8c30883d6dcf 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,13 @@ 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"));
+ if (Flag && Flag->getZExtValue() == 1)
+ HasSignedPersonality = true;
+ else
+ HasSignedPersonality = false;
+}
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index ce50a3c19ffe04..d5342b5d3651f1 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,6 +432,13 @@ void TargetLoweringObjectFileELF::emitPersonalityValue(
Streamer.emitELFSize(Label, E);
Streamer.emitLabel(Label);
+ emitPersonalityValueImpl(Streamer, DL, Sym, MMI);
+}
+
+void TargetLoweringObjectFileELF::emitPersonalityValueImpl(
+ MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym,
+ const MachineModuleInfo *MMI) const {
+ unsigned Size = DL.getPointerSize();
Streamer.emitSymbolValue(Sym, Size);
}
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@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
+@_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}
|
@llvm/pr-subscribers-backend-aarch64 Author: Daniil Kovalev (kovdan01) ChangesRe-apply #113148 after revert in #119331 If function pointer signing is enabled, sign personality function pointer stored in Full diff: https://github.com/llvm/llvm-project/pull/119361.diff 14 Files Affected:
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..0d8c30883d6dcf 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,13 @@ 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"));
+ if (Flag && Flag->getZExtValue() == 1)
+ HasSignedPersonality = true;
+ else
+ HasSignedPersonality = false;
+}
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index ce50a3c19ffe04..d5342b5d3651f1 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,6 +432,13 @@ void TargetLoweringObjectFileELF::emitPersonalityValue(
Streamer.emitELFSize(Label, E);
Streamer.emitLabel(Label);
+ emitPersonalityValueImpl(Streamer, DL, Sym, MMI);
+}
+
+void TargetLoweringObjectFileELF::emitPersonalityValueImpl(
+ MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym,
+ const MachineModuleInfo *MMI) const {
+ unsigned Size = DL.getPointerSize();
Streamer.emitSymbolValue(Sym, Size);
}
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@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
+@_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}
|
const Module *M = MMI.getModule(); | ||
const auto *Flag = mdconst::extract_or_null<ConstantInt>( | ||
M->getModuleFlag("ptrauth-sign-personality")); | ||
if (Flag && Flag->getZExtValue() == 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HasSignedPersonality = Flag && ... == 1
void TargetLoweringObjectFileELF::emitPersonalityValueImpl( | ||
MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym, | ||
const MachineModuleInfo *MMI) const { | ||
unsigned Size = DL.getPointerSize(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inline used-once variable
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.