Skip to content

[PAC][ELF][AArch64] Support signed personality function pointer #113148

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

Merged
merged 5 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
5 changes: 5 additions & 0 deletions clang/test/CodeGen/ptrauth-module-flags.c
Original file line number Diff line number Diff line change
@@ -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-
8 changes: 7 additions & 1 deletion llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
3 changes: 2 additions & 1 deletion llvm/include/llvm/Target/TargetLoweringObjectFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
10 changes: 9 additions & 1 deletion llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand All @@ -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);
}

Expand Down
32 changes: 32 additions & 0 deletions llvm/lib/Target/AArch64/AArch64MachineModuleInfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//===--- AArch64MachineModuleInfo.cpp ---------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
/// \file
/// AArch64 Machine Module Info.
///
//
//===----------------------------------------------------------------------===//

#include "AArch64MachineModuleInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Module.h"

namespace llvm {

AArch64MachineModuleInfo::AArch64MachineModuleInfo(const MachineModuleInfo &MMI)
: MachineModuleInfoELF(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;
}

} // end namespace llvm
35 changes: 35 additions & 0 deletions llvm/lib/Target/AArch64/AArch64MachineModuleInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//===--- AArch64MachineModuleInfo.h -----------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
/// \file
/// AArch64 Machine Module Info.
///
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_AARCH64_AARCH64MACHINEMODULEINFO_H
#define LLVM_LIB_TARGET_AARCH64_AARCH64MACHINEMODULEINFO_H

#include "llvm/CodeGen/MachineModuleInfoImpls.h"

namespace llvm {

class AArch64MachineModuleInfo final : public MachineModuleInfoELF {
/// HasSignedPersonality is true if the corresponding IR module has the
/// "ptrauth-sign-personality" flag set to 1.
bool HasSignedPersonality = false;

public:
AArch64MachineModuleInfo(const MachineModuleInfo &);

bool hasSignedPersonality() const { return HasSignedPersonality; }
};

} // end namespace llvm

#endif // LLVM_LIB_TARGET_AARCH64_AARCH64MACHINEMODULEINFO_H
17 changes: 17 additions & 0 deletions llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
//===----------------------------------------------------------------------===//

#include "AArch64TargetObjectFile.h"
#include "AArch64MachineModuleInfo.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"
Expand All @@ -28,6 +30,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<AArch64MachineModuleInfo>().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 {
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/AArch64/AArch64TargetObjectFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/AArch64/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ add_llvm_target(AArch64CodeGen
AArch64LoadStoreOptimizer.cpp
AArch64LowerHomogeneousPrologEpilog.cpp
AArch64MachineFunctionInfo.cpp
AArch64MachineModuleInfo.cpp
AArch64MachineScheduler.cpp
AArch64MacroFusion.cpp
AArch64MIPeepholeOpt.cpp
Expand Down
10 changes: 10 additions & 0 deletions llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use Streamer.getContext() and remove Ctx parameter

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in bb04654, thanks for suggestion

HasAddressDiversity,
Streamer.getContext()),
8);
}

// The constant pool handling is shared by all AArch64TargetStreamer
// implementations.
const MCExpr *AArch64TargetStreamer::addConstantPoolEntry(const MCExpr *Expr,
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);

Expand Down
7 changes: 3 additions & 4 deletions llvm/lib/Target/TargetLoweringObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
39 changes: 39 additions & 0 deletions llvm/test/CodeGen/AArch64/ptrauth-sign-personality.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
; RUN: llc -mtriple=aarch64-linux -filetype=asm %s -o - | FileCheck %s
; RUN: llc -mtriple=aarch64-linux -filetype=obj %s -o - | \
; RUN: llvm-readelf -r -x .data.DW.ref.__gxx_personality_v0 - | \
; RUN: FileCheck --check-prefix=RELOC %s

@_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()

!llvm.module.flags = !{!0}
!0 = !{i32 8, !"ptrauth-sign-personality", i32 1}

; CHECK: DW.ref.__gxx_personality_v0:
; CHECK-NEXT: .xword __gxx_personality_v0@AUTH(ia,32429,addr)

; RELOC: Relocation section '.rela.data.DW.ref.__gxx_personality_v0' at offset 0x2a0 contains 1 entries:
; RELOC-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend
; RELOC-NEXT: 0000000000000000 0000000f00000244 R_AARCH64_AUTH_ABS64 0000000000000000 __gxx_personality_v0 + 0

; RELOC: Hex dump of section '.data.DW.ref.__gxx_personality_v0':
; RELOC-NEXT: 0x00000000 00000000 ad7e0080
; ^^^^ 0x7EAD = discriminator
; ^^ 0b10000000: bit 63 = 1 -> address diversity enabled, bits 61:60 = 0b00 -> key is IA
1 change: 1 addition & 0 deletions llvm/utils/gn/secondary/llvm/lib/Target/AArch64/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ static_library("LLVMAArch64CodeGen") {
"AArch64MCInstLower.cpp",
"AArch64MIPeepholeOpt.cpp",
"AArch64MachineFunctionInfo.cpp",
"AArch64MachineModuleInfo.cpp",
"AArch64MachineScheduler.cpp",
"AArch64MacroFusion.cpp",
"AArch64PBQPRegAlloc.cpp",
Expand Down
Loading