34namespace GDBJITInterface {
36#ifdef ENABLE_GDB_JIT_INTERFACE
42using DebugObject = MachO;
43using DebugSection = MachOSection;
48using DebugObject = ELF;
49using DebugSection = ELFSection;
54 explicit Writer(DebugObject* debug_object)
55 : debug_object_(debug_object),
58 buffer_(
reinterpret_cast<uint8_t*
>(base::Malloc(capacity_))) {}
60 ~Writer() { base::Free(
buffer_); }
69 T* operator->() {
return w_->RawSlotAt<T>(
offset_); }
71 void set(
const T& value) {
72 base::WriteUnalignedValue(w_->AddressAt<T>(
offset_), value);
75 Slot<T> at(
int i) {
return Slot<T>(w_,
offset_ +
sizeof(T) *
i); }
83 void Write(
const T& val) {
85 base::WriteUnalignedValue(AddressAt<T>(
position_), val);
90 Slot<T> SlotAt(uintptr_t
offset) {
91 Ensure(
offset +
sizeof(T));
92 return Slot<T>(
this,
offset);
96 Slot<T> CreateSlotHere() {
97 return CreateSlotsHere<T>(1);
100 template <
typename T>
101 Slot<T> CreateSlotsHere(uint32_t
count) {
105 return SlotAt<T>(slot_position);
108 void Ensure(uintptr_t
pos) {
109 if (capacity_ <
pos) {
110 while (capacity_ <
pos) capacity_ *= 2;
111 buffer_ =
reinterpret_cast<uint8_t*
>(base::Realloc(
buffer_, capacity_));
115 DebugObject* debug_object() {
return debug_object_; }
117 uint8_t* buffer() {
return buffer_; }
119 void Align(uintptr_t align) {
121 if (delta == 0)
return;
122 uintptr_t padding = align - delta;
127 void WriteULEB128(uintptr_t value) {
129 uint8_t
byte = value & 0x7F;
131 if (value != 0)
byte |= 0x80;
132 Write<uint8_t>(
byte);
133 }
while (value != 0);
136 void WriteSLEB128(intptr_t value) {
139 int8_t
byte = value & 0x7F;
140 bool byte_sign =
byte & 0x40;
143 if ((value == 0 && !byte_sign) || (value == -1 && byte_sign)) {
153 void WriteString(
const char* str) {
160 template <
typename T>
163 template <
typename T>
164 Address AddressAt(uintptr_t
offset) {
169 template <
typename T>
170 T* RawSlotAt(uintptr_t
offset) {
175 DebugObject* debug_object_;
183template <
typename THeader>
186 virtual ~DebugSectionBase() =
default;
188 virtual void WriteBody(Writer::Slot<THeader> header, Writer* writer) {
189 uintptr_t
start = writer->position();
190 if (WriteBodyInternal(writer)) {
191 uintptr_t
end = writer->position();
192 header->offset =
static_cast<uint32_t
>(
start);
200 virtual bool WriteBodyInternal(Writer* writer) {
return false; }
202 using Header = THeader;
205struct MachOSectionHeader {
208#if V8_TARGET_ARCH_IA32
224class MachOSection :
public DebugSectionBase<MachOSectionHeader> {
228 S_ATTR_COALESCED = 0xBu,
229 S_ATTR_SOME_INSTRUCTIONS = 0x400u,
230 S_ATTR_DEBUG = 0x02000000u,
231 S_ATTR_PURE_INSTRUCTIONS = 0x80000000u
234 MachOSection(
const char* name,
const char* segment, uint32_t align,
238 DCHECK(base::bits::IsPowerOfTwo(align));
239 align_ = base::bits::WhichPowerOfTwo(align_);
243 ~MachOSection()
override =
default;
245 virtual void PopulateHeader(Writer::Slot<Header> header) {
249 header->align = align_;
253 header->reserved1 = 0;
254 header->reserved2 = 0;
255 memset(header->sectname, 0,
sizeof(header->sectname));
256 memset(header->segname, 0,
sizeof(header->segname));
259 strncpy(header->sectname,
name_,
sizeof(header->sectname));
260 strncpy(header->segname,
segment_,
sizeof(header->segname));
270struct ELFSectionHeader {
280 uintptr_t entry_size;
284class ELFSection :
public DebugSectionBase<ELFSectionHeader> {
299 TYPE_LOPROC = 0x70000000,
300 TYPE_X86_64_UNWIND = 0x70000001,
301 TYPE_HIPROC = 0x7FFFFFFF,
302 TYPE_LOUSER = 0x80000000,
303 TYPE_HIUSER = 0xFFFFFFFF
306 enum Flags { FLAG_WRITE = 1, FLAG_ALLOC = 2, FLAG_EXEC = 4 };
308 enum SpecialIndexes { INDEX_ABSOLUTE = 0xFFF1 };
310 ELFSection(
const char* name,
Type type, uintptr_t align)
313 ~ELFSection()
override =
default;
315 void PopulateHeader(Writer::Slot<Header> header, ELFStringTable* strtab);
317 void WriteBody(Writer::Slot<Header> header, Writer* w)
override {
318 uintptr_t
start = w->position();
319 if (WriteBodyInternal(w)) {
320 uintptr_t
end = w->position();
321 header->offset =
start;
326 bool WriteBodyInternal(Writer* w)
override {
return false; }
332 virtual void PopulateHeader(Writer::Slot<Header> header) {
339 header->entry_size = 0;
351class MachOTextSection :
public MachOSection {
353 MachOTextSection(uint32_t align, uintptr_t addr, uintptr_t size)
354 : MachOSection(
"__text",
"__TEXT", align,
355 MachOSection::S_REGULAR |
356 MachOSection::S_ATTR_SOME_INSTRUCTIONS |
357 MachOSection::S_ATTR_PURE_INSTRUCTIONS),
362 virtual void PopulateHeader(Writer::Slot<Header> header) {
363 MachOSection::PopulateHeader(header);
364 header->addr = addr_;
365 header->size =
size_;
375class FullHeaderELFSection :
public ELFSection {
377 FullHeaderELFSection(
const char* name,
Type type, uintptr_t align,
378 uintptr_t addr, uintptr_t
offset, uintptr_t size,
380 : ELFSection(name, type, align),
387 void PopulateHeader(Writer::Slot<Header> header)
override {
388 ELFSection::PopulateHeader(header);
389 header->address = addr_;
391 header->size =
size_;
402class ELFStringTable :
public ELFSection {
404 explicit ELFStringTable(
const char* name)
405 : ELFSection(name, TYPE_STRTAB, 1),
410 uintptr_t Add(
const char* str) {
411 if (*str ==
'\0')
return 0;
418 void AttachWriter(Writer* w) {
426 void DetachWriter() { writer_ =
nullptr; }
428 void WriteBody(Writer::Slot<Header> header, Writer* w)
override {
431 header->size =
size_;
435 void WriteString(
const char* str) {
436 uintptr_t written = 0;
438 writer_->Write(*str);
450void ELFSection::PopulateHeader(Writer::Slot<ELFSection::Header> header,
451 ELFStringTable* strtab) {
452 header->name =
static_cast<uint32_t
>(strtab->Add(
name_));
453 header->type =
type_;
454 header->alignment = align_;
455 PopulateHeader(header);
462 explicit MachO(
Zone* zone) : sections_(zone) {}
464 size_t AddSection(MachOSection* section) {
465 sections_.push_back(section);
466 return sections_.size() - 1;
469 void Write(Writer* w, uintptr_t code_start, uintptr_t code_size) {
470 Writer::Slot<MachOHeader> header = WriteHeader(w);
471 uintptr_t load_command_start = w->position();
472 Writer::Slot<MachOSegmentCommand> cmd =
473 WriteSegmentCommand(w, code_start, code_size);
474 WriteSections(w, cmd, header, load_command_start);
486#if V8_TARGET_ARCH_X64
491 struct MachOSegmentCommand {
495#if V8_TARGET_ARCH_IA32
512 enum MachOLoadCommandCmd {
513 LC_SEGMENT_32 = 0x00000001u,
514 LC_SEGMENT_64 = 0x00000019u
517 Writer::Slot<MachOHeader> WriteHeader(Writer* w) {
519 Writer::Slot<MachOHeader> header = w->CreateSlotHere<MachOHeader>();
520#if V8_TARGET_ARCH_IA32
521 header->magic = 0xFEEDFACEu;
523 header->cpusubtype = 3;
524#elif V8_TARGET_ARCH_X64
525 header->magic = 0xFEEDFACFu;
526 header->cputype = 7 | 0x01000000;
527 header->cpusubtype = 3;
528 header->reserved = 0;
530#error Unsupported target architecture.
532 header->filetype = 0x1;
534 header->sizeofcmds = 0;
539 Writer::Slot<MachOSegmentCommand> WriteSegmentCommand(Writer* w,
540 uintptr_t code_start,
541 uintptr_t code_size) {
542 Writer::Slot<MachOSegmentCommand> cmd =
543 w->CreateSlotHere<MachOSegmentCommand>();
544#if V8_TARGET_ARCH_IA32
545 cmd->cmd = LC_SEGMENT_32;
547 cmd->cmd = LC_SEGMENT_64;
549 cmd->vmaddr = code_start;
550 cmd->vmsize = code_size;
556 cmd->nsects =
static_cast<uint32_t
>(sections_.size());
557 memset(cmd->segname, 0, 16);
558 cmd->cmdsize =
sizeof(MachOSegmentCommand) +
559 sizeof(MachOSection::Header) * cmd->nsects;
563 void WriteSections(Writer* w, Writer::Slot<MachOSegmentCommand> cmd,
564 Writer::Slot<MachOHeader> header,
565 uintptr_t load_command_start) {
566 Writer::Slot<MachOSection::Header> headers =
567 w->CreateSlotsHere<MachOSection::Header>(
568 static_cast<uint32_t
>(sections_.size()));
569 cmd->fileoff = w->position();
571 static_cast<uint32_t
>(w->position() - load_command_start);
573 for (MachOSection* section : sections_) {
574 section->PopulateHeader(headers.at(index));
575 section->WriteBody(headers.at(index), w);
578 cmd->filesize = w->position() - (uintptr_t)cmd->fileoff;
588 explicit ELF(
Zone* zone) : sections_(zone) {
589 sections_.push_back(zone->
New<ELFSection>(
"", ELFSection::TYPE_NULL, 0));
590 sections_.push_back(zone->
New<ELFStringTable>(
".shstrtab"));
593 void Write(Writer* w) {
595 WriteSectionTable(w);
599 ELFSection* SectionAt(uint32_t index) {
return *sections_.Find(index); }
601 size_t AddSection(ELFSection* section) {
602 sections_.push_back(section);
603 section->set_index(sections_.size() - 1);
604 return sections_.size() - 1;
614 uintptr_t pht_offset;
615 uintptr_t sht_offset;
617 uint16_t header_size;
618 uint16_t pht_entry_size;
619 uint16_t pht_entry_num;
620 uint16_t sht_entry_size;
621 uint16_t sht_entry_num;
622 uint16_t sht_strtab_index;
625 void WriteHeader(Writer* w) {
627 Writer::Slot<ELFHeader> header = w->CreateSlotHere<ELFHeader>();
628#if (V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM)
629 const uint8_t ident[16] = {0x7F,
'E',
'L',
'F', 1, 1, 1, 0,
630 0, 0, 0, 0, 0, 0, 0, 0};
631#elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_64_BIT || \
632 V8_TARGET_ARCH_PPC64 && V8_TARGET_LITTLE_ENDIAN
633 const uint8_t ident[16] = {0x7F,
'E',
'L',
'F', 2, 1, 1, 0,
634 0, 0, 0, 0, 0, 0, 0, 0};
635#elif V8_TARGET_ARCH_S390X
636 const uint8_t ident[16] = {0x7F,
'E',
'L',
'F', 2, 2, 1, 3,
637 0, 0, 0, 0, 0, 0, 0, 0};
639#error Unsupported target architecture.
641 memcpy(header->ident, ident, 16);
643#if V8_TARGET_ARCH_IA32
645#elif V8_TARGET_ARCH_X64
649 header->machine = 62;
650#elif V8_TARGET_ARCH_ARM
653 header->machine = 40;
654#elif V8_TARGET_ARCH_PPC64 && V8_OS_LINUX
661 header->machine = 21;
662#elif V8_TARGET_ARCH_S390X
666 header->machine = 22;
668#error Unsupported target architecture.
672 header->pht_offset = 0;
673 header->sht_offset =
sizeof(ELFHeader);
675 header->header_size =
sizeof(ELFHeader);
676 header->pht_entry_size = 0;
677 header->pht_entry_num = 0;
678 header->sht_entry_size =
sizeof(ELFSection::Header);
679 header->sht_entry_num = sections_.size();
680 header->sht_strtab_index = 1;
683 void WriteSectionTable(Writer* w) {
685 DCHECK(w->position() ==
sizeof(ELFHeader));
687 Writer::Slot<ELFSection::Header> headers =
688 w->CreateSlotsHere<ELFSection::Header>(
689 static_cast<uint32_t
>(sections_.size()));
692 ELFStringTable* strtab =
static_cast<ELFStringTable*
>(SectionAt(1));
693 strtab->AttachWriter(w);
695 for (ELFSection* section : sections_) {
696 section->PopulateHeader(headers.at(index), strtab);
699 strtab->DetachWriter();
702 int SectionHeaderPosition(uint32_t section_index) {
703 return sizeof(ELFHeader) +
sizeof(ELFSection::Header) * section_index;
706 void WriteSections(Writer* w) {
707 Writer::Slot<ELFSection::Header> headers =
708 w->SlotAt<ELFSection::Header>(
sizeof(ELFHeader));
711 for (ELFSection* section : sections_) {
712 section->WriteBody(headers.at(index), w);
740 ELFSymbol(
const char* name, uintptr_t value, uintptr_t size, Binding binding,
741 Type type, uint16_t section)
745 info((binding << 4) | type),
749 Binding binding()
const {
return static_cast<Binding
>(info >> 4); }
750#if (V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM)
751 struct SerializedLayout {
752 SerializedLayout(uint32_t name, uintptr_t value, uintptr_t size,
753 Binding binding,
Type type, uint16_t section)
757 info((binding << 4) | type),
768#elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_64_BIT || \
769 V8_TARGET_ARCH_PPC64 && V8_OS_LINUX || V8_TARGET_ARCH_S390X
770 struct SerializedLayout {
771 SerializedLayout(uint32_t name, uintptr_t value, uintptr_t size,
772 Binding binding,
Type type, uint16_t section)
774 info((binding << 4) | type),
789 void Write(Writer::Slot<SerializedLayout> s, ELFStringTable* t)
const {
791 s->name =
static_cast<uint32_t
>(t->Add(name));
796 s->section = section;
808class ELFSymbolTable :
public ELFSection {
810 ELFSymbolTable(
const char* name,
Zone* zone)
811 : ELFSection(name, TYPE_SYMTAB,
sizeof(uintptr_t)),
815 void WriteBody(Writer::Slot<Header> header, Writer* w)
override {
816 w->Align(header->alignment);
818 header->offset = w->position();
820 Writer::Slot<ELFSymbol::SerializedLayout> symbols =
821 w->CreateSlotsHere<ELFSymbol::SerializedLayout>(
822 static_cast<uint32_t
>(total_symbols));
824 header->size = w->position() - header->offset;
827 ELFStringTable* strtab =
828 static_cast<ELFStringTable*
>(w->debug_object()->SectionAt(
index() + 1));
829 strtab->AttachWriter(w);
830 symbols.at(0).set(ELFSymbol::SerializedLayout(
831 0, 0, 0, ELFSymbol::BIND_LOCAL, ELFSymbol::TYPE_NOTYPE, 0));
832 WriteSymbolsList(&
locals_, symbols.at(1), strtab);
834 symbols.at(
static_cast<uint32_t
>(
locals_.size() + 1)),
836 strtab->DetachWriter();
839 void Add(
const ELFSymbol& symbol) {
840 if (symbol.binding() == ELFSymbol::BIND_LOCAL) {
848 void PopulateHeader(Writer::Slot<Header> header)
override {
849 ELFSection::PopulateHeader(header);
851 header->link =
index() + 1;
852 header->info =
static_cast<uint32_t
>(
locals_.size() + 1);
853 header->entry_size =
sizeof(ELFSymbol::SerializedLayout);
858 Writer::Slot<ELFSymbol::SerializedLayout> dst,
859 ELFStringTable* strtab) {
861 for (
const ELFSymbol& symbol : *src) {
862 symbol.Write(dst.at(
i++), strtab);
873 void SetPosition(intptr_t
pc,
int pos,
bool is_statement) {
874 AddPCInfo(PCInfo(
pc,
pos, is_statement));
878 PCInfo(intptr_t
pc,
int pos,
bool is_statement)
886 std::vector<PCInfo>* pc_info() {
return &pc_info_; }
889 void AddPCInfo(
const PCInfo& pc_info) { pc_info_.push_back(pc_info); }
891 std::vector<PCInfo> pc_info_;
894class CodeDescription {
896#if V8_TARGET_ARCH_X64
909 shared_info_(shared),
911 is_function_(is_function),
912 code_region_(region) {}
914 const char*
name()
const {
return name_; }
916 LineInfo* lineinfo()
const {
return lineinfo_; }
918 bool is_function()
const {
return is_function_; }
920 bool has_scope_info()
const {
return !shared_info_.is_null(); }
924 return shared_info_->scope_info();
927 uintptr_t CodeStart()
const {
return code_region_.begin(); }
929 uintptr_t CodeEnd()
const {
return code_region_.end(); }
931 uintptr_t CodeSize()
const {
return code_region_.size(); }
934 return !shared_info_.is_null() && IsScript(shared_info_->script());
937 Tagged<Script> script() {
return Cast<Script>(shared_info_->script()); }
939 bool IsLineInfoAvailable() {
return lineinfo_ !=
nullptr; }
943#if V8_TARGET_ARCH_X64
944 uintptr_t GetStackStateStartAddress(
StackState state)
const {
945 DCHECK(state < STACK_STATE_MAX);
946 return stack_state_start_addresses_[
state];
949 void SetStackStateStartAddress(
StackState state, uintptr_t addr) {
950 DCHECK(state < STACK_STATE_MAX);
951 stack_state_start_addresses_[
state] = addr;
955 std::unique_ptr<char[]> GetFilename() {
956 if (!shared_info_.is_null() && IsString(script()->
name())) {
957 return Cast<String>(script()->
name())->ToCString();
959 std::unique_ptr<char[]>
result(
new char[1]);
965 int GetScriptLineNumber(
int pos) {
966 if (!shared_info_.is_null()) {
967 return script()->GetLineNumber(
pos) + 1;
979#if V8_TARGET_ARCH_X64
980 uintptr_t stack_state_start_addresses_[STACK_STATE_MAX];
985static void CreateSymbolsTable(CodeDescription* desc,
Zone* zone, ELF* elf,
986 size_t text_section_index) {
987 ELFSymbolTable* symtab = zone->
New<ELFSymbolTable>(
".symtab", zone);
988 ELFStringTable* strtab = zone->
New<ELFStringTable>(
".strtab");
991 elf->AddSection(symtab);
992 elf->AddSection(strtab);
994 symtab->Add(ELFSymbol(
"V8 Code", 0, 0, ELFSymbol::BIND_LOCAL,
995 ELFSymbol::TYPE_FILE, ELFSection::INDEX_ABSOLUTE));
997 symtab->Add(ELFSymbol(desc->name(), 0, desc->CodeSize(),
998 ELFSymbol::BIND_GLOBAL, ELFSymbol::TYPE_FUNC,
999 text_section_index));
1003class DebugInfoSection :
public DebugSection {
1005 explicit DebugInfoSection(CodeDescription* desc)
1007 : ELFSection(
".debug_info", TYPE_PROGBITS, 1),
1009 : MachOSection(
"__debug_info",
"__DWARF", 1,
1010 MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG),
1016 enum DWARF2LocationOp {
1052 enum DWARF2Encoding { DW_ATE_ADDRESS = 0x1, DW_ATE_SIGNED = 0x5 };
1054 bool WriteBodyInternal(Writer* w)
override {
1055 uintptr_t cu_start = w->position();
1056 Writer::Slot<uint32_t> size = w->CreateSlotHere<uint32_t>();
1057 uintptr_t
start = w->position();
1058 w->Write<uint16_t>(2);
1059 w->Write<uint32_t>(0);
1060 w->Write<uint8_t>(
sizeof(intptr_t));
1063 w->WriteString(desc_->GetFilename().get());
1064 w->Write<intptr_t>(desc_->CodeStart());
1065 w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize());
1066 w->Write<uint32_t>(0);
1068 uint32_t ty_offset =
static_cast<uint32_t
>(w->position() - cu_start);
1071 w->WriteString(
"v8value");
1073 if (desc_->has_scope_info()) {
1076 w->WriteString(desc_->name());
1077 w->Write<intptr_t>(desc_->CodeStart());
1078 w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize());
1079 Writer::Slot<uint32_t> fb_block_size = w->CreateSlotHere<uint32_t>();
1080 uintptr_t fb_block_start = w->position();
1081#if V8_TARGET_ARCH_IA32
1082 w->Write<uint8_t>(DW_OP_reg5);
1083#elif V8_TARGET_ARCH_X64
1084 w->Write<uint8_t>(DW_OP_reg6);
1085#elif V8_TARGET_ARCH_ARM
1087#elif V8_TARGET_ARCH_MIPS
1089#elif V8_TARGET_ARCH_MIPS64
1091#elif V8_TARGET_ARCH_LOONG64
1093#elif V8_TARGET_ARCH_PPC64 && V8_OS_LINUX
1094 w->Write<uint8_t>(DW_OP_reg31);
1095#elif V8_TARGET_ARCH_S390X
1096 w->Write<uint8_t>(DW_OP_reg11);
1098#error Unsupported target architecture.
1100 fb_block_size.set(
static_cast<uint32_t
>(w->position() - fb_block_start));
1102 int params = scope->ParameterCount();
1103 int context_slots = scope->ContextLocalCount();
1105 int internal_slots = scope->ContextHeaderLength();
1106 int current_abbreviation = 4;
1108 for (
int param = 0; param < params; ++param) {
1109 w->WriteULEB128(current_abbreviation++);
1110 w->WriteString(
"param");
1111 w->Write(std::to_string(param).c_str());
1112 w->Write<uint32_t>(ty_offset);
1113 Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
1114 uintptr_t block_start = w->position();
1115 w->Write<uint8_t>(DW_OP_fbreg);
1116 w->WriteSLEB128(StandardFrameConstants::kFixedFrameSizeAboveFp +
1118 block_size.set(
static_cast<uint32_t
>(w->position() - block_start));
1122 DCHECK(internal_slots == 2 || internal_slots == 3);
1123 DCHECK_EQ(Context::SCOPE_INFO_INDEX, 0);
1126 w->WriteULEB128(current_abbreviation++);
1127 w->WriteString(
".scope_info");
1128 w->WriteULEB128(current_abbreviation++);
1129 w->WriteString(
".previous");
1130 if (internal_slots == 3) {
1131 w->WriteULEB128(current_abbreviation++);
1132 w->WriteString(
".extension");
1135 for (
int context_slot = 0; context_slot < context_slots; ++context_slot) {
1136 w->WriteULEB128(current_abbreviation++);
1137 w->WriteString(
"context_slot");
1138 w->Write(std::to_string(context_slot + internal_slots).c_str());
1142 w->WriteULEB128(current_abbreviation++);
1143 w->WriteString(
"__function");
1144 w->Write<uint32_t>(ty_offset);
1145 Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
1146 uintptr_t block_start = w->position();
1147 w->Write<uint8_t>(DW_OP_fbreg);
1148 w->WriteSLEB128(StandardFrameConstants::kFunctionOffset);
1149 block_size.set(
static_cast<uint32_t
>(w->position() - block_start));
1153 w->WriteULEB128(current_abbreviation++);
1154 w->WriteString(
"__context");
1155 w->Write<uint32_t>(ty_offset);
1156 Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
1157 uintptr_t block_start = w->position();
1158 w->Write<uint8_t>(DW_OP_fbreg);
1159 w->WriteSLEB128(StandardFrameConstants::kContextOffset);
1160 block_size.set(
static_cast<uint32_t
>(w->position() - block_start));
1167 size.set(
static_cast<uint32_t
>(w->position() -
start));
1172 CodeDescription* desc_;
1175class DebugAbbrevSection :
public DebugSection {
1177 explicit DebugAbbrevSection(CodeDescription* desc)
1179 : ELFSection(
".debug_abbrev", TYPE_PROGBITS, 1),
1181 : MachOSection(
"__debug_abbrev",
"__DWARF", 1,
1182 MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG),
1189 DW_TAG_FORMAL_PARAMETER = 0x05,
1190 DW_TAG_POINTER_TYPE = 0xF,
1191 DW_TAG_COMPILE_UNIT = 0x11,
1192 DW_TAG_STRUCTURE_TYPE = 0x13,
1193 DW_TAG_BASE_TYPE = 0x24,
1194 DW_TAG_SUBPROGRAM = 0x2E,
1195 DW_TAG_VARIABLE = 0x34
1199 enum DWARF2ChildrenDetermination { DW_CHILDREN_NO = 0, DW_CHILDREN_YES = 1 };
1202 enum DWARF2Attribute {
1203 DW_AT_LOCATION = 0x2,
1205 DW_AT_BYTE_SIZE = 0xB,
1206 DW_AT_STMT_LIST = 0x10,
1207 DW_AT_LOW_PC = 0x11,
1208 DW_AT_HIGH_PC = 0x12,
1209 DW_AT_ENCODING = 0x3E,
1210 DW_AT_FRAME_BASE = 0x40,
1215 enum DWARF2AttributeForm {
1217 DW_FORM_BLOCK4 = 0x4,
1218 DW_FORM_STRING = 0x8,
1219 DW_FORM_DATA4 = 0x6,
1220 DW_FORM_BLOCK = 0x9,
1221 DW_FORM_DATA1 = 0xB,
1226 void WriteVariableAbbreviation(Writer* w,
int abbreviation_code,
1227 bool has_value,
bool is_parameter) {
1228 w->WriteULEB128(abbreviation_code);
1229 w->WriteULEB128(is_parameter ? DW_TAG_FORMAL_PARAMETER : DW_TAG_VARIABLE);
1230 w->Write<uint8_t>(DW_CHILDREN_NO);
1231 w->WriteULEB128(DW_AT_NAME);
1232 w->WriteULEB128(DW_FORM_STRING);
1234 w->WriteULEB128(DW_AT_TYPE);
1235 w->WriteULEB128(DW_FORM_REF4);
1236 w->WriteULEB128(DW_AT_LOCATION);
1237 w->WriteULEB128(DW_FORM_BLOCK4);
1243 bool WriteBodyInternal(Writer* w)
override {
1244 int current_abbreviation = 1;
1245 bool extra_info = desc_->has_scope_info();
1246 DCHECK(desc_->IsLineInfoAvailable());
1247 w->WriteULEB128(current_abbreviation++);
1248 w->WriteULEB128(DW_TAG_COMPILE_UNIT);
1249 w->Write<uint8_t>(extra_info ? DW_CHILDREN_YES : DW_CHILDREN_NO);
1250 w->WriteULEB128(DW_AT_NAME);
1251 w->WriteULEB128(DW_FORM_STRING);
1252 w->WriteULEB128(DW_AT_LOW_PC);
1253 w->WriteULEB128(DW_FORM_ADDR);
1254 w->WriteULEB128(DW_AT_HIGH_PC);
1255 w->WriteULEB128(DW_FORM_ADDR);
1256 w->WriteULEB128(DW_AT_STMT_LIST);
1257 w->WriteULEB128(DW_FORM_DATA4);
1263 int params = scope->ParameterCount();
1264 int context_slots = scope->ContextLocalCount();
1266 int internal_slots = Context::MIN_CONTEXT_SLOTS;
1272 w->WriteULEB128(current_abbreviation++);
1273 w->WriteULEB128(DW_TAG_SUBPROGRAM);
1274 w->Write<uint8_t>(DW_CHILDREN_YES);
1275 w->WriteULEB128(DW_AT_NAME);
1276 w->WriteULEB128(DW_FORM_STRING);
1277 w->WriteULEB128(DW_AT_LOW_PC);
1278 w->WriteULEB128(DW_FORM_ADDR);
1279 w->WriteULEB128(DW_AT_HIGH_PC);
1280 w->WriteULEB128(DW_FORM_ADDR);
1281 w->WriteULEB128(DW_AT_FRAME_BASE);
1282 w->WriteULEB128(DW_FORM_BLOCK4);
1286 w->WriteULEB128(current_abbreviation++);
1287 w->WriteULEB128(DW_TAG_STRUCTURE_TYPE);
1288 w->Write<uint8_t>(DW_CHILDREN_NO);
1289 w->WriteULEB128(DW_AT_BYTE_SIZE);
1290 w->WriteULEB128(DW_FORM_DATA1);
1291 w->WriteULEB128(DW_AT_NAME);
1292 w->WriteULEB128(DW_FORM_STRING);
1296 for (
int param = 0; param < params; ++param) {
1297 WriteVariableAbbreviation(w, current_abbreviation++,
true,
true);
1300 for (
int internal_slot = 0; internal_slot < internal_slots;
1302 WriteVariableAbbreviation(w, current_abbreviation++,
false,
false);
1305 for (
int context_slot = 0; context_slot < context_slots; ++context_slot) {
1306 WriteVariableAbbreviation(w, current_abbreviation++,
false,
false);
1310 WriteVariableAbbreviation(w, current_abbreviation++,
true,
false);
1313 WriteVariableAbbreviation(w, current_abbreviation++,
true,
false);
1323 CodeDescription* desc_;
1326class DebugLineSection :
public DebugSection {
1328 explicit DebugLineSection(CodeDescription* desc)
1330 : ELFSection(
".debug_line", TYPE_PROGBITS, 1),
1332 : MachOSection(
"__debug_line",
"__DWARF", 1,
1333 MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG),
1339 enum DWARF2Opcodes {
1341 DW_LNS_ADVANCE_PC = 2,
1342 DW_LNS_ADVANCE_LINE = 3,
1343 DW_LNS_SET_FILE = 4,
1344 DW_LNS_SET_COLUMN = 5,
1345 DW_LNS_NEGATE_STMT = 6
1349 enum DWARF2ExtendedOpcode {
1350 DW_LNE_END_SEQUENCE = 1,
1351 DW_LNE_SET_ADDRESS = 2,
1352 DW_LNE_DEFINE_FILE = 3
1355 bool WriteBodyInternal(Writer* w)
override {
1357 Writer::Slot<uint32_t> total_length = w->CreateSlotHere<uint32_t>();
1358 uintptr_t
start = w->position();
1361 const int8_t line_base = 1;
1362 const uint8_t line_range = 7;
1363 const int8_t max_line_incr = (line_base + line_range - 1);
1364 const uint8_t opcode_base = DW_LNS_NEGATE_STMT + 1;
1366 w->Write<uint16_t>(2);
1367 Writer::Slot<uint32_t> prologue_length = w->CreateSlotHere<uint32_t>();
1368 uintptr_t prologue_start = w->position();
1369 w->Write<uint8_t>(1);
1370 w->Write<uint8_t>(1);
1371 w->Write<int8_t>(line_base);
1372 w->Write<uint8_t>(line_range);
1373 w->Write<uint8_t>(opcode_base);
1374 w->Write<uint8_t>(0);
1375 w->Write<uint8_t>(1);
1376 w->Write<uint8_t>(1);
1377 w->Write<uint8_t>(1);
1378 w->Write<uint8_t>(1);
1379 w->Write<uint8_t>(0);
1380 w->Write<uint8_t>(0);
1381 w->WriteString(desc_->GetFilename().get());
1385 w->Write<uint8_t>(0);
1386 prologue_length.set(
static_cast<uint32_t
>(w->position() - prologue_start));
1388 WriteExtendedOpcode(w, DW_LNE_SET_ADDRESS,
sizeof(intptr_t));
1389 w->Write<intptr_t>(desc_->CodeStart());
1390 w->Write<uint8_t>(DW_LNS_COPY);
1394 bool is_statement =
true;
1396 std::vector<LineInfo::PCInfo>* pc_info = desc_->lineinfo()->pc_info();
1397 std::sort(pc_info->begin(), pc_info->end(), &ComparePCInfo);
1399 for (
size_t i = 0;
i < pc_info->size();
i++) {
1400 LineInfo::PCInfo* info = &pc_info->at(
i);
1405 intptr_t new_line = desc_->GetScriptLineNumber(info->pos_);
1406 if (new_line == line) {
1414 if ((
i + 1) == pc_info->size()) {
1415 if (!is_statement) {
1416 w->Write<uint8_t>(DW_LNS_NEGATE_STMT);
1418 }
else if (is_statement != info->is_statement_) {
1419 w->Write<uint8_t>(DW_LNS_NEGATE_STMT);
1420 is_statement = !is_statement;
1426 uintptr_t pc_diff = info->pc_ -
pc;
1427 intptr_t line_diff = new_line - line;
1430 intptr_t special_opcode =
1431 (line_diff - line_base) + (line_range * pc_diff) + opcode_base;
1438 if ((special_opcode >= opcode_base) && (special_opcode <= 255) &&
1439 (line_diff <= max_line_incr) && (line_diff >= line_base)) {
1440 w->Write<uint8_t>(special_opcode);
1442 w->Write<uint8_t>(DW_LNS_ADVANCE_PC);
1443 w->WriteSLEB128(pc_diff);
1444 w->Write<uint8_t>(DW_LNS_ADVANCE_LINE);
1445 w->WriteSLEB128(line_diff);
1446 w->Write<uint8_t>(DW_LNS_COPY);
1455 w->Write<uint8_t>(DW_LNS_ADVANCE_PC);
1456 w->WriteSLEB128(desc_->CodeSize() -
pc);
1457 WriteExtendedOpcode(w, DW_LNE_END_SEQUENCE, 0);
1458 total_length.set(
static_cast<uint32_t
>(w->position() -
start));
1463 void WriteExtendedOpcode(Writer* w, DWARF2ExtendedOpcode op,
1464 size_t operands_size) {
1465 w->Write<uint8_t>(0);
1466 w->WriteULEB128(operands_size + 1);
1467 w->Write<uint8_t>(op);
1470 static bool ComparePCInfo(
const LineInfo::PCInfo& a,
1471 const LineInfo::PCInfo& b) {
1472 if (a.pc_ == b.pc_) {
1473 if (a.is_statement_ != b.is_statement_) {
1474 return !b.is_statement_;
1478 return a.pc_ < b.pc_;
1481 CodeDescription* desc_;
1484#if V8_TARGET_ARCH_X64
1486class UnwindInfoSection :
public DebugSection {
1488 explicit UnwindInfoSection(CodeDescription* desc);
1489 bool WriteBodyInternal(Writer* w)
override;
1491 int WriteCIE(Writer* w);
1492 void WriteFDE(Writer* w,
int);
1494 void WriteFDEStateOnEntry(Writer* w);
1495 void WriteFDEStateAfterRBPPush(Writer* w);
1496 void WriteFDEStateAfterRBPSet(Writer* w);
1497 void WriteFDEStateAfterRBPPop(Writer* w);
1499 void WriteLength(Writer* w, Writer::Slot<uint32_t>* length_slot,
1500 int initial_position);
1503 CodeDescription* desc_;
1506 enum CFIInstructions {
1507 DW_CFA_ADVANCE_LOC = 0x40,
1508 DW_CFA_OFFSET = 0x80,
1509 DW_CFA_RESTORE = 0xC0,
1511 DW_CFA_SET_LOC = 0x01,
1512 DW_CFA_ADVANCE_LOC1 = 0x02,
1513 DW_CFA_ADVANCE_LOC2 = 0x03,
1514 DW_CFA_ADVANCE_LOC4 = 0x04,
1515 DW_CFA_OFFSET_EXTENDED = 0x05,
1516 DW_CFA_RESTORE_EXTENDED = 0x06,
1517 DW_CFA_UNDEFINED = 0x07,
1518 DW_CFA_SAME_VALUE = 0x08,
1519 DW_CFA_REGISTER = 0x09,
1520 DW_CFA_REMEMBER_STATE = 0x0A,
1521 DW_CFA_RESTORE_STATE = 0x0B,
1522 DW_CFA_DEF_CFA = 0x0C,
1523 DW_CFA_DEF_CFA_REGISTER = 0x0D,
1524 DW_CFA_DEF_CFA_OFFSET = 0x0E,
1526 DW_CFA_DEF_CFA_EXPRESSION = 0x0F,
1527 DW_CFA_EXPRESSION = 0x10,
1528 DW_CFA_OFFSET_EXTENDED_SF = 0x11,
1529 DW_CFA_DEF_CFA_SF = 0x12,
1530 DW_CFA_DEF_CFA_OFFSET_SF = 0x13,
1531 DW_CFA_VAL_OFFSET = 0x14,
1532 DW_CFA_VAL_OFFSET_SF = 0x15,
1533 DW_CFA_VAL_EXPRESSION = 0x16
1537 enum RegisterMapping {
1547 CODE_ALIGN_FACTOR = 1,
1548 DATA_ALIGN_FACTOR = 1,
1549 RETURN_ADDRESS_REGISTER = AMD64_RA
1553void UnwindInfoSection::WriteLength(Writer* w,
1554 Writer::Slot<uint32_t>* length_slot,
1555 int initial_position) {
1560 w->Write<uint8_t>(DW_CFA_NOP);
1565 length_slot->set(
static_cast<uint32_t
>(w->position() - initial_position));
1568UnwindInfoSection::UnwindInfoSection(CodeDescription* desc)
1570 : ELFSection(
".eh_frame", TYPE_X86_64_UNWIND, 1),
1572 : MachOSection(
"__eh_frame",
"__TEXT",
sizeof(uintptr_t),
1573 MachOSection::S_REGULAR),
1578int UnwindInfoSection::WriteCIE(Writer* w) {
1579 Writer::Slot<uint32_t> cie_length_slot = w->CreateSlotHere<uint32_t>();
1580 uint32_t cie_position =
static_cast<uint32_t
>(w->position());
1585 w->Write<uint32_t>(CIE_ID);
1586 w->Write<uint8_t>(CIE_VERSION);
1587 w->Write<uint8_t>(0);
1588 w->WriteSLEB128(CODE_ALIGN_FACTOR);
1589 w->WriteSLEB128(DATA_ALIGN_FACTOR);
1590 w->Write<uint8_t>(RETURN_ADDRESS_REGISTER);
1592 WriteLength(w, &cie_length_slot, cie_position);
1594 return cie_position;
1597void UnwindInfoSection::WriteFDE(Writer* w,
int cie_position) {
1599 Writer::Slot<uint32_t> fde_length_slot = w->CreateSlotHere<uint32_t>();
1600 int fde_position =
static_cast<uint32_t
>(w->position());
1601 w->Write<int32_t>(fde_position - cie_position + 4);
1603 w->Write<uintptr_t>(desc_->CodeStart());
1604 w->Write<uintptr_t>(desc_->CodeSize());
1606 WriteFDEStateOnEntry(w);
1607 WriteFDEStateAfterRBPPush(w);
1608 WriteFDEStateAfterRBPSet(w);
1609 WriteFDEStateAfterRBPPop(w);
1611 WriteLength(w, &fde_length_slot, fde_position);
1614void UnwindInfoSection::WriteFDEStateOnEntry(Writer* w) {
1620 w->Write<uint8_t>(DW_CFA_DEF_CFA_SF);
1621 w->WriteULEB128(AMD64_RSP);
1626 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED);
1627 w->WriteULEB128(AMD64_RA);
1631 w->Write<uint8_t>(DW_CFA_SAME_VALUE);
1632 w->WriteULEB128(AMD64_RBP);
1635 w->Write<uint8_t>(DW_CFA_SET_LOC);
1637 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_PUSH));
1640void UnwindInfoSection::WriteFDEStateAfterRBPPush(Writer* w) {
1645 w->Write<uint8_t>(DW_CFA_DEF_CFA_OFFSET);
1650 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED);
1651 w->WriteULEB128(AMD64_RBP);
1655 w->Write<uint8_t>(DW_CFA_SET_LOC);
1657 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_SET));
1660void UnwindInfoSection::WriteFDEStateAfterRBPSet(Writer* w) {
1664 w->Write<uint8_t>(DW_CFA_DEF_CFA);
1665 w->WriteULEB128(AMD64_RBP);
1669 w->Write<uint8_t>(DW_CFA_SET_LOC);
1671 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_POP));
1674void UnwindInfoSection::WriteFDEStateAfterRBPPop(Writer* w) {
1679 w->Write<uint8_t>(DW_CFA_DEF_CFA_SF);
1680 w->WriteULEB128(AMD64_RSP);
1684 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED);
1685 w->WriteULEB128(AMD64_RBP);
1689 w->Write<uint8_t>(DW_CFA_SET_LOC);
1690 w->Write<uint64_t>(desc_->CodeEnd());
1693bool UnwindInfoSection::WriteBodyInternal(Writer* w) {
1694 uint32_t cie_position = WriteCIE(w);
1695 WriteFDE(w, cie_position);
1701static void CreateDWARFSections(CodeDescription* desc,
Zone* zone,
1703 if (desc->IsLineInfoAvailable()) {
1704 obj->AddSection(zone->
New<DebugInfoSection>(desc));
1705 obj->AddSection(zone->
New<DebugAbbrevSection>(desc));
1706 obj->AddSection(zone->
New<DebugLineSection>(desc));
1708#if V8_TARGET_ARCH_X64
1709 obj->AddSection(zone->
New<UnwindInfoSection>(desc));
1717enum JITAction { JIT_NOACTION = 0, JIT_REGISTER_FN, JIT_UNREGISTER_FN };
1719struct JITCodeEntry {
1720 JITCodeEntry* next_;
1721 JITCodeEntry*
prev_;
1722 Address symfile_addr_;
1723 uint64_t symfile_size_;
1726struct JITDescriptor {
1728 uint32_t action_flag_;
1729 JITCodeEntry* relevant_entry_;
1730 JITCodeEntry* first_entry_;
1736void __attribute__((noinline)) __jit_debug_register_code() { __asm__(
""); }
1741JITDescriptor __jit_debug_descriptor = {1, 0,
nullptr,
nullptr};
1744void __gdb_print_v8_object(
TaggedBase object) {
1752static JITCodeEntry* CreateCodeEntry(
Address symfile_addr,
1753 uintptr_t symfile_size) {
1754 JITCodeEntry* entry =
static_cast<JITCodeEntry*
>(
1757 entry->symfile_addr_ =
reinterpret_cast<Address>(entry + 1);
1758 entry->symfile_size_ = symfile_size;
1759 MemCopy(
reinterpret_cast<void*
>(entry->symfile_addr_),
1760 reinterpret_cast<void*
>(symfile_addr), symfile_size);
1762 entry->prev_ = entry->next_ =
nullptr;
1767static void DestroyCodeEntry(JITCodeEntry* entry) {
base::Free(entry); }
1769static void RegisterCodeEntry(JITCodeEntry* entry) {
1770 entry->next_ = __jit_debug_descriptor.first_entry_;
1771 if (entry->next_ !=
nullptr) entry->next_->prev_ = entry;
1772 __jit_debug_descriptor.first_entry_ = __jit_debug_descriptor.relevant_entry_ =
1775 __jit_debug_descriptor.action_flag_ = JIT_REGISTER_FN;
1776 __jit_debug_register_code();
1779static void UnregisterCodeEntry(JITCodeEntry* entry) {
1780 if (entry->prev_ !=
nullptr) {
1781 entry->prev_->next_ = entry->next_;
1783 __jit_debug_descriptor.first_entry_ = entry->next_;
1786 if (entry->next_ !=
nullptr) {
1787 entry->next_->prev_ = entry->prev_;
1790 __jit_debug_descriptor.relevant_entry_ = entry;
1791 __jit_debug_descriptor.action_flag_ = JIT_UNREGISTER_FN;
1792 __jit_debug_register_code();
1795static JITCodeEntry* CreateELFObject(CodeDescription* desc,
Isolate* isolate) {
1798 MachO mach_o(&zone);
1801 const uint32_t code_alignment =
static_cast<uint32_t
>(
kCodeAlignment);
1803 "Unsupported code alignment value");
1804 mach_o.AddSection(zone.
New<MachOTextSection>(
1805 code_alignment, desc->CodeStart(), desc->CodeSize()));
1807 CreateDWARFSections(desc, &zone, &mach_o);
1809 mach_o.Write(&w, desc->CodeStart(), desc->CodeSize());
1815 size_t text_section_index = elf.AddSection(zone.
New<FullHeaderELFSection>(
1816 ".text", ELFSection::TYPE_NOBITS,
kCodeAlignment, desc->CodeStart(), 0,
1817 desc->CodeSize(), ELFSection::FLAG_ALLOC | ELFSection::FLAG_EXEC));
1819 CreateSymbolsTable(desc, &zone, &elf, text_section_index);
1821 CreateDWARFSections(desc, &zone, &elf);
1826 return CreateCodeEntry(
reinterpret_cast<Address>(w.buffer()), w.position());
1831struct AddressRegionLess {
1834 if (a.begin() == b.
begin())
return a.end() < b.
end();
1835 return a.begin() < b.
begin();
1839using CodeMap = std::map<base::AddressRegion, JITCodeEntry*, AddressRegionLess>;
1841static CodeMap* GetCodeMap() {
1843 static CodeMap* code_map =
nullptr;
1844 if (code_map ==
nullptr) code_map =
new CodeMap();
1848static uint32_t HashCodeAddress(
Address addr) {
1849 static const uintptr_t kGoldenRatio = 2654435761u;
1855 if (line_map ==
nullptr) {
1861static void PutLineInfo(
Address addr, LineInfo* info) {
1864 reinterpret_cast<void*
>(addr), HashCodeAddress(addr));
1865 if (e->
value !=
nullptr)
delete static_cast<LineInfo*
>(e->
value);
1869static LineInfo* GetLineInfo(
Address addr) {
1870 void* value = GetLineMap()->Remove(
reinterpret_cast<void*
>(addr),
1871 HashCodeAddress(addr));
1872 return static_cast<LineInfo*
>(
value);
1875static void AddUnwindInfo(CodeDescription* desc) {
1876#if V8_TARGET_ARCH_X64
1877 if (desc->is_function()) {
1881 static const int kFramePointerPushOffset = 1;
1882 static const int kFramePointerSetOffset = 4;
1883 static const int kFramePointerPopOffset = -3;
1885 uintptr_t frame_pointer_push_address =
1886 desc->CodeStart() + kFramePointerPushOffset;
1888 uintptr_t frame_pointer_set_address =
1889 desc->CodeStart() + kFramePointerSetOffset;
1891 uintptr_t frame_pointer_pop_address =
1892 desc->CodeEnd() + kFramePointerPopOffset;
1894 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_PUSH,
1895 frame_pointer_push_address);
1896 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_SET,
1897 frame_pointer_set_address);
1898 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_POP,
1899 frame_pointer_pop_address);
1901 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_PUSH,
1903 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_SET,
1905 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_POP,
1913static std::optional<std::pair<CodeMap::iterator, CodeMap::iterator>>
1915 DCHECK_LT(region.begin(), region.end());
1917 if (map->empty())
return {};
1923 auto it = map->lower_bound(region);
1926 if (it == map->end()) {
1927 start_it = map->begin();
1929 for (; start_it != map->end(); ++start_it) {
1930 if (start_it->first.end() > region.begin()) {
1934 }
else if (it != map->begin()) {
1935 for (--it; it != map->begin(); --it) {
1936 if ((*it).first.end() <= region.begin())
break;
1939 if (it == map->begin() && it->first.end() > region.begin()) {
1944 if (start_it == map->end()) {
1950 const auto end_it = map->lower_bound({region.end(), 0});
1954 if (std::distance(start_it, end_it) < 1)
1957 return {{start_it, end_it}};
1962static void RemoveJITCodeEntries(CodeMap* map,
1964 if (
auto overlap = GetOverlappingRegions(map, region)) {
1965 auto start_it = overlap->first;
1966 auto end_it = overlap->second;
1967 for (
auto it = start_it; it != end_it; it++) {
1968 JITCodeEntry* old_entry = (*it).second;
1969 UnregisterCodeEntry(old_entry);
1970 DestroyCodeEntry(old_entry);
1973 map->erase(start_it, end_it);
1979 JITCodeEntry* entry,
bool dump_if_enabled,
1980 const char* name_hint) {
1981#if defined(DEBUG) && !V8_OS_WIN
1982 static int file_num = 0;
1983 if (
v8_flags.gdbjit_dump && dump_if_enabled) {
1984 static const int kMaxFileNameSize = 64;
1988 "/tmp/elfdump%s%d.o", (name_hint !=
nullptr) ? name_hint :
"",
1990 WriteBytes(file_name,
reinterpret_cast<uint8_t*
>(entry->symfile_addr_),
1991 static_cast<int>(entry->symfile_size_));
1995 auto result = map->emplace(region, entry);
1999 RegisterCodeEntry(entry);
2004 Isolate* isolate,
bool is_function) {
2006 CodeDescription
code_desc(name, region, shared, lineinfo, is_function);
2008 CodeMap* code_map = GetCodeMap();
2009 RemoveJITCodeEntries(code_map, region);
2017 JITCodeEntry* entry = CreateELFObject(&
code_desc, isolate);
2021 const char* name_hint =
nullptr;
2022 bool should_dump =
false;
2024 if (strlen(
v8_flags.gdbjit_dump_filter) == 0) {
2027 }
else if (name !=
nullptr) {
2028 name_hint = strstr(name,
v8_flags.gdbjit_dump_filter);
2029 should_dump = (name_hint !=
nullptr);
2032 AddJITCodeEntry(code_map, region, entry, should_dump, name_hint);
2042 switch (event->
type) {
2045 LineInfo* lineinfo = GetLineInfo(addr);
2052 bool is_function =
false;
2062 isolate->heap()->FindCodeForInnerPointer(addr);
2065 AddCode(event_name.c_str(), {addr, event->code_len}, shared, lineinfo,
2066 isolate, is_function);
2077 LineInfo* line_info =
reinterpret_cast<LineInfo*
>(
event->user_data);
2078 line_info->SetPosition(
static_cast<intptr_t
>(event->
line_info.
offset),
2086 mutable_event->
user_data =
new LineInfo();
2090 LineInfo* line_info =
reinterpret_cast<LineInfo*
>(
event->user_data);
2099 auto result = GetCodeMap()->emplace(region,
nullptr);
2104void ClearCodeMapForTesting() { GetCodeMap()->clear(); }
2107 if (
auto overlaps = GetOverlappingRegions(GetCodeMap(), region)) {
2108 return std::distance(overlaps->first, overlaps->second);