#ifndef TOOLS_CLANG_STACK_MAPS_GC_STACK_MAP_PARSER_H_
#define TOOLS_CLANG_STACK_MAPS_GC_STACK_MAP_PARSER_H_
#include "gc_api.h"
extern const char __LLVM_StackMaps;
namespace stackmap {
struct __attribute__((packed)) StkMapHeader {
uint8_t version;
uint8_t reserved1;
uint16_t reserved2;
uint32_t num_functions;
uint32_t num_constants;
uint32_t num_records;
};
struct __attribute__((packed)) StkSizeRecord {
uint64_t address;
uint64_t stack_size;
uint64_t record_count; };
struct __attribute__((packed)) StkMapRecordHeader {
uint64_t patchpoint_id;
uint32_t return_addr; uint16_t flags;
uint16_t num_locations;
};
enum LocationKind {
kRegister = 0x1,
kDirect = 0x2,
kIndirect = 0x3,
kConstant = 0x4,
kConstIndex = 0x5
};
struct __attribute__((packed)) StkMapLocation {
uint8_t kind; uint8_t flags; uint16_t location_size;
uint16_t reg_num; uint16_t reserved; int32_t offset; };
struct __attribute__((packed)) LiveOutsHeader {
uint16_t padding;
uint16_t num_liveouts;
};
struct __attribute__((packed)) LiveOut {
uint16_t reg_num; uint8_t flags;
uint8_t size; };
class StackmapV3Parser {
public:
StackmapV3Parser() : cursor_(&__LLVM_StackMaps) {}
SafepointTable Parse();
private:
static constexpr uint8_t kStackmapVersion = 3;
static constexpr uint8_t kSizeConstantEntry = 8; static constexpr uint8_t kSkipLocs = 2;
const char* cursor_;
const StkMapRecordHeader* cur_frame_;
template <typename T, typename U>
inline T ptr_offset(U ptr, int bytes) {
auto* newptr = reinterpret_cast<const char*>(ptr);
newptr += bytes;
return reinterpret_cast<T>(newptr);
}
template <typename T>
inline T* align_8(T* ptr) {
auto* c = reinterpret_cast<const char*>(ptr);
return reinterpret_cast<T*>(((uintptr_t)c + 7) & ~7);
}
FrameRoots ParseFrame();
};
}
#endif