Skip to content
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

[lld][AArch64][ELF][PAC] Support AUTH relocations and AUTH ELF marking #72714

Merged
merged 45 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
c493d78
[lld][AArch64][ELF][PAC] Support AUTH relocations and AUTH ELF marking
kovdan01 Sep 28, 2023
589c645
Address trivial review comments
kovdan01 Dec 12, 2023
a021f15
Merge branch 'main' into pauth-lld-20240109
kovdan01 Jan 9, 2024
d341159
Use `pack-relative-relocs` for both regular and auth relr relocs
kovdan01 Jan 9, 2024
b791da9
Rename aarch64-ptrauth.s to aarch64-reloc-pauth.s
kovdan01 Jan 9, 2024
b95dcf8
Remove unneeded test directives
kovdan01 Jan 9, 2024
594f8a0
Do not emit AUTH relocations in read-only sections
kovdan01 Jan 11, 2024
d793c0c
Merge branch 'main' into pauth-lld
kovdan01 Jan 27, 2024
acb1730
Apply fix from 37efa70 accidently deleted in d793c0c
kovdan01 Jan 31, 2024
de73eae
Address review comments
kovdan01 Jan 31, 2024
321a6a9
Merge branch 'main' into pauth-lld
kovdan01 Feb 15, 2024
aff3a96
Address several review comments
kovdan01 Feb 15, 2024
4e53afa
Address several review comments
kovdan01 Feb 15, 2024
ec1c632
Address review comments
kovdan01 Feb 17, 2024
2136ad1
Simplify RelocationScanner::processAux
MaskRay Feb 20, 2024
9ea8c5c
Fix error message in a read-only section when the symbol is local
MaskRay Feb 20, 2024
e3a64d2
Simplify aarch64-reloc-pauth.s
MaskRay Feb 20, 2024
865c983
Force dynamic relocation in -no-pie mode
MaskRay Feb 20, 2024
1448a4a
Address the following review comments:
kovdan01 Feb 27, 2024
203f61e
Use `relocs` instead of `relocsVec` inside `lock(relocMutex)` scope
kovdan01 Feb 28, 2024
1b8c52b
Allow arbitrary offset for dynamic section: no need to rely on it in …
kovdan01 Feb 28, 2024
e9b5337
Fix relocs with wide addends for non-preemptible symbols
kovdan01 Feb 28, 2024
aec9155
Merge branch 'main' into pauth-lld
kovdan01 Mar 8, 2024
b215b0d
Address review comments
kovdan01 Mar 8, 2024
90dbcf4
Merge branch 'main' into pauth-lld
kovdan01 Mar 18, 2024
d32b8e3
Address some review comments
kovdan01 Mar 18, 2024
978ed06
Use `.note.gnu.property` instead of `.note.AARCH64-PAUTH-ABI-tag`
kovdan01 Mar 18, 2024
ec04d8c
Merge branch 'main' into pauth-lld-new
kovdan01 Mar 19, 2024
728c933
Rename PAuth ABI Tag to PAuth ABI Core Info
kovdan01 Mar 19, 2024
4409838
Update comments
kovdan01 Mar 19, 2024
128831c
Rename PAuth ABI compatibility info to PAuth ABI core info
kovdan01 Mar 19, 2024
83eddae
Merge branch 'main' into pauth-lld & resolve conflict after 691b97c88…
kovdan01 Mar 25, 2024
08c749d
Merge branch 'main' into pauth-lld & fix conflict after 276335389133d…
kovdan01 Mar 29, 2024
e4a37a6
Merge branch 'main' into pauth-lld
kovdan01 Apr 2, 2024
05cf361
Delete RELR-related changes
kovdan01 Apr 2, 2024
eb02b6a
Merge branch 'main' into pauth-lld
kovdan01 Apr 3, 2024
f459527
Simplify a short/long message with just "invalid"
MaskRay Apr 3, 2024
2846e76
[test] add --implicit-check-not=error and avoid expensive .* regex
MaskRay Apr 3, 2024
45fcbb9
add release note
MaskRay Apr 3, 2024
0eb272a
Mention `R_AARCH64_AUTH_RELATIVE` in release notes
kovdan01 Apr 3, 2024
964e9fe
Add `-z pauth-report` description to lld's man page
kovdan01 Apr 3, 2024
2e8ec83
Remove unneeded blank line
kovdan01 Apr 3, 2024
99df511
Update test run line for `-z pauth-report`
kovdan01 Apr 3, 2024
b6e0e28
Merge branch 'main' into pauth-lld
kovdan01 Apr 4, 2024
cbc380a
Add single quotes around `referenceFileName`
kovdan01 Apr 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lld/ELF/Arch/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
case R_AARCH64_MOVW_UABS_G2_NC:
case R_AARCH64_MOVW_UABS_G3:
return R_ABS;
case R_AARCH64_AUTH_ABS64:
return R_AARCH64_AUTH;
case R_AARCH64_TLSDESC_ADR_PAGE21:
return R_AARCH64_TLSDESC_PAGE;
case R_AARCH64_TLSDESC_LD64_LO12:
Expand Down Expand Up @@ -204,7 +206,7 @@ bool AArch64::usesOnlyLowPageBits(RelType type) const {
}

