[lld] [lld][GNU Properties] Refactor storage of PAuth ABI core info (PR #141785)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 29 02:37:21 PDT 2025
https://github.com/sivan-shani updated https://github.com/llvm/llvm-project/pull/141785
>From 2383795024326e8da8d123395497102db77010e5 Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Wed, 28 May 2025 13:01:27 +0100
Subject: [PATCH 1/2] [lld][GNU Properties] Refactor storage of PAuth ABI core
info
Previously, the AArch64 PAuth ABI core values were stored as an ArrayRef<uint8_t>,
introducing unnecessary indirection.
This patch replaces the ArrayRef with two explicit uint64_t fields:
aarch64PauthAbiPlatform and aarch64PauthAbiVersion. This simplifies the
representation and improves readability.
No functional change intended.
---
lld/ELF/Arch/AArch64.cpp | 5 ++--
lld/ELF/Config.h | 8 ++++-
lld/ELF/Driver.cpp | 45 ++++++++++++++++++++--------
lld/ELF/InputFiles.cpp | 8 +++--
lld/ELF/InputFiles.h | 2 +-
lld/ELF/SyntheticSections.cpp | 16 +++++-----
lld/test/ELF/aarch64-feature-pauth.s | 6 ++--
7 files changed, 62 insertions(+), 28 deletions(-)
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 9538dd4a70bae..3900712cf2312 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -1044,8 +1044,9 @@ AArch64BtiPac::AArch64BtiPac(Ctx &ctx) : AArch64(ctx) {
// instructions.
if (ctx.arg.zPacPlt) {
- if (llvm::any_of(ctx.aarch64PauthAbiCoreInfo,
- [](uint8_t c) { return c != 0; }))
+ if (ctx.aarch64PauthAbiCoreInfo.has_value() &&
+ (ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiPlatform != 0 ||
+ ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiVersion != 0))
pacEntryKind = PEK_Auth;
else
pacEntryKind = PEK_AuthHint;
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index f0e9592d85dd6..fcf56cd1d5edb 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -29,6 +29,7 @@
#include "llvm/Support/GlobPattern.h"
#include "llvm/Support/TarWriter.h"
#include <atomic>
+#include <cstdint>
#include <memory>
#include <mutex>
#include <optional>
@@ -139,6 +140,11 @@ enum class GcsPolicy { Implicit, Never, Always };
// For some options that resemble -z bti-report={none,warning,error}
enum class ReportPolicy { None, Warning, Error };
+struct AArch64PauthAbiCoreInfo {
+ uint64_t aarch64PauthAbiPlatform;
+ uint64_t aarch64PauthAbiVersion;
+};
+
struct SymbolVersion {
llvm::StringRef name;
bool isExternCpp;
@@ -695,7 +701,7 @@ struct Ctx : CommonLinkerContext {
llvm::raw_fd_ostream openAuxiliaryFile(llvm::StringRef, std::error_code &);
- ArrayRef<uint8_t> aarch64PauthAbiCoreInfo;
+ std::optional<AArch64PauthAbiCoreInfo> aarch64PauthAbiCoreInfo;
};
// The first two elements of versionDefinitions represent VER_NDX_LOCAL and
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 76a37b706c5fa..1ec409408515b 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -2841,15 +2841,21 @@ static void readSecurityNotes(Ctx &ctx) {
StringRef referenceFileName;
if (ctx.arg.emachine == EM_AARCH64) {
auto it = llvm::find_if(ctx.objectFiles, [](const ELFFileBase *f) {
- return !f->aarch64PauthAbiCoreInfo.empty();
+ return f->aarch64PauthAbiCoreInfo.has_value();
});
if (it != ctx.objectFiles.end()) {
- ctx.aarch64PauthAbiCoreInfo = (*it)->aarch64PauthAbiCoreInfo;
+ ctx.aarch64PauthAbiCoreInfo.emplace();
+ ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiPlatform =
+ (*it)->aarch64PauthAbiCoreInfo->aarch64PauthAbiPlatform;
+ ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiVersion =
+ (*it)->aarch64PauthAbiCoreInfo->aarch64PauthAbiVersion;
referenceFileName = (*it)->getName();
}
}
- bool hasValidPauthAbiCoreInfo = llvm::any_of(
- ctx.aarch64PauthAbiCoreInfo, [](uint8_t c) { return c != 0; });
+ bool hasValidPauthAbiCoreInfo =
+ ctx.aarch64PauthAbiCoreInfo.has_value() &&
+ (ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiPlatform != 0 ||
+ ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiVersion != 0);
auto report = [&](ReportPolicy policy) -> ELFSyncStream {
return {ctx, toDiagLevel(policy)};
@@ -2909,10 +2915,10 @@ static void readSecurityNotes(Ctx &ctx) {
}
ctx.arg.andFeatures &= features;
- if (ctx.aarch64PauthAbiCoreInfo.empty())
+ if (!ctx.aarch64PauthAbiCoreInfo)
continue;
- if (f->aarch64PauthAbiCoreInfo.empty()) {
+ if (!f->aarch64PauthAbiCoreInfo) {
report(ctx.arg.zPauthReport)
<< f
<< ": -z pauth-report: file does not have AArch64 "
@@ -2921,12 +2927,27 @@ static void readSecurityNotes(Ctx &ctx) {
continue;
}
- if (ctx.aarch64PauthAbiCoreInfo != f->aarch64PauthAbiCoreInfo)
- Err(ctx) << "incompatible values of AArch64 PAuth core info found\n>>> "
- << referenceFileName << ": 0x"
- << toHex(ctx.aarch64PauthAbiCoreInfo, /*LowerCase=*/true)
- << "\n>>> " << f << ": 0x"
- << toHex(f->aarch64PauthAbiCoreInfo, /*LowerCase=*/true);
+ if (ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiPlatform !=
+ f->aarch64PauthAbiCoreInfo->aarch64PauthAbiPlatform)
+ Err(ctx)
+ << "incompatible values of AArch64 PAuth Platform Values found\n>>> "
+ << referenceFileName << ": 0x"
+ << toHex(ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiPlatform,
+ /*LowerCase=*/true)
+ << "\n>>> " << f << ": 0x"
+ << toHex(f->aarch64PauthAbiCoreInfo->aarch64PauthAbiPlatform,
+ /*LowerCase=*/true);
+
+ if (ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiVersion !=
+ f->aarch64PauthAbiCoreInfo->aarch64PauthAbiVersion)
+ Err(ctx)
+ << "incompatible values of AArch64 PAuth Version Values found\n>>> "
+ << referenceFileName << ": 0x"
+ << toHex(ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiVersion,
+ /*LowerCase=*/true)
+ << "\n>>> " << f << ": 0x"
+ << toHex(f->aarch64PauthAbiCoreInfo->aarch64PauthAbiVersion,
+ /*LowerCase=*/true);
}
// Force enable Shadow Stack.
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 5f6d2b6b647ee..73ff437907066 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -950,7 +950,7 @@ static void parseGnuPropertyNote(Ctx &ctx, ELFFileBase &f,
} else if (ctx.arg.emachine == EM_AARCH64 &&
type == GNU_PROPERTY_AARCH64_FEATURE_PAUTH) {
ArrayRef<uint8_t> contents = data ? *data : desc;
- if (!f.aarch64PauthAbiCoreInfo.empty()) {
+ if (f.aarch64PauthAbiCoreInfo) {
return void(
err(contents.data())
<< "multiple GNU_PROPERTY_AARCH64_FEATURE_PAUTH entries are "
@@ -961,7 +961,11 @@ static void parseGnuPropertyNote(Ctx &ctx, ELFFileBase &f,
"is invalid: expected 16 bytes, but got "
<< size);
}
- f.aarch64PauthAbiCoreInfo = desc;
+ f.aarch64PauthAbiCoreInfo.emplace();
+ f.aarch64PauthAbiCoreInfo->aarch64PauthAbiPlatform =
+ support::endian::read64<ELFT::Endianness>(&desc[0]);
+ f.aarch64PauthAbiCoreInfo->aarch64PauthAbiVersion =
+ support::endian::read64<ELFT::Endianness>(&desc[8]);
}
// Padding is present in the note descriptor, if necessary.
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index 808cb5d24079f..ba844ad18f637 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -241,7 +241,7 @@ class ELFFileBase : public InputFile {
StringRef sourceFile;
uint32_t andFeatures = 0;
bool hasCommonSyms = false;
- ArrayRef<uint8_t> aarch64PauthAbiCoreInfo;
+ std::optional<AArch64PauthAbiCoreInfo> aarch64PauthAbiCoreInfo;
};
// .o file.
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 46591e909ba4f..f777bc20b8fcc 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -344,11 +344,13 @@ void GnuPropertySection::writeTo(uint8_t *buf) {
offset += 16;
}
- if (!ctx.aarch64PauthAbiCoreInfo.empty()) {
+ if (ctx.aarch64PauthAbiCoreInfo) {
write32(ctx, buf + offset + 0, GNU_PROPERTY_AARCH64_FEATURE_PAUTH);
- write32(ctx, buf + offset + 4, ctx.aarch64PauthAbiCoreInfo.size());
- memcpy(buf + offset + 8, ctx.aarch64PauthAbiCoreInfo.data(),
- ctx.aarch64PauthAbiCoreInfo.size());
+ write32(ctx, buf + offset + 4, sizeof(uint64_t) * 2);
+ write64(ctx, buf + offset + 8,
+ ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiPlatform);
+ write64(ctx, buf + offset + 16,
+ ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiVersion);
}
}
@@ -356,8 +358,8 @@ size_t GnuPropertySection::getSize() const {
uint32_t contentSize = 0;
if (ctx.arg.andFeatures != 0)
contentSize += ctx.arg.is64 ? 16 : 12;
- if (!ctx.aarch64PauthAbiCoreInfo.empty())
- contentSize += 4 + 4 + ctx.aarch64PauthAbiCoreInfo.size();
+ if (ctx.aarch64PauthAbiCoreInfo)
+ contentSize += 4 + 4 + sizeof(uint64_t) * 2;
assert(contentSize != 0);
return contentSize + 16;
}
@@ -4959,7 +4961,7 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
ctx.in.iplt = std::make_unique<IpltSection>(ctx);
add(*ctx.in.iplt);
- if (ctx.arg.andFeatures || !ctx.aarch64PauthAbiCoreInfo.empty()) {
+ if (ctx.arg.andFeatures || ctx.aarch64PauthAbiCoreInfo) {
ctx.in.gnuProperty = std::make_unique<GnuPropertySection>(ctx);
add(*ctx.in.gnuProperty);
}
diff --git a/lld/test/ELF/aarch64-feature-pauth.s b/lld/test/ELF/aarch64-feature-pauth.s
index bc58f69d32f2b..2dcc403cc4693 100644
--- a/lld/test/ELF/aarch64-feature-pauth.s
+++ b/lld/test/ELF/aarch64-feature-pauth.s
@@ -12,9 +12,9 @@
# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag2.s -o tag2.o
# RUN: not ld.lld tag1.o tag1a.o tag2.o -o /dev/null 2>&1 | FileCheck --check-prefix ERR1 %s
-# ERR1: error: incompatible values of AArch64 PAuth core info found
-# ERR1-NEXT: >>> tag1.o: 0x2a000000000000000{{1|2}}00000000000000
-# ERR1-NEXT: >>> tag2.o: 0x2a000000000000000{{1|2}}00000000000000
+# ERR1: error: incompatible values of AArch64 PAuth Version Values found
+# ERR1-NEXT: >>> tag1.o: 0x01
+# ERR1-NEXT: >>> tag2.o: 0x02
# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag-short.s -o short.o
# RUN: not ld.lld short.o -o /dev/null 2>&1 | FileCheck --check-prefix ERR2 %s
>From 7b4adcdd993e325207893459db2ea370cde60f2d Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Thu, 29 May 2025 10:37:06 +0100
Subject: [PATCH 2/2] std::optional can be assigned safely; no need for emplace
and separate field assignments
---
lld/ELF/Driver.cpp | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 1ec409408515b..0024df472e84a 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -2844,12 +2844,7 @@ static void readSecurityNotes(Ctx &ctx) {
return f->aarch64PauthAbiCoreInfo.has_value();
});
if (it != ctx.objectFiles.end()) {
- ctx.aarch64PauthAbiCoreInfo.emplace();
- ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiPlatform =
- (*it)->aarch64PauthAbiCoreInfo->aarch64PauthAbiPlatform;
- ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiVersion =
- (*it)->aarch64PauthAbiCoreInfo->aarch64PauthAbiVersion;
- referenceFileName = (*it)->getName();
+ ctx.aarch64PauthAbiCoreInfo = (*it)->aarch64PauthAbiCoreInfo;
}
}
bool hasValidPauthAbiCoreInfo =
More information about the llvm-commits
mailing list