Skip to content

[PAC][AArch64] Lower ptrauth constants in data #94240

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 11, 2024

Conversation

kovdan01
Copy link
Contributor

@kovdan01 kovdan01 commented Jun 3, 2024

Lower global references to ptrauth constants into @AUTH MCExpr's.
The logic is common for MachO and ELF - test both.

Co-authored-by: Ahmed Bougacha [email protected]

Lower global references to ptrauth constants into `@AUTH` `MCExpr`'s.
The logic is common for MachO and ELF - test both.

Co-authored-by: Ahmed Bougacha <[email protected]>
@kovdan01 kovdan01 force-pushed the ptrauth-constants-in-data branch from 6d28d51 to eb7cc2f Compare June 3, 2024 20:30
@kovdan01 kovdan01 linked an issue Jun 3, 2024 that may be closed by this pull request
@kovdan01 kovdan01 self-assigned this Jun 3, 2024
@kovdan01 kovdan01 marked this pull request as ready for review June 3, 2024 20:37
@llvmbot
Copy link
Member

llvmbot commented Jun 3, 2024

@llvm/pr-subscribers-backend-aarch64

Author: Daniil Kovalev (kovdan01)

Changes

Lower global references to ptrauth constants into @<!-- -->AUTH MCExpr's.
The logic is common for MachO and ELF - test both.

Co-authored-by: Ahmed Bougacha <[email protected]>


Full diff: https://github.com/llvm/llvm-project/pull/94240.diff

4 Files Affected:

  • (modified) llvm/include/llvm/CodeGen/AsmPrinter.h (+6)
  • (modified) llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (+3)
  • (modified) llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp (+48)
  • (added) llvm/test/CodeGen/AArch64/ptrauth-reloc.ll (+176)
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index 81c3e4be95e9f..e918590e8193f 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -38,6 +38,7 @@ class BasicBlock;
 class BlockAddress;
 class Constant;
 class ConstantArray;
+class ConstantPtrAuth;
 class DataLayout;
 class DIE;
 class DIEAbbrev;
@@ -585,6 +586,11 @@ class AsmPrinter : public MachineFunctionPass {
     emitGlobalConstant(DL, CV);
   }
 
+  /// Lower the specified ptrauth constant to an MCExpr.
+  virtual const MCExpr *lowerConstantPtrAuth(const ConstantPtrAuth &CPA) {
+    report_fatal_error("ptrauth constant lowering not implemented");
+  }
+
   /// Return true if the basic block has exactly one predecessor and the control
   /// transfer mechanism between the predecessor and this block is a
   /// fall-through.
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index c5755b9bdc8d0..a668b951e337e 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -3177,6 +3177,9 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) {
   if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV))
     return MCConstantExpr::create(CI->getZExtValue(), Ctx);
 
+  if (const ConstantPtrAuth *CPA = dyn_cast<ConstantPtrAuth>(CV))
+    return lowerConstantPtrAuth(*CPA);
+
   if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV))
     return MCSymbolRefExpr::create(getSymbol(GV), Ctx);
 
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index 7da540f8ef8e5..51f52bd2379eb 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -43,6 +43,8 @@
 #include "llvm/CodeGen/TargetRegisterInfo.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCInst.h"
@@ -90,6 +92,8 @@ class AArch64AsmPrinter : public AsmPrinter {
     return MCInstLowering.lowerOperand(MO, MCOp);
   }
 
+  const MCExpr *lowerConstantPtrAuth(const ConstantPtrAuth &CPA) override;
+
   void emitStartOfAsmFile(Module &M) override;
   void emitJumpTableInfo() override;
   std::tuple<const MCSymbol *, uint64_t, const MCSymbol *,
@@ -1575,6 +1579,50 @@ void AArch64AsmPrinter::emitPtrauthBranch(const MachineInstr *MI) {
   assert(STI->getInstrInfo()->getInstSizeInBytes(*MI) >= InstsEmitted * 4);
 }
 
