summaryrefslogtreecommitdiff
path: root/lld/ELF
diff options
context:
space:
mode:
authorMitch Phillips <31459023+hctim@users.noreply.github.com>2023-03-01 11:00:49 -0800
committerMitch Phillips <31459023+hctim@users.noreply.github.com>2023-03-01 11:14:05 -0800
commitc574e93afd2e5f7986abeece88449c84ebd2e76d (patch)
treefb4d25064af6f08d22b0055a2c2d640a1d24aee0 /lld/ELF
parent4e7d40e0928cfe448ba947d2a67895fccaa3535f (diff)
downloadllvm-c574e93afd2e5f7986abeece88449c84ebd2e76d.tar.gz
[lld] [MTE] Add DT_AARCH64_MEMTAG_* dynamic entries, and small cleanup
Adds the new AArch64-ABI dynamic entry generation to LLD. This will allow Android to move from the Android-specific ELF note onto the dynamic entries. Change the behaviour of an unspecified --android-memtag-mode. Now, when unspecified, this will print a warning that you're doing a no-op, rather than implicitly turning on sync mode. This is important for MTE globals later, where a binary containing static tagged global descriptors shouldn't have MTE turned on without specific intent being passed to the linker. For now, continue to emit the Android ELF note by default. In future, we can probably make it only emit the note when provided a flag. Do a quick NFC-cleanup of the ELF note while we're here. It doesn't change anything about the ELF note itself, but makes it more clear to the reader of the code what alignment requirements are being (previously implicitly) met. Reviewed By: fmayer, MaskRay Differential Revision: https://reviews.llvm.org/D143769
Diffstat (limited to 'lld/ELF')
-rw-r--r--lld/ELF/Driver.cpp19
-rw-r--r--lld/ELF/SyntheticSections.cpp18
2 files changed, 26 insertions, 11 deletions
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 93caf755196f..d9915be8ca88 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -736,15 +736,24 @@ static StringRef getDynamicLinker(opt::InputArgList &args) {
static int getMemtagMode(opt::InputArgList &args) {
StringRef memtagModeArg = args.getLastArgValue(OPT_android_memtag_mode);
+ if (memtagModeArg.empty()) {
+ if (config->androidMemtagStack)
+ warn("--android-memtag-mode is unspecified, leaving "
+ "--android-memtag-stack a no-op");
+ else if (config->androidMemtagHeap)
+ warn("--android-memtag-mode is unspecified, leaving "
+ "--android-memtag-heap a no-op");
+ return ELF::NT_MEMTAG_LEVEL_NONE;
+ }
+
if (!config->androidMemtagHeap && !config->androidMemtagStack) {
- if (!memtagModeArg.empty())
- error("when using --android-memtag-mode, at least one of "
- "--android-memtag-heap or "
- "--android-memtag-stack is required");
+ error("when using --android-memtag-mode, at least one of "
+ "--android-memtag-heap or "
+ "--android-memtag-stack is required");
return ELF::NT_MEMTAG_LEVEL_NONE;
}
- if (memtagModeArg == "sync" || memtagModeArg.empty())
+ if (memtagModeArg == "sync")
return ELF::NT_MEMTAG_LEVEL_SYNC;
if (memtagModeArg == "async")
return ELF::NT_MEMTAG_LEVEL_ASYNC;
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 24c8b1f7772d..277ed3931973 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -1441,6 +1441,12 @@ DynamicSection<ELFT>::computeContents() {
addInt(DT_AARCH64_BTI_PLT, 0);
if (config->zPacPlt)
addInt(DT_AARCH64_PAC_PLT, 0);
+
+ if (config->androidMemtagMode != ELF::NT_MEMTAG_LEVEL_NONE) {
+ addInt(DT_AARCH64_MEMTAG_MODE, config->androidMemtagMode == NT_MEMTAG_LEVEL_ASYNC);
+ addInt(DT_AARCH64_MEMTAG_HEAP, config->androidMemtagHeap);
+ addInt(DT_AARCH64_MEMTAG_STACK, config->androidMemtagStack);
+ }
}
addInSec(DT_SYMTAB, *part.dynSymTab);
@@ -3835,16 +3841,16 @@ void InStruct::reset() {
constexpr char kMemtagAndroidNoteName[] = "Android";
void MemtagAndroidNote::writeTo(uint8_t *buf) {
- static_assert(sizeof(kMemtagAndroidNoteName) == 8,
- "ABI check for Android 11 & 12.");
- assert((config->androidMemtagStack || config->androidMemtagHeap) &&
- "Should only be synthesizing a note if heap || stack is enabled.");
+ static_assert(
+ sizeof(kMemtagAndroidNoteName) == 8,
+ "Android 11 & 12 have an ABI that the note name is 8 bytes long. Keep it "
+ "that way for backwards compatibility.");
write32(buf, sizeof(kMemtagAndroidNoteName));
write32(buf + 4, sizeof(uint32_t));
write32(buf + 8, ELF::NT_ANDROID_TYPE_MEMTAG);
memcpy(buf + 12, kMemtagAndroidNoteName, sizeof(kMemtagAndroidNoteName));
- buf += 12 + sizeof(kMemtagAndroidNoteName);
+ buf += 12 + alignTo(sizeof(kMemtagAndroidNoteName), 4);
uint32_t value = 0;
value |= config->androidMemtagMode;
@@ -3859,7 +3865,7 @@ void MemtagAndroidNote::writeTo(uint8_t *buf) {
size_t MemtagAndroidNote::getSize() const {
return sizeof(llvm::ELF::Elf64_Nhdr) +
- /*namesz=*/sizeof(kMemtagAndroidNoteName) +
+ /*namesz=*/alignTo(sizeof(kMemtagAndroidNoteName), 4) +
/*descsz=*/sizeof(uint32_t);
}