Skip to content

Commit 46bb529

Browse files
sivan-shanitomtor
authored andcommitted
[lld] Refactor storage of PAuth ABI core info (llvm#141920)
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, aside from improved error messages.
1 parent d5856e5 commit 46bb529

File tree

7 files changed

+54
-25
lines changed

7 files changed

+54
-25
lines changed

lld/ELF/Arch/AArch64.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,8 +1043,7 @@ AArch64BtiPac::AArch64BtiPac(Ctx &ctx) : AArch64(ctx) {
10431043
// instructions.
10441044

10451045
if (ctx.arg.zPacPlt) {
1046-
if (llvm::any_of(ctx.aarch64PauthAbiCoreInfo,
1047-
[](uint8_t c) { return c != 0; }))
1046+
if (ctx.aarch64PauthAbiCoreInfo && ctx.aarch64PauthAbiCoreInfo->isValid())
10481047
pacEntryKind = PEK_Auth;
10491048
else
10501049
pacEntryKind = PEK_AuthHint;

lld/ELF/Config.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,23 @@ enum class GcsPolicy { Implicit, Never, Always };
139139
// For some options that resemble -z bti-report={none,warning,error}
140140
enum class ReportPolicy { None, Warning, Error };
141141

142+
// Describes the signing schema for a file using the PAuth ABI extension.
143+
// Two files are considered compatible when both `platform` and `version` match.
144+
// The pair (0, 0) is reserved to indicate incompatibility with the PAuth ABI.
145+
struct AArch64PauthAbiCoreInfo {
146+
uint64_t platform;
147+
uint64_t version;
148+
// Returns true if the core info is not the reserved (0, 0) value.
149+
bool isValid() const { return platform || version; }
150+
static constexpr size_t size() { return sizeof(platform) + sizeof(version); }
151+
bool operator==(const AArch64PauthAbiCoreInfo &other) const {
152+
return platform == other.platform && version == other.version;
153+
}
154+
bool operator!=(const AArch64PauthAbiCoreInfo &other) const {
155+
return !(*this == other);
156+
}
157+
};
158+
142159
struct SymbolVersion {
143160
llvm::StringRef name;
144161
bool isExternCpp;
@@ -699,7 +716,7 @@ struct Ctx : CommonLinkerContext {
699716

700717
llvm::raw_fd_ostream openAuxiliaryFile(llvm::StringRef, std::error_code &);
701718

702-
ArrayRef<uint8_t> aarch64PauthAbiCoreInfo;
719+
std::optional<AArch64PauthAbiCoreInfo> aarch64PauthAbiCoreInfo;
703720
};
704721

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

lld/ELF/Driver.cpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2857,15 +2857,15 @@ static void readSecurityNotes(Ctx &ctx) {
28572857
StringRef referenceFileName;
28582858
if (ctx.arg.emachine == EM_AARCH64) {
28592859
auto it = llvm::find_if(ctx.objectFiles, [](const ELFFileBase *f) {
2860-
return !f->aarch64PauthAbiCoreInfo.empty();
2860+
return f->aarch64PauthAbiCoreInfo.has_value();
28612861
});
28622862
if (it != ctx.objectFiles.end()) {
28632863
ctx.aarch64PauthAbiCoreInfo = (*it)->aarch64PauthAbiCoreInfo;
28642864
referenceFileName = (*it)->getName();
28652865
}
28662866
}
2867-
bool hasValidPauthAbiCoreInfo = llvm::any_of(
2868-
ctx.aarch64PauthAbiCoreInfo, [](uint8_t c) { return c != 0; });
2867+
bool hasValidPauthAbiCoreInfo =
2868+
ctx.aarch64PauthAbiCoreInfo && ctx.aarch64PauthAbiCoreInfo->isValid();
28692869

28702870
auto report = [&](ReportPolicy policy) -> ELFSyncStream {
28712871
return {ctx, toDiagLevel(policy)};
@@ -2952,10 +2952,10 @@ static void readSecurityNotes(Ctx &ctx) {
29522952
}
29532953
ctx.arg.andFeatures &= features;
29542954

2955-
if (ctx.aarch64PauthAbiCoreInfo.empty())
2955+
if (!ctx.aarch64PauthAbiCoreInfo)
29562956
continue;
29572957

2958-
if (f->aarch64PauthAbiCoreInfo.empty()) {
2958+
if (!f->aarch64PauthAbiCoreInfo) {
29592959
report(ctx.arg.zPauthReport)
29602960
<< f
29612961
<< ": -z pauth-report: file does not have AArch64 "
@@ -2965,11 +2965,18 @@ static void readSecurityNotes(Ctx &ctx) {
29652965
}
29662966

29672967
if (ctx.aarch64PauthAbiCoreInfo != f->aarch64PauthAbiCoreInfo)
2968-
Err(ctx) << "incompatible values of AArch64 PAuth core info found\n>>> "
2969-
<< referenceFileName << ": 0x"
2970-
<< toHex(ctx.aarch64PauthAbiCoreInfo, /*LowerCase=*/true)
2971-
<< "\n>>> " << f << ": 0x"
2972-
<< toHex(f->aarch64PauthAbiCoreInfo, /*LowerCase=*/true);
2968+
Err(ctx)
2969+
<< "incompatible values of AArch64 PAuth core info found\n"
2970+
<< "platform:\n"
2971+
<< ">>> " << referenceFileName << ": 0x"
2972+
<< toHex(ctx.aarch64PauthAbiCoreInfo->platform, /*LowerCase=*/true)
2973+
<< "\n>>> " << f << ": 0x"
2974+
<< toHex(f->aarch64PauthAbiCoreInfo->platform, /*LowerCase=*/true)
2975+
<< "\nversion:\n"
2976+
<< ">>> " << referenceFileName << ": 0x"
2977+
<< toHex(ctx.aarch64PauthAbiCoreInfo->version, /*LowerCase=*/true)
2978+
<< "\n>>> " << f << ": 0x"
2979+
<< toHex(f->aarch64PauthAbiCoreInfo->version, /*LowerCase=*/true);
29732980
}
29742981

29752982
// Force enable Shadow Stack.

lld/ELF/InputFiles.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -948,7 +948,7 @@ static void parseGnuPropertyNote(Ctx &ctx, ELFFileBase &f,
948948
} else if (ctx.arg.emachine == EM_AARCH64 &&
949949
type == GNU_PROPERTY_AARCH64_FEATURE_PAUTH) {
950950
ArrayRef<uint8_t> contents = data ? *data : desc;
951-
if (!f.aarch64PauthAbiCoreInfo.empty()) {
951+
if (f.aarch64PauthAbiCoreInfo) {
952952
return void(
953953
err(contents.data())
954954
<< "multiple GNU_PROPERTY_AARCH64_FEATURE_PAUTH entries are "
@@ -959,7 +959,9 @@ static void parseGnuPropertyNote(Ctx &ctx, ELFFileBase &f,
959959
"is invalid: expected 16 bytes, but got "
960960
<< size);
961961
}
962-
f.aarch64PauthAbiCoreInfo = desc;
962+
f.aarch64PauthAbiCoreInfo = {
963+
support::endian::read64<ELFT::Endianness>(&desc[0]),
964+
support::endian::read64<ELFT::Endianness>(&desc[8])};
963965
}
964966

965967
// 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: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -354,20 +354,20 @@ void GnuPropertySection::writeTo(uint8_t *buf) {
354354
offset += 16;
355355
}
356356

357-
if (!ctx.aarch64PauthAbiCoreInfo.empty()) {
357+
if (ctx.aarch64PauthAbiCoreInfo) {
358358
write32(ctx, buf + offset + 0, GNU_PROPERTY_AARCH64_FEATURE_PAUTH);
359-
write32(ctx, buf + offset + 4, ctx.aarch64PauthAbiCoreInfo.size());
360-
memcpy(buf + offset + 8, ctx.aarch64PauthAbiCoreInfo.data(),
361-
ctx.aarch64PauthAbiCoreInfo.size());
359+
write32(ctx, buf + offset + 4, AArch64PauthAbiCoreInfo::size());
360+
write64(ctx, buf + offset + 8, ctx.aarch64PauthAbiCoreInfo->platform);
361+
write64(ctx, buf + offset + 16, ctx.aarch64PauthAbiCoreInfo->version);
362362
}
363363
}
364364

365365
size_t GnuPropertySection::getSize() const {
366366
uint32_t contentSize = 0;
367367
if (ctx.arg.andFeatures != 0)
368368
contentSize += ctx.arg.is64 ? 16 : 12;
369-
if (!ctx.aarch64PauthAbiCoreInfo.empty())
370-
contentSize += 4 + 4 + ctx.aarch64PauthAbiCoreInfo.size();
369+
if (ctx.aarch64PauthAbiCoreInfo)
370+
contentSize += 4 + 4 + AArch64PauthAbiCoreInfo::size();
371371
assert(contentSize != 0);
372372
return contentSize + 16;
373373
}
@@ -4967,7 +4967,7 @@ template <class ELFT> void elf::createSyntheticSections(Ctx &ctx) {
49674967
ctx.in.iplt = std::make_unique<IpltSection>(ctx);
49684968
add(*ctx.in.iplt);
49694969

4970-
if (ctx.arg.andFeatures || !ctx.aarch64PauthAbiCoreInfo.empty()) {
4970+
if (ctx.arg.andFeatures || ctx.aarch64PauthAbiCoreInfo) {
49714971
ctx.in.gnuProperty = std::make_unique<GnuPropertySection>(ctx);
49724972
add(*ctx.in.gnuProperty);
49734973
}

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,12 @@
1313
# RUN: not ld.lld tag1.o tag1a.o tag2.o -o /dev/null 2>&1 | FileCheck --check-prefix ERR1 %s
1414

1515
# 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
16+
# ERR1-NEXT: platform:
17+
# ERR1-NEXT: >>> tag1.o: 0x2a
18+
# ERR1-NEXT: >>> tag2.o: 0x2a
19+
# ERR1-NEXT: version:
20+
# ERR1-NEXT: >>> tag1.o: 0x01
21+
# ERR1-NEXT: >>> tag2.o: 0x02
1822

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

0 commit comments

Comments
 (0)