+const MCExpr *
+AArch64AsmPrinter::lowerConstantPtrAuth(const ConstantPtrAuth &CPA) {
+  MCContext &Ctx = OutContext;
+
+  // Figure out the base symbol and the addend, if any.
+  APInt Offset(64, 0);
+  const Value *BaseGV = CPA.getPointer()->stripAndAccumulateConstantOffsets(
+      getDataLayout(), Offset, /*AllowNonInbounds=*/true);
+
+  auto *BaseGVB = dyn_cast<GlobalValue>(BaseGV);
+
+  // If we can't understand the referenced ConstantExpr, there's nothing
+  // else we can do: emit an error.
+  if (!BaseGVB) {
+    BaseGV->getContext().emitError(
+        "cannot resolve target base/addend of ptrauth constant");
+    return nullptr;
+  }
+
+  // If there is an addend, turn that into the appropriate MCExpr.
+  const MCExpr *Sym = MCSymbolRefExpr::create(getSymbol(BaseGVB), Ctx);
+  if (Offset.sgt(0))
+    Sym = MCBinaryExpr::createAdd(
+        Sym, MCConstantExpr::create(Offset.getSExtValue(), Ctx), Ctx);
+  else if (Offset.slt(0))
+    Sym = MCBinaryExpr::createSub(
+        Sym, MCConstantExpr::create((-Offset).getSExtValue(), Ctx), Ctx);
+
+  uint64_t KeyID = CPA.getKey()->getZExtValue();
+  // We later rely on valid KeyID value in AArch64PACKeyIDToString call from
+  // AArch64AuthMCExpr::printImpl, so fail fast.
+  if (KeyID > AArch64PACKey::LAST)
+    report_fatal_error("invalid AArch64 PAC Key ID '" + Twine(KeyID) + "'");
+
+  uint64_t Disc = CPA.getDiscriminator()->getZExtValue();
+  if (!isUInt<16>(Disc))
+    report_fatal_error("invalid AArch64 PAC Discriminator '" + Twine(Disc) +
+                       "'");
+
+  // Finally build the complete @AUTH expr.
+  return AArch64AuthMCExpr::create(Sym, Disc, AArch64PACKey::ID(KeyID),
+                                   CPA.hasAddressDiscriminator(), Ctx);
+}
+
 // Simple pseudo-instructions have their lowering (with expansion to real
 // instructions) auto-generated.
 #include "AArch64GenMCPseudoLowering.inc"
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-reloc.ll b/llvm/test/CodeGen/AArch64/ptrauth-reloc.ll
new file mode 100644
index 0000000000000..8a8dc16f3dd9e
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/ptrauth-reloc.ll
@@ -0,0 +1,176 @@
+; RUN: rm -rf %t && split-file %s %t && cd %t
+
+;--- ok.ll
+
+; RUN: llc < ok.ll -mtriple arm64e-apple-darwin \
+; RUN:   | FileCheck %s --check-prefix=CHECK-MACHO
+; RUN: llc < ok.ll -mtriple aarch64-elf -mattr=+pauth \
+; RUN:   | FileCheck %s --check-prefix=CHECK-ELF
+
+; RUN: llc < ok.ll -mtriple arm64e-apple-darwin \
+; RUN:   -global-isel -verify-machineinstrs -global-isel-abort=1 \
+; RUN:   | FileCheck %s --check-prefix=CHECK-MACHO
+; RUN: llc < ok.ll -mtriple aarch64-elf -mattr=+pauth \
+; RUN:   -global-isel -verify-machineinstrs -global-isel-abort=1 \
+; RUN:   | FileCheck %s --check-prefix=CHECK-ELF
+
+@g = external global i32
+
+@g_weak = extern_weak global i32
+
+@g_strong_def = constant i32 42
+
+; CHECK-ELF-LABEL:     .globl g.ref.ia.0
+; CHECK-ELF-NEXT:      .p2align 4
+; CHECK-ELF-NEXT:    g.ref.ia.0:
+; CHECK-ELF-NEXT:      .xword 5
+; CHECK-ELF-NEXT:      .xword g@AUTH(ia,0)
+; CHECK-ELF-NEXT:      .xword 6
+
+; CHECK-MACHO-LABEL:   .section __DATA,__const
+; CHECK-MACHO-NEXT:    .globl _g.ref.ia.0
+; CHECK-MACHO-NEXT:    .p2align 4
+; CHECK-MACHO-NEXT:  _g.ref.ia.0:
+; CHECK-MACHO-NEXT:    .quad 5
+; CHECK-MACHO-NEXT:    .quad _g@AUTH(ia,0)
+; CHECK-MACHO-NEXT:    .quad 6
+
+@g.ref.ia.0 = constant { i64, ptr, i64 } { i64 5, ptr ptrauth (ptr @g, i32 0), i64 6 }
+
+; CHECK-ELF-LABEL:     .globl g.ref.ia.42
+; CHECK-ELF-NEXT:      .p2align 3
+; CHECK-ELF-NEXT:    g.ref.ia.42:
+; CHECK-ELF-NEXT:      .xword g@AUTH(ia,42)
+
+; CHECK-MACHO-LABEL:   .globl _g.ref.ia.42
+; CHECK-MACHO-NEXT:    .p2align 3
+; CHECK-MACHO-NEXT:  _g.ref.ia.42:
+; CHECK-MACHO-NEXT:    .quad _g@AUTH(ia,42)
+
+@g.ref.ia.42 = constant ptr ptrauth (ptr @g, i32 0, i64 42)
+
+; CHECK-ELF-LABEL:     .globl g.ref.ib.0
+; CHECK-ELF-NEXT:      .p2align 4
+; CHECK-ELF-NEXT:    g.ref.ib.0:
+; CHECK-ELF-NEXT:      .xword 5
+; CHECK-ELF-NEXT:      .xword g@AUTH(ib,0)
+; CHECK-ELF-NEXT:      .xword 6
+
+; CHECK-MACHO-LABEL:   .globl _g.ref.ib.0
+; CHECK-MACHO-NEXT:    .p2align 4
+; CHECK-MACHO-NEXT:  _g.ref.ib.0:
+; CHECK-MACHO-NEXT:    .quad 5
+; CHECK-MACHO-NEXT:    .quad _g@AUTH(ib,0)
+; CHECK-MACHO-NEXT:    .quad 6
+
+@g.ref.ib.0 = constant { i64, ptr, i64 } { i64 5, ptr ptrauth (ptr @g, i32 1, i64 0), i64 6 }
+
+; CHECK-ELF-LABEL:     .globl g.ref.da.42.addr
+; CHECK-ELF-NEXT:      .p2align 3
+; CHECK-ELF-NEXT:    g.ref.da.42.addr:
+; CHECK-ELF-NEXT:      .xword g@AUTH(da,42,addr)
+
+; CHECK-MACHO-LABEL:   .globl _g.ref.da.42.addr
+; CHECK-MACHO-NEXT:    .p2align 3
+; CHECK-MACHO-NEXT:  _g.ref.da.42.addr:
+; CHECK-MACHO-NEXT:    .quad _g@AUTH(da,42,addr)
+
+@g.ref.da.42.addr = constant ptr ptrauth (ptr @g, i32 2, i64 42, ptr @g.ref.da.42.addr)
+
+; CHECK-ELF-LABEL:     .globl g.offset.ref.da.0
+; CHECK-ELF-NEXT:      .p2align 3
+; CHECK-ELF-NEXT:    g.offset.ref.da.0:
+; CHECK-ELF-NEXT:      .xword (g+16)@AUTH(da,0)
+
+; CHECK-MACHO-LABEL:   .globl _g.offset.ref.da.0
+; CHECK-MACHO-NEXT:    .p2align 3
+; CHECK-MACHO-NEXT:  _g.offset.ref.da.0:
+; CHECK-MACHO-NEXT:    .quad (_g+16)@AUTH(da,0)
+
+@g.offset.ref.da.0 = constant ptr ptrauth (i8* getelementptr (i8, ptr @g, i64 16), i32 2)
+
+; CHECK-ELF-LABEL:     .globl g.big_offset.ref.da.0
+; CHECK-ELF-NEXT:      .p2align 3
+; CHECK-ELF-NEXT:    g.big_offset.ref.da.0:
+; CHECK-ELF-NEXT:      .xword (g+2147549185)@AUTH(da,0)
+
+; CHECK-MACHO-LABEL:   .globl _g.big_offset.ref.da.0
+; CHECK-MACHO-NEXT:    .p2align 3
+; CHECK-MACHO-NEXT:  _g.big_offset.ref.da.0:
+; CHECK-MACHO-NEXT:    .quad (_g+2147549185)@AUTH(da,0)
+
+@g.big_offset.ref.da.0 = constant ptr ptrauth (i8* getelementptr (i8, ptr @g, i64 add (i64 2147483648, i64 65537)), i32 2)
+
+; CHECK-ELF-LABEL:     .globl g.weird_ref.da.0
+; CHECK-ELF-NEXT:      .p2align 3
+; CHECK-ELF-NEXT:    g.weird_ref.da.0:
+; CHECK-ELF-NEXT:      .xword (g+16)@AUTH(da,0)
+
+; CHECK-MACHO-LABEL:   .globl _g.weird_ref.da.0
+; CHECK-MACHO-NEXT:    .p2align 3
+; CHECK-MACHO-NEXT:  _g.weird_ref.da.0:
+; CHECK-MACHO-NEXT:    .quad (_g+16)@AUTH(da,0)
+
+@g.weird_ref.da.0 = constant i64 ptrtoint (ptr inttoptr (i64 ptrtoint (ptr ptrauth (i8* getelementptr (i8, ptr @g, i64 16), i32 2) to i64) to ptr) to i64)
+
+; CHECK-ELF-LABEL:     .globl g_weak.ref.ia.42
+; CHECK-ELF-NEXT:      .p2align 3
+; CHECK-ELF-NEXT:    g_weak.ref.ia.42:
+; CHECK-ELF-NEXT:      .xword g_weak@AUTH(ia,42)
+
+; CHECK-MACHO-LABEL:   .globl _g_weak.ref.ia.42
+; CHECK-MACHO-NEXT:    .p2align 3
+; CHECK-MACHO-NEXT:  _g_weak.ref.ia.42:
+; CHECK-MACHO-NEXT:    .quad _g_weak@AUTH(ia,42)
+
+@g_weak.ref.ia.42 = constant ptr ptrauth (ptr @g_weak, i32 0, i64 42)
+
+; CHECK-ELF-LABEL:     .globl g_strong_def.ref.da.0
+; CHECK-ELF-NEXT:      .p2align 3
+; CHECK-ELF-NEXT:    g_strong_def.ref.da.0:
+; CHECK-ELF-NEXT:      .xword g_strong_def@AUTH(da,0)
+
+; CHECK-MACHO-LABEL:   .globl _g_strong_def.ref.da.0
+; CHECK-MACHO-NEXT:    .p2align 3
+; CHECK-MACHO-NEXT:  _g_strong_def.ref.da.0:
+; CHECK-MACHO-NEXT:    .quad _g_strong_def@AUTH(da,0)
+
+@g_strong_def.ref.da.0 = constant ptr ptrauth (ptr @g_strong_def, i32 2)
+
+;--- err-key.ll
+
+; RUN: not --crash llc < err-key.ll -mtriple arm64e-apple-darwin 2>&1 \
+; RUN:   | FileCheck %s --check-prefix=CHECK-ERR-KEY
+; RUN: not --crash llc < err-key.ll -mtriple aarch64-elf -mattr=+pauth 2>&1 \
+; RUN:   | FileCheck %s --check-prefix=CHECK-ERR-KEY
+
+; RUN: not --crash llc < err-key.ll -mtriple arm64e-apple-darwin \
+; RUN:   -global-isel -verify-machineinstrs -global-isel-abort=1  2>&1 \
+; RUN:   | FileCheck %s --check-prefix=CHECK-ERR-KEY
+; RUN: not --crash llc < err-key.ll -mtriple aarch64-elf -mattr=+pauth \
+; RUN:   -global-isel -verify-machineinstrs -global-isel-abort=1 2>&1 \
+; RUN:   | FileCheck %s --check-prefix=CHECK-ERR-KEY
+
+; CHECK-ERR-KEY: LLVM ERROR: invalid AArch64 PAC Key ID '4'
+
+@g = external global i32
+@g.ref.4.0 = constant ptr ptrauth (ptr @g, i32 4, i64 0)
+
+;--- err-disc.ll
+
+; RUN: not --crash llc < err-disc.ll -mtriple arm64e-apple-darwin 2>&1 \
+; RUN:   | FileCheck %s --check-prefix=CHECK-ERR-DISC
+; RUN: not --crash llc < err-disc.ll -mtriple aarch64-elf -mattr=+pauth 2>&1 \
+; RUN:   | FileCheck %s --check-prefix=CHECK-ERR-DISC
+
+; RUN: not --crash llc < err-disc.ll -mtriple arm64e-apple-darwin \
+; RUN:   -global-isel -verify-machineinstrs -global-isel-abort=1  2>&1 \
+; RUN:   | FileCheck %s --check-prefix=CHECK-ERR-DISC
+; RUN: not --crash llc < err-disc.ll -mtriple aarch64-elf -mattr=+pauth \
+; RUN:   -global-isel -verify-machineinstrs -global-isel-abort=1 2>&1 \
+; RUN:   | FileCheck %s --check-prefix=CHECK-ERR-DISC
+
+; CHECK-ERR-DISC: LLVM ERROR: invalid AArch64 PAC Discriminator '65536'
+
+@g = external global i32
+@g.ref.ia.65536 = constant ptr ptrauth (ptr @g, i32 0, i64 65536)

