Skip to content

Commit 25ee99e

Browse files
committed
[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.
1 parent dc25ab3 commit 25ee99e

File tree

7 files changed

+53
-25
lines changed

7 files changed

+53
-25
lines changed

lld/ELF/Arch/AArch64.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,8 +1044,9 @@ AArch64BtiPac::AArch64BtiPac(Ctx &ctx) : AArch64(ctx) {
10441044
// instructions.
10451045

10461046
if (ctx.arg.zPacPlt) {
1047-
if (llvm::any_of(ctx.aarch64PauthAbiCoreInfo,
1048-
[](uint8_t c) { return c != 0; }))
1047+
if (ctx.aarch64PauthAbiCoreInfo.has_value() &&
1048+
(ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiPlatform != 0 ||
1049+
ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiVersion != 0))
10491050
pacEntryKind = PEK_Auth;
10501051
else
10511052
pacEntryKind = PEK_AuthHint;

lld/ELF/Config.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "llvm/Support/GlobPattern.h"
3030
#include "llvm/Support/TarWriter.h"
3131
#include <atomic>
32+
#include <cstdint>
3233
#include <memory>
3334
#include <mutex>
3435
#include <optional>
@@ -139,6 +140,11 @@ enum class GcsPolicy { Implicit, Never, Always };
139140
// For some options that resemble -z bti-report={none,warning,error}
140141
enum class ReportPolicy { None, Warning, Error };
141142

143+
struct AArch64PauthAbiCoreInfo {
144+
uint64_t aarch64PauthAbiPlatform;
145+
uint64_t aarch64PauthAbiVersion;
146+
};
147+
142148
struct SymbolVersion {
143149
llvm::StringRef name;
144150
bool isExternCpp;
@@ -695,7 +701,7 @@ struct Ctx : CommonLinkerContext {
695701

696702
llvm::raw_fd_ostream openAuxiliaryFile(llvm::StringRef, std::error_code &);
697703

698-
ArrayRef<uint8_t> aarch64PauthAbiCoreInfo;
704+
std::optional<AArch64PauthAbiCoreInfo> aarch64PauthAbiCoreInfo;
699705
};
700706

701707
// The first two elements of versionDefinitions represent VER_NDX_LOCAL and

lld/ELF/Driver.cpp

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2841,15 +2841,17 @@ static void readSecurityNotes(Ctx &ctx) {
28412841
StringRef referenceFileName;
28422842
if (ctx.arg.emachine == EM_AARCH64) {
28432843
auto it = llvm::find_if(ctx.objectFiles, [](const ELFFileBase *f) {
2844-
return !f->aarch64PauthAbiCoreInfo.empty();
2844+
return f->aarch64PauthAbiCoreInfo.has_value();
28452845
});
28462846
if (it != ctx.objectFiles.end()) {
28472847
ctx.aarch64PauthAbiCoreInfo = (*it)->aarch64PauthAbiCoreInfo;
28482848
referenceFileName = (*it)->getName();
28492849
}
28502850
}
2851-
bool hasValidPauthAbiCoreInfo = llvm::any_of(
2852-
ctx.aarch64PauthAbiCoreInfo, [](uint8_t c) { return c != 0; });
2851+
bool hasValidPauthAbiCoreInfo =
2852+
ctx.aarch64PauthAbiCoreInfo.has_value() &&
2853+
(ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiPlatform != 0 ||
2854+
ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiVersion != 0);
28532855

28542856
auto report = [&](ReportPolicy policy) -> ELFSyncStream {
28552857
return {ctx, toDiagLevel(policy)};
@@ -2909,10 +2911,10 @@ static void readSecurityNotes(Ctx &ctx) {
29092911
}
29102912
ctx.arg.andFeatures &= features;
29112913

2912-
if (ctx.aarch64PauthAbiCoreInfo.empty())
2914+
if (!ctx.aarch64PauthAbiCoreInfo)
29132915
continue;
29142916

2915-
if (f->aarch64PauthAbiCoreInfo.empty()) {
2917+
if (!f->aarch64PauthAbiCoreInfo) {
29162918
report(ctx.arg.zPauthReport)
29172919
<< f
29182920
<< ": -z pauth-report: file does not have AArch64 "
@@ -2921,12 +2923,25 @@ static void readSecurityNotes(Ctx &ctx) {
29212923
continue;
29222924
}
29232925

2924-
if (ctx.aarch64PauthAbiCoreInfo != f->aarch64PauthAbiCoreInfo)
2925-
Err(ctx) << "incompatible values of AArch64 PAuth core info found\n>>> "
2926+
if (ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiPlatform !=
2927+
f->aarch64PauthAbiCoreInfo->aarch64PauthAbiPlatform)
2928+
Err(ctx) << "incompatible AArch64 PAuth Platform Values\n>>> "
29262929
<< referenceFileName << ": 0x"
2927-
<< toHex(ctx.aarch64PauthAbiCoreInfo, /*LowerCase=*/true)
2930+
<< toHex(ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiPlatform,
2931+
/*LowerCase=*/true)
29282932
<< "\n>>> " << f << ": 0x"
2929-
<< toHex(f->aarch64PauthAbiCoreInfo, /*LowerCase=*/true);
2933+
<< toHex(f->aarch64PauthAbiCoreInfo->aarch64PauthAbiPlatform,
2934+
/*LowerCase=*/true);
2935+
2936+
if (ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiVersion !=
2937+
f->aarch64PauthAbiCoreInfo->aarch64PauthAbiVersion)
2938+
Err(ctx) << "incompatible AArch64 PAuth Version Values\n>>> "
2939+
<< referenceFileName << ": 0x"
2940+
<< toHex(ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiVersion,
2941+
/*LowerCase=*/true)
2942+
<< "\n>>> " << f << ": 0x"
2943+
<< toHex(f->aarch64PauthAbiCoreInfo->aarch64PauthAbiVersion,
2944+
/*LowerCase=*/true);
29302945
}
29312946

29322947
// Force enable Shadow Stack.

lld/ELF/InputFiles.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,7 @@ static void parseGnuPropertyNote(Ctx &ctx, ELFFileBase &f,
950950
} else if (ctx.arg.emachine == EM_AARCH64 &&
951951
type == GNU_PROPERTY_AARCH64_FEATURE_PAUTH) {
952952
ArrayRef<uint8_t> contents = data ? *data : desc;
953-
if (!f.aarch64PauthAbiCoreInfo.empty()) {
953+
if (f.aarch64PauthAbiCoreInfo) {
954954
return void(
955955
err(contents.data())
956956
<< "multiple GNU_PROPERTY_AARCH64_FEATURE_PAUTH entries are "
@@ -961,7 +961,11 @@ static void parseGnuPropertyNote(Ctx &ctx, ELFFileBase &f,
961961
"is invalid: expected 16 bytes, but got "
962962
<< size);
963963
}
964-
f.aarch64PauthAbiCoreInfo = desc;
964+
f.aarch64PauthAbiCoreInfo.emplace();
965+
f.aarch64PauthAbiCoreInfo->aarch64PauthAbiPlatform =
966+
support::endian::read64<ELFT::Endianness>(&desc[0]);
967+
f.aarch64PauthAbiCoreInfo->aarch64PauthAbiVersion =
968+
support::endian::read64<ELFT::Endianness>(&desc[8]);
965969
}
966970

967971
// Padding is present in the note descriptor, if necessary.

lld/ELF/InputFiles.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ class ELFFileBase : public InputFile {
241241
StringRef sourceFile;
242242
uint32_t andFeatures = 0;
243243
bool hasCommonSyms = false;
244-
ArrayRef<uint8_t> aarch64PauthAbiCoreInfo;
244+
std::optional<AArch64PauthAbiCoreInfo> aarch64PauthAbiCoreInfo;
245245
};
246246

247247
// .o file.

lld/ELF/SyntheticSections.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -344,20 +344,22 @@ void GnuPropertySection::writeTo(uint8_t *buf) {
344344
offset += 16;
345345
}
346346

347-
if (!ctx.aarch64PauthAbiCoreInfo.empty()) {
347+
if (ctx.aarch64PauthAbiCoreInfo) {
348348
write32(ctx, buf + offset + 0, GNU_PROPERTY_AARCH64_FEATURE_PAUTH);
349-
write32(ctx, buf + offset + 4, ctx.aarch64PauthAbiCoreInfo.size());
350-
memcpy(buf + offset + 8, ctx.aarch64PauthAbiCoreInfo.data(),
351-
ctx.aarch64PauthAbiCoreInfo.size());
349+
write32(ctx, buf + offset + 4, sizeof(uint64_t) * 2);
350+
write64(ctx, buf + offset + 8,
351+
ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiPlatform);
352+
write64(ctx, buf + offset + 16,
353+
ctx.aarch64PauthAbiCoreInfo->aarch64PauthAbiVersion);
352354
}
353355
}
354356

355357
size_t GnuPropertySection::getSize() const {
356358
uint32_t contentSize = 0;
357359
if (ctx.arg.andFeatures != 0)
358360
contentSize += ctx.arg.is64 ? 16 : 12;
359-
if (!ctx.aarch64PauthAbiCoreInfo.empty())
360-
contentSize += 4 + 4 + ctx.aarch64PauthAbiCoreInfo.size();
361+
if (ctx.aarch64PauthAbiCoreInfo)
362+
contentSize += 4 + 4 + sizeof(uint64_t) * 2;
361363
assert(contentSize != 0);
362364
return contentSize + 16;
363365
}
@@ -4959,7 +4961,7 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
49594961
ctx.in.iplt = std::make_unique<IpltSection>(ctx);
49604962
add(*ctx.in.iplt);
49614963

4962-
if (ctx.arg.andFeatures || !ctx.aarch64PauthAbiCoreInfo.empty()) {
4964+
if (ctx.arg.andFeatures || ctx.aarch64PauthAbiCoreInfo) {
49634965
ctx.in.gnuProperty = std::make_unique<GnuPropertySection>(ctx);
49644966
add(*ctx.in.gnuProperty);
49654967
}

lld/test/ELF/aarch64-feature-pauth.s

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag2.s -o tag2.o
1313
# RUN: not ld.lld tag1.o tag1a.o tag2.o -o /dev/null 2>&1 | FileCheck --check-prefix ERR1 %s
1414

15-
# ERR1: error: incompatible values of AArch64 PAuth core info found
16-
# ERR1-NEXT: >>> tag1.o: 0x2a000000000000000{{1|2}}00000000000000
17-
# ERR1-NEXT: >>> tag2.o: 0x2a000000000000000{{1|2}}00000000000000
15+
# ERR1: error: incompatible AArch64 PAuth Version Values
16+
# ERR1-NEXT: >>> tag1.o: 0x01
17+
# ERR1-NEXT: >>> tag2.o: 0x02
1818

1919
# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag-short.s -o short.o
2020
# RUN: not ld.lld short.o -o /dev/null 2>&1 | FileCheck --check-prefix ERR2 %s

0 commit comments

Comments
 (0)