RelType AArch64::getDynRel(RelType type) const {
if (type == R_AARCH64_ABS64)
if (type == R_AARCH64_ABS64 || type == R_AARCH64_AUTH_ABS64)
return type;
return R_AARCH64_NONE;
}
Expand Down
3 changes: 3 additions & 0 deletions lld/ELF/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ struct Config {
llvm::StringRef cmseOutputLib;
StringRef zBtiReport = "none";
StringRef zCetReport = "none";
StringRef zPauthReport = "none";
bool ltoBBAddrMap;
llvm::StringRef ltoBasicBlockSections;
std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;
Expand Down Expand Up @@ -499,6 +500,8 @@ struct Ctx {
void reset();

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

ArrayRef<uint8_t> aarch64PauthAbiCoreInfo;
};

LLVM_LIBRARY_VISIBILITY extern Ctx ctx;
Expand Down
70 changes: 55 additions & 15 deletions lld/ELF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "lld/Common/Strings.h"
#include "lld/Common/TargetOptionsCommandFlags.h"
#include "lld/Common/Version.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
Expand Down Expand Up @@ -461,6 +462,8 @@ static void checkOptions() {
error("-z force-bti only supported on AArch64");
if (config->zBtiReport != "none")
error("-z bti-report only supported on AArch64");
if (config->zPauthReport != "none")
error("-z pauth-report only supported on AArch64");
MaskRay marked this conversation as resolved.
Show resolved Hide resolved
}

if (config->emachine != EM_386 && config->emachine != EM_X86_64 &&
Expand Down Expand Up @@ -1501,7 +1504,8 @@ static void readConfigs(opt::InputArgList &args) {
}

auto reports = {std::make_pair("bti-report", &config->zBtiReport),
std::make_pair("cet-report", &config->zCetReport)};
std::make_pair("cet-report", &config->zCetReport),
std::make_pair("pauth-report", &config->zPauthReport)};
for (opt::Arg *arg : args.filtered(OPT_z)) {
std::pair<StringRef, StringRef> option =
StringRef(arg->getValue()).split('=');
Expand Down Expand Up @@ -2599,14 +2603,17 @@ static void redirectSymbols(ArrayRef<WrappedSymbol> wrapped) {
symtab.wrap(w.sym, w.real, w.wrap);
}

static void reportMissingFeature(StringRef config, const Twine &report) {
if (config == "error")
error(report);
else if (config == "warning")
warn(report);
}

static void checkAndReportMissingFeature(StringRef config, uint32_t features,
uint32_t mask, const Twine &report) {
if (!(features & mask)) {
if (config == "error")
error(report);
else if (config == "warning")
warn(report);
}
if (!(features & mask))
reportMissingFeature(config, report);
}

// To enable CET (x86's hardware-assisted control flow enforcement), each
Expand All @@ -2617,12 +2624,28 @@ static void checkAndReportMissingFeature(StringRef config, uint32_t features,
//
// This is also the case with AARCH64's BTI and PAC which use the similar
// GNU_PROPERTY_AARCH64_FEATURE_1_AND mechanism.
static uint32_t getAndFeatures() {
//
// For AArch64 PAuth-enabled object files, the core info of all of them must
// match. Missing info for some object files with matching info for remaining
// ones can be allowed (see -z pauth-report).
static void readSecurityNotes() {
if (config->emachine != EM_386 && config->emachine != EM_X86_64 &&
config->emachine != EM_AARCH64)
return 0;
return;

config->andFeatures = -1;

StringRef referenceFileName;
Copy link
Member

@MaskRay MaskRay Apr 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This loop tries to find a reference filename, but the loop can be removed.

Consider cherry picking the simplification at https://github.com/maskray/llvm-project/tree/lld-pauth ? The branch assumes that #87434 is brought back.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This actually can't be removed - try to change files order in corresponding lld run lines in test/ELF/aarch64-feature-pauth.s from tag1.o noinfo1.o noinfo2.o to noinfo1.o tag1.o noinfo2.o, and you'll get an error. I'll submitted this update - see 99df511.

Explanation: if there are some files w/o PAuth core info which are processed before file with it, we'll never get a corresponding warning/error which we expect when enable -z pauth-report=warning|error. That's why it's crucial to find a file with PAuth core info first (if any), and then check others against it.

Please let me know if I miss something and there is a room for simplification even given the case above.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, and thanks for the test improvement.

Add single quotes around referenceFileName and this patch LGTM!

if (config->emachine == EM_AARCH64) {
auto it = llvm::find_if(ctx.objectFiles, [](const ELFFileBase *f) {
return !f->aarch64PauthAbiCoreInfo.empty();
});
if (it != ctx.objectFiles.end()) {
ctx.aarch64PauthAbiCoreInfo = (*it)->aarch64PauthAbiCoreInfo;
referenceFileName = (*it)->getName();
}
}

uint32_t ret = -1;
for (ELFFileBase *f : ctx.objectFiles) {
uint32_t features = f->andFeatures;

Expand Down Expand Up @@ -2658,14 +2681,31 @@ static uint32_t getAndFeatures() {
"GNU_PROPERTY_AARCH64_FEATURE_1_PAC property");
features |= GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
}
ret &= features;
config->andFeatures &= features;

if (ctx.aarch64PauthAbiCoreInfo.empty())
continue;

if (f->aarch64PauthAbiCoreInfo.empty()) {
reportMissingFeature(config->zPauthReport,
toString(f) +
": -z pauth-report: file does not have AArch64 "
"PAuth core info while " +
referenceFileName + " has one");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

single quotes around referenceFileName

(We place single quotes around an identifier when it is placed beside a non-identifier word.)

continue;
}

if (ctx.aarch64PauthAbiCoreInfo != f->aarch64PauthAbiCoreInfo)
errorOrWarn("incompatible values of AArch64 PAuth core info found\n>>> " +
referenceFileName + ": 0x" +
toHex(ctx.aarch64PauthAbiCoreInfo, /*LowerCase=*/true) +
"\n>>> " + toString(f) + ": 0x" +
toHex(f->aarch64PauthAbiCoreInfo, /*LowerCase=*/true));
}

// Force enable Shadow Stack.
if (config->zShstk)
ret |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;

return ret;
config->andFeatures |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
}

static void initSectionsAndLocalSyms(ELFFileBase *file, bool ignoreComdats) {
Expand Down Expand Up @@ -2944,7 +2984,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {

// Read .note.gnu.property sections from input object files which
// contain a hint to tweak linker's and loader's behaviors.
config->andFeatures = getAndFeatures();
readSecurityNotes();

// The Target instance handles target-specific stuff, such as applying
// relocations or writing a PLT section. It also contains target-dependent
Expand Down
41 changes: 22 additions & 19 deletions lld/ELF/InputFiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -926,25 +926,18 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
handleSectionGroup<ELFT>(this->sections, entries);
}

// If a source file is compiled with x86 hardware-assisted call flow control
// enabled, the generated object file contains feature flags indicating that
// fact. This function reads the feature flags and returns it.
//
// Essentially we want to read a single 32-bit value in this function, but this
// function is rather complicated because the value is buried deep inside a
// .note.gnu.property section.
//
// The section consists of one or more NOTE records. Each NOTE record consists
// of zero or more type-length-value fields. We want to find a field of a
// certain type. It seems a bit too much to just store a 32-bit value, perhaps
// the ABI is unnecessarily complicated.
template <class ELFT> static uint32_t readAndFeatures(const InputSection &sec) {
// Read the following info from the .note.gnu.property section and write it to
// the corresponding fields in `ObjFile`:
// - Feature flags (32 bits) representing x86 or AArch64 features for
// hardware-assisted call flow control;
// - AArch64 PAuth ABI core info (16 bytes).
template <class ELFT>
void readGnuProperty(const InputSection &sec, ObjFile<ELFT> &f) {
using Elf_Nhdr = typename ELFT::Nhdr;
using Elf_Note = typename ELFT::Note;

uint32_t featuresSet = 0;
ArrayRef<uint8_t> data = sec.content();
auto reportFatal = [&](const uint8_t *place, const char *msg) {
auto reportFatal = [&](const uint8_t *place, const Twine &msg) {
fatal(toString(sec.file) + ":(" + sec.name + "+0x" +
Twine::utohexstr(place - sec.content().data()) + "): " + msg);
};
Expand Down Expand Up @@ -983,7 +976,19 @@ template <class ELFT> static uint32_t readAndFeatures(const InputSection &sec) {
// accumulate the bits set.
if (size < 4)
reportFatal(place, "FEATURE_1_AND entry is too short");
featuresSet |= read32<ELFT::Endianness>(desc.data());
f.andFeatures |= read32<ELFT::Endianness>(desc.data());
} else if (config->emachine == EM_AARCH64 &&
type == GNU_PROPERTY_AARCH64_FEATURE_PAUTH) {
if (!f.aarch64PauthAbiCoreInfo.empty()) {
reportFatal(data.data(),
"multiple GNU_PROPERTY_AARCH64_FEATURE_PAUTH entries are "
"not supported");
} else if (size != 16) {
reportFatal(data.data(), "GNU_PROPERTY_AARCH64_FEATURE_PAUTH entry "
"is invalid: expected 16 bytes, but got " +
Twine(size));
}
f.aarch64PauthAbiCoreInfo = desc;
}

// Padding is present in the note descriptor, if necessary.
Expand All @@ -993,8 +998,6 @@ template <class ELFT> static uint32_t readAndFeatures(const InputSection &sec) {
// Go to next NOTE record to look for more FEATURE_1_AND descriptions.
data = data.slice(nhdr->getSize(sec.addralign));
}

return featuresSet;
}

template <class ELFT>
Expand Down Expand Up @@ -1051,7 +1054,7 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
// .note.gnu.property containing a single AND'ed bitmap, we discard an input
// file's .note.gnu.property section.
if (name == ".note.gnu.property") {
this->andFeatures = readAndFeatures<ELFT>(InputSection(*this, sec, name));
readGnuProperty<ELFT>(InputSection(*this, sec, name), *this);
return &InputSection::discarded;
}

Expand Down
1 change: 1 addition & 0 deletions lld/ELF/InputFiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ class ELFFileBase : public InputFile {
public:
uint32_t andFeatures = 0;
bool hasCommonSyms = false;
ArrayRef<uint8_t> aarch64PauthAbiCoreInfo;
};

// .o file.
Expand Down
1 change: 1 addition & 0 deletions lld/ELF/InputSection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,7 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type,
case R_DTPREL:
case R_RELAX_TLS_LD_TO_LE_ABS:
case R_RELAX_GOT_PC_NOPIC:
case R_AARCH64_AUTH:
case R_RISCV_ADD:
case R_RISCV_LEB128:
return sym.getVA(a);
Expand Down
28 changes: 23 additions & 5 deletions lld/ELF/Relocations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -995,7 +995,8 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
if (e == R_GOT || e == R_PLT)
return target->usesOnlyLowPageBits(type) || !config->isPic;

if (sym.isPreemptible)
// R_AARCH64_AUTH_ABS64 requires a dynamic relocation.
if (sym.isPreemptible || e == R_AARCH64_AUTH)
return false;
if (!config->isPic)
return true;
Expand Down Expand Up @@ -1141,12 +1142,26 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
(rel == target->symbolicRel && !sym.isPreemptible)) {
addRelativeReloc<true>(*sec, offset, sym, addend, expr, type);
return;
} else if (rel != 0) {
}
if (rel != 0) {
if (config->emachine == EM_MIPS && rel == target->symbolicRel)
rel = target->relativeRel;
std::lock_guard<std::mutex> lock(relocMutex);
sec->getPartition().relaDyn->addSymbolReloc(rel, *sec, offset, sym,
addend, type);
Partition &part = sec->getPartition();
if (config->emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64) {
// For a preemptible symbol, we can't use a relative relocation. For an
// undefined symbol, we can't compute offset at link-time and use a
// relative relocation. Use a symbolic relocation instead.
if (sym.isPreemptible) {
part.relaDyn->addSymbolReloc(type, *sec, offset, sym, addend, type);
} else {
part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, sec, offset,
DynamicReloc::AddendOnlyWithTargetVA, sym,
addend, R_ABS});
}
return;
}
part.relaDyn->addSymbolReloc(rel, *sec, offset, sym, addend, type);

// MIPS ABI turns using of GOT and dynamic relocations inside out.
// While regular ABI uses dynamic relocations to fill up GOT entries
Expand All @@ -1171,7 +1186,10 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,

// When producing an executable, we can perform copy relocations (for
// STT_OBJECT) and canonical PLT (for STT_FUNC) if sym is defined by a DSO.
if (!config->shared && sym.isShared()) {
// Copy relocations/canonical PLT entries are unsupported for
// R_AARCH64_AUTH_ABS64.
if (!config->shared && sym.isShared() &&
!(config->emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64)) {
if (!canDefineSymbolInExecutable(sym)) {
errorOrWarn("cannot preempt symbol: " + toString(sym) +
getLocation(*sec, sym, offset));
Expand Down
1 change: 1 addition & 0 deletions lld/ELF/Relocations.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ enum RelExpr {
R_AARCH64_PAGE_PC,
R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC,
R_AARCH64_TLSDESC_PAGE,
R_AARCH64_AUTH,
R_ARM_PCA,
R_ARM_SBREL,
R_MIPS_GOTREL,
Expand Down
40 changes: 30 additions & 10 deletions lld/ELF/SyntheticSections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,22 +314,42 @@ GnuPropertySection::GnuPropertySection()
config->wordsize, ".note.gnu.property") {}

void GnuPropertySection::writeTo(uint8_t *buf) {
write32(buf, 4); // Name size
write32(buf + 4, getSize() - 16); // Content size
write32(buf + 8, NT_GNU_PROPERTY_TYPE_0); // Type
memcpy(buf + 12, "GNU", 4); // Name string

uint32_t featureAndType = config->emachine == EM_AARCH64
? GNU_PROPERTY_AARCH64_FEATURE_1_AND
: GNU_PROPERTY_X86_FEATURE_1_AND;

write32(buf, 4); // Name size
write32(buf + 4, config->is64 ? 16 : 12); // Content size
write32(buf + 8, NT_GNU_PROPERTY_TYPE_0); // Type
memcpy(buf + 12, "GNU", 4); // Name string
write32(buf + 16, featureAndType); // Feature type
write32(buf + 20, 4); // Feature size
write32(buf + 24, config->andFeatures); // Feature flags
if (config->is64)
write32(buf + 28, 0); // Padding
unsigned offset = 16;
if (config->andFeatures != 0) {
write32(buf + offset + 0, featureAndType); // Feature type
write32(buf + offset + 4, 4); // Feature size
write32(buf + offset + 8, config->andFeatures); // Feature flags
if (config->is64)
write32(buf + offset + 12, 0); // Padding
offset += 16;
}

if (!ctx.aarch64PauthAbiCoreInfo.empty()) {
write32(buf + offset + 0, GNU_PROPERTY_AARCH64_FEATURE_PAUTH);
write32(buf + offset + 4, ctx.aarch64PauthAbiCoreInfo.size());
memcpy(buf + offset + 8, ctx.aarch64PauthAbiCoreInfo.data(),
ctx.aarch64PauthAbiCoreInfo.size());
}
}

size_t GnuPropertySection::getSize() const { return config->is64 ? 32 : 28; }
size_t GnuPropertySection::getSize() const {
uint32_t contentSize = 0;
if (config->andFeatures != 0)
contentSize += config->is64 ? 16 : 12;
if (!ctx.aarch64PauthAbiCoreInfo.empty())
contentSize += 4 + 4 + ctx.aarch64PauthAbiCoreInfo.size();
assert(contentSize != 0);
return contentSize + 16;
}

BuildIdSection::BuildIdSection()
: SyntheticSection(SHF_ALLOC, SHT_NOTE, 4, ".note.gnu.build-id"),
Expand Down
3 changes: 2 additions & 1 deletion lld/ELF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "lld/Common/CommonLinkerContext.h"
#include "lld/Common/Filesystem.h"
#include "lld/Common/Strings.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/BLAKE3.h"
#include "llvm/Support/Parallel.h"
Expand Down Expand Up @@ -564,7 +565,7 @@ template <class ELFT> void elf::createSyntheticSections() {
in.iplt = std::make_unique<IpltSection>();
add(*in.iplt);

if (config->andFeatures)
if (config->andFeatures || !ctx.aarch64PauthAbiCoreInfo.empty())
add(*make<GnuPropertySection>());

// .note.GNU-stack is always added when we are creating a re-linkable
Expand Down
3 changes: 3 additions & 0 deletions lld/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ ELF Improvements
* ``--compress-sections <section-glib>=[none|zlib|zstd]`` is added to compress
matched output sections without the ``SHF_ALLOC`` flag.
(`#84855 <https://github.com/llvm/llvm-project/pull/84855>`_)
* ``GNU_PROPERTY_AARCH64_FEATURE_PAUTH`` notes, ``R_AARCH64_AUTH_ABS64`` and
``R_AARCH64_AUTH_RELATIVE`` relocations are now supported.
(`#72714 <https://github.com/llvm/llvm-project/pull/72714>`_)

Breaking changes
----------------
Expand Down
Loading
Loading