-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[lld][AArch64][ELF][PAC] Support AUTH relocations and AUTH ELF marking #72714
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
Changes from all commits
c493d78
589c645
a021f15
d341159
b791da9
b95dcf8
594f8a0
d793c0c
acb1730
de73eae
321a6a9
aff3a96
4e53afa
ec1c632
2136ad1
9ea8c5c
e3a64d2
865c983
1448a4a
203f61e
1b8c52b
e9b5337
aec9155
b215b0d
90dbcf4
d32b8e3
978ed06
ec04d8c
728c933
4409838
128831c
83eddae
08c749d
e4a37a6
05cf361
eb02b6a
f459527
2846e76
45fcbb9
0eb272a
964e9fe
2e8ec83
99df511
b6e0e28
cbc380a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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" | ||
|
@@ -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"); | ||
} | ||
|
||
if (config->emachine != EM_386 && config->emachine != EM_X86_64 && | ||
|
@@ -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('='); | ||
|
@@ -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 | ||
|
@@ -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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 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 Please let me know if I miss something and there is a room for simplification even given the case above. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
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; | ||
|
||
|
@@ -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"); | ||
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) { | ||
|
@@ -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 | ||
|
Uh oh!
There was an error while loading. Please reload this page.