Merge changes from topic "revert-2709995-VVPYYBKIHY" into main
* changes:
Revert "Linker support for MTE globals."
Revert "Add a memtag-globals test to bionic"
diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp
index 0d557f1..1b539f2 100644
--- a/libc/bionic/__libc_init_main_thread.cpp
+++ b/libc/bionic/__libc_init_main_thread.cpp
@@ -44,7 +44,7 @@
// Declared in "private/bionic_ssp.h".
uintptr_t __stack_chk_guard = 0;
-BIONIC_USED_BEFORE_LINKER_RELOCATES static pthread_internal_t main_thread;
+static pthread_internal_t main_thread;
// Setup for the main thread. For dynamic executables, this is called by the
// linker _before_ libc is mapped in memory. This means that all writes to
diff --git a/libc/bionic/bionic_call_ifunc_resolver.cpp b/libc/bionic/bionic_call_ifunc_resolver.cpp
index d5a812c..e44d998 100644
--- a/libc/bionic/bionic_call_ifunc_resolver.cpp
+++ b/libc/bionic/bionic_call_ifunc_resolver.cpp
@@ -31,7 +31,6 @@
#include <sys/hwprobe.h>
#include <sys/ifunc.h>
-#include "bionic/macros.h"
#include "private/bionic_auxv.h"
// This code is called in the linker before it has been relocated, so minimize calls into other
@@ -41,8 +40,8 @@
ElfW(Addr) __bionic_call_ifunc_resolver(ElfW(Addr) resolver_addr) {
#if defined(__aarch64__)
typedef ElfW(Addr) (*ifunc_resolver_t)(uint64_t, __ifunc_arg_t*);
- BIONIC_USED_BEFORE_LINKER_RELOCATES static __ifunc_arg_t arg;
- BIONIC_USED_BEFORE_LINKER_RELOCATES static bool initialized = false;
+ static __ifunc_arg_t arg;
+ static bool initialized = false;
if (!initialized) {
initialized = true;
arg._size = sizeof(__ifunc_arg_t);
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index 181a729..f46d702 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -410,7 +410,6 @@
// We did not enable MTE, so we do not need to arm the upgrade timer.
__libc_shared_globals()->heap_tagging_upgrade_timer_sec = 0;
}
-
#else // __aarch64__
void __libc_init_mte(const memtag_dynamic_entries_t*, const void*, size_t, uintptr_t, void*) {}
#endif // __aarch64__
@@ -505,6 +504,6 @@
// compiled with -ffreestanding to avoid implicit string.h function calls. (It shouldn't strictly
// be necessary, though.)
__LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals() {
- BIONIC_USED_BEFORE_LINKER_RELOCATES static libc_shared_globals globals;
+ static libc_shared_globals globals;
return &globals;
}
diff --git a/libc/platform/bionic/macros.h b/libc/platform/bionic/macros.h
index b781731..93268c1 100644
--- a/libc/platform/bionic/macros.h
+++ b/libc/platform/bionic/macros.h
@@ -97,17 +97,3 @@
static inline T* _Nonnull untag_address(T* _Nonnull p) {
return reinterpret_cast<T*>(untag_address(reinterpret_cast<uintptr_t>(p)));
}
-
-// MTE globals protects internal and external global variables. One of the main
-// things that MTE globals does is force all global variables accesses to go
-// through the GOT. In the linker though, some global variables are accessed (or
-// address-taken) prior to relocations being processed. Because relocations
-// haven't run yet, the GOT entry hasn't been populated, and this leads to
-// crashes. Thus, any globals used by the linker prior to relocation should be
-// annotated with this attribute, which suppresses tagging of this global
-// variable, restoring the pc-relative address computation.
-#if __has_feature(memtag_globals)
-#define BIONIC_USED_BEFORE_LINKER_RELOCATES __attribute__((no_sanitize("memtag")))
-#else // __has_feature(memtag_globals)
-#define BIONIC_USED_BEFORE_LINKER_RELOCATES
-#endif // __has_feature(memtag_globals)
diff --git a/libc/platform/bionic/mte.h b/libc/platform/bionic/mte.h
index dc25098..73cd821 100644
--- a/libc/platform/bionic/mte.h
+++ b/libc/platform/bionic/mte.h
@@ -28,7 +28,6 @@
#pragma once
-#include <stddef.h>
#include <sys/auxv.h>
#include <sys/prctl.h>
@@ -47,36 +46,6 @@
return supported;
}
-inline void* get_tagged_address(const void* ptr) {
-#if defined(__aarch64__)
- if (mte_supported()) {
- __asm__ __volatile__(".arch_extension mte; ldg %0, [%0]" : "+r"(ptr));
- }
-#endif // aarch64
- return const_cast<void*>(ptr);
-}
-
-// Inserts a random tag tag to `ptr`, using any of the set lower 16 bits in
-// `mask` to exclude the corresponding tag from being generated. Note: This does
-// not tag memory.
-inline void* insert_random_tag(const void* ptr, __attribute__((unused)) uint64_t mask = 0) {
-#if defined(__aarch64__)
- if (mte_supported() && ptr) {
- __asm__ __volatile__(".arch_extension mte; irg %0, %0, %1" : "+r"(ptr) : "r"(mask));
- }
-#endif // aarch64
- return const_cast<void*>(ptr);
-}
-
-// Stores the address tag in `ptr` to memory, at `ptr`.
-inline void set_memory_tag(__attribute__((unused)) void* ptr) {
-#if defined(__aarch64__)
- if (mte_supported()) {
- __asm__ __volatile__(".arch_extension mte; stg %0, [%0]" : "+r"(ptr));
- }
-#endif // aarch64
-}
-
#ifdef __aarch64__
class ScopedDisableMTE {
size_t prev_tco_;
diff --git a/linker/Android.bp b/linker/Android.bp
index 2875263..2ca962a 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -328,10 +328,6 @@
sanitize: {
hwaddress: false,
- // TODO(mitchp): For now, disable MTE globals in the linker. MTE globals
- // change the relocation semantics, and GVs that are touched before the
- // linker has the chance to relocate itself have to be annotated.
- memtag_globals: false,
},
static_libs: [
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index 82f2728..fee19f4 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -331,7 +331,6 @@
__libdl_info->gnu_bloom_filter_ = linker_si.gnu_bloom_filter_;
__libdl_info->gnu_bucket_ = linker_si.gnu_bucket_;
__libdl_info->gnu_chain_ = linker_si.gnu_chain_;
- __libdl_info->memtag_dynamic_entries_ = linker_si.memtag_dynamic_entries_;
__libdl_info->ref_count_ = 1;
__libdl_info->strtab_size_ = linker_si.strtab_size_;
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 13ce6ef..135eaa3 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -51,7 +51,6 @@
#include <android-base/scopeguard.h>
#include <async_safe/log.h>
#include <bionic/pthread_internal.h>
-#include <platform/bionic/mte.h>
// Private C library headers.
@@ -2340,7 +2339,7 @@
void* tls_block = get_tls_block_for_this_thread(tls_module, /*should_alloc=*/true);
*symbol = static_cast<char*>(tls_block) + sym->st_value;
} else {
- *symbol = get_tagged_address(reinterpret_cast<void*>(found->resolve_symbol_address(sym)));
+ *symbol = reinterpret_cast<void*>(found->resolve_symbol_address(sym));
}
failure_guard.Disable();
LD_LOG(kLogDlsym,
@@ -2771,11 +2770,8 @@
}
void soinfo::apply_relr_reloc(ElfW(Addr) offset) {
- ElfW(Addr)* tagged_address = reinterpret_cast<ElfW(Addr)*>(
- get_tagged_address(reinterpret_cast<void*>(offset + load_bias)));
- ElfW(Addr) tagged_result = reinterpret_cast<ElfW(Addr)>(
- get_tagged_address(reinterpret_cast<void*>(*tagged_address + load_bias)));
- *tagged_address = tagged_result;
+ ElfW(Addr) address = offset + load_bias;
+ *reinterpret_cast<ElfW(Addr)*>(address) += load_bias;
}
// Process relocations in SHT_RELR section (experimental).
@@ -3308,18 +3304,6 @@
// it each time we look up a symbol with a version.
if (!validate_verdef_section(this)) return false;
- // MTE globals requires remapping data segments with PROT_MTE as anonymous mappings, because file
- // based mappings may not be backed by tag-capable memory (see "MAP_ANONYMOUS" on
- // https://www.kernel.org/doc/html/latest/arch/arm64/memory-tagging-extension.html). This is only
- // done if the binary has MTE globals (evidenced by the dynamic table entries), as it destroys
- // page sharing. It's also only done on devices that support MTE, because the act of remapping
- // pages is unnecessary on non-MTE devices (where we might still run MTE-globals enabled code).
- if (mte_supported() && memtag_globals() && memtag_globalssz() &&
- remap_memtag_globals_segments(phdr, phnum, base) == 0) {
- tag_globals();
- protect_memtag_globals_ro_segments(phdr, phnum, base);
- }
-
flags_ |= FLAG_PRELINKED;
return true;
}
@@ -3391,14 +3375,6 @@
return false;
}
- if (mte_supported() && memtag_globals() && memtag_globalssz()) {
- // The linker's full path is not available until the main executable is loaded, as it's obtained
- // from DT_INTERP. We manually rename the linker's segments later, but have a best-effort name
- // in case we find a bug prior to loading the main executable.
- const char* soname = is_linker() ? "linker" : get_realpath();
- name_memtag_globals_segments(phdr, phnum, base, soname);
- }
-
/* Handle serializing/sharing the RELRO segment */
if (extinfo && (extinfo->flags & ANDROID_DLEXT_WRITE_RELRO)) {
if (phdr_table_serialize_gnu_relro(phdr, phnum, load_bias,
@@ -3431,47 +3407,6 @@
return true;
}
-// https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#global-variable-tagging
-void soinfo::tag_globals() {
- if (is_linked()) return;
- if (flags_ & FLAG_GLOBALS_TAGGED) return;
- flags_ |= FLAG_GLOBALS_TAGGED;
-
- constexpr size_t kTagGranuleSize = 16;
- const uint8_t* descriptor_stream = reinterpret_cast<const uint8_t*>(memtag_globals());
-
- if (memtag_globalssz() == 0) {
- DL_ERR("Invalid memtag descriptor pool size: %zu", memtag_globalssz());
- }
-
- uint64_t addr = 0;
- uleb128_decoder decoder(descriptor_stream, memtag_globalssz());
- // Don't ever generate tag zero, to easily distinguish between tagged and
- // untagged globals in register/tag dumps.
- uint64_t last_tag_mask = 1;
- constexpr uint64_t kMemtagStepVarintReservedBits = 3;
-
- while (decoder.has_bytes()) {
- uint64_t value = decoder.pop_front();
- uint64_t step = value >> kMemtagStepVarintReservedBits;
- uint64_t granules_to_tag = value & ((1 << kMemtagStepVarintReservedBits) - 1);
- if (granules_to_tag == 0) {
- granules_to_tag = decoder.pop_front() + 1;
- }
-
- addr += step * kTagGranuleSize;
- void* tagged_addr = insert_random_tag(reinterpret_cast<void*>(addr + load_bias), last_tag_mask);
- uint64_t tag = (reinterpret_cast<uint64_t>(tagged_addr) >> 56) & 0x0f;
- last_tag_mask = 1 | (1 << tag);
-
- for (size_t k = 0; k < granules_to_tag; k++) {
- auto* granule = static_cast<uint8_t*>(tagged_addr) + k * kTagGranuleSize;
- set_memory_tag(static_cast<void*>(granule));
- }
- addr += granules_to_tag * kTagGranuleSize;
- }
-}
-
static std::vector<android_namespace_t*> init_default_namespace_no_config(bool is_asan, bool is_hwasan) {
g_default_namespace.set_isolated(false);
auto default_ld_paths = is_asan ? kAsanDefaultLdPaths : (
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index c1a8929..5f5eba4 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -44,9 +44,7 @@
#include "linker_tls.h"
#include "linker_utils.h"
-#include "platform/bionic/macros.h"
#include "private/KernelArgumentBlock.h"
-#include "private/bionic_auxv.h"
#include "private/bionic_call_ifunc_resolver.h"
#include "private/bionic_globals.h"
#include "private/bionic_tls.h"
@@ -80,8 +78,7 @@
// TODO (dimtiry): remove somain, rename solist to solist_head
static soinfo* solist;
static soinfo* sonext;
-// main process, always the one after libdl_info
-BIONIC_USED_BEFORE_LINKER_RELOCATES static soinfo* somain;
+static soinfo* somain; // main process, always the one after libdl_info
static soinfo* solinker;
static soinfo* vdso; // vdso if present
@@ -393,16 +390,9 @@
interp = kFallbackLinkerPath;
}
solinker->set_realpath(interp);
- if (solinker->memtag_globals() && solinker->memtag_globalssz()) {
- name_memtag_globals_segments(solinker->phdr, solinker->phnum, solinker->load_bias,
- solinker->get_realpath());
- }
init_link_map_head(*solinker);
#if defined(__aarch64__)
- __libc_init_mte(somain->memtag_dynamic_entries(), somain->phdr, somain->phnum, somain->load_bias,
- args.argv);
-
if (exe_to_load == nullptr) {
// Kernel does not add PROT_BTI to executable pages of the loaded ELF.
// Apply appropriate protections here if it is needed.
@@ -414,6 +404,9 @@
strerror(errno));
}
}
+
+ __libc_init_mte(somain->memtag_dynamic_entries(), somain->phdr, somain->phnum, somain->load_bias,
+ args.argv);
#endif
// Register the main executable and the linker upfront to have
@@ -612,7 +605,7 @@
const unsigned kRelSzTag = DT_RELSZ;
#endif
-BIONIC_USED_BEFORE_LINKER_RELOCATES extern __LIBC_HIDDEN__ ElfW(Ehdr) __ehdr_start;
+extern __LIBC_HIDDEN__ ElfW(Ehdr) __ehdr_start;
static void call_ifunc_resolvers_for_section(RelType* begin, RelType* end) {
auto ehdr = reinterpret_cast<ElfW(Addr)>(&__ehdr_start);
@@ -670,16 +663,6 @@
}
}
-// Remapping MTE globals segments happens before the linker relocates itself, and so can't use
-// memcpy() from string.h. This function is compiled with -ffreestanding.
-void linker_memcpy(void* dest, const void* src, size_t n) {
- char* dest_bytes = reinterpret_cast<char*>(dest);
- const char* src_bytes = reinterpret_cast<const char*>(src);
- for (size_t i = 0; i < n; ++i) {
- dest_bytes[i] = src_bytes[i];
- }
-}
-
// Detect an attempt to run the linker on itself. e.g.:
// /system/bin/linker64 /system/bin/linker64
// Use priority-1 to run this constructor before other constructors.
diff --git a/linker/linker_main.h b/linker/linker_main.h
index 53fc58b..724f43c 100644
--- a/linker/linker_main.h
+++ b/linker/linker_main.h
@@ -70,5 +70,3 @@
soinfo* solist_get_head();
soinfo* solist_get_somain();
soinfo* solist_get_vdso();
-
-void linker_memcpy(void* dest, const void* src, size_t n);
\ No newline at end of file
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index bec6994..0ad0fd5 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -36,12 +36,10 @@
#include <sys/stat.h>
#include <unistd.h>
-#include "android-base/unique_fd.h"
#include "linker.h"
-#include "linker_debug.h"
#include "linker_dlwarning.h"
#include "linker_globals.h"
-#include "linker_main.h"
+#include "linker_debug.h"
#include "linker_utils.h"
#include "private/CFIShadow.h" // For kLibraryAlignment
@@ -864,108 +862,6 @@
return _phdr_table_set_load_prot(phdr_table, phdr_count, load_bias, prot);
}
-static bool segment_needs_memtag_globals_remapping(const ElfW(Phdr) * phdr) {
- // For now, MTE globals is only supported on writeable data segments.
- return phdr->p_type == PT_LOAD && !(phdr->p_flags & PF_X) && (phdr->p_flags & PF_W);
-}
-
-/* When MTE globals are requested by the binary, and when the hardware supports
- * it, remap the executable's PT_LOAD data pages to have PROT_MTE.
- *
- * Input:
- * phdr_table -> program header table
- * phdr_count -> number of entries in tables
- * load_bias -> load bias
- * Return:
- * 0 on success, -1 on failure (error code in errno).
- */
-int remap_memtag_globals_segments(const ElfW(Phdr) * phdr_table, size_t phdr_count,
- ElfW(Addr) load_bias) {
- for (const ElfW(Phdr)* phdr = phdr_table; phdr < phdr_table + phdr_count; phdr++) {
- if (!segment_needs_memtag_globals_remapping(phdr)) {
- continue;
- }
-
- uintptr_t seg_page_start = page_start(phdr->p_vaddr) + load_bias;
- uintptr_t seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
- size_t seg_page_aligned_size = seg_page_end - seg_page_start;
-
- int prot = PFLAGS_TO_PROT(phdr->p_flags);
- // For anonymous private mappings, it may be possible to simply mprotect()
- // the PROT_MTE flag over the top. For file-based mappings, this will fail,
- // and we'll need to fall back. We also allow PROT_WRITE here to allow
- // writing memory tags (in `soinfo::tag_globals()`), and set these sections
- // back to read-only after tags are applied (similar to RELRO).
-#if defined(__aarch64__)
- prot |= PROT_MTE;
-#endif // defined(__aarch64__)
- if (mprotect(reinterpret_cast<void*>(seg_page_start), seg_page_aligned_size,
- prot | PROT_WRITE) == 0) {
- continue;
- }
-
- void* mapping_copy = mmap(nullptr, seg_page_aligned_size, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- linker_memcpy(mapping_copy, reinterpret_cast<void*>(seg_page_start), seg_page_aligned_size);
-
- void* seg_addr = mmap(reinterpret_cast<void*>(seg_page_start), seg_page_aligned_size,
- prot | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- if (seg_addr == MAP_FAILED) return -1;
-
- linker_memcpy(seg_addr, mapping_copy, seg_page_aligned_size);
- munmap(mapping_copy, seg_page_aligned_size);
- }
-
- return 0;
-}
-
-void protect_memtag_globals_ro_segments(const ElfW(Phdr) * phdr_table, size_t phdr_count,
- ElfW(Addr) load_bias) {
- for (const ElfW(Phdr)* phdr = phdr_table; phdr < phdr_table + phdr_count; phdr++) {
- int prot = PFLAGS_TO_PROT(phdr->p_flags);
- if (!segment_needs_memtag_globals_remapping(phdr) || (prot & PROT_WRITE)) {
- continue;
- }
-
-#if defined(__aarch64__)
- prot |= PROT_MTE;
-#endif // defined(__aarch64__)
-
- uintptr_t seg_page_start = page_start(phdr->p_vaddr) + load_bias;
- uintptr_t seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
- size_t seg_page_aligned_size = seg_page_end - seg_page_start;
- mprotect(reinterpret_cast<void*>(seg_page_start), seg_page_aligned_size, prot);
- }
-}
-
-void name_memtag_globals_segments(const ElfW(Phdr) * phdr_table, size_t phdr_count,
- ElfW(Addr) load_bias, const char* soname) {
- for (const ElfW(Phdr)* phdr = phdr_table; phdr < phdr_table + phdr_count; phdr++) {
- if (!segment_needs_memtag_globals_remapping(phdr)) {
- continue;
- }
-
- uintptr_t seg_page_start = page_start(phdr->p_vaddr) + load_bias;
- uintptr_t seg_page_end = page_end(phdr->p_vaddr + phdr->p_memsz) + load_bias;
- size_t seg_page_aligned_size = seg_page_end - seg_page_start;
-
- // For file-based mappings that we're now forcing to be anonymous mappings, set the VMA name to
- // make debugging easier. The previous Android-kernel specific implementation captured the name
- // by pointer from userspace, which meant we had to persist the name permanently in memory.
- // Since Android13-5.10 (https://android-review.git.corp.google.com/c/kernel/common/+/1934723)
- // though, we use the upstream-kernel implementation
- // (https://github.com/torvalds/linux/commit/9a10064f5625d5572c3626c1516e0bebc6c9fe9b), which
- // copies the name into kernel memory. It's a safe bet that any devices with Android 14 are
- // using a kernel >= 5.10.
- constexpr unsigned kVmaNameLimit = 80;
- char vma_name[kVmaNameLimit];
- async_safe_format_buffer(vma_name, kVmaNameLimit, "memtag:%s+0x%" PRIxPTR, soname,
- page_start(phdr->p_vaddr));
- prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, reinterpret_cast<void*>(seg_page_start),
- seg_page_aligned_size, vma_name);
- }
-}
-
/* Change the protection of all loaded segments in memory to writable.
* This is useful before performing relocations. Once completed, you
* will have to call phdr_table_protect_segments to restore the original
diff --git a/linker/linker_phdr.h b/linker/linker_phdr.h
index 092ea5d..98bf020 100644
--- a/linker/linker_phdr.h
+++ b/linker/linker_phdr.h
@@ -148,12 +148,3 @@
const char* phdr_table_get_interpreter_name(const ElfW(Phdr)* phdr_table, size_t phdr_count,
ElfW(Addr) load_bias);
-
-int remap_memtag_globals_segments(const ElfW(Phdr) * phdr_table, size_t phdr_count,
- ElfW(Addr) load_bias);
-
-void protect_memtag_globals_ro_segments(const ElfW(Phdr) * phdr_table, size_t phdr_count,
- ElfW(Addr) load_bias);
-
-void name_memtag_globals_segments(const ElfW(Phdr) * phdr_table, size_t phdr_count,
- ElfW(Addr) load_bias, const char* soname);
diff --git a/linker/linker_relocate.cpp b/linker/linker_relocate.cpp
index 1ee7bc6..952dade 100644
--- a/linker/linker_relocate.cpp
+++ b/linker/linker_relocate.cpp
@@ -44,8 +44,6 @@
#include "linker_soinfo.h"
#include "private/bionic_globals.h"
-#include <platform/bionic/mte.h>
-
static bool is_tls_reloc(ElfW(Word) type) {
switch (type) {
case R_GENERIC_TLS_DTPMOD:
@@ -159,19 +157,12 @@
static bool process_relocation_general(Relocator& relocator, const rel_t& reloc);
-static ElfW(Addr) apply_memtag(ElfW(Addr) sym_addr) {
- if (sym_addr == 0) return sym_addr; // Handle undefined weak symbols.
-
- return reinterpret_cast<ElfW(Addr)>(get_tagged_address(reinterpret_cast<void*>(sym_addr)));
-}
-
template <RelocMode Mode>
__attribute__((always_inline))
static bool process_relocation_impl(Relocator& relocator, const rel_t& reloc) {
constexpr bool IsGeneral = Mode == RelocMode::General;
- void* const rel_target =
- reinterpret_cast<void*>(apply_memtag(reloc.r_offset + relocator.si->load_bias));
+ void* const rel_target = reinterpret_cast<void*>(reloc.r_offset + relocator.si->load_bias);
const uint32_t r_type = ELFW(R_TYPE)(reloc.r_info);
const uint32_t r_sym = ELFW(R_SYM)(reloc.r_info);
@@ -334,7 +325,7 @@
// common in non-platform binaries.
if (r_type == R_GENERIC_ABSOLUTE) {
count_relocation_if<IsGeneral>(kRelocAbsolute);
- const ElfW(Addr) result = apply_memtag(sym_addr) + get_addend_rel();
+ const ElfW(Addr) result = sym_addr + get_addend_rel();
trace_reloc("RELO ABSOLUTE %16p <- %16p %s",
rel_target, reinterpret_cast<void*>(result), sym_name);
*static_cast<ElfW(Addr)*>(rel_target) = result;
@@ -344,29 +335,16 @@
// document (IHI0044F) specifies that R_ARM_GLOB_DAT has an addend, but Bionic isn't adding
// it.
count_relocation_if<IsGeneral>(kRelocAbsolute);
- ElfW(Addr) result = apply_memtag(sym_addr) + get_addend_norel();
- trace_reloc("RELO GLOB_DAT %16p <- %16p %s", rel_target, reinterpret_cast<void*>(result),
- sym_name);
+ const ElfW(Addr) result = sym_addr + get_addend_norel();
+ trace_reloc("RELO GLOB_DAT %16p <- %16p %s",
+ rel_target, reinterpret_cast<void*>(result), sym_name);
*static_cast<ElfW(Addr)*>(rel_target) = result;
return true;
} else if (r_type == R_GENERIC_RELATIVE) {
// In practice, r_sym is always zero, but if it weren't, the linker would still look up the
// referenced symbol (and abort if the symbol isn't found), even though it isn't used.
count_relocation_if<IsGeneral>(kRelocRelative);
- ElfW(Addr) result;
- // MTE globals reuses the place bits for additional tag-derivation metadata for
- // R_AARCH64_RELATIVE relocations, which makes it incompatible with
- // `-Wl,--apply-dynamic-relocs`. This is enforced by lld, however there's nothing stopping
- // Android binaries (particularly prebuilts) from building with this linker flag if they're
- // not built with MTE globals. Thus, don't use the new relocation semantics if this DSO
- // doesn't have MTE globals.
- if (relocator.si->memtag_globals() && relocator.si->memtag_globalssz()) {
- int64_t* place = static_cast<int64_t*>(rel_target);
- int64_t offset = *place;
- result = apply_memtag(relocator.si->load_bias + get_addend_rel() + offset) - offset;
- } else {
- result = relocator.si->load_bias + get_addend_rel();
- }
+ const ElfW(Addr) result = relocator.si->load_bias + get_addend_rel();
trace_reloc("RELO RELATIVE %16p <- %16p",
rel_target, reinterpret_cast<void*>(result));
*static_cast<ElfW(Addr)*>(rel_target) = result;
diff --git a/linker/linker_sleb128.h b/linker/linker_sleb128.h
index f48fda8..6bb3199 100644
--- a/linker/linker_sleb128.h
+++ b/linker/linker_sleb128.h
@@ -69,32 +69,3 @@
const uint8_t* current_;
const uint8_t* const end_;
};
-
-class uleb128_decoder {
- public:
- uleb128_decoder(const uint8_t* buffer, size_t count) : current_(buffer), end_(buffer + count) {}
-
- uint64_t pop_front() {
- uint64_t value = 0;
-
- size_t shift = 0;
- uint8_t byte;
-
- do {
- if (current_ >= end_) {
- async_safe_fatal("uleb128_decoder ran out of bounds");
- }
- byte = *current_++;
- value |= (static_cast<size_t>(byte & 127) << shift);
- shift += 7;
- } while (byte & 128);
-
- return value;
- }
-
- bool has_bytes() { return current_ < end_; }
-
- private:
- const uint8_t* current_;
- const uint8_t* const end_;
-};
diff --git a/linker/linker_soinfo.h b/linker/linker_soinfo.h
index 092cbcc..622719d 100644
--- a/linker/linker_soinfo.h
+++ b/linker/linker_soinfo.h
@@ -66,10 +66,9 @@
// soinfo is executed and this flag is
// unset.
#define FLAG_PRELINKED 0x00000400 // prelink_image has successfully processed this soinfo
-#define FLAG_GLOBALS_TAGGED 0x00000800 // globals have been tagged by MTE.
#define FLAG_NEW_SOINFO 0x40000000 // new soinfo format
-#define SOINFO_VERSION 7
+#define SOINFO_VERSION 6
ElfW(Addr) call_ifunc_resolver(ElfW(Addr) resolver_addr);
@@ -258,8 +257,6 @@
const android_dlextinfo* extinfo, size_t* relro_fd_offset);
bool protect_relro();
- void tag_globals();
-
void add_child(soinfo* child);
void remove_all_links();
diff --git a/tests/Android.bp b/tests/Android.bp
index 3aea968..14b4e3e 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -353,89 +353,6 @@
},
}
-cc_defaults {
- name: "memtag_globals_defaults",
- defaults: [
- "bionic_testlib_defaults",
- "bionic_targets_only"
- ],
- cflags: [
- "-Wno-array-bounds",
- "-Wno-unused-variable",
- ],
- header_libs: ["bionic_libc_platform_headers"],
- sanitize: {
- hwaddress: false,
- memtag_heap: true,
- memtag_globals: true,
- diag: {
- memtag_heap: true,
- }
- },
- relative_install_path: "bionic-loader-test-libs/prebuilt-elf-files",
-}
-
-/// The following library and binary is to be used for testing the bionic linker
-/// against memtag globals. While we wait for the compiler to be updated, the
-/// files come as prebuilts (built using) the corresponding 'regular'
-/// cc_test_library and cc_test rules below, just with a tip-of-tree version of
-/// LLVM.
-///
-/// Updating the prebuilts can be done by installing a tip-of-tree compiler, and
-/// running:
-/// - m memtag_globals_binary memtag_globals_dso
-/// - cp $ANDROID_PRODUCT_OUT/symbols/data/nativetest64/bionic-loader-test-libs/prebuilt-elf-files/memtag_globals_* \
-/// $ANDROID_BUILD_TOP/bionic/tests/prebuilt-elf-files/arm64/
-///
-// cc_test_library {
-// name: "memtag_globals_dso",
-// defaults: [ "memtag_globals_defaults" ],
-// srcs: ["prebuilt-elf-files/arm64/src/memtag_globals_dso.cpp"],
-// }
-//
-// cc_test {
-// name: "memtag_globals_binary",
-// // Not actually a '.so' file, this is an executable; but the only way to
-// // get soong to be able to produce a properly located and linked prebuilt
-// // variant of this binary was through the cc_prebuilt_test_library_shared
-// // rule, which appends '.so' to the end. Once the prebuilts are removed,
-// // the suffix can be removed.
-// suffix: ".so",
-// defaults: [ "memtag_globals_defaults" ],
-// srcs: ["prebuilt-elf-files/arm64/src/memtag_globals_binary.cpp"],
-// shared_libs: [ "memtag_globals_dso" ],
-// // This binary is used in the bionic-unit-tests as a data dependency, and is
-// // in the same folder as memtag_globals_dso. But, the default cc_test rules
-// // make this binary (when just explicitly built and shoved in
-// // /data/nativetest64/) end up in a subfolder called
-// // 'memtag_globals_binary'. When this happens, the explicit build fails to
-// // find the DSO because the default rpath is just ${ORIGIN}, and because we
-// // want this to be usable both from bionic-unit-tests and explicit builds,
-// // let's just not put it in a subdirectory.
-// no_named_install_directory: true,
-// }
-
-cc_prebuilt_test_library_shared {
- name: "memtag_globals_dso",
- defaults: [ "memtag_globals_defaults" ],
- arch: {
- arm64: {
- srcs: ["prebuilt-elf-files/arm64/memtag_globals_dso.so"],
- },
- }
-}
-
-cc_prebuilt_test_library_shared {
- name: "memtag_globals_binary",
- defaults: [ "memtag_globals_defaults" ],
- arch: {
- arm64: {
- srcs: ["prebuilt-elf-files/arm64/memtag_globals_binary.so"],
- shared_libs: [ "memtag_globals_dso" ],
- },
- }
-}
-
// -----------------------------------------------------------------------------
// All standard tests.
// -----------------------------------------------------------------------------
@@ -510,7 +427,6 @@
"math_test.cpp",
"membarrier_test.cpp",
"memtag_stack_test.cpp",
- "memtag_globals_test.cpp",
"mntent_test.cpp",
"mte_test.cpp",
"netdb_test.cpp",
@@ -966,8 +882,6 @@
"preinit_syscall_test_helper",
"thread_exit_cb_helper",
"tls_properties_helper",
- "memtag_globals_binary",
- "memtag_globals_dso",
],
data_libs: [
"libatest_simple_zip",
diff --git a/tests/memtag_globals_test.cpp b/tests/memtag_globals_test.cpp
deleted file mode 100644
index 3736d4c..0000000
--- a/tests/memtag_globals_test.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <gtest/gtest.h>
-
-#if defined(__BIONIC__)
-#include "gtest_globals.h"
-#include "platform/bionic/mte.h"
-#include "utils.h"
-#endif
-
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string>
-
-TEST(MemtagGlobalsTest, test) {
-#if defined(__BIONIC__) && defined(__aarch64__)
- std::string binary = GetPrebuiltElfDir() + "/memtag_globals_binary.so";
- chmod(binary.c_str(), 0755);
- ExecTestHelper eth;
- eth.SetArgs({binary.c_str(), nullptr});
- eth.Run(
- [&]() {
- execve(binary.c_str(), eth.GetArgs(), eth.GetEnv());
- GTEST_FAIL() << "Failed to execve: " << strerror(errno) << "\n";
- },
- // We catch the global-buffer-overflow and crash only when MTE is
- // supported.
- mte_supported() ? -SIGSEGV : 0, "Assertions were passed");
-#else
- GTEST_SKIP() << "bionic/arm64 only";
-#endif
-}
diff --git a/tests/prebuilt-elf-files/arm64/memtag_globals_binary.so b/tests/prebuilt-elf-files/arm64/memtag_globals_binary.so
deleted file mode 100755
index 43d7443..0000000
--- a/tests/prebuilt-elf-files/arm64/memtag_globals_binary.so
+++ /dev/null
Binary files differ
diff --git a/tests/prebuilt-elf-files/arm64/memtag_globals_dso.so b/tests/prebuilt-elf-files/arm64/memtag_globals_dso.so
deleted file mode 100755
index f472a70..0000000
--- a/tests/prebuilt-elf-files/arm64/memtag_globals_dso.so
+++ /dev/null
Binary files differ
diff --git a/tests/prebuilt-elf-files/arm64/src/memtag_globals.h b/tests/prebuilt-elf-files/arm64/src/memtag_globals.h
deleted file mode 100644
index b9a2ef1..0000000
--- a/tests/prebuilt-elf-files/arm64/src/memtag_globals.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <utility>
-#include <vector>
-
-void check_tagged(const void* a);
-void check_untagged(const void* a);
-void check_matching_tags(const void* a, const void* b);
-void check_eq(const void* a, const void* b);
-
-void dso_check_assertions(bool enforce_tagged);
-void dso_print_variables();
-
-void print_variable_address(const char* name, const void* ptr);
-void print_variables(const char* header,
- const std::vector<std::pair<const char*, const void*>>& tagged_variables,
- const std::vector<std::pair<const char*, const void*>>& untagged_variables);
\ No newline at end of file
diff --git a/tests/prebuilt-elf-files/arm64/src/memtag_globals_binary.cpp b/tests/prebuilt-elf-files/arm64/src/memtag_globals_binary.cpp
deleted file mode 100644
index c9ad261..0000000
--- a/tests/prebuilt-elf-files/arm64/src/memtag_globals_binary.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <string>
-#include <vector>
-
-#include "memtag_globals.h"
-
-// Adapted from the LLD test suite: lld/test/ELF/Inputs/aarch64-memtag-globals.s
-
-/// Global variables defined here, of various semantics.
-char global[30] = {};
-__attribute__((no_sanitize("memtag"))) int global_untagged = 0;
-const int const_global = 0;
-static const int hidden_const_global = 0;
-static char hidden_global[12] = {};
-__attribute__((visibility("hidden"))) int hidden_attr_global = 0;
-__attribute__((visibility("hidden"))) const int hidden_attr_const_global = 0;
-
-/// Should be untagged.
-__thread int tls_global;
-__thread static int hidden_tls_global;
-
-/// Tagged, from the other file.
-extern int global_extern;
-/// Untagged, from the other file.
-extern __attribute__((no_sanitize("memtag"))) int global_extern_untagged;
-/// Tagged here, but untagged in the definition found in the sister objfile
-/// (explicitly).
-extern int global_extern_untagged_definition_but_tagged_import;
-
-/// ABS64 relocations. Also, forces symtab entries for local and external
-/// globals.
-char* pointer_to_global = &global[0];
-char* pointer_inside_global = &global[17];
-char* pointer_to_global_end = &global[30];
-char* pointer_past_global_end = &global[48];
-int* pointer_to_global_untagged = &global_untagged;
-const int* pointer_to_const_global = &const_global;
-/// RELATIVE relocations.
-const int* pointer_to_hidden_const_global = &hidden_const_global;
-char* pointer_to_hidden_global = &hidden_global[0];
-int* pointer_to_hidden_attr_global = &hidden_attr_global;
-const int* pointer_to_hidden_attr_const_global = &hidden_attr_const_global;
-/// RELATIVE relocations with special AArch64 MemtagABI semantics, with the
-/// offset ('12' or '16') encoded in the place.
-char* pointer_to_hidden_global_end = &hidden_global[12];
-char* pointer_past_hidden_global_end = &hidden_global[16];
-/// ABS64 relocations.
-int* pointer_to_global_extern = &global_extern;
-int* pointer_to_global_extern_untagged = &global_extern_untagged;
-int* pointer_to_global_extern_untagged_definition_but_tagged_import =
- &global_extern_untagged_definition_but_tagged_import;
-
-// Force materialization of these globals into the symtab.
-int* get_address_to_tls_global() {
- return &tls_global;
-}
-int* get_address_to_hidden_tls_global() {
- return &hidden_tls_global;
-}
-
-static const std::vector<std::pair<const char*, const void*>>& get_expected_tagged_vars() {
- static std::vector<std::pair<const char*, const void*>> expected_tagged_vars = {
- {"global", &global},
- {"pointer_inside_global", pointer_inside_global},
- {"pointer_to_global_end", pointer_to_global_end},
- {"pointer_past_global_end", pointer_past_global_end},
- {"hidden_global", &hidden_global},
- {"hidden_attr_global", &hidden_attr_global},
- {"global_extern", &global_extern},
- };
- return expected_tagged_vars;
-}
-
-static const std::vector<std::pair<const char*, const void*>>& get_expected_untagged_vars() {
- static std::vector<std::pair<const char*, const void*>> expected_untagged_vars = {
- {"global_extern_untagged", &global_extern_untagged},
- {"global_extern_untagged_definition_but_tagged_import",
- &global_extern_untagged_definition_but_tagged_import},
- {"global_untagged", &global_untagged},
- {"const_global", &const_global},
- {"hidden_const_global", &hidden_const_global},
- {"hidden_attr_const_global", &hidden_attr_const_global},
- {"tls_global", &tls_global},
- {"hidden_tls_global", &hidden_tls_global},
- };
- return expected_untagged_vars;
-}
-
-void exe_print_variables() {
- print_variables(" Variables accessible from the binary:\n", get_expected_tagged_vars(),
- get_expected_untagged_vars());
-}
-
-// Dump the addresses of the global variables to stderr
-void dso_print();
-void dso_print_others();
-
-void exe_check_assertions(bool check_pointers_are_tagged) {
- // Check that non-const variables are writeable.
- *pointer_to_global = 0;
- *pointer_inside_global = 0;
- *(pointer_to_global_end - 1) = 0;
- *pointer_to_global_untagged = 0;
- *pointer_to_hidden_global = 0;
- *pointer_to_hidden_attr_global = 0;
- *(pointer_to_hidden_global_end - 1) = 0;
- *pointer_to_global_extern = 0;
- *pointer_to_global_extern_untagged = 0;
- *pointer_to_global_extern_untagged_definition_but_tagged_import = 0;
-
- if (check_pointers_are_tagged) {
- for (const auto& [_, pointer] : get_expected_tagged_vars()) {
- check_tagged(pointer);
- }
- }
-
- for (const auto& [_, pointer] : get_expected_untagged_vars()) {
- check_untagged(pointer);
- }
-
- check_matching_tags(pointer_to_global, pointer_inside_global);
- check_matching_tags(pointer_to_global, pointer_to_global_end);
- check_matching_tags(pointer_to_global, pointer_past_global_end);
- check_eq(pointer_inside_global, pointer_to_global + 17);
- check_eq(pointer_to_global_end, pointer_to_global + 30);
- check_eq(pointer_past_global_end, pointer_to_global + 48);
-
- check_matching_tags(pointer_to_hidden_global, pointer_to_hidden_global_end);
- check_matching_tags(pointer_to_hidden_global, pointer_past_hidden_global_end);
- check_eq(pointer_to_hidden_global_end, pointer_to_hidden_global + 12);
- check_eq(pointer_past_hidden_global_end, pointer_to_hidden_global + 16);
-}
-
-void crash() {
- *pointer_past_global_end = 0;
-}
-
-int main(int argc, char** argv) {
- bool check_pointers_are_tagged = false;
- // For an MTE-capable device, provide argv[1] == '1' to enable the assertions
- // that pointers should be tagged.
- if (argc >= 2 && argv[1][0] == '1') {
- check_pointers_are_tagged = true;
- }
-
- char* heap_ptr = static_cast<char*>(malloc(1));
- print_variable_address("heap address", heap_ptr);
- *heap_ptr = 0;
- if (check_pointers_are_tagged) check_tagged(heap_ptr);
- free(heap_ptr);
-
- exe_print_variables();
- dso_print_variables();
-
- exe_check_assertions(check_pointers_are_tagged);
- dso_check_assertions(check_pointers_are_tagged);
-
- printf("Assertions were passed. Now doing a global-buffer-overflow.\n");
- fflush(stdout);
- crash();
- printf("global-buffer-overflow went uncaught.\n");
- return 0;
-}
\ No newline at end of file
diff --git a/tests/prebuilt-elf-files/arm64/src/memtag_globals_dso.cpp b/tests/prebuilt-elf-files/arm64/src/memtag_globals_dso.cpp
deleted file mode 100644
index 877108e..0000000
--- a/tests/prebuilt-elf-files/arm64/src/memtag_globals_dso.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <vector>
-
-#include "memtag_globals.h"
-
-// Adapted from the LLD test suite: lld/test/ELF/Inputs/aarch64-memtag-globals.s
-
-int global_extern;
-static int global_extern_hidden;
-__attribute__((no_sanitize("memtag"))) int global_extern_untagged;
-__attribute__((no_sanitize("memtag"))) int global_extern_untagged_definition_but_tagged_import;
-
-void assertion_failure() {
- exit(1);
-}
-
-void check_tagged(const void* a) {
- uintptr_t a_uptr = reinterpret_cast<uintptr_t>(a);
-#if defined(__aarch64__)
- if ((a_uptr >> 56) == 0) {
- fprintf(stderr, "**********************************\n");
- fprintf(stderr, "Failed assertion:\n");
- fprintf(stderr, " tag(0x%zx) != 0\n", a_uptr);
- fprintf(stderr, "**********************************\n");
-
- assertion_failure();
- }
-#endif // defined(__aarch64__)
-}
-
-void check_untagged(const void* a) {
- uintptr_t a_uptr = reinterpret_cast<uintptr_t>(a);
-#if defined(__aarch64__)
- if ((a_uptr >> 56) != 0) {
- fprintf(stderr, "**********************************\n");
- fprintf(stderr, "Failed assertion:\n");
- fprintf(stderr, " tag(0x%zx) == 0\n", a_uptr);
- fprintf(stderr, "**********************************\n");
-
- assertion_failure();
- }
-#endif // defined(__aarch64__)
-}
-
-void check_matching_tags(const void* a, const void* b) {
- uintptr_t a_uptr = reinterpret_cast<uintptr_t>(a);
- uintptr_t b_uptr = reinterpret_cast<uintptr_t>(b);
-#if defined(__aarch64__)
- if (a_uptr >> 56 != b_uptr >> 56) {
- fprintf(stderr, "**********************************\n");
- fprintf(stderr, "Failed assertion:\n");
- fprintf(stderr, " tag(0x%zx) != tag(0x%zx)\n", a_uptr, b_uptr);
- fprintf(stderr, "**********************************\n");
-
- assertion_failure();
- }
-#endif // defined(__aarch64__)
-}
-
-void check_eq(const void* a, const void* b) {
- if (a != b) {
- fprintf(stderr, "**********************************\n");
- fprintf(stderr, "Failed assertion:\n");
- fprintf(stderr, " %p != %p\n", a, b);
- fprintf(stderr, "**********************************\n");
-
- assertion_failure();
- }
-}
-
-#define LONGEST_VARIABLE_NAME "51"
-void print_variable_address(const char* name, const void* ptr) {
- printf("%" LONGEST_VARIABLE_NAME "s: %16p\n", name, ptr);
-}
-
-static const std::vector<std::pair<const char*, const void*>>& get_expected_tagged_vars() {
- static std::vector<std::pair<const char*, const void*>> expected_tagged_vars = {
- {"global_extern", &global_extern},
- {"global_extern_hidden", &global_extern_hidden},
- };
- return expected_tagged_vars;
-}
-
-static const std::vector<std::pair<const char*, const void*>>& get_expected_untagged_vars() {
- static std::vector<std::pair<const char*, const void*>> expected_untagged_vars = {
- {"global_extern_untagged", &global_extern_untagged},
- {"global_extern_untagged_definition_but_tagged_import",
- &global_extern_untagged_definition_but_tagged_import},
- };
- return expected_untagged_vars;
-}
-
-void dso_print_variables() {
- print_variables(" Variables declared in the DSO:\n", get_expected_tagged_vars(),
- get_expected_untagged_vars());
-}
-
-void print_variables(const char* header,
- const std::vector<std::pair<const char*, const void*>>& tagged_variables,
- const std::vector<std::pair<const char*, const void*>>& untagged_variables) {
- printf("==========================================================\n");
- printf("%s", header);
- printf("==========================================================\n");
- printf(" Variables expected to be tagged:\n");
- printf("----------------------------------------------------------\n");
- for (const auto& [name, pointer] : tagged_variables) {
- print_variable_address(name, pointer);
- }
-
- printf("\n----------------------------------------------------------\n");
- printf(" Variables expected to be untagged:\n");
- printf("----------------------------------------------------------\n");
- for (const auto& [name, pointer] : untagged_variables) {
- print_variable_address(name, pointer);
- }
- printf("\n");
-}
-
-void dso_check_assertions(bool check_pointers_are_tagged) {
- // Check that non-const variables are writeable.
- global_extern = 0;
- global_extern_hidden = 0;
- global_extern_untagged = 0;
- global_extern_untagged_definition_but_tagged_import = 0;
-
- if (check_pointers_are_tagged) {
- for (const auto& [_, pointer] : get_expected_tagged_vars()) {
- check_tagged(pointer);
- }
- }
-
- for (const auto& [_, pointer] : get_expected_untagged_vars()) {
- check_untagged(pointer);
- }
-}