[llvm] 464fa3b - [AArch64][MachO] Encode @AUTH to ARM64_RELOC_AUTHENTICATED_POINTER.

Ahmed Bougacha via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 16 11:59:43 PDT 2024


Author: Ahmed Bougacha
Date: 2024-08-16T11:59:27-07:00
New Revision: 464fa3b3b047518699689b57c473c87701986593

URL: https://github.com/llvm/llvm-project/commit/464fa3b3b047518699689b57c473c87701986593
DIFF: https://github.com/llvm/llvm-project/commit/464fa3b3b047518699689b57c473c87701986593.diff

LOG: [AArch64][MachO] Encode @AUTH to ARM64_RELOC_AUTHENTICATED_POINTER.

This adds MachO support for emission of authenticated pointer
relocations.

We already support AArch64AuthMCExpr, to represent assembly expressions
such as:
  .quad <symbol>@AUTH(<key>, <discriminator> [, addr])
For example:
  .quad _g3 at AUTH(ib, 1234, addr)

These @AUTH expressions lower to a new kind of MachO relocation:
  ARM64_RELOC_AUTHENTICATED_POINTER (11)

The relocation points to the referenced symbol.
The other data, describing the signing scheme and original addend
(only 32 bits instead of 64), is encoded into the addend (in the
relocated location):

  |63|62|61-51|50-49|  48  |47     -     32|31  -  0|
  | 1| 0|  0  | key | addr | discriminator | addend |

Added: 
    llvm/test/MC/AArch64/arm64e-authenticated-pointer-reloc.s

Modified: 
    llvm/docs/PointerAuth.md
    llvm/lib/Object/MachOObjectFile.cpp
    llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/docs/PointerAuth.md b/llvm/docs/PointerAuth.md
