-
Notifications
You must be signed in to change notification settings - Fork 12.3k
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
[AArch64][PAC][MC][ELF] Support PAuth ABI compatibility tag #85236
Conversation
Emit `GNU_PROPERTY_AARCH64_FEATURE_PAUTH` property in `.note.gnu.property` section depending on `aarch64-elf-pauthabi-platform` and `aarch64-elf-pauthabi-version` llvm module flags.
Buildkite job expectedly fails since the PR depends on #85235 unmerged yet |
@llvm/pr-subscribers-llvm-ir @llvm/pr-subscribers-backend-aarch64 Author: Daniil Kovalev (kovdan01) ChangesDepends on #85235 Emit Full diff: https://github.com/llvm/llvm-project/pull/85236.diff 4 Files Affected:
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index 4fa719ad67cf33..6f7d1548d09c76 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -268,13 +268,24 @@ void AArch64AsmPrinter::emitStartOfAsmFile(Module &M) {
if (Sign->getZExtValue())
Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
- if (Flags == 0)
- return;
+ uint64_t PAuthABIPlatform = -1;
+ if (const auto *PAP = mdconst::extract_or_null<ConstantInt>(
+ M.getModuleFlag("aarch64-elf-pauthabi-platform")))
+ PAuthABIPlatform = PAP->getZExtValue();
+ uint64_t PAuthABIVersion = -1;
+ if (const auto *PAV = mdconst::extract_or_null<ConstantInt>(
+ M.getModuleFlag("aarch64-elf-pauthabi-version")))
+ PAuthABIVersion = PAV->getZExtValue();
+
+ if ((PAuthABIPlatform == uint64_t(-1)) != (PAuthABIVersion == uint64_t(-1)))
+ report_fatal_error(
+ "either both or no 'aarch64-elf-pauthabi-platform' and "
+ "'aarch64-elf-pauthabi-version' module flags must be present");
// Emit a .note.gnu.property section with the flags.
auto *TS =
static_cast<AArch64TargetStreamer *>(OutStreamer->getTargetStreamer());
- TS->emitNoteSection(Flags);
+ TS->emitNoteSection(Flags, PAuthABIPlatform, PAuthABIVersion);
}
void AArch64AsmPrinter::emitFunctionHeaderComment() {
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
index e1d6dd7a056bce..dc5383ce941ed9 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
@@ -58,8 +58,17 @@ void AArch64TargetStreamer::finish() {
emitNoteSection(ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI);
}
-void AArch64TargetStreamer::emitNoteSection(unsigned Flags) {
- if (Flags == 0)
+void AArch64TargetStreamer::emitNoteSection(unsigned Flags,
+ uint64_t PAuthABIPlatform,
+ uint64_t PAuthABIVersion) {
+ assert((PAuthABIPlatform == uint64_t(-1)) ==
+ (PAuthABIVersion == uint64_t(-1)));
+ uint64_t DescSz = 0;
+ if (Flags != 0)
+ DescSz += 4 * 4;
+ if (PAuthABIPlatform != uint64_t(-1))
+ DescSz += 4 + 4 + 8 * 2;
+ if (DescSz == 0)
return;
MCStreamer &OutStreamer = getStreamer();
@@ -80,15 +89,25 @@ void AArch64TargetStreamer::emitNoteSection(unsigned Flags) {
// Emit the note header.
OutStreamer.emitValueToAlignment(Align(8));
OutStreamer.emitIntValue(4, 4); // data size for "GNU\0"
- OutStreamer.emitIntValue(4 * 4, 4); // Elf_Prop size
+ OutStreamer.emitIntValue(DescSz, 4); // Elf_Prop array size
OutStreamer.emitIntValue(ELF::NT_GNU_PROPERTY_TYPE_0, 4);
OutStreamer.emitBytes(StringRef("GNU", 4)); // note name
// Emit the PAC/BTI properties.
- OutStreamer.emitIntValue(ELF::GNU_PROPERTY_AARCH64_FEATURE_1_AND, 4);
- OutStreamer.emitIntValue(4, 4); // data size
- OutStreamer.emitIntValue(Flags, 4); // data
- OutStreamer.emitIntValue(0, 4); // pad
+ if (Flags != 0) {
+ OutStreamer.emitIntValue(ELF::GNU_PROPERTY_AARCH64_FEATURE_1_AND, 4);
+ OutStreamer.emitIntValue(4, 4); // data size
+ OutStreamer.emitIntValue(Flags, 4); // data
+ OutStreamer.emitIntValue(0, 4); // pad
+ }
+
+ // Emit the PAuth ABI compatibility info
+ if (PAuthABIPlatform != uint64_t(-1)) {
+ OutStreamer.emitIntValue(ELF::GNU_PROPERTY_AARCH64_FEATURE_PAUTH, 4);
+ OutStreamer.emitIntValue(8 * 2, 4); // data size
+ OutStreamer.emitIntValue(PAuthABIPlatform, 8);
+ OutStreamer.emitIntValue(PAuthABIVersion, 8);
+ }
OutStreamer.endSection(Nt);
OutStreamer.switchSection(Cur);
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
index 7676d88a82b5c7..e8a9dc445b96b1 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
@@ -35,7 +35,8 @@ class AArch64TargetStreamer : public MCTargetStreamer {
void emitCurrentConstantPool();
/// Callback used to implement the .note.gnu.property section.
- void emitNoteSection(unsigned Flags);
+ void emitNoteSection(unsigned Flags, uint64_t PAuthABIPlatform = -1,
+ uint64_t PAuthABIVersion = -1);
/// Callback used to implement the .inst directive.
virtual void emitInst(uint32_t Inst);
diff --git a/llvm/test/CodeGen/AArch64/note-gnu-property-elf-pauthabi.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-elf-pauthabi.ll
new file mode 100644
index 00000000000000..1eb6a2c7aceac3
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/note-gnu-property-elf-pauthabi.ll
@@ -0,0 +1,50 @@
+; RUN: rm -rf %t && split-file %s %t && cd %t
+
+;--- ok.ll
+
+; RUN: llc -mtriple=aarch64-linux ok.ll -o - | \
+; RUN: FileCheck %s --check-prefix=ASM
+; RUN: llc -mtriple=aarch64-linux ok.ll -filetype=obj -o - | \
+; RUN: llvm-readelf --notes - | FileCheck %s --check-prefix=OBJ
+
+!llvm.module.flags = !{!0, !1}
+
+!0 = !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+!1 = !{i32 1, !"aarch64-elf-pauthabi-version", i32 85}
+
+; ASM: .section .note.gnu.property,"a",@note
+; ASM-NEXT: .p2align 3, 0x0
+; ASM-NEXT: .word 4
+; ASM-NEXT: .word 24
+; ASM-NEXT: .word 5
+; ASM-NEXT: .asciz "GNU"
+; 3221225473 = 0xc0000001 = GNU_PROPERTY_AARCH64_FEATURE_PAUTH
+; ASM-NEXT: .word 3221225473
+; ASM-NEXT: .word 16
+; ASM-NEXT: .xword 268435458
+; ASM-NEXT: .xword 85
+
+; OBJ: Displaying notes found in: .note.gnu.property
+; OBJ-NEXT: Owner Data size Description
+; OBJ-NEXT: GNU 0x00000018 NT_GNU_PROPERTY_TYPE_0 (property note)
+; OBJ-NEXT: AArch64 PAuth ABI tag: platform 0x10000002 (llvm_linux), version 0x55 (PointerAuthIntrinsics, !PointerAuthCalls, PointerAuthReturns, !PointerAuthAuthTraps, PointerAuthVTPtrAddressDiscrimination, !PointerAuthVTPtrTypeDiscrimination, PointerAuthInitFini)
+
+; ERR: either both or no 'aarch64-elf-pauthabi-platform' and 'aarch64-elf-pauthabi-version' module flags must be present
+
+;--- err1.ll
+
+; RUN: not --crash llc -mtriple=aarch64-linux err1.ll 2>&1 -o - | \
+; RUN: FileCheck %s --check-prefix=ERR
+
+!llvm.module.flags = !{!0}
+
+!0 = !{i32 1, !"aarch64-elf-pauthabi-platform", i32 2}
+
+;--- err2.ll
+
+; RUN: not --crash llc -mtriple=aarch64-linux err2.ll 2>&1 -o - | \
+; RUN: FileCheck %s --check-prefix=ERR
+
+!llvm.module.flags = !{!0}
+
+!0 = !{i32 1, !"aarch64-elf-pauthabi-version", i32 31}
|
M.getModuleFlag("aarch64-elf-pauthabi-version"))) | ||
PAuthABIVersion = PAV->getZExtValue(); | ||
|
||
if ((PAuthABIPlatform == uint64_t(-1)) != (PAuthABIVersion == uint64_t(-1))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could this check be added to the verifier?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for suggestion, see ab89fdc
llvm/lib/IR/Verifier.cpp
Outdated
} | ||
|
||
if ((PAuthABIPlatform == uint64_t(-1)) != (PAuthABIVersion == uint64_t(-1))) | ||
report_fatal_error( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
report_fatal_error( | |
CheckFailed( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, thanks, see 2f6dc0a
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you consider adding a test for the verifier?
- Use `CheckFailed` instead of `report_fatal_error` in verifier - Add tests for verifier
@DanielKristofKiss Thanks for suggestion, see llvm/test/Verifier/module-flags-note-gnu-property-elf-pauthabi.ll added in 2f6dc0a |
✅ With the latest revision this PR passed the C/C++ code formatter. |
The buildkite failure is unrelated (tools/flang/unittests/Runtime/FlangRuntimeTests.exe fails on Windows), so merging |
Depends on #87545
Emit
GNU_PROPERTY_AARCH64_FEATURE_PAUTH
property in.note.gnu.property
section depending onaarch64-elf-pauthabi-platform
andaarch64-elf-pauthabi-version
llvm module flags.