Skip to content

Commit f65a21a

Browse files
authored
[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.
1 parent 54dac27 commit f65a21a

14 files changed

+156
-10
lines changed

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,9 @@ void CodeGenModule::Release() {
12181218
getModule().addModuleFlag(llvm::Module::Min, "ptrauth-elf-got", 1);
12191219

12201220
if (getTriple().isOSLinux()) {
1221+
if (LangOpts.PointerAuthCalls)
1222+
getModule().addModuleFlag(llvm::Module::Min, "ptrauth-sign-personality",
1223+
1);
12211224
assert(getTriple().isOSBinFormatELF());
12221225
using namespace llvm::ELF;
12231226
uint64_t PAuthABIVersion =
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=OFF
22
// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-elf-got -emit-llvm %s -o - | FileCheck %s --check-prefix=ELFGOT
3+
// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -emit-llvm %s -o - | FileCheck %s --check-prefix=PERSONALITY
34

45
// ELFGOT: !llvm.module.flags = !{
56
// ELFGOT-SAME: !1
67
// ELFGOT: !1 = !{i32 8, !"ptrauth-elf-got", i32 1}
78

9+
// PERSONALITY: !llvm.module.flags = !{
10+
// PERSONALITY-SAME: !1
11+
// PERSONALITY: !1 = !{i32 8, !"ptrauth-sign-personality", i32 1}
12+
813
// OFF-NOT: "ptrauth-

llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,14 @@ class MachineModuleInfoELF : public MachineModuleInfoImpl {
8383
/// extern_weak symbols.
8484
DenseMap<MCSymbol *, const MCExpr *> AuthPtrStubs;
8585

86+
/// HasSignedPersonality is true if the corresponding IR module has the
87+
/// "ptrauth-sign-personality" flag set to 1.
88+
bool HasSignedPersonality = false;
89+
8690
virtual void anchor(); // Out of line virtual method.
8791

8892
public:
89-
MachineModuleInfoELF(const MachineModuleInfo &) {}
93+
MachineModuleInfoELF(const MachineModuleInfo &);
9094

9195
StubValueTy &getGVStubEntry(MCSymbol *Sym) {
9296
assert(Sym && "Key cannot be null");
@@ -105,6 +109,8 @@ class MachineModuleInfoELF : public MachineModuleInfoImpl {
105109
ExprStubListTy getAuthGVStubList() {
106110
return getSortedExprStubs(AuthPtrStubs);
107111
}
112+
113+
bool hasSignedPersonality() const { return HasSignedPersonality; }
108114
};
109115

110116
/// MachineModuleInfoCOFF - This is a MachineModuleInfoImpl implementation

llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,13 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
5252
void emitModuleMetadata(MCStreamer &Streamer, Module &M) const override;
5353

5454
void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &DL,
55-
const MCSymbol *Sym) const override;
55+
const MCSymbol *Sym,
56+
const MachineModuleInfo *MMI) const override;
57+
58+
virtual void emitPersonalityValueImpl(MCStreamer &Streamer,
59+
const DataLayout &DL,
60+
const MCSymbol *Sym,
61+
const MachineModuleInfo *MMI) const;
5662

5763
/// Given a constant with the SectionKind, return a section that it should be
5864
/// placed in.

llvm/include/llvm/Target/TargetLoweringObjectFile.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ class TargetLoweringObjectFile : public MCObjectFileInfo {
8282
virtual void Initialize(MCContext &ctx, const TargetMachine &TM);
8383

8484
virtual void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &TM,
85-
const MCSymbol *Sym) const;
85+
const MCSymbol *Sym,
86+
const MachineModuleInfo *MMI) const;
8687

8788
/// Emit the module-level metadata that the platform cares about.
8889
virtual void emitModuleMetadata(MCStreamer &Streamer, Module &M) const {}

llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ void DwarfCFIException::endModule() {
5050
// Emit indirect reference table for all used personality functions
5151
for (const GlobalValue *Personality : Personalities) {
5252
MCSymbol *Sym = Asm->getSymbol(Personality);
53-
TLOF.emitPersonalityValue(*Asm->OutStreamer, Asm->getDataLayout(), Sym);
53+
TLOF.emitPersonalityValue(*Asm->OutStreamer, Asm->getDataLayout(), Sym,
54+
Asm->MMI);
5455
}
5556
Personalities.clear();
5657
}

llvm/lib/CodeGen/MachineModuleInfoImpls.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
1515
#include "llvm/ADT/DenseMap.h"
1616
#include "llvm/ADT/STLExtras.h"
17+
#include "llvm/IR/Constants.h"
18+
#include "llvm/IR/Module.h"
1719
#include "llvm/MC/MCSymbol.h"
1820

1921
using namespace llvm;
@@ -59,3 +61,10 @@ MachineModuleInfoImpl::ExprStubListTy MachineModuleInfoImpl::getSortedExprStubs(
5961
ExprStubs.clear();
6062
return List;
6163
}
64+
65+
MachineModuleInfoELF::MachineModuleInfoELF(const MachineModuleInfo &MMI) {
66+
const Module *M = MMI.getModule();
67+
const auto *Flag = mdconst::extract_or_null<ConstantInt>(
68+
M->getModuleFlag("ptrauth-sign-personality"));
69+
HasSignedPersonality = Flag && Flag->getZExtValue() == 1;
70+
}

llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,8 @@ MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol(
413413
}
414414

415415
void TargetLoweringObjectFileELF::emitPersonalityValue(
416-
MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym) const {
416+
MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym,
417+
const MachineModuleInfo *MMI) const {
417418
SmallString<64> NameData("DW.ref.");
418419
NameData += Sym->getName();
419420
MCSymbolELF *Label =
@@ -431,7 +432,13 @@ void TargetLoweringObjectFileELF::emitPersonalityValue(
431432
Streamer.emitELFSize(Label, E);
432433
Streamer.emitLabel(Label);
433434

434-
Streamer.emitSymbolValue(Sym, Size);
435+
emitPersonalityValueImpl(Streamer, DL, Sym, MMI);
436+
}
437+
438+
void TargetLoweringObjectFileELF::emitPersonalityValueImpl(
439+
MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym,
440+
const MachineModuleInfo *MMI) const {
441+
Streamer.emitSymbolValue(Sym, DL.getPointerSize());
435442
}
436443

437444
const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference(

llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "AArch64TargetObjectFile.h"
1010
#include "AArch64TargetMachine.h"
1111
#include "MCTargetDesc/AArch64MCExpr.h"
12+
#include "MCTargetDesc/AArch64TargetStreamer.h"
1213
#include "llvm/BinaryFormat/Dwarf.h"
1314
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
1415
#include "llvm/IR/Mangler.h"
@@ -28,6 +29,21 @@ void AArch64_ELFTargetObjectFile::Initialize(MCContext &Ctx,
2829
SupportDebugThreadLocalLocation = false;
2930
}
3031

32+
void AArch64_ELFTargetObjectFile::emitPersonalityValueImpl(
33+
MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym,
34+
const MachineModuleInfo *MMI) const {
35+
if (!MMI->getObjFileInfo<MachineModuleInfoELF>().hasSignedPersonality()) {
36+
TargetLoweringObjectFileELF::emitPersonalityValueImpl(Streamer, DL, Sym,
37+
MMI);
38+
return;
39+
}
40+
auto *TS = static_cast<AArch64TargetStreamer *>(Streamer.getTargetStreamer());
41+
// The value is ptrauth_string_discriminator("personality")
42+
constexpr uint16_t Discriminator = 0x7EAD;
43+
TS->emitAuthValue(MCSymbolRefExpr::create(Sym, getContext()), Discriminator,
44+
AArch64PACKey::IA, /*HasAddressDiversity=*/true);
45+
}
46+
3147
const MCExpr *AArch64_ELFTargetObjectFile::getIndirectSymViaGOTPCRel(
3248
const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV,
3349
int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const {

llvm/lib/Target/AArch64/AArch64TargetObjectFile.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ class AArch64_ELFTargetObjectFile : public TargetLoweringObjectFileELF {
3535
MachineModuleInfo *MMI, const MCSymbol *RawSym,
3636
AArch64PACKey::ID Key,
3737
uint16_t Discriminator) const;
38+
39+
void emitPersonalityValueImpl(MCStreamer &Streamer, const DataLayout &DL,
40+
const MCSymbol *Sym,
41+
const MachineModuleInfo *MMI) const override;
3842
};
3943

4044
/// AArch64_MachoTargetObjectFile - This TLOF implementation is used for Darwin.

0 commit comments

Comments
 (0)