#include #include #include #include int main() { printf("main\n"); } namespace { #define FN(X) \ if (pc == reinterpret_cast(X)) \ return #X const char *symbolize(uintptr_t pc) { FUNCTIONS; return nullptr; } template T consume(const char *&pos, const char *end) { T v; // We need to memcpy from pos, because it's not guaranteed that every entry // has the required alignment of T. memcpy(&v, pos, sizeof(T)); pos += sizeof(T); assert(pos <= end); return v; } uint64_t consume_uleb128(const char *&pos, const char *end) { uint64_t val = 0; int shift = 0; uint8_t cur; do { cur = *pos++; val |= uint64_t{cur & 0x7fu} << shift; shift += 7; } while (cur & 0x80); assert(shift < 64); assert(pos <= end); return val; } constexpr uint32_t kSanitizerBinaryMetadataUARHasSize = 1 << 2; uint32_t meta_version; const char *meta_start; const char *meta_end; const char *atomics_start; const char *atomics_end; }; // namespace extern "C" { void __sanitizer_metadata_covered_add(uint32_t version, const char *start, const char *end) { const uint32_t version_base = version & 0xffff; const bool offset_ptr_sized = version & (1 << 16); assert(version_base == 2); printf("metadata add version %u\n", version_base); for (const char *pos = start; pos < end;) { const auto base = reinterpret_cast(pos); const intptr_t offset = offset_ptr_sized ? consume(pos, end) : consume(pos, end); [[maybe_unused]] const uint64_t size = consume_uleb128(pos, end); const uint64_t features = consume_uleb128(pos, end); uint64_t stack_args = 0; if (features & kSanitizerBinaryMetadataUARHasSize) stack_args = consume_uleb128(pos, end); if (const char *name = symbolize(base + offset)) printf("%s: features=%lx stack_args=%lu\n", name, features, stack_args); } meta_version = version; meta_start = start; meta_end = end; } void __sanitizer_metadata_covered_del(uint32_t version, const char *start, const char *end) { assert(version == meta_version); assert(start == meta_start); assert(end == meta_end); } void __sanitizer_metadata_atomics_add(uint32_t version, const char *start, const char *end) { assert(version == meta_version); assert(start); assert(end >= end); atomics_start = start; atomics_end = end; } void __sanitizer_metadata_atomics_del(uint32_t version, const char *start, const char *end) { assert(version == meta_version); assert(atomics_start == start); assert(atomics_end == end); } }