Skip to content

[PAC][AArch64] Lower ptrauth constants in code #94241

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 4 commits into from
Jun 27, 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
11 changes: 11 additions & 0 deletions llvm/docs/GlobalISel/GenericOpcode.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,17 @@ The address of a global value.

%0(p0) = G_GLOBAL_VALUE @var_local

G_PTRAUTH_GLOBAL_VALUE
^^^^^^^^^^^^^^^^^^^^^^

The signed address of a global value. Operands: address to be signed (pointer),
key (32-bit imm), address for address discrimination (zero if not needed) and
an extra discriminator (64-bit imm).

.. code-block:: none

%0:_(p0) = G_PTRAUTH_GLOBAL_VALUE %1:_(p0), s32, %2:_(p0), s64
Copy link
Member

Choose a reason for hiding this comment

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

I think this really does need the extra newline after .. code-block:: none

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, thanks, see 2b12acb


G_BLOCK_ADDR
^^^^^^^^^^^^

Expand Down
7 changes: 7 additions & 0 deletions llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,13 @@ class MachineIRBuilder {
MachineInstrBuilder buildFConstant(const DstOp &Res, double Val);
MachineInstrBuilder buildFConstant(const DstOp &Res, const APFloat &Val);

/// Build and insert G_PTRAUTH_GLOBAL_VALUE
///
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildConstantPtrAuth(const DstOp &Res,
const ConstantPtrAuth *CPA,
Register Addr, Register AddrDisc);

/// Build and insert \p Res = COPY Op
///
/// Register-to-register COPY sets \p Res to \p Op.
Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/CodeGen/ISDOpcodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ enum NodeType {
ExternalSymbol,
BlockAddress,

/// A ptrauth constant.
/// ptr, key, addr-disc, disc
/// Note that the addr-disc can be a non-constant value, to allow representing
/// a constant global address signed using address-diversification, in code.
PtrAuthGlobalAddress,

/// The address of the GOT
GLOBAL_OFFSET_TABLE,

Expand Down
20 changes: 20 additions & 0 deletions llvm/include/llvm/CodeGen/MachineModuleInfoImpls.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,20 @@ class MachineModuleInfoMachO : public MachineModuleInfoImpl {
/// MachineModuleInfoELF - This is a MachineModuleInfoImpl implementation
/// for ELF targets.
class MachineModuleInfoELF : public MachineModuleInfoImpl {
public:
struct AuthStubInfo {
const MCExpr *AuthPtrRef;
};

private:
/// GVStubs - These stubs are used to materialize global addresses in PIC
/// mode.
DenseMap<MCSymbol *, StubValueTy> GVStubs;

/// AuthPtrStubs - These stubs are used to materialize signed addresses for
/// extern_weak symbols.
DenseMap<MCSymbol *, AuthStubInfo> AuthPtrStubs;

virtual void anchor(); // Out of line virtual method.

public:
Expand All @@ -75,9 +85,19 @@ class MachineModuleInfoELF : public MachineModuleInfoImpl {
return GVStubs[Sym];
}

AuthStubInfo &getAuthPtrStubEntry(MCSymbol *Sym) {
assert(Sym && "Key cannot be null");
return AuthPtrStubs[Sym];
}

/// Accessor methods to return the set of stubs in sorted order.

SymbolListTy GetGVStubList() { return getSortedStubs(GVStubs); }

using AuthStubPairTy = std::pair<MCSymbol *, AuthStubInfo>;
typedef std::vector<AuthStubPairTy> AuthStubListTy;

AuthStubListTy getAuthGVStubList();
};

/// MachineModuleInfoCOFF - This is a MachineModuleInfoImpl implementation
Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/Support/TargetOpcodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,9 @@ HANDLE_TARGET_OPCODE(G_FRAME_INDEX)
/// Generic reference to global value.
HANDLE_TARGET_OPCODE(G_GLOBAL_VALUE)

/// Generic ptrauth-signed reference to global value.
HANDLE_TARGET_OPCODE(G_PTRAUTH_GLOBAL_VALUE)

/// Generic instruction to materialize the address of an object in the constant
/// pool.
HANDLE_TARGET_OPCODE(G_CONSTANT_POOL)
Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/Target/GenericOpcodes.td
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ def G_GLOBAL_VALUE : GenericInstruction {
let hasSideEffects = false;
}

def G_PTRAUTH_GLOBAL_VALUE : GenericInstruction {
Copy link

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for suggestion! Done

let OutOperandList = (outs type0:$dst);
let InOperandList = (ins unknown:$addr, i32imm:$key, type1:$addrdisc, i64imm:$disc);
let hasSideEffects = 0;
}

def G_CONSTANT_POOL : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins unknown:$src);
Expand Down
6 changes: 5 additions & 1 deletion llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3494,7 +3494,11 @@ bool IRTranslator::translate(const Constant &C, Register Reg) {
EntryBuilder->buildConstant(Reg, 0);
else if (auto GV = dyn_cast<GlobalValue>(&C))
EntryBuilder->buildGlobalValue(Reg, GV);
else if (auto CAZ = dyn_cast<ConstantAggregateZero>(&C)) {
else if (auto CPA = dyn_cast<ConstantPtrAuth>(&C)) {
Register Addr = getOrCreateVReg(*CPA->getPointer());
Register AddrDisc = getOrCreateVReg(*CPA->getAddrDiscriminator());
EntryBuilder->buildConstantPtrAuth(Reg, CPA, Addr, AddrDisc);
} else if (auto CAZ = dyn_cast<ConstantAggregateZero>(&C)) {
if (!isa<FixedVectorType>(CAZ->getType()))
return false;
// Return the scalar if it is a <1 x Ty> vector.
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,19 @@ MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res,
return buildFConstant(Res, *CFP);
}

MachineInstrBuilder
MachineIRBuilder::buildConstantPtrAuth(const DstOp &Res,
const ConstantPtrAuth *CPA,
Register Addr, Register AddrDisc) {
auto MIB = buildInstr(TargetOpcode::G_PTRAUTH_GLOBAL_VALUE);
Res.addDefToMIB(*getMRI(), MIB);
MIB.addUse(Addr);
MIB.addImm(CPA->getKey()->getZExtValue());
MIB.addUse(AddrDisc);
MIB.addImm(CPA->getDiscriminator()->getZExtValue());
return MIB;
}

MachineInstrBuilder MachineIRBuilder::buildBrCond(const SrcOp &Tst,
MachineBasicBlock &Dest) {
assert(Tst.getLLTTy(*getMRI()).isScalar() && "invalid operand type");
Expand Down
23 changes: 23 additions & 0 deletions llvm/lib/CodeGen/MachineModuleInfoImpls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCSymbol.h"

using namespace llvm;
Expand Down Expand Up @@ -41,3 +42,25 @@ MachineModuleInfoImpl::SymbolListTy MachineModuleInfoImpl::getSortedStubs(
Map.clear();
return List;
}

template <typename MachineModuleInfoTarget>
static typename MachineModuleInfoTarget::AuthStubListTy getAuthGVStubListHelper(
DenseMap<MCSymbol *, typename MachineModuleInfoTarget::AuthStubInfo>
&AuthPtrStubs) {
typename MachineModuleInfoTarget::AuthStubListTy List(AuthPtrStubs.begin(),
AuthPtrStubs.end());

if (!List.empty())
llvm::sort(List.begin(), List.end(),
[](const typename MachineModuleInfoTarget::AuthStubPairTy &LHS,
const typename MachineModuleInfoTarget::AuthStubPairTy &RHS) {
return LHS.first->getName() < RHS.first->getName();
});

AuthPtrStubs.clear();
return List;
}

MachineModuleInfoELF::AuthStubListTy MachineModuleInfoELF::getAuthGVStubList() {
return getAuthGVStubListHelper<MachineModuleInfoELF>(AuthPtrStubs);
}
6 changes: 6 additions & 0 deletions llvm/lib/CodeGen/MachineVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2066,6 +2066,12 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
report("Dst operand 0 must be a pointer", MI);
break;
}
case TargetOpcode::G_PTRAUTH_GLOBAL_VALUE: {
const MachineOperand &AddrOp = MI->getOperand(1);
if (!AddrOp.isReg() || !MRI->getType(AddrOp.getReg()).isPointer())
report("addr operand must be a pointer", &AddrOp, 1);
break;
}
default:
break;
}
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1802,6 +1802,13 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
return DAG.getGlobalAddress(GV, getCurSDLoc(), VT);

if (const ConstantPtrAuth *CPA = dyn_cast<ConstantPtrAuth>(C)) {
return DAG.getNode(ISD::PtrAuthGlobalAddress, getCurSDLoc(), VT,
getValue(CPA->getPointer()), getValue(CPA->getKey()),
getValue(CPA->getAddrDiscriminator()),
getValue(CPA->getDiscriminator()));
}

if (isa<ConstantPointerNull>(C)) {
unsigned AS = V->getType()->getPointerAddressSpace();
return DAG.getConstant(0, getCurSDLoc(),
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
}
return "<<Unknown Node #" + utostr(getOpcode()) + ">>";

// clang-format off
#ifndef NDEBUG
case ISD::DELETED_NODE: return "<<Deleted Node!>>";
#endif
Expand Down Expand Up @@ -126,6 +127,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::ConstantFP: return "ConstantFP";
case ISD::GlobalAddress: return "GlobalAddress";
case ISD::GlobalTLSAddress: return "GlobalTLSAddress";
case ISD::PtrAuthGlobalAddress: return "PtrAuthGlobalAddress";
case ISD::FrameIndex: return "FrameIndex";
case ISD::JumpTable: return "JumpTable";
case ISD::JUMP_TABLE_DEBUG_INFO:
Expand Down Expand Up @@ -168,8 +170,6 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
return "OpaqueTargetConstant";
return "TargetConstant";

// clang-format off

case ISD::TargetConstantFP: return "TargetConstantFP";
case ISD::TargetGlobalAddress: return "TargetGlobalAddress";
case ISD::TargetGlobalTLSAddress: return "TargetGlobalTLSAddress";
Expand Down
Loading
Loading