@kovdan01 kovdan01 requested a review from smithp35 June 3, 2024 20:38
@@ -585,6 +586,11 @@ class AsmPrinter : public MachineFunctionPass {
emitGlobalConstant(DL, CV);
}

/// Lower the specified ptrauth constant to an MCExpr.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: This comment doesn't add anything over the function prototype

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense, deleted the comment, see 9633e04

uint64_t Disc = CPA.getDiscriminator()->getZExtValue();
if (!isUInt<16>(Disc))
report_fatal_error("invalid AArch64 PAC Discriminator '" + Twine(Disc) +
"'");
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: "expected uint16"?

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, I've changed the error message here and above to "AArch64 PAC Discriminator 'XXX' out of range [0, 0xFFFF]" - this looks like a common format for similar error messages across llvm. See 9633e04

@fmayer fmayer requested a review from pcc June 5, 2024 20:24
@kovdan01
Copy link
Contributor Author

kovdan01 commented Jun 7, 2024

@fmayer Thanks for feedback! Do I get it right that you want me not to merge the PR until @pcc looks through the changes? Alternatively, I can merge this "as is" since we already have an approve, and, if there are some issues, just submit a follow-up patch later. This one is a prerequisite for PR94241, so it would be nice to get this merged relatively soon.

@kovdan01 kovdan01 requested a review from fmayer June 7, 2024 10:20
@kovdan01
Copy link
Contributor Author

@fmayer @pcc Please let me know if you want to leave some feedback before this is merged or if I can merge it "as is"

@kovdan01
Copy link
Contributor Author

Pushed merge commit 20ed224 to re-trigger builkite (previously failed due to unrelated reasons)

@kovdan01 kovdan01 merged commit 690480f into llvm:main Jun 11, 2024
7 checks passed
Lukacma pushed a commit to Lukacma/llvm-project that referenced this pull request Jun 12, 2024
Lower global references to ptrauth constants into `@AUTH` `MCExpr`'s.
The logic is common for MachO and ELF - test both.

---------

Co-authored-by: Ahmed Bougacha <[email protected]>
@HerrCai0907 HerrCai0907 mentioned this pull request Jun 13, 2024
kovdan01 added a commit that referenced this pull request Jun 27, 2024
Depends on #94240.

Define the following pseudos for lowering ptrauth constants in code:

- non-`extern_weak`:
  - no GOT load needed: `MOVaddrPAC` - similar to `MOVaddr`, with added
    PAC;
  - GOT load needed: `LOADgotPAC` - similar to `LOADgot`, with added PAC;
- `extern_weak`: `LOADauthptrstatic` - similar to `LOADgot`, but use a
  special stub slot named `sym$auth_ptr$key$disc` filled by dynamic linker
  during relocation resolving instead of a GOT slot.

---------

Co-authored-by: Ahmed Bougacha <[email protected]>
arsenm pushed a commit that referenced this pull request Jun 27, 2024
Depends on #94240.

Define the following pseudos for lowering ptrauth constants in code:

- non-`extern_weak`:
  - no GOT load needed: `MOVaddrPAC` - similar to `MOVaddr`, with added
    PAC;
  - GOT load needed: `LOADgotPAC` - similar to `LOADgot`, with added PAC;
- `extern_weak`: `LOADauthptrstatic` - similar to `LOADgot`, but use a
  special stub slot named `sym$auth_ptr$key$disc` filled by dynamic linker
  during relocation resolving instead of a GOT slot.

---------

Co-authored-by: Ahmed Bougacha <[email protected]>
kovdan01 added a commit to kovdan01/llvm-project that referenced this pull request Jun 27, 2024
This re-applies llvm#94241 after fixing buildbot failure, see
https://lab.llvm.org/buildbot/#/builders/51/builds/570

According to standard, `constexpr` variables can be used in lambdas w/o
capturing - see https://en.cppreference.com/w/cpp/language/lambda.
However, MSVC used on buildkite seems to ignore that rule and does not
allow using uncaptured `constexpr` variables in lambdas: we have
"error C3493: 'Mask16' cannot be implicitly captured because no default
capture mode has been specified" - see
https://buildkite.com/llvm-project/github-pull-requests/builds/73238

Explicitly capturing a `constexpr` variable, however, makes buildbot
fail with "error: lambda capture 'Mask16' is not required to be captured
for this use [-Werror,-Wunused-lambda-capture]" - see
https://lab.llvm.org/buildbot/#/builders/51/builds/570.

Fix both cases by using `const` instead of `constexpr` and explicitly
capturing the variable.

Original PR description below.

Depends on llvm#94240.

Define the following pseudos for lowering ptrauth constants in code:

- non-`extern_weak`:
  - no GOT load needed: `MOVaddrPAC` - similar to `MOVaddr`, with added
    PAC;
  - GOT load needed: `LOADgotPAC` - similar to `LOADgot`, with added PAC;
- `extern_weak`: `LOADauthptrstatic` - similar to `LOADgot`, but use a
  special stub slot named `sym$auth_ptr$key$disc` filled by dynamic linker
  during relocation resolving instead of a GOT slot.

---------

Co-authored-by: Ahmed Bougacha <[email protected]>
arsenm pushed a commit that referenced this pull request Jun 27, 2024
Depends on #94240.

Define the following pseudos for lowering ptrauth constants in code:

- non-`extern_weak`:
  - no GOT load needed: `MOVaddrPAC` - similar to `MOVaddr`, with added
    PAC;
  - GOT load needed: `LOADgotPAC` - similar to `LOADgot`, with added PAC;
- `extern_weak`: `LOADauthptrstatic` - similar to `LOADgot`, but use a
  special stub slot named `sym$auth_ptr$key$disc` filled by dynamic linker
  during relocation resolving instead of a GOT slot.

---------

Co-authored-by: Ahmed Bougacha <[email protected]>
kovdan01 added a commit that referenced this pull request Jun 28, 2024
This re-applies #94241 after fixing buildbot failure, see
https://lab.llvm.org/buildbot/#/builders/51/builds/570

According to standard, `constexpr` variables and `const` variables
initialized with constant expressions can be used in lambdas w/o
capturing - see https://en.cppreference.com/w/cpp/language/lambda.
However, MSVC used on buildkite seems to ignore that rule and does not
allow using such uncaptured variables in lambdas: we have "error C3493:
'Mask16' cannot be implicitly captured because no default capture mode
has been specified" - see
https://buildkite.com/llvm-project/github-pull-requests/builds/73238

Explicitly capturing such a variable, however, makes buildbot fail with
"error: lambda capture 'Mask16' is not required to be captured for this
use [-Werror,-Wunused-lambda-capture]" - see
https://lab.llvm.org/buildbot/#/builders/51/builds/570.

Fix both cases by using `0xffff` value directly instead of giving a name
to it.

Original PR description below.

Depends on #94240.

Define the following pseudos for lowering ptrauth constants in code:

- non-`extern_weak`:
  - no GOT load needed: `MOVaddrPAC` - similar to `MOVaddr`, with added
PAC;
  - GOT load needed: `LOADgotPAC` - similar to `LOADgot`, with added PAC;
- `extern_weak`: `LOADauthptrstatic` - similar to `LOADgot`, but use a
special stub slot named `sym$auth_ptr$key$disc` filled by dynamic linker
during relocation resolving instead of a GOT slot.

---------

Co-authored-by: Ahmed Bougacha <[email protected]>
lravenclaw pushed a commit to lravenclaw/llvm-project that referenced this pull request Jul 3, 2024
Depends on llvm#94240.

Define the following pseudos for lowering ptrauth constants in code:

- non-`extern_weak`:
  - no GOT load needed: `MOVaddrPAC` - similar to `MOVaddr`, with added
    PAC;
  - GOT load needed: `LOADgotPAC` - similar to `LOADgot`, with added PAC;
- `extern_weak`: `LOADauthptrstatic` - similar to `LOADgot`, but use a
  special stub slot named `sym$auth_ptr$key$disc` filled by dynamic linker
  during relocation resolving instead of a GOT slot.

---------

Co-authored-by: Ahmed Bougacha <[email protected]>
lravenclaw pushed a commit to lravenclaw/llvm-project that referenced this pull request Jul 3, 2024
This re-applies llvm#94241 after fixing buildbot failure, see
https://lab.llvm.org/buildbot/#/builders/51/builds/570

According to standard, `constexpr` variables and `const` variables
initialized with constant expressions can be used in lambdas w/o
capturing - see https://en.cppreference.com/w/cpp/language/lambda.
However, MSVC used on buildkite seems to ignore that rule and does not
allow using such uncaptured variables in lambdas: we have "error C3493:
'Mask16' cannot be implicitly captured because no default capture mode
has been specified" - see
https://buildkite.com/llvm-project/github-pull-requests/builds/73238

Explicitly capturing such a variable, however, makes buildbot fail with
"error: lambda capture 'Mask16' is not required to be captured for this
use [-Werror,-Wunused-lambda-capture]" - see
https://lab.llvm.org/buildbot/#/builders/51/builds/570.

Fix both cases by using `0xffff` value directly instead of giving a name
to it.

Original PR description below.

Depends on llvm#94240.

Define the following pseudos for lowering ptrauth constants in code:

- non-`extern_weak`:
  - no GOT load needed: `MOVaddrPAC` - similar to `MOVaddr`, with added
PAC;
  - GOT load needed: `LOADgotPAC` - similar to `LOADgot`, with added PAC;
- `extern_weak`: `LOADauthptrstatic` - similar to `LOADgot`, but use a
special stub slot named `sym$auth_ptr$key$disc` filled by dynamic linker
during relocation resolving instead of a GOT slot.

---------

Co-authored-by: Ahmed Bougacha <[email protected]>
AlexisPerry pushed a commit to llvm-project-tlp/llvm-project that referenced this pull request Jul 9, 2024
Depends on llvm#94240.

Define the following pseudos for lowering ptrauth constants in code:

- non-`extern_weak`:
  - no GOT load needed: `MOVaddrPAC` - similar to `MOVaddr`, with added
    PAC;
  - GOT load needed: `LOADgotPAC` - similar to `LOADgot`, with added PAC;
- `extern_weak`: `LOADauthptrstatic` - similar to `LOADgot`, but use a
  special stub slot named `sym$auth_ptr$key$disc` filled by dynamic linker
  during relocation resolving instead of a GOT slot.

---------

Co-authored-by: Ahmed Bougacha <[email protected]>
searlmc1 pushed a commit to ROCm/llvm-project that referenced this pull request Sep 6, 2024
This re-applies llvm#94241 after fixing buildbot failure, see
https://lab.llvm.org/buildbot/#/builders/51/builds/570

According to standard, `constexpr` variables and `const` variables
initialized with constant expressions can be used in lambdas w/o
capturing - see https://en.cppreference.com/w/cpp/language/lambda.
However, MSVC used on buildkite seems to ignore that rule and does not
allow using such uncaptured variables in lambdas: we have "error C3493:
'Mask16' cannot be implicitly captured because no default capture mode
has been specified" - see
https://buildkite.com/llvm-project/github-pull-requests/builds/73238

Explicitly capturing such a variable, however, makes buildbot fail with
"error: lambda capture 'Mask16' is not required to be captured for this
use [-Werror,-Wunused-lambda-capture]" - see
https://lab.llvm.org/buildbot/#/builders/51/builds/570.

Fix both cases by using `0xffff` value directly instead of giving a name
to it.

Original PR description below.

Depends on llvm#94240.

Define the following pseudos for lowering ptrauth constants in code:

- non-`extern_weak`:
  - no GOT load needed: `MOVaddrPAC` - similar to `MOVaddr`, with added
PAC;
  - GOT load needed: `LOADgotPAC` - similar to `LOADgot`, with added PAC;
- `extern_weak`: `LOADauthptrstatic` - similar to `LOADgot`, but use a
special stub slot named `sym$auth_ptr$key$disc` filled by dynamic linker
during relocation resolving instead of a GOT slot.

---------

Co-authored-by: Ahmed Bougacha <[email protected]>

Change-Id: Ic59980fe9466834f29d0818436149acfd1ebc1da
searlmc1 pushed a commit to ROCm/llvm-project that referenced this pull request Sep 23, 2024
add back -fallow-half-arguments-and-returns for hipRuntime builds.

----------------------------------------------------------------------

Revert "[PAC][AArch64] Lower ptrauth constants in code (llvm#96879)"

This reverts commit 88dd10c.

----------------------------------------------------------------------

