xref: /llvm-project/compiler-rt/test/metadata/common.h (revision 0f61ba679fa1942397c8d2661f3339c305cc101b)
1dbe8c2c3SDmitry Vyukov #include <assert.h>
2dbe8c2c3SDmitry Vyukov #include <stdint.h>
3dbe8c2c3SDmitry Vyukov #include <stdio.h>
43d53b527SMarco Elver #include <string.h>
5dbe8c2c3SDmitry Vyukov 
main()6dbe8c2c3SDmitry Vyukov int main() { printf("main\n"); }
7dbe8c2c3SDmitry Vyukov 
83d53b527SMarco Elver namespace {
9dbe8c2c3SDmitry Vyukov #define FN(X)                                                                  \
103d53b527SMarco Elver   if (pc == reinterpret_cast<uintptr_t>(X))                                    \
11dbe8c2c3SDmitry Vyukov   return #X
12dbe8c2c3SDmitry Vyukov 
symbolize(uintptr_t pc)133d53b527SMarco Elver const char *symbolize(uintptr_t pc) {
14dbe8c2c3SDmitry Vyukov   FUNCTIONS;
15dbe8c2c3SDmitry Vyukov   return nullptr;
16dbe8c2c3SDmitry Vyukov }
17dbe8c2c3SDmitry Vyukov 
consume(const char * & pos,const char * end)18dbe8c2c3SDmitry Vyukov template <typename T> T consume(const char *&pos, const char *end) {
193d53b527SMarco Elver   T v;
203d53b527SMarco Elver   // We need to memcpy from pos, because it's not guaranteed that every entry
213d53b527SMarco Elver   // has the required alignment of T.
223d53b527SMarco Elver   memcpy(&v, pos, sizeof(T));
23dbe8c2c3SDmitry Vyukov   pos += sizeof(T);
24dbe8c2c3SDmitry Vyukov   assert(pos <= end);
25dbe8c2c3SDmitry Vyukov   return v;
26dbe8c2c3SDmitry Vyukov }
27dbe8c2c3SDmitry Vyukov 
consume_uleb128(const char * & pos,const char * end)28bf9814b7SMarco Elver uint64_t consume_uleb128(const char *&pos, const char *end) {
29bf9814b7SMarco Elver   uint64_t val = 0;
30bf9814b7SMarco Elver   int shift = 0;
31bf9814b7SMarco Elver   uint8_t cur;
32bf9814b7SMarco Elver   do {
33bf9814b7SMarco Elver     cur = *pos++;
34bf9814b7SMarco Elver     val |= uint64_t{cur & 0x7fu} << shift;
35bf9814b7SMarco Elver     shift += 7;
36bf9814b7SMarco Elver   } while (cur & 0x80);
37bf9814b7SMarco Elver   assert(shift < 64);
38bf9814b7SMarco Elver   assert(pos <= end);
39bf9814b7SMarco Elver   return val;
40bf9814b7SMarco Elver }
41bf9814b7SMarco Elver 
423d53b527SMarco Elver constexpr uint32_t kSanitizerBinaryMetadataUARHasSize = 1 << 2;
433d53b527SMarco Elver 
44dbe8c2c3SDmitry Vyukov uint32_t meta_version;
45dbe8c2c3SDmitry Vyukov const char *meta_start;
46dbe8c2c3SDmitry Vyukov const char *meta_end;
473d53b527SMarco Elver const char *atomics_start;
483d53b527SMarco Elver const char *atomics_end;
49*0f61ba67SMarco Elver }  // namespace
50dbe8c2c3SDmitry Vyukov 
51dbe8c2c3SDmitry Vyukov extern "C" {
__sanitizer_metadata_covered_add(uint32_t version,const char * start,const char * end)52dbe8c2c3SDmitry Vyukov void __sanitizer_metadata_covered_add(uint32_t version, const char *start,
53dbe8c2c3SDmitry Vyukov                                       const char *end) {
543d53b527SMarco Elver   const uint32_t version_base = version & 0xffff;
553d53b527SMarco Elver   const bool offset_ptr_sized = version & (1 << 16);
563d53b527SMarco Elver   assert(version_base == 2);
573d53b527SMarco Elver   printf("metadata add version %u\n", version_base);
58dbe8c2c3SDmitry Vyukov   for (const char *pos = start; pos < end;) {
593d53b527SMarco Elver     const auto base = reinterpret_cast<uintptr_t>(pos);
603d53b527SMarco Elver     const intptr_t offset = offset_ptr_sized ? consume<intptr_t>(pos, end)
613d53b527SMarco Elver                                              : consume<int32_t>(pos, end);
62bf9814b7SMarco Elver     [[maybe_unused]] const uint64_t size = consume_uleb128(pos, end);
63bf9814b7SMarco Elver     const uint64_t features = consume_uleb128(pos, end);
64bf9814b7SMarco Elver     uint64_t stack_args = 0;
653d53b527SMarco Elver     if (features & kSanitizerBinaryMetadataUARHasSize)
66bf9814b7SMarco Elver       stack_args = consume_uleb128(pos, end);
67dbe8c2c3SDmitry Vyukov     if (const char *name = symbolize(base + offset))
68bf9814b7SMarco Elver       printf("%s: features=%lx stack_args=%lu\n", name, features, stack_args);
69dbe8c2c3SDmitry Vyukov   }
70dbe8c2c3SDmitry Vyukov   meta_version = version;
71dbe8c2c3SDmitry Vyukov   meta_start = start;
72dbe8c2c3SDmitry Vyukov   meta_end = end;
73dbe8c2c3SDmitry Vyukov }
74dbe8c2c3SDmitry Vyukov 
__sanitizer_metadata_covered_del(uint32_t version,const char * start,const char * end)75dbe8c2c3SDmitry Vyukov void __sanitizer_metadata_covered_del(uint32_t version, const char *start,
76dbe8c2c3SDmitry Vyukov                                       const char *end) {
77dbe8c2c3SDmitry Vyukov   assert(version == meta_version);
78dbe8c2c3SDmitry Vyukov   assert(start == meta_start);
79dbe8c2c3SDmitry Vyukov   assert(end == meta_end);
80dbe8c2c3SDmitry Vyukov }
81dbe8c2c3SDmitry Vyukov 
__sanitizer_metadata_atomics_add(uint32_t version,const char * start,const char * end)82dbe8c2c3SDmitry Vyukov void __sanitizer_metadata_atomics_add(uint32_t version, const char *start,
83dbe8c2c3SDmitry Vyukov                                       const char *end) {
84dbe8c2c3SDmitry Vyukov   assert(version == meta_version);
85dbe8c2c3SDmitry Vyukov   assert(start);
86dbe8c2c3SDmitry Vyukov   assert(end >= end);
87dbe8c2c3SDmitry Vyukov   atomics_start = start;
88dbe8c2c3SDmitry Vyukov   atomics_end = end;
89dbe8c2c3SDmitry Vyukov }
90dbe8c2c3SDmitry Vyukov 
__sanitizer_metadata_atomics_del(uint32_t version,const char * start,const char * end)91dbe8c2c3SDmitry Vyukov void __sanitizer_metadata_atomics_del(uint32_t version, const char *start,
92dbe8c2c3SDmitry Vyukov                                       const char *end) {
93dbe8c2c3SDmitry Vyukov   assert(version == meta_version);
94dbe8c2c3SDmitry Vyukov   assert(atomics_start == start);
95dbe8c2c3SDmitry Vyukov   assert(atomics_end == end);
96dbe8c2c3SDmitry Vyukov }
97dbe8c2c3SDmitry Vyukov }
98