index e027c902e58e12..84e0af7577c7d6 100644
--- a/llvm/docs/PointerAuth.md
+++ b/llvm/docs/PointerAuth.md
@@ -374,6 +374,19 @@ For example:
     .quad _sym at AUTH(ia,12,addr)
 ```
 
+#### MachO Object File Representation
+
+At the object file level, authenticated relocations are represented using the
+``ARM64_RELOC_AUTHENTICATED_POINTER`` relocation kind (with value ``11``).
+
+The pointer authentication information is encoded into the addend as follows:
+
+```
+| 63 | 62 | 61-51 | 50-49 |   48   | 47     -     32 | 31  -  0 |
+| -- | -- | ----- | ----- | ------ | --------------- | -------- |
+|  1 |  0 |   0   |  key  |  addr  |  discriminator  |  addend  |
+```
+
 #### ELF Object File Representation
 
 At the object file level, authenticated relocations are represented

diff  --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp
index ff55a847c34327..e2d1723b1fa981 100644
--- a/llvm/lib/Object/MachOObjectFile.cpp
+++ b/llvm/lib/Object/MachOObjectFile.cpp
@@ -2341,7 +2341,7 @@ void MachOObjectFile::getRelocationTypeName(
         "ARM64_RELOC_PAGEOFF12",          "ARM64_RELOC_GOT_LOAD_PAGE21",
         "ARM64_RELOC_GOT_LOAD_PAGEOFF12", "ARM64_RELOC_POINTER_TO_GOT",
         "ARM64_RELOC_TLVP_LOAD_PAGE21",   "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
-        "ARM64_RELOC_ADDEND"
+        "ARM64_RELOC_ADDEND",             "ARM64_RELOC_AUTHENTICATED_POINTER"
       };
 
       if (RType >= std::size(Table))

diff  --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp
index 33f0ca237b26dd..ed0a972cc50abd 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "MCTargetDesc/AArch64FixupKinds.h"
+#include "MCTargetDesc/AArch64MCExpr.h"
 #include "MCTargetDesc/AArch64MCTargetDesc.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/BinaryFormat/MachO.h"
@@ -394,6 +395,46 @@ void AArch64MachObjectWriter::recordRelocation(
     Value = 0;
   }
 
+  if (Target.getRefKind() == AArch64MCExpr::VK_AUTH ||
+      Target.getRefKind() == AArch64MCExpr::VK_AUTHADDR) {
+    auto *Expr = cast<AArch64AuthMCExpr>(Fixup.getValue());
+
+    assert(Type == MachO::ARM64_RELOC_UNSIGNED);
+
+    if (IsPCRel) {
+      Asm.getContext().reportError(Fixup.getLoc(),
+                                   "invalid PC relative auth relocation");
+      return;
+    }
+
+    if (Log2Size != 3) {
+      Asm.getContext().reportError(
+          Fixup.getLoc(), "invalid auth relocation size, must be 8 bytes");
+      return;
+    }
+
+    if (Target.getSymB()) {
+      Asm.getContext().reportError(
+          Fixup.getLoc(),
+          "invalid auth relocation, can't reference two symbols");
+      return;
+    }
+
+    uint16_t Discriminator = Expr->getDiscriminator();
+    AArch64PACKey::ID Key = Expr->getKey();
+
+    if (!isInt<32>(Value)) {
+      Asm.getContext().reportError(Fixup.getLoc(),
+                                   "addend too big for relocation");
+      return;
+    }
+
+    Type = MachO::ARM64_RELOC_AUTHENTICATED_POINTER;
+    Value = (uint32_t(Value)) | (uint64_t(Discriminator) << 32) |
+            (uint64_t(Expr->hasAddressDiversity()) << 48) |
+            (uint64_t(Key) << 49) | (1ULL << 63);
+  }
+
   // If there's any addend left to handle, encode it in the instruction.
   FixedValue = Value;
 

diff  --git a/llvm/test/MC/AArch64/arm64e-authenticated-pointer-reloc.s b/llvm/test/MC/AArch64/arm64e-authenticated-pointer-reloc.s
new file mode 100644
index 00000000000000..04fa5098c4a3e2
--- /dev/null
+++ b/llvm/test/MC/AArch64/arm64e-authenticated-pointer-reloc.s
@@ -0,0 +1,119 @@
+// RUN: llvm-mc -triple=arm64-apple-darwin < %s | \
+// RUN:   FileCheck %s --check-prefix=ASM
+
+// RUN: llvm-mc -triple=arm64-apple-darwin -filetype=obj < %s | \
+// RUN:   llvm-readobj --expand-relocs --sections \
+// RUN:   --section-relocations --section-data - | \
+// RUN:   FileCheck %s --check-prefix=RELOC
+
+
+
+// RELOC:    Sections [
+// RELOC-LABEL: Section {
+// RELOC-LABEL: Section {
+// RELOC-NEXT:   Index: 1
+// RELOC-NEXT:   Name: __const (5F 5F 63 6F 6E 73 74 00 00 00 00 00 00 00 00 00)
+// RELOC-NEXT:   Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
+
+.section	__DATA,__const
+.p2align	3
+
+// RELOC-LABEL: Relocations [
+// RELOC-NEXT:   Relocation {
+// RELOC-NEXT:     Offset: 0x70
+// RELOC-NEXT:     PCRel: 0
+// RELOC-NEXT:     Length: 3
+// RELOC-NEXT:     Type: ARM64_RELOC_AUTHENTICATED_POINTER (11)
+// RELOC-NEXT:     Symbol: _g 7
+// RELOC-NEXT:   }
+// RELOC-NEXT:   Relocation {
+// RELOC-NEXT:     Offset: 0x60
+// RELOC-NEXT:     PCRel: 0
+// RELOC-NEXT:     Length: 3
+// RELOC-NEXT:     Type: ARM64_RELOC_AUTHENTICATED_POINTER (11)
+// RELOC-NEXT:     Symbol: _g 6
+// RELOC-NEXT:   }
+// RELOC-NEXT:   Relocation {
+// RELOC-NEXT:     Offset: 0x50
+// RELOC-NEXT:     PCRel: 0
+// RELOC-NEXT:     Length: 3
+// RELOC-NEXT:     Type: ARM64_RELOC_AUTHENTICATED_POINTER (11)
+// RELOC-NEXT:     Symbol: _g5
+// RELOC-NEXT:   }
+// RELOC-NEXT:   Relocation {
+// RELOC-NEXT:     Offset: 0x40
+// RELOC-NEXT:     PCRel: 0
+// RELOC-NEXT:     Length: 3
+// RELOC-NEXT:     Type: ARM64_RELOC_AUTHENTICATED_POINTER (11)
+// RELOC-NEXT:     Symbol: _g4
+// RELOC-NEXT:   }
+// RELOC-NEXT:   Relocation {
+// RELOC-NEXT:     Offset: 0x30
+// RELOC-NEXT:     PCRel: 0
+// RELOC-NEXT:     Length: 3
+// RELOC-NEXT:     Type: ARM64_RELOC_AUTHENTICATED_POINTER (11)
+// RELOC-NEXT:     Symbol: _g3
+// RELOC-NEXT:   }
+// RELOC-NEXT:   Relocation {
+// RELOC-NEXT:     Offset: 0x20
+// RELOC-NEXT:     PCRel: 0
+// RELOC-NEXT:     Length: 3
+// RELOC-NEXT:     Type: ARM64_RELOC_AUTHENTICATED_POINTER (11)
+// RELOC-NEXT:     Symbol: _g2
+// RELOC-NEXT:   }
+// RELOC-NEXT:   Relocation {
+// RELOC-NEXT:     Offset: 0x10
+// RELOC-NEXT:     PCRel: 0
+// RELOC-NEXT:     Length: 3
+// RELOC-NEXT:     Type: ARM64_RELOC_AUTHENTICATED_POINTER (11)
+// RELOC-NEXT:     Symbol: _g1
+// RELOC-NEXT:   }
+// RELOC-NEXT:   Relocation {
+// RELOC-NEXT:     Offset: 0x0
+// RELOC-NEXT:     PCRel: 0
+// RELOC-NEXT:     Length: 3
+// RELOC-NEXT:     Type: ARM64_RELOC_AUTHENTICATED_POINTER (11)
+// RELOC-NEXT:     Symbol: _g0
+// RELOC-NEXT:   }
+// RELOC-NEXT: ]
+// RELOC-NEXT: SectionData (
+
+// RELOC-NEXT:   0000: 00000000 2A000080
+// ASM:          .quad _g0 at AUTH(ia,42)
+.quad _g0 at AUTH(ia,42)
+.quad 0
+
+// RELOC-NEXT:   0010: 00000000 00000280
+// ASM:          .quad _g1 at AUTH(ib,0)
+.quad _g1 at AUTH(ib,0)
+.quad 0
+
+// RELOC-NEXT:   0020: 00000000 05000580
+// ASM:          .quad _g2 at AUTH(da,5,addr)
+.quad _g2 at AUTH(da,5,addr)
+.quad 0
+
+// RELOC-NEXT:   0030: 00000000 FFFF0780
+// ASM:          .quad _g3 at AUTH(db,65535,addr)
+.quad _g3 at AUTH(db,0xffff,addr)
+.quad 0
+
+// RELOC-NEXT:   0040: 07000000 00000080
+// ASM:          .quad (_g4+7)@AUTH(ia,0)
+.quad (_g4 + 7)@AUTH(ia,0)
+.quad 0
+
+// RELOC-NEXT:   0050: FDFFFFFF 00DE0280
+// ASM:          .quad (_g5-3)@AUTH(ib,56832)
+.quad (_g5 - 3)@AUTH(ib,0xde00)
+.quad 0
+
+// RELOC-NEXT:   0060: 00000000 FF000780
+// ASM:          .quad "_g 6"@AUTH(db,255,addr)
+.quad "_g 6"@AUTH(db,0xff,addr)
+.quad 0
+
+// RELOC-NEXT:   0070: 07000000 10000080
+// ASM:          .quad ("_g 7"+7)@AUTH(ia,16)
+.quad ("_g 7" + 7)@AUTH(ia,16)
+.quad 0


        


More information about the llvm-commits mailing list