[PAC][AArch64] Lower ptrauth constants in code (llvm#96879)

This re-applies llvm#94241 after fixing buildbot failure, see
https://lab.llvm.org/buildbot/#/builders/51/builds/570

According to standard, `constexpr` variables and `const` variables
initialized with constant expressions can be used in lambdas w/o
capturing - see https://en.cppreference.com/w/cpp/language/lambda.
However, MSVC used on buildkite seems to ignore that rule and does not
allow using such uncaptured variables in lambdas: we have "error C3493:
'Mask16' cannot be implicitly captured because no default capture mode
has been specified" - see
https://buildkite.com/llvm-project/github-pull-requests/builds/73238

Explicitly capturing such a variable, however, makes buildbot fail with
"error: lambda capture 'Mask16' is not required to be captured for this
use [-Werror,-Wunused-lambda-capture]" - see
https://lab.llvm.org/buildbot/#/builders/51/builds/570.

Fix both cases by using `0xffff` value directly instead of giving a name
to it.

Original PR description below.

Depends on llvm#94240.

Define the following pseudos for lowering ptrauth constants in code:

- non-`extern_weak`:
  - no GOT load needed: `MOVaddrPAC` - similar to `MOVaddr`, with added
PAC;
  - GOT load needed: `LOADgotPAC` - similar to `LOADgot`, with added PAC;
- `extern_weak`: `LOADauthptrstatic` - similar to `LOADgot`, but use a
special stub slot named `sym$auth_ptr$key$disc` filled by dynamic linker
during relocation resolving instead of a GOT slot.

---------

Co-authored-by: Ahmed Bougacha <[email protected]>

(cherry picked from commit 1488fb4)

----------------------------------------------------------------------

[AArch64][PAC] Lower ptrauth constants in code for MachO. (llvm#97665)

This also adds support for auth stubs on MachO using __DATA,__auth_ptr.

Some of the machinery for auth stubs is already implemented;  this
generalizes that a bit to support MachO, and moves some of the shared
logic into MMIImpls.

In particular, this originally had an AuthStubInfo struct, but we no
longer need it beyond a single MCExpr.  So this provides variants of
the symbol stub helper type declarations and functions for "expr
stubs", where a stub points at an arbitrary MCExpr, rather than
a simple MCSymbol (and a bit).

(cherry picked from commit 5f1bb62)

----------------------------------------------------------------------

[AArch64][PAC] Sign block addresses used in indirectbr. (llvm#97647)

Enabled in clang using:
    -fptrauth-indirect-gotos

and at the IR level using function attribute:
    "ptrauth-indirect-gotos"

Signing uses IA and a per-function integer discriminator. The
discriminator isn't ABI-visible, and is currently:
    ptrauth_string_discriminator("<function_name> blockaddress")

A sufficiently sophisticated frontend could benefit from per-indirectbr
discrimination, which would need additional machinery, such as allowing
"ptrauth" bundles on indirectbr. For our purposes, the simple scheme
above is sufficient.

This approach doesn't support subtracting label addresses and using
the result as offsets, because each label address is signed.
Pointer arithmetic on signed pointers corrupts the signature bits,
and because label address expressions aren't typed beyond void*,
we can't do anything reliably intelligent on the arithmetic exprs.
Not signing addresses when used to form offsets would allow
easily hijacking control flow by overwriting the offset.

This diagnoses the basic cases (`&&lbl2 - &&lbl1`) in the frontend,
while we evaluate either alternative implementations (e.g., lowering
blockaddress to a bb number, and indirectbr to a checked jump-table),
or better diagnostics (both at the frontend level and on unencodable
IR constants).

(cherry picked from commit b8721fa)

----------------------------------------------------------------------

[AArch64][PAC] Lower auth/resign into checked sequence. (llvm#79024)

This introduces 3 hardening modes in the authentication step of
auth/resign lowering:
- unchecked, which uses the AUT instructions as-is
- poison, which detects authentication failure (using an XPAC+CMP
  sequence), explicitly yielding the XPAC result rather than the
  AUT result, to avoid leaking
- trap, which additionally traps on authentication failure,
  using BRK #0xC470 + key (IA C470, IB C471, DA C472, DB C473.)

Not all modes are necessarily useful in all contexts, and there
are more performant alternative lowerings in specific contexts
(e.g., when I/D TBI enablement is a target ABI guarantee.)
These will be implemented separately.

This is controlled by the `ptrauth-auth-traps` function attributes,
and can be overridden using `-aarch64-ptrauth-auth-checks=`.

This also adds the FPAC extension, which we haven't needed
before, to improve isel when we can rely on HW checking.

(cherry picked from commit d7e8a74)

----------------------------------------------------------------------

[Clang][Arm] Convert -fallow-half-arguments-and-returns to a target option. NFC

This cc1 option -fallow-half-arguments-and-returns allows __fp16 to be
passed by argument and returned, without giving an error. It is
currently always enabled for Arm and AArch64, by forcing the option in
the driver. This means any cc1 tests (especially those needing
arm_neon.h) need to specify the option too, to prevent the error from
being emitted.

This changes it to a target option instead, set to true for Arm and
AArch64. This allows the option to be removed. Previously it was implied
by -fnative_half_arguments_and_returns, which is set for certain
languages like open_cl, renderscript and hlsl, so that option now too
controls the errors. There were are few other non-arm uses of
-fallow-half-arguments-and-returns but I believe they were unnecessary.
The strictfp_builtins.c tests were converted from __fp16 to _Float16 to
avoid the issues.

Differential Revision: https://reviews.llvm.org/D133885

(cherry picked from commit 9ef11036505c0ae6cdb56ff49f39ab7abcded3cf)

----------------------------------------------------------------------

[clang] XFAIL a few tests due to 'noundef' etc

Not all, but most of these are failing due to the presence of a 'noundef' call
return attribute on some intrinsics.

This is not present on upstream 'main' due to the AlwaysInliner pass being run.
See commit 1a2e77c.

----------------------------------------------------------------------

[DebugInfo] Restore missing disabled ptrauth support

See "[DebugInfo] Teach LLVM and LLDB about ptrauth in DWARF":

    commit a8c3d98
    Author: Jonas Devlieghere <[email protected]>
    Date:   Wed Jul 27 10:44:15 2022 -0700

----------------------------------------------------------------------

Apply simple-do.ll test change from b46c085

----------------------------------------------------------------------

Adjust ptrauth.s test for ptrauth_authentication_mode encoding

----------------------------------------------------------------------

Fix dwarf-eh-prepare-dbg.ll test: dwarfAddressSpace=>addressSpace

----------------------------------------------------------------------

Update some SLPVectorizer/AArch64 tests from upstream

----------------------------------------------------------------------

Regenerate assertions in arm_mult_q15.ll

----------------------------------------------------------------------

[AsmPrinter] Handle null extracted addr class

----------------------------------------------------------------------

[PowerPC] Account for custom LLVM moniker in aix tests

----------------------------------------------------------------------

[LoongArch] Add "Verify Heterogeneous Debug Preconditions" to pipeline test

----------------------------------------------------------------------

[JITLink][RISCV] Un-XFAIL ELF_pc_indirect.s

----------------------------------------------------------------------

Change-Id: Ie6ab500b2451b3ed070dfad0bc16d003e5e2fe10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

[PAC][ELF] Implement codegen support for signed constants
4 participants