1 // Copyright 2010 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifdef ENABLE_GDB_JIT_INTERFACE 6 #include "src/v8.h" 7 #include "src/gdb-jit.h" 8 9 #include "src/bootstrapper.h" 10 #include "src/compiler.h" 11 #include "src/frames.h" 12 #include "src/frames-inl.h" 13 #include "src/global-handles.h" 14 #include "src/messages.h" 15 #include "src/natives.h" 16 #include "src/platform.h" 17 #include "src/scopes.h" 18 19 namespace v8 { 20 namespace internal { 21 22 #ifdef __APPLE__ 23 #define __MACH_O 24 class MachO; 25 class MachOSection; 26 typedef MachO DebugObject; 27 typedef MachOSection DebugSection; 28 #else 29 #define __ELF 30 class ELF; 31 class ELFSection; 32 typedef ELF DebugObject; 33 typedef ELFSection DebugSection; 34 #endif 35 36 class Writer BASE_EMBEDDED { 37 public: 38 explicit Writer(DebugObject* debug_object) 39 : debug_object_(debug_object), 40 position_(0), 41 capacity_(1024), 42 buffer_(reinterpret_cast<byte*>(malloc(capacity_))) { 43 } 44 45 ~Writer() { 46 free(buffer_); 47 } 48 49 uintptr_t position() const { 50 return position_; 51 } 52 53 template<typename T> 54 class Slot { 55 public: 56 Slot(Writer* w, uintptr_t offset) : w_(w), offset_(offset) { } 57 58 T* operator-> () { 59 return w_->RawSlotAt<T>(offset_); 60 } 61 62 void set(const T& value) { 63 *w_->RawSlotAt<T>(offset_) = value; 64 } 65 66 Slot<T> at(int i) { 67 return Slot<T>(w_, offset_ + sizeof(T) * i); 68 } 69 70 private: 71 Writer* w_; 72 uintptr_t offset_; 73 }; 74 75 template<typename T> 76 void Write(const T& val) { 77 Ensure(position_ + sizeof(T)); 78 *RawSlotAt<T>(position_) = val; 79 position_ += sizeof(T); 80 } 81 82 template<typename T> 83 Slot<T> SlotAt(uintptr_t offset) { 84 Ensure(offset + sizeof(T)); 85 return Slot<T>(this, offset); 86 } 87 88 template<typename T> 89 Slot<T> CreateSlotHere() { 90 return CreateSlotsHere<T>(1); 91 } 92 93 template<typename T> 94 Slot<T> CreateSlotsHere(uint32_t count) { 95 uintptr_t slot_position = position_; 96 position_ += sizeof(T) * count; 97 Ensure(position_); 98 return SlotAt<T>(slot_position); 99 } 100 101 void Ensure(uintptr_t pos) { 102 if (capacity_ < pos) { 103 while (capacity_ < pos) capacity_ *= 2; 104 buffer_ = reinterpret_cast<byte*>(realloc(buffer_, capacity_)); 105 } 106 } 107 108 DebugObject* debug_object() { return debug_object_; } 109 110 byte* buffer() { return buffer_; } 111 112 void Align(uintptr_t align) { 113 uintptr_t delta = position_ % align; 114 if (delta == 0) return; 115 uintptr_t padding = align - delta; 116 Ensure(position_ += padding); 117 ASSERT((position_ % align) == 0); 118 } 119 120 void WriteULEB128(uintptr_t value) { 121 do { 122 uint8_t byte = value & 0x7F; 123 value >>= 7; 124 if (value != 0) byte |= 0x80; 125 Write<uint8_t>(byte); 126 } while (value != 0); 127 } 128 129 void WriteSLEB128(intptr_t value) { 130 bool more = true; 131 while (more) { 132 int8_t byte = value & 0x7F; 133 bool byte_sign = byte & 0x40; 134 value >>= 7; 135 136 if ((value == 0 && !byte_sign) || (value == -1 && byte_sign)) { 137 more = false; 138 } else { 139 byte |= 0x80; 140 } 141 142 Write<int8_t>(byte); 143 } 144 } 145 146 void WriteString(const char* str) { 147 do { 148 Write<char>(*str); 149 } while (*str++); 150 } 151 152 private: 153 template<typename T> friend class Slot; 154 155 template<typename T> 156 T* RawSlotAt(uintptr_t offset) { 157 ASSERT(offset < capacity_ && offset + sizeof(T) <= capacity_); 158 return reinterpret_cast<T*>(&buffer_[offset]); 159 } 160 161 DebugObject* debug_object_; 162 uintptr_t position_; 163 uintptr_t capacity_; 164 byte* buffer_; 165 }; 166 167 class ELFStringTable; 168 169 template<typename THeader> 170 class DebugSectionBase : public ZoneObject { 171 public: 172 virtual ~DebugSectionBase() { } 173 174 virtual void WriteBody(Writer::Slot<THeader> header, Writer* writer) { 175 uintptr_t start = writer->position(); 176 if (WriteBodyInternal(writer)) { 177 uintptr_t end = writer->position(); 178 header->offset = start; 179 #if defined(__MACH_O) 180 header->addr = 0; 181 #endif 182 header->size = end - start; 183 } 184 } 185 186 virtual bool WriteBodyInternal(Writer* writer) { 187 return false; 188 } 189 190 typedef THeader Header; 191 }; 192 193 194 struct MachOSectionHeader { 195 char sectname[16]; 196 char segname[16]; 197 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87 198 uint32_t addr; 199 uint32_t size; 200 #else 201 uint64_t addr; 202 uint64_t size; 203 #endif 204 uint32_t offset; 205 uint32_t align; 206 uint32_t reloff; 207 uint32_t nreloc; 208 uint32_t flags; 209 uint32_t reserved1; 210 uint32_t reserved2; 211 }; 212 213 214 class MachOSection : public DebugSectionBase<MachOSectionHeader> { 215 public: 216 enum Type { 217 S_REGULAR = 0x0u, 218 S_ATTR_COALESCED = 0xbu, 219 S_ATTR_SOME_INSTRUCTIONS = 0x400u, 220 S_ATTR_DEBUG = 0x02000000u, 221 S_ATTR_PURE_INSTRUCTIONS = 0x80000000u 222 }; 223 224 MachOSection(const char* name, 225 const char* segment, 226 uintptr_t align, 227 uint32_t flags) 228 : name_(name), 229 segment_(segment), 230 align_(align), 231 flags_(flags) { 232 if (align_ != 0) { 233 ASSERT(IsPowerOf2(align)); 234 align_ = WhichPowerOf2(align_); 235 } 236 } 237 238 virtual ~MachOSection() { } 239 240 virtual void PopulateHeader(Writer::Slot<Header> header) { 241 header->addr = 0; 242 header->size = 0; 243 header->offset = 0; 244 header->align = align_; 245 header->reloff = 0; 246 header->nreloc = 0; 247 header->flags = flags_; 248 header->reserved1 = 0; 249 header->reserved2 = 0; 250 memset(header->sectname, 0, sizeof(header->sectname)); 251 memset(header->segname, 0, sizeof(header->segname)); 252 ASSERT(strlen(name_) < sizeof(header->sectname)); 253 ASSERT(strlen(segment_) < sizeof(header->segname)); 254 strncpy(header->sectname, name_, sizeof(header->sectname)); 255 strncpy(header->segname, segment_, sizeof(header->segname)); 256 } 257 258 private: 259 const char* name_; 260 const char* segment_; 261 uintptr_t align_; 262 uint32_t flags_; 263 }; 264 265 266 struct ELFSectionHeader { 267 uint32_t name; 268 uint32_t type; 269 uintptr_t flags; 270 uintptr_t address; 271 uintptr_t offset; 272 uintptr_t size; 273 uint32_t link; 274 uint32_t info; 275 uintptr_t alignment; 276 uintptr_t entry_size; 277 }; 278 279 280 #if defined(__ELF) 281 class ELFSection : public DebugSectionBase<ELFSectionHeader> { 282 public: 283 enum Type { 284 TYPE_NULL = 0, 285 TYPE_PROGBITS = 1, 286 TYPE_SYMTAB = 2, 287 TYPE_STRTAB = 3, 288 TYPE_RELA = 4, 289 TYPE_HASH = 5, 290 TYPE_DYNAMIC = 6, 291 TYPE_NOTE = 7, 292 TYPE_NOBITS = 8, 293 TYPE_REL = 9, 294 TYPE_SHLIB = 10, 295 TYPE_DYNSYM = 11, 296 TYPE_LOPROC = 0x70000000, 297 TYPE_X86_64_UNWIND = 0x70000001, 298 TYPE_HIPROC = 0x7fffffff, 299 TYPE_LOUSER = 0x80000000, 300 TYPE_HIUSER = 0xffffffff 301 }; 302 303 enum Flags { 304 FLAG_WRITE = 1, 305 FLAG_ALLOC = 2, 306 FLAG_EXEC = 4 307 }; 308 309 enum SpecialIndexes { 310 INDEX_ABSOLUTE = 0xfff1 311 }; 312 313 ELFSection(const char* name, Type type, uintptr_t align) 314 : name_(name), type_(type), align_(align) { } 315 316 virtual ~ELFSection() { } 317 318 void PopulateHeader(Writer::Slot<Header> header, ELFStringTable* strtab); 319 320 virtual void WriteBody(Writer::Slot<Header> header, Writer* w) { 321 uintptr_t start = w->position(); 322 if (WriteBodyInternal(w)) { 323 uintptr_t end = w->position(); 324 header->offset = start; 325 header->size = end - start; 326 } 327 } 328 329 virtual bool WriteBodyInternal(Writer* w) { 330 return false; 331 } 332 333 uint16_t index() const { return index_; } 334 void set_index(uint16_t index) { index_ = index; } 335 336 protected: 337 virtual void PopulateHeader(Writer::Slot<Header> header) { 338 header->flags = 0; 339 header->address = 0; 340 header->offset = 0; 341 header->size = 0; 342 header->link = 0; 343 header->info = 0; 344 header->entry_size = 0; 345 } 346 347 private: 348 const char* name_; 349 Type type_; 350 uintptr_t align_; 351 uint16_t index_; 352 }; 353 #endif // defined(__ELF) 354 355 356 #if defined(__MACH_O) 357 class MachOTextSection : public MachOSection { 358 public: 359 MachOTextSection(uintptr_t align, 360 uintptr_t addr, 361 uintptr_t size) 362 : MachOSection("__text", 363 "__TEXT", 364 align, 365 MachOSection::S_REGULAR | 366 MachOSection::S_ATTR_SOME_INSTRUCTIONS | 367 MachOSection::S_ATTR_PURE_INSTRUCTIONS), 368 addr_(addr), 369 size_(size) { } 370 371 protected: 372 virtual void PopulateHeader(Writer::Slot<Header> header) { 373 MachOSection::PopulateHeader(header); 374 header->addr = addr_; 375 header->size = size_; 376 } 377 378 private: 379 uintptr_t addr_; 380 uintptr_t size_; 381 }; 382 #endif // defined(__MACH_O) 383 384 385 #if defined(__ELF) 386 class FullHeaderELFSection : public ELFSection { 387 public: 388 FullHeaderELFSection(const char* name, 389 Type type, 390 uintptr_t align, 391 uintptr_t addr, 392 uintptr_t offset, 393 uintptr_t size, 394 uintptr_t flags) 395 : ELFSection(name, type, align), 396 addr_(addr), 397 offset_(offset), 398 size_(size), 399 flags_(flags) { } 400 401 protected: 402 virtual void PopulateHeader(Writer::Slot<Header> header) { 403 ELFSection::PopulateHeader(header); 404 header->address = addr_; 405 header->offset = offset_; 406 header->size = size_; 407 header->flags = flags_; 408 } 409 410 private: 411 uintptr_t addr_; 412 uintptr_t offset_; 413 uintptr_t size_; 414 uintptr_t flags_; 415 }; 416 417 418 class ELFStringTable : public ELFSection { 419 public: 420 explicit ELFStringTable(const char* name) 421 : ELFSection(name, TYPE_STRTAB, 1), writer_(NULL), offset_(0), size_(0) { 422 } 423 424 uintptr_t Add(const char* str) { 425 if (*str == '\0') return 0; 426 427 uintptr_t offset = size_; 428 WriteString(str); 429 return offset; 430 } 431 432 void AttachWriter(Writer* w) { 433 writer_ = w; 434 offset_ = writer_->position(); 435 436 // First entry in the string table should be an empty string. 437 WriteString(""); 438 } 439 440 void DetachWriter() { 441 writer_ = NULL; 442 } 443 444 virtual void WriteBody(Writer::Slot<Header> header, Writer* w) { 445 ASSERT(writer_ == NULL); 446 header->offset = offset_; 447 header->size = size_; 448 } 449 450 private: 451 void WriteString(const char* str) { 452 uintptr_t written = 0; 453 do { 454 writer_->Write(*str); 455 written++; 456 } while (*str++); 457 size_ += written; 458 } 459 460 Writer* writer_; 461 462 uintptr_t offset_; 463 uintptr_t size_; 464 }; 465 466 467 void ELFSection::PopulateHeader(Writer::Slot<ELFSection::Header> header, 468 ELFStringTable* strtab) { 469 header->name = strtab->Add(name_); 470 header->type = type_; 471 header->alignment = align_; 472 PopulateHeader(header); 473 } 474 #endif // defined(__ELF) 475 476 477 #if defined(__MACH_O) 478 class MachO BASE_EMBEDDED { 479 public: 480 explicit MachO(Zone* zone) : zone_(zone), sections_(6, zone) { } 481 482 uint32_t AddSection(MachOSection* section) { 483 sections_.Add(section, zone_); 484 return sections_.length() - 1; 485 } 486 487 void Write(Writer* w, uintptr_t code_start, uintptr_t code_size) { 488 Writer::Slot<MachOHeader> header = WriteHeader(w); 489 uintptr_t load_command_start = w->position(); 490 Writer::Slot<MachOSegmentCommand> cmd = WriteSegmentCommand(w, 491 code_start, 492 code_size); 493 WriteSections(w, cmd, header, load_command_start); 494 } 495 496 private: 497 struct MachOHeader { 498 uint32_t magic; 499 uint32_t cputype; 500 uint32_t cpusubtype; 501 uint32_t filetype; 502 uint32_t ncmds; 503 uint32_t sizeofcmds; 504 uint32_t flags; 505 #if V8_TARGET_ARCH_X64 506 uint32_t reserved; 507 #endif 508 }; 509 510 struct MachOSegmentCommand { 511 uint32_t cmd; 512 uint32_t cmdsize; 513 char segname[16]; 514 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87 515 uint32_t vmaddr; 516 uint32_t vmsize; 517 uint32_t fileoff; 518 uint32_t filesize; 519 #else 520 uint64_t vmaddr; 521 uint64_t vmsize; 522 uint64_t fileoff; 523 uint64_t filesize; 524 #endif 525 uint32_t maxprot; 526 uint32_t initprot; 527 uint32_t nsects; 528 uint32_t flags; 529 }; 530 531 enum MachOLoadCommandCmd { 532 LC_SEGMENT_32 = 0x00000001u, 533 LC_SEGMENT_64 = 0x00000019u 534 }; 535 536 537 Writer::Slot<MachOHeader> WriteHeader(Writer* w) { 538 ASSERT(w->position() == 0); 539 Writer::Slot<MachOHeader> header = w->CreateSlotHere<MachOHeader>(); 540 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87 541 header->magic = 0xFEEDFACEu; 542 header->cputype = 7; // i386 543 header->cpusubtype = 3; // CPU_SUBTYPE_I386_ALL 544 #elif V8_TARGET_ARCH_X64 545 header->magic = 0xFEEDFACFu; 546 header->cputype = 7 | 0x01000000; // i386 | 64-bit ABI 547 header->cpusubtype = 3; // CPU_SUBTYPE_I386_ALL 548 header->reserved = 0; 549 #else 550 #error Unsupported target architecture. 551 #endif 552 header->filetype = 0x1; // MH_OBJECT 553 header->ncmds = 1; 554 header->sizeofcmds = 0; 555 header->flags = 0; 556 return header; 557 } 558 559 560 Writer::Slot<MachOSegmentCommand> WriteSegmentCommand(Writer* w, 561 uintptr_t code_start, 562 uintptr_t code_size) { 563 Writer::Slot<MachOSegmentCommand> cmd = 564 w->CreateSlotHere<MachOSegmentCommand>(); 565 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87 566 cmd->cmd = LC_SEGMENT_32; 567 #else 568 cmd->cmd = LC_SEGMENT_64; 569 #endif 570 cmd->vmaddr = code_start; 571 cmd->vmsize = code_size; 572 cmd->fileoff = 0; 573 cmd->filesize = 0; 574 cmd->maxprot = 7; 575 cmd->initprot = 7; 576 cmd->flags = 0; 577 cmd->nsects = sections_.length(); 578 memset(cmd->segname, 0, 16); 579 cmd->cmdsize = sizeof(MachOSegmentCommand) + sizeof(MachOSection::Header) * 580 cmd->nsects; 581 return cmd; 582 } 583 584 585 void WriteSections(Writer* w, 586 Writer::Slot<MachOSegmentCommand> cmd, 587 Writer::Slot<MachOHeader> header, 588 uintptr_t load_command_start) { 589 Writer::Slot<MachOSection::Header> headers = 590 w->CreateSlotsHere<MachOSection::Header>(sections_.length()); 591 cmd->fileoff = w->position(); 592 header->sizeofcmds = w->position() - load_command_start; 593 for (int section = 0; section < sections_.length(); ++section) { 594 sections_[section]->PopulateHeader(headers.at(section)); 595 sections_[section]->WriteBody(headers.at(section), w); 596 } 597 cmd->filesize = w->position() - (uintptr_t)cmd->fileoff; 598 } 599 600 Zone* zone_; 601 ZoneList<MachOSection*> sections_; 602 }; 603 #endif // defined(__MACH_O) 604 605 606 #if defined(__ELF) 607 class ELF BASE_EMBEDDED { 608 public: 609 explicit ELF(Zone* zone) : zone_(zone), sections_(6, zone) { 610 sections_.Add(new(zone) ELFSection("", ELFSection::TYPE_NULL, 0), zone); 611 sections_.Add(new(zone) ELFStringTable(".shstrtab"), zone); 612 } 613 614 void Write(Writer* w) { 615 WriteHeader(w); 616 WriteSectionTable(w); 617 WriteSections(w); 618 } 619 620 ELFSection* SectionAt(uint32_t index) { 621 return sections_[index]; 622 } 623 624 uint32_t AddSection(ELFSection* section) { 625 sections_.Add(section, zone_); 626 section->set_index(sections_.length() - 1); 627 return sections_.length() - 1; 628 } 629 630 private: 631 struct ELFHeader { 632 uint8_t ident[16]; 633 uint16_t type; 634 uint16_t machine; 635 uint32_t version; 636 uintptr_t entry; 637 uintptr_t pht_offset; 638 uintptr_t sht_offset; 639 uint32_t flags; 640 uint16_t header_size; 641 uint16_t pht_entry_size; 642 uint16_t pht_entry_num; 643 uint16_t sht_entry_size; 644 uint16_t sht_entry_num; 645 uint16_t sht_strtab_index; 646 }; 647 648 649 void WriteHeader(Writer* w) { 650 ASSERT(w->position() == 0); 651 Writer::Slot<ELFHeader> header = w->CreateSlotHere<ELFHeader>(); 652 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X87 653 const uint8_t ident[16] = 654 { 0x7f, 'E', 'L', 'F', 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 655 #elif V8_TARGET_ARCH_X64 656 const uint8_t ident[16] = 657 { 0x7f, 'E', 'L', 'F', 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 658 #else 659 #error Unsupported target architecture. 660 #endif 661 memcpy(header->ident, ident, 16); 662 header->type = 1; 663 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87 664 header->machine = 3; 665 #elif V8_TARGET_ARCH_X64 666 // Processor identification value for x64 is 62 as defined in 667 // System V ABI, AMD64 Supplement 668 // http://www.x86-64.org/documentation/abi.pdf 669 header->machine = 62; 670 #elif V8_TARGET_ARCH_ARM 671 // Set to EM_ARM, defined as 40, in "ARM ELF File Format" at 672 // infocenter.arm.com/help/topic/com.arm.doc.dui0101a/DUI0101A_Elf.pdf 673 header->machine = 40; 674 #else 675 #error Unsupported target architecture. 676 #endif 677 header->version = 1; 678 header->entry = 0; 679 header->pht_offset = 0; 680 header->sht_offset = sizeof(ELFHeader); // Section table follows header. 681 header->flags = 0; 682 header->header_size = sizeof(ELFHeader); 683 header->pht_entry_size = 0; 684 header->pht_entry_num = 0; 685 header->sht_entry_size = sizeof(ELFSection::Header); 686 header->sht_entry_num = sections_.length(); 687 header->sht_strtab_index = 1; 688 } 689 690 void WriteSectionTable(Writer* w) { 691 // Section headers table immediately follows file header. 692 ASSERT(w->position() == sizeof(ELFHeader)); 693 694 Writer::Slot<ELFSection::Header> headers = 695 w->CreateSlotsHere<ELFSection::Header>(sections_.length()); 696 697 // String table for section table is the first section. 698 ELFStringTable* strtab = static_cast<ELFStringTable*>(SectionAt(1)); 699 strtab->AttachWriter(w); 700 for (int i = 0, length = sections_.length(); 701 i < length; 702 i++) { 703 sections_[i]->PopulateHeader(headers.at(i), strtab); 704 } 705 strtab->DetachWriter(); 706 } 707 708 int SectionHeaderPosition(uint32_t section_index) { 709 return sizeof(ELFHeader) + sizeof(ELFSection::Header) * section_index; 710 } 711 712 void WriteSections(Writer* w) { 713 Writer::Slot<ELFSection::Header> headers = 714 w->SlotAt<ELFSection::Header>(sizeof(ELFHeader)); 715 716 for (int i = 0, length = sections_.length(); 717 i < length; 718 i++) { 719 sections_[i]->WriteBody(headers.at(i), w); 720 } 721 } 722 723 Zone* zone_; 724 ZoneList<ELFSection*> sections_; 725 }; 726 727 728 class ELFSymbol BASE_EMBEDDED { 729 public: 730 enum Type { 731 TYPE_NOTYPE = 0, 732 TYPE_OBJECT = 1, 733 TYPE_FUNC = 2, 734 TYPE_SECTION = 3, 735 TYPE_FILE = 4, 736 TYPE_LOPROC = 13, 737 TYPE_HIPROC = 15 738 }; 739 740 enum Binding { 741 BIND_LOCAL = 0, 742 BIND_GLOBAL = 1, 743 BIND_WEAK = 2, 744 BIND_LOPROC = 13, 745 BIND_HIPROC = 15 746 }; 747 748 ELFSymbol(const char* name, 749 uintptr_t value, 750 uintptr_t size, 751 Binding binding, 752 Type type, 753 uint16_t section) 754 : name(name), 755 value(value), 756 size(size), 757 info((binding << 4) | type), 758 other(0), 759 section(section) { 760 } 761 762 Binding binding() const { 763 return static_cast<Binding>(info >> 4); 764 } 765 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X87 766 struct SerializedLayout { 767 SerializedLayout(uint32_t name, 768 uintptr_t value, 769 uintptr_t size, 770 Binding binding, 771 Type type, 772 uint16_t section) 773 : name(name), 774 value(value), 775 size(size), 776 info((binding << 4) | type), 777 other(0), 778 section(section) { 779 } 780 781 uint32_t name; 782 uintptr_t value; 783 uintptr_t size; 784 uint8_t info; 785 uint8_t other; 786 uint16_t section; 787 }; 788 #elif V8_TARGET_ARCH_X64 789 struct SerializedLayout { 790 SerializedLayout(uint32_t name, 791 uintptr_t value, 792 uintptr_t size, 793 Binding binding, 794 Type type, 795 uint16_t section) 796 : name(name), 797 info((binding << 4) | type), 798 other(0), 799 section(section), 800 value(value), 801 size(size) { 802 } 803 804 uint32_t name; 805 uint8_t info; 806 uint8_t other; 807 uint16_t section; 808 uintptr_t value; 809 uintptr_t size; 810 }; 811 #endif 812 813 void Write(Writer::Slot<SerializedLayout> s, ELFStringTable* t) { 814 // Convert symbol names from strings to indexes in the string table. 815 s->name = t->Add(name); 816 s->value = value; 817 s->size = size; 818 s->info = info; 819 s->other = other; 820 s->section = section; 821 } 822 823 private: 824 const char* name; 825 uintptr_t value; 826 uintptr_t size; 827 uint8_t info; 828 uint8_t other; 829 uint16_t section; 830 }; 831 832 833 class ELFSymbolTable : public ELFSection { 834 public: 835 ELFSymbolTable(const char* name, Zone* zone) 836 : ELFSection(name, TYPE_SYMTAB, sizeof(uintptr_t)), 837 locals_(1, zone), 838 globals_(1, zone) { 839 } 840 841 virtual void WriteBody(Writer::Slot<Header> header, Writer* w) { 842 w->Align(header->alignment); 843 int total_symbols = locals_.length() + globals_.length() + 1; 844 header->offset = w->position(); 845 846 Writer::Slot<ELFSymbol::SerializedLayout> symbols = 847 w->CreateSlotsHere<ELFSymbol::SerializedLayout>(total_symbols); 848 849 header->size = w->position() - header->offset; 850 851 // String table for this symbol table should follow it in the section table. 852 ELFStringTable* strtab = 853 static_cast<ELFStringTable*>(w->debug_object()->SectionAt(index() + 1)); 854 strtab->AttachWriter(w); 855 symbols.at(0).set(ELFSymbol::SerializedLayout(0, 856 0, 857 0, 858 ELFSymbol::BIND_LOCAL, 859 ELFSymbol::TYPE_NOTYPE, 860 0)); 861 WriteSymbolsList(&locals_, symbols.at(1), strtab); 862 WriteSymbolsList(&globals_, symbols.at(locals_.length() + 1), strtab); 863 strtab->DetachWriter(); 864 } 865 866 void Add(const ELFSymbol& symbol, Zone* zone) { 867 if (symbol.binding() == ELFSymbol::BIND_LOCAL) { 868 locals_.Add(symbol, zone); 869 } else { 870 globals_.Add(symbol, zone); 871 } 872 } 873 874 protected: 875 virtual void PopulateHeader(Writer::Slot<Header> header) { 876 ELFSection::PopulateHeader(header); 877 // We are assuming that string table will follow symbol table. 878 header->link = index() + 1; 879 header->info = locals_.length() + 1; 880 header->entry_size = sizeof(ELFSymbol::SerializedLayout); 881 } 882 883 private: 884 void WriteSymbolsList(const ZoneList<ELFSymbol>* src, 885 Writer::Slot<ELFSymbol::SerializedLayout> dst, 886 ELFStringTable* strtab) { 887 for (int i = 0, len = src->length(); 888 i < len; 889 i++) { 890 src->at(i).Write(dst.at(i), strtab); 891 } 892 } 893 894 ZoneList<ELFSymbol> locals_; 895 ZoneList<ELFSymbol> globals_; 896 }; 897 #endif // defined(__ELF) 898 899 900 class CodeDescription BASE_EMBEDDED { 901 public: 902 #if V8_TARGET_ARCH_X64 903 enum StackState { 904 POST_RBP_PUSH, 905 POST_RBP_SET, 906 POST_RBP_POP, 907 STACK_STATE_MAX 908 }; 909 #endif 910 911 CodeDescription(const char* name, 912 Code* code, 913 Handle<Script> script, 914 GDBJITLineInfo* lineinfo, 915 GDBJITInterface::CodeTag tag, 916 CompilationInfo* info) 917 : name_(name), 918 code_(code), 919 script_(script), 920 lineinfo_(lineinfo), 921 tag_(tag), 922 info_(info) { 923 } 924 925 const char* name() const { 926 return name_; 927 } 928 929 GDBJITLineInfo* lineinfo() const { 930 return lineinfo_; 931 } 932 933 GDBJITInterface::CodeTag tag() const { 934 return tag_; 935 } 936 937 CompilationInfo* info() const { 938 return info_; 939 } 940 941 bool IsInfoAvailable() const { 942 return info_ != NULL; 943 } 944 945 uintptr_t CodeStart() const { 946 return reinterpret_cast<uintptr_t>(code_->instruction_start()); 947 } 948 949 uintptr_t CodeEnd() const { 950 return reinterpret_cast<uintptr_t>(code_->instruction_end()); 951 } 952 953 uintptr_t CodeSize() const { 954 return CodeEnd() - CodeStart(); 955 } 956 957 bool IsLineInfoAvailable() { 958 return !script_.is_null() && 959 script_->source()->IsString() && 960 script_->HasValidSource() && 961 script_->name()->IsString() && 962 lineinfo_ != NULL; 963 } 964 965 #if V8_TARGET_ARCH_X64 966 uintptr_t GetStackStateStartAddress(StackState state) const { 967 ASSERT(state < STACK_STATE_MAX); 968 return stack_state_start_addresses_[state]; 969 } 970 971 void SetStackStateStartAddress(StackState state, uintptr_t addr) { 972 ASSERT(state < STACK_STATE_MAX); 973 stack_state_start_addresses_[state] = addr; 974 } 975 #endif 976 977 SmartArrayPointer<char> GetFilename() { 978 return String::cast(script_->name())->ToCString(); 979 } 980 981 int GetScriptLineNumber(int pos) { 982 return script_->GetLineNumber(pos) + 1; 983 } 984 985 986 private: 987 const char* name_; 988 Code* code_; 989 Handle<Script> script_; 990 GDBJITLineInfo* lineinfo_; 991 GDBJITInterface::CodeTag tag_; 992 CompilationInfo* info_; 993 #if V8_TARGET_ARCH_X64 994 uintptr_t stack_state_start_addresses_[STACK_STATE_MAX]; 995 #endif 996 }; 997 998 #if defined(__ELF) 999 static void CreateSymbolsTable(CodeDescription* desc, 1000 Zone* zone, 1001 ELF* elf, 1002 int text_section_index) { 1003 ELFSymbolTable* symtab = new(zone) ELFSymbolTable(".symtab", zone); 1004 ELFStringTable* strtab = new(zone) ELFStringTable(".strtab"); 1005 1006 // Symbol table should be followed by the linked string table. 1007 elf->AddSection(symtab); 1008 elf->AddSection(strtab); 1009 1010 symtab->Add(ELFSymbol("V8 Code", 1011 0, 1012 0, 1013 ELFSymbol::BIND_LOCAL, 1014 ELFSymbol::TYPE_FILE, 1015 ELFSection::INDEX_ABSOLUTE), 1016 zone); 1017 1018 symtab->Add(ELFSymbol(desc->name(), 1019 0, 1020 desc->CodeSize(), 1021 ELFSymbol::BIND_GLOBAL, 1022 ELFSymbol::TYPE_FUNC, 1023 text_section_index), 1024 zone); 1025 } 1026 #endif // defined(__ELF) 1027 1028 1029 class DebugInfoSection : public DebugSection { 1030 public: 1031 explicit DebugInfoSection(CodeDescription* desc) 1032 #if defined(__ELF) 1033 : ELFSection(".debug_info", TYPE_PROGBITS, 1), 1034 #else 1035 : MachOSection("__debug_info", 1036 "__DWARF", 1037 1, 1038 MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG), 1039 #endif 1040 desc_(desc) { } 1041 1042 // DWARF2 standard 1043 enum DWARF2LocationOp { 1044 DW_OP_reg0 = 0x50, 1045 DW_OP_reg1 = 0x51, 1046 DW_OP_reg2 = 0x52, 1047 DW_OP_reg3 = 0x53, 1048 DW_OP_reg4 = 0x54, 1049 DW_OP_reg5 = 0x55, 1050 DW_OP_reg6 = 0x56, 1051 DW_OP_reg7 = 0x57, 1052 DW_OP_fbreg = 0x91 // 1 param: SLEB128 offset 1053 }; 1054 1055 enum DWARF2Encoding { 1056 DW_ATE_ADDRESS = 0x1, 1057 DW_ATE_SIGNED = 0x5 1058 }; 1059 1060 bool WriteBodyInternal(Writer* w) { 1061 uintptr_t cu_start = w->position(); 1062 Writer::Slot<uint32_t> size = w->CreateSlotHere<uint32_t>(); 1063 uintptr_t start = w->position(); 1064 w->Write<uint16_t>(2); // DWARF version. 1065 w->Write<uint32_t>(0); // Abbreviation table offset. 1066 w->Write<uint8_t>(sizeof(intptr_t)); 1067 1068 w->WriteULEB128(1); // Abbreviation code. 1069 w->WriteString(desc_->GetFilename().get()); 1070 w->Write<intptr_t>(desc_->CodeStart()); 1071 w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize()); 1072 w->Write<uint32_t>(0); 1073 1074 uint32_t ty_offset = static_cast<uint32_t>(w->position() - cu_start); 1075 w->WriteULEB128(3); 1076 w->Write<uint8_t>(kPointerSize); 1077 w->WriteString("v8value"); 1078 1079 if (desc_->IsInfoAvailable()) { 1080 Scope* scope = desc_->info()->scope(); 1081 w->WriteULEB128(2); 1082 w->WriteString(desc_->name()); 1083 w->Write<intptr_t>(desc_->CodeStart()); 1084 w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize()); 1085 Writer::Slot<uint32_t> fb_block_size = w->CreateSlotHere<uint32_t>(); 1086 uintptr_t fb_block_start = w->position(); 1087 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87 1088 w->Write<uint8_t>(DW_OP_reg5); // The frame pointer's here on ia32 1089 #elif V8_TARGET_ARCH_X64 1090 w->Write<uint8_t>(DW_OP_reg6); // and here on x64. 1091 #elif V8_TARGET_ARCH_ARM 1092 UNIMPLEMENTED(); 1093 #elif V8_TARGET_ARCH_MIPS 1094 UNIMPLEMENTED(); 1095 #else 1096 #error Unsupported target architecture. 1097 #endif 1098 fb_block_size.set(static_cast<uint32_t>(w->position() - fb_block_start)); 1099 1100 int params = scope->num_parameters(); 1101 int slots = scope->num_stack_slots(); 1102 int context_slots = scope->ContextLocalCount(); 1103 // The real slot ID is internal_slots + context_slot_id. 1104 int internal_slots = Context::MIN_CONTEXT_SLOTS; 1105 int locals = scope->StackLocalCount(); 1106 int current_abbreviation = 4; 1107 1108 for (int param = 0; param < params; ++param) { 1109 w->WriteULEB128(current_abbreviation++); 1110 w->WriteString( 1111 scope->parameter(param)->name()->ToCString(DISALLOW_NULLS).get()); 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( 1117 JavaScriptFrameConstants::kLastParameterOffset + 1118 kPointerSize * (params - param - 1)); 1119 block_size.set(static_cast<uint32_t>(w->position() - block_start)); 1120 } 1121 1122 EmbeddedVector<char, 256> buffer; 1123 StringBuilder builder(buffer.start(), buffer.length()); 1124 1125 for (int slot = 0; slot < slots; ++slot) { 1126 w->WriteULEB128(current_abbreviation++); 1127 builder.Reset(); 1128 builder.AddFormatted("slot%d", slot); 1129 w->WriteString(builder.Finalize()); 1130 } 1131 1132 // See contexts.h for more information. 1133 ASSERT(Context::MIN_CONTEXT_SLOTS == 4); 1134 ASSERT(Context::CLOSURE_INDEX == 0); 1135 ASSERT(Context::PREVIOUS_INDEX == 1); 1136 ASSERT(Context::EXTENSION_INDEX == 2); 1137 ASSERT(Context::GLOBAL_OBJECT_INDEX == 3); 1138 w->WriteULEB128(current_abbreviation++); 1139 w->WriteString(".closure"); 1140 w->WriteULEB128(current_abbreviation++); 1141 w->WriteString(".previous"); 1142 w->WriteULEB128(current_abbreviation++); 1143 w->WriteString(".extension"); 1144 w->WriteULEB128(current_abbreviation++); 1145 w->WriteString(".global"); 1146 1147 for (int context_slot = 0; 1148 context_slot < context_slots; 1149 ++context_slot) { 1150 w->WriteULEB128(current_abbreviation++); 1151 builder.Reset(); 1152 builder.AddFormatted("context_slot%d", context_slot + internal_slots); 1153 w->WriteString(builder.Finalize()); 1154 } 1155 1156 ZoneList<Variable*> stack_locals(locals, scope->zone()); 1157 ZoneList<Variable*> context_locals(context_slots, scope->zone()); 1158 scope->CollectStackAndContextLocals(&stack_locals, &context_locals); 1159 for (int local = 0; local < locals; ++local) { 1160 w->WriteULEB128(current_abbreviation++); 1161 w->WriteString( 1162 stack_locals[local]->name()->ToCString(DISALLOW_NULLS).get()); 1163 w->Write<uint32_t>(ty_offset); 1164 Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>(); 1165 uintptr_t block_start = w->position(); 1166 w->Write<uint8_t>(DW_OP_fbreg); 1167 w->WriteSLEB128( 1168 JavaScriptFrameConstants::kLocal0Offset - 1169 kPointerSize * local); 1170 block_size.set(static_cast<uint32_t>(w->position() - block_start)); 1171 } 1172 1173 { 1174 w->WriteULEB128(current_abbreviation++); 1175 w->WriteString("__function"); 1176 w->Write<uint32_t>(ty_offset); 1177 Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>(); 1178 uintptr_t block_start = w->position(); 1179 w->Write<uint8_t>(DW_OP_fbreg); 1180 w->WriteSLEB128(JavaScriptFrameConstants::kFunctionOffset); 1181 block_size.set(static_cast<uint32_t>(w->position() - block_start)); 1182 } 1183 1184 { 1185 w->WriteULEB128(current_abbreviation++); 1186 w->WriteString("__context"); 1187 w->Write<uint32_t>(ty_offset); 1188 Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>(); 1189 uintptr_t block_start = w->position(); 1190 w->Write<uint8_t>(DW_OP_fbreg); 1191 w->WriteSLEB128(StandardFrameConstants::kContextOffset); 1192 block_size.set(static_cast<uint32_t>(w->position() - block_start)); 1193 } 1194 1195 w->WriteULEB128(0); // Terminate the sub program. 1196 } 1197 1198 w->WriteULEB128(0); // Terminate the compile unit. 1199 size.set(static_cast<uint32_t>(w->position() - start)); 1200 return true; 1201 } 1202 1203 private: 1204 CodeDescription* desc_; 1205 }; 1206 1207 1208 class DebugAbbrevSection : public DebugSection { 1209 public: 1210 explicit DebugAbbrevSection(CodeDescription* desc) 1211 #ifdef __ELF 1212 : ELFSection(".debug_abbrev", TYPE_PROGBITS, 1), 1213 #else 1214 : MachOSection("__debug_abbrev", 1215 "__DWARF", 1216 1, 1217 MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG), 1218 #endif 1219 desc_(desc) { } 1220 1221 // DWARF2 standard, figure 14. 1222 enum DWARF2Tags { 1223 DW_TAG_FORMAL_PARAMETER = 0x05, 1224 DW_TAG_POINTER_TYPE = 0xf, 1225 DW_TAG_COMPILE_UNIT = 0x11, 1226 DW_TAG_STRUCTURE_TYPE = 0x13, 1227 DW_TAG_BASE_TYPE = 0x24, 1228 DW_TAG_SUBPROGRAM = 0x2e, 1229 DW_TAG_VARIABLE = 0x34 1230 }; 1231 1232 // DWARF2 standard, figure 16. 1233 enum DWARF2ChildrenDetermination { 1234 DW_CHILDREN_NO = 0, 1235 DW_CHILDREN_YES = 1 1236 }; 1237 1238 // DWARF standard, figure 17. 1239 enum DWARF2Attribute { 1240 DW_AT_LOCATION = 0x2, 1241 DW_AT_NAME = 0x3, 1242 DW_AT_BYTE_SIZE = 0xb, 1243 DW_AT_STMT_LIST = 0x10, 1244 DW_AT_LOW_PC = 0x11, 1245 DW_AT_HIGH_PC = 0x12, 1246 DW_AT_ENCODING = 0x3e, 1247 DW_AT_FRAME_BASE = 0x40, 1248 DW_AT_TYPE = 0x49 1249 }; 1250 1251 // DWARF2 standard, figure 19. 1252 enum DWARF2AttributeForm { 1253 DW_FORM_ADDR = 0x1, 1254 DW_FORM_BLOCK4 = 0x4, 1255 DW_FORM_STRING = 0x8, 1256 DW_FORM_DATA4 = 0x6, 1257 DW_FORM_BLOCK = 0x9, 1258 DW_FORM_DATA1 = 0xb, 1259 DW_FORM_FLAG = 0xc, 1260 DW_FORM_REF4 = 0x13 1261 }; 1262 1263 void WriteVariableAbbreviation(Writer* w, 1264 int abbreviation_code, 1265 bool has_value, 1266 bool is_parameter) { 1267 w->WriteULEB128(abbreviation_code); 1268 w->WriteULEB128(is_parameter ? DW_TAG_FORMAL_PARAMETER : DW_TAG_VARIABLE); 1269 w->Write<uint8_t>(DW_CHILDREN_NO); 1270 w->WriteULEB128(DW_AT_NAME); 1271 w->WriteULEB128(DW_FORM_STRING); 1272 if (has_value) { 1273 w->WriteULEB128(DW_AT_TYPE); 1274 w->WriteULEB128(DW_FORM_REF4); 1275 w->WriteULEB128(DW_AT_LOCATION); 1276 w->WriteULEB128(DW_FORM_BLOCK4); 1277 } 1278 w->WriteULEB128(0); 1279 w->WriteULEB128(0); 1280 } 1281 1282 bool WriteBodyInternal(Writer* w) { 1283 int current_abbreviation = 1; 1284 bool extra_info = desc_->IsInfoAvailable(); 1285 ASSERT(desc_->IsLineInfoAvailable()); 1286 w->WriteULEB128(current_abbreviation++); 1287 w->WriteULEB128(DW_TAG_COMPILE_UNIT); 1288 w->Write<uint8_t>(extra_info ? DW_CHILDREN_YES : DW_CHILDREN_NO); 1289 w->WriteULEB128(DW_AT_NAME); 1290 w->WriteULEB128(DW_FORM_STRING); 1291 w->WriteULEB128(DW_AT_LOW_PC); 1292 w->WriteULEB128(DW_FORM_ADDR); 1293 w->WriteULEB128(DW_AT_HIGH_PC); 1294 w->WriteULEB128(DW_FORM_ADDR); 1295 w->WriteULEB128(DW_AT_STMT_LIST); 1296 w->WriteULEB128(DW_FORM_DATA4); 1297 w->WriteULEB128(0); 1298 w->WriteULEB128(0); 1299 1300 if (extra_info) { 1301 Scope* scope = desc_->info()->scope(); 1302 int params = scope->num_parameters(); 1303 int slots = scope->num_stack_slots(); 1304 int context_slots = scope->ContextLocalCount(); 1305 // The real slot ID is internal_slots + context_slot_id. 1306 int internal_slots = Context::MIN_CONTEXT_SLOTS; 1307 int locals = scope->StackLocalCount(); 1308 // Total children is params + slots + context_slots + internal_slots + 1309 // locals + 2 (__function and __context). 1310 1311 // The extra duplication below seems to be necessary to keep 1312 // gdb from getting upset on OSX. 1313 w->WriteULEB128(current_abbreviation++); // Abbreviation code. 1314 w->WriteULEB128(DW_TAG_SUBPROGRAM); 1315 w->Write<uint8_t>(DW_CHILDREN_YES); 1316 w->WriteULEB128(DW_AT_NAME); 1317 w->WriteULEB128(DW_FORM_STRING); 1318 w->WriteULEB128(DW_AT_LOW_PC); 1319 w->WriteULEB128(DW_FORM_ADDR); 1320 w->WriteULEB128(DW_AT_HIGH_PC); 1321 w->WriteULEB128(DW_FORM_ADDR); 1322 w->WriteULEB128(DW_AT_FRAME_BASE); 1323 w->WriteULEB128(DW_FORM_BLOCK4); 1324 w->WriteULEB128(0); 1325 w->WriteULEB128(0); 1326 1327 w->WriteULEB128(current_abbreviation++); 1328 w->WriteULEB128(DW_TAG_STRUCTURE_TYPE); 1329 w->Write<uint8_t>(DW_CHILDREN_NO); 1330 w->WriteULEB128(DW_AT_BYTE_SIZE); 1331 w->WriteULEB128(DW_FORM_DATA1); 1332 w->WriteULEB128(DW_AT_NAME); 1333 w->WriteULEB128(DW_FORM_STRING); 1334 w->WriteULEB128(0); 1335 w->WriteULEB128(0); 1336 1337 for (int param = 0; param < params; ++param) { 1338 WriteVariableAbbreviation(w, current_abbreviation++, true, true); 1339 } 1340 1341 for (int slot = 0; slot < slots; ++slot) { 1342 WriteVariableAbbreviation(w, current_abbreviation++, false, false); 1343 } 1344 1345 for (int internal_slot = 0; 1346 internal_slot < internal_slots; 1347 ++internal_slot) { 1348 WriteVariableAbbreviation(w, current_abbreviation++, false, false); 1349 } 1350 1351 for (int context_slot = 0; 1352 context_slot < context_slots; 1353 ++context_slot) { 1354 WriteVariableAbbreviation(w, current_abbreviation++, false, false); 1355 } 1356 1357 for (int local = 0; local < locals; ++local) { 1358 WriteVariableAbbreviation(w, current_abbreviation++, true, false); 1359 } 1360 1361 // The function. 1362 WriteVariableAbbreviation(w, current_abbreviation++, true, false); 1363 1364 // The context. 1365 WriteVariableAbbreviation(w, current_abbreviation++, true, false); 1366 1367 w->WriteULEB128(0); // Terminate the sibling list. 1368 } 1369 1370 w->WriteULEB128(0); // Terminate the table. 1371 return true; 1372 } 1373 1374 private: 1375 CodeDescription* desc_; 1376 }; 1377 1378 1379 class DebugLineSection : public DebugSection { 1380 public: 1381 explicit DebugLineSection(CodeDescription* desc) 1382 #ifdef __ELF 1383 : ELFSection(".debug_line", TYPE_PROGBITS, 1), 1384 #else 1385 : MachOSection("__debug_line", 1386 "__DWARF", 1387 1, 1388 MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG), 1389 #endif 1390 desc_(desc) { } 1391 1392 // DWARF2 standard, figure 34. 1393 enum DWARF2Opcodes { 1394 DW_LNS_COPY = 1, 1395 DW_LNS_ADVANCE_PC = 2, 1396 DW_LNS_ADVANCE_LINE = 3, 1397 DW_LNS_SET_FILE = 4, 1398 DW_LNS_SET_COLUMN = 5, 1399 DW_LNS_NEGATE_STMT = 6 1400 }; 1401 1402 // DWARF2 standard, figure 35. 1403 enum DWARF2ExtendedOpcode { 1404 DW_LNE_END_SEQUENCE = 1, 1405 DW_LNE_SET_ADDRESS = 2, 1406 DW_LNE_DEFINE_FILE = 3 1407 }; 1408 1409 bool WriteBodyInternal(Writer* w) { 1410 // Write prologue. 1411 Writer::Slot<uint32_t> total_length = w->CreateSlotHere<uint32_t>(); 1412 uintptr_t start = w->position(); 1413 1414 // Used for special opcodes 1415 const int8_t line_base = 1; 1416 const uint8_t line_range = 7; 1417 const int8_t max_line_incr = (line_base + line_range - 1); 1418 const uint8_t opcode_base = DW_LNS_NEGATE_STMT + 1; 1419 1420 w->Write<uint16_t>(2); // Field version. 1421 Writer::Slot<uint32_t> prologue_length = w->CreateSlotHere<uint32_t>(); 1422 uintptr_t prologue_start = w->position(); 1423 w->Write<uint8_t>(1); // Field minimum_instruction_length. 1424 w->Write<uint8_t>(1); // Field default_is_stmt. 1425 w->Write<int8_t>(line_base); // Field line_base. 1426 w->Write<uint8_t>(line_range); // Field line_range. 1427 w->Write<uint8_t>(opcode_base); // Field opcode_base. 1428 w->Write<uint8_t>(0); // DW_LNS_COPY operands count. 1429 w->Write<uint8_t>(1); // DW_LNS_ADVANCE_PC operands count. 1430 w->Write<uint8_t>(1); // DW_LNS_ADVANCE_LINE operands count. 1431 w->Write<uint8_t>(1); // DW_LNS_SET_FILE operands count. 1432 w->Write<uint8_t>(1); // DW_LNS_SET_COLUMN operands count. 1433 w->Write<uint8_t>(0); // DW_LNS_NEGATE_STMT operands count. 1434 w->Write<uint8_t>(0); // Empty include_directories sequence. 1435 w->WriteString(desc_->GetFilename().get()); // File name. 1436 w->WriteULEB128(0); // Current directory. 1437 w->WriteULEB128(0); // Unknown modification time. 1438 w->WriteULEB128(0); // Unknown file size. 1439 w->Write<uint8_t>(0); 1440 prologue_length.set(static_cast<uint32_t>(w->position() - prologue_start)); 1441 1442 WriteExtendedOpcode(w, DW_LNE_SET_ADDRESS, sizeof(intptr_t)); 1443 w->Write<intptr_t>(desc_->CodeStart()); 1444 w->Write<uint8_t>(DW_LNS_COPY); 1445 1446 intptr_t pc = 0; 1447 intptr_t line = 1; 1448 bool is_statement = true; 1449 1450 List<GDBJITLineInfo::PCInfo>* pc_info = desc_->lineinfo()->pc_info(); 1451 pc_info->Sort(&ComparePCInfo); 1452 1453 int pc_info_length = pc_info->length(); 1454 for (int i = 0; i < pc_info_length; i++) { 1455 GDBJITLineInfo::PCInfo* info = &pc_info->at(i); 1456 ASSERT(info->pc_ >= pc); 1457 1458 // Reduce bloating in the debug line table by removing duplicate line 1459 // entries (per DWARF2 standard). 1460 intptr_t new_line = desc_->GetScriptLineNumber(info->pos_); 1461 if (new_line == line) { 1462 continue; 1463 } 1464 1465 // Mark statement boundaries. For a better debugging experience, mark 1466 // the last pc address in the function as a statement (e.g. "}"), so that 1467 // a user can see the result of the last line executed in the function, 1468 // should control reach the end. 1469 if ((i+1) == pc_info_length) { 1470 if (!is_statement) { 1471 w->Write<uint8_t>(DW_LNS_NEGATE_STMT); 1472 } 1473 } else if (is_statement != info->is_statement_) { 1474 w->Write<uint8_t>(DW_LNS_NEGATE_STMT); 1475 is_statement = !is_statement; 1476 } 1477 1478 // Generate special opcodes, if possible. This results in more compact 1479 // debug line tables. See the DWARF 2.0 standard to learn more about 1480 // special opcodes. 1481 uintptr_t pc_diff = info->pc_ - pc; 1482 intptr_t line_diff = new_line - line; 1483 1484 // Compute special opcode (see DWARF 2.0 standard) 1485 intptr_t special_opcode = (line_diff - line_base) + 1486 (line_range * pc_diff) + opcode_base; 1487 1488 // If special_opcode is less than or equal to 255, it can be used as a 1489 // special opcode. If line_diff is larger than the max line increment 1490 // allowed for a special opcode, or if line_diff is less than the minimum 1491 // line that can be added to the line register (i.e. line_base), then 1492 // special_opcode can't be used. 1493 if ((special_opcode >= opcode_base) && (special_opcode <= 255) && 1494 (line_diff <= max_line_incr) && (line_diff >= line_base)) { 1495 w->Write<uint8_t>(special_opcode); 1496 } else { 1497 w->Write<uint8_t>(DW_LNS_ADVANCE_PC); 1498 w->WriteSLEB128(pc_diff); 1499 w->Write<uint8_t>(DW_LNS_ADVANCE_LINE); 1500 w->WriteSLEB128(line_diff); 1501 w->Write<uint8_t>(DW_LNS_COPY); 1502 } 1503 1504 // Increment the pc and line operands. 1505 pc += pc_diff; 1506 line += line_diff; 1507 } 1508 // Advance the pc to the end of the routine, since the end sequence opcode 1509 // requires this. 1510 w->Write<uint8_t>(DW_LNS_ADVANCE_PC); 1511 w->WriteSLEB128(desc_->CodeSize() - pc); 1512 WriteExtendedOpcode(w, DW_LNE_END_SEQUENCE, 0); 1513 total_length.set(static_cast<uint32_t>(w->position() - start)); 1514 return true; 1515 } 1516 1517 private: 1518 void WriteExtendedOpcode(Writer* w, 1519 DWARF2ExtendedOpcode op, 1520 size_t operands_size) { 1521 w->Write<uint8_t>(0); 1522 w->WriteULEB128(operands_size + 1); 1523 w->Write<uint8_t>(op); 1524 } 1525 1526 static int ComparePCInfo(const GDBJITLineInfo::PCInfo* a, 1527 const GDBJITLineInfo::PCInfo* b) { 1528 if (a->pc_ == b->pc_) { 1529 if (a->is_statement_ != b->is_statement_) { 1530 return b->is_statement_ ? +1 : -1; 1531 } 1532 return 0; 1533 } else if (a->pc_ > b->pc_) { 1534 return +1; 1535 } else { 1536 return -1; 1537 } 1538 } 1539 1540 CodeDescription* desc_; 1541 }; 1542 1543 1544 #if V8_TARGET_ARCH_X64 1545 1546 class UnwindInfoSection : public DebugSection { 1547 public: 1548 explicit UnwindInfoSection(CodeDescription* desc); 1549 virtual bool WriteBodyInternal(Writer* w); 1550 1551 int WriteCIE(Writer* w); 1552 void WriteFDE(Writer* w, int); 1553 1554 void WriteFDEStateOnEntry(Writer* w); 1555 void WriteFDEStateAfterRBPPush(Writer* w); 1556 void WriteFDEStateAfterRBPSet(Writer* w); 1557 void WriteFDEStateAfterRBPPop(Writer* w); 1558 1559 void WriteLength(Writer* w, 1560 Writer::Slot<uint32_t>* length_slot, 1561 int initial_position); 1562 1563 private: 1564 CodeDescription* desc_; 1565 1566 // DWARF3 Specification, Table 7.23 1567 enum CFIInstructions { 1568 DW_CFA_ADVANCE_LOC = 0x40, 1569 DW_CFA_OFFSET = 0x80, 1570 DW_CFA_RESTORE = 0xC0, 1571 DW_CFA_NOP = 0x00, 1572 DW_CFA_SET_LOC = 0x01, 1573 DW_CFA_ADVANCE_LOC1 = 0x02, 1574 DW_CFA_ADVANCE_LOC2 = 0x03, 1575 DW_CFA_ADVANCE_LOC4 = 0x04, 1576 DW_CFA_OFFSET_EXTENDED = 0x05, 1577 DW_CFA_RESTORE_EXTENDED = 0x06, 1578 DW_CFA_UNDEFINED = 0x07, 1579 DW_CFA_SAME_VALUE = 0x08, 1580 DW_CFA_REGISTER = 0x09, 1581 DW_CFA_REMEMBER_STATE = 0x0A, 1582 DW_CFA_RESTORE_STATE = 0x0B, 1583 DW_CFA_DEF_CFA = 0x0C, 1584 DW_CFA_DEF_CFA_REGISTER = 0x0D, 1585 DW_CFA_DEF_CFA_OFFSET = 0x0E, 1586 1587 DW_CFA_DEF_CFA_EXPRESSION = 0x0F, 1588 DW_CFA_EXPRESSION = 0x10, 1589 DW_CFA_OFFSET_EXTENDED_SF = 0x11, 1590 DW_CFA_DEF_CFA_SF = 0x12, 1591 DW_CFA_DEF_CFA_OFFSET_SF = 0x13, 1592 DW_CFA_VAL_OFFSET = 0x14, 1593 DW_CFA_VAL_OFFSET_SF = 0x15, 1594 DW_CFA_VAL_EXPRESSION = 0x16 1595 }; 1596 1597 // System V ABI, AMD64 Supplement, Version 0.99.5, Figure 3.36 1598 enum RegisterMapping { 1599 // Only the relevant ones have been added to reduce clutter. 1600 AMD64_RBP = 6, 1601 AMD64_RSP = 7, 1602 AMD64_RA = 16 1603 }; 1604 1605 enum CFIConstants { 1606 CIE_ID = 0, 1607 CIE_VERSION = 1, 1608 CODE_ALIGN_FACTOR = 1, 1609 DATA_ALIGN_FACTOR = 1, 1610 RETURN_ADDRESS_REGISTER = AMD64_RA 1611 }; 1612 }; 1613 1614 1615 void UnwindInfoSection::WriteLength(Writer* w, 1616 Writer::Slot<uint32_t>* length_slot, 1617 int initial_position) { 1618 uint32_t align = (w->position() - initial_position) % kPointerSize; 1619 1620 if (align != 0) { 1621 for (uint32_t i = 0; i < (kPointerSize - align); i++) { 1622 w->Write<uint8_t>(DW_CFA_NOP); 1623 } 1624 } 1625 1626 ASSERT((w->position() - initial_position) % kPointerSize == 0); 1627 length_slot->set(w->position() - initial_position); 1628 } 1629 1630 1631 UnwindInfoSection::UnwindInfoSection(CodeDescription* desc) 1632 #ifdef __ELF 1633 : ELFSection(".eh_frame", TYPE_X86_64_UNWIND, 1), 1634 #else 1635 : MachOSection("__eh_frame", "__TEXT", sizeof(uintptr_t), 1636 MachOSection::S_REGULAR), 1637 #endif 1638 desc_(desc) { } 1639 1640 int UnwindInfoSection::WriteCIE(Writer* w) { 1641 Writer::Slot<uint32_t> cie_length_slot = w->CreateSlotHere<uint32_t>(); 1642 uint32_t cie_position = w->position(); 1643 1644 // Write out the CIE header. Currently no 'common instructions' are 1645 // emitted onto the CIE; every FDE has its own set of instructions. 1646 1647 w->Write<uint32_t>(CIE_ID); 1648 w->Write<uint8_t>(CIE_VERSION); 1649 w->Write<uint8_t>(0); // Null augmentation string. 1650 w->WriteSLEB128(CODE_ALIGN_FACTOR); 1651 w->WriteSLEB128(DATA_ALIGN_FACTOR); 1652 w->Write<uint8_t>(RETURN_ADDRESS_REGISTER); 1653 1654 WriteLength(w, &cie_length_slot, cie_position); 1655 1656 return cie_position; 1657 } 1658 1659 1660 void UnwindInfoSection::WriteFDE(Writer* w, int cie_position) { 1661 // The only FDE for this function. The CFA is the current RBP. 1662 Writer::Slot<uint32_t> fde_length_slot = w->CreateSlotHere<uint32_t>(); 1663 int fde_position = w->position(); 1664 w->Write<int32_t>(fde_position - cie_position + 4); 1665 1666 w->Write<uintptr_t>(desc_->CodeStart()); 1667 w->Write<uintptr_t>(desc_->CodeSize()); 1668 1669 WriteFDEStateOnEntry(w); 1670 WriteFDEStateAfterRBPPush(w); 1671 WriteFDEStateAfterRBPSet(w); 1672 WriteFDEStateAfterRBPPop(w); 1673 1674 WriteLength(w, &fde_length_slot, fde_position); 1675 } 1676 1677 1678 void UnwindInfoSection::WriteFDEStateOnEntry(Writer* w) { 1679 // The first state, just after the control has been transferred to the the 1680 // function. 1681 1682 // RBP for this function will be the value of RSP after pushing the RBP 1683 // for the previous function. The previous RBP has not been pushed yet. 1684 w->Write<uint8_t>(DW_CFA_DEF_CFA_SF); 1685 w->WriteULEB128(AMD64_RSP); 1686 w->WriteSLEB128(-kPointerSize); 1687 1688 // The RA is stored at location CFA + kCallerPCOffset. This is an invariant, 1689 // and hence omitted from the next states. 1690 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); 1691 w->WriteULEB128(AMD64_RA); 1692 w->WriteSLEB128(StandardFrameConstants::kCallerPCOffset); 1693 1694 // The RBP of the previous function is still in RBP. 1695 w->Write<uint8_t>(DW_CFA_SAME_VALUE); 1696 w->WriteULEB128(AMD64_RBP); 1697 1698 // Last location described by this entry. 1699 w->Write<uint8_t>(DW_CFA_SET_LOC); 1700 w->Write<uint64_t>( 1701 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_PUSH)); 1702 } 1703 1704 1705 void UnwindInfoSection::WriteFDEStateAfterRBPPush(Writer* w) { 1706 // The second state, just after RBP has been pushed. 1707 1708 // RBP / CFA for this function is now the current RSP, so just set the 1709 // offset from the previous rule (from -8) to 0. 1710 w->Write<uint8_t>(DW_CFA_DEF_CFA_OFFSET); 1711 w->WriteULEB128(0); 1712 1713 // The previous RBP is stored at CFA + kCallerFPOffset. This is an invariant 1714 // in this and the next state, and hence omitted in the next state. 1715 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); 1716 w->WriteULEB128(AMD64_RBP); 1717 w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset); 1718 1719 // Last location described by this entry. 1720 w->Write<uint8_t>(DW_CFA_SET_LOC); 1721 w->Write<uint64_t>( 1722 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_SET)); 1723 } 1724 1725 1726 void UnwindInfoSection::WriteFDEStateAfterRBPSet(Writer* w) { 1727 // The third state, after the RBP has been set. 1728 1729 // The CFA can now directly be set to RBP. 1730 w->Write<uint8_t>(DW_CFA_DEF_CFA); 1731 w->WriteULEB128(AMD64_RBP); 1732 w->WriteULEB128(0); 1733 1734 // Last location described by this entry. 1735 w->Write<uint8_t>(DW_CFA_SET_LOC); 1736 w->Write<uint64_t>( 1737 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_POP)); 1738 } 1739 1740 1741 void UnwindInfoSection::WriteFDEStateAfterRBPPop(Writer* w) { 1742 // The fourth (final) state. The RBP has been popped (just before issuing a 1743 // return). 1744 1745 // The CFA can is now calculated in the same way as in the first state. 1746 w->Write<uint8_t>(DW_CFA_DEF_CFA_SF); 1747 w->WriteULEB128(AMD64_RSP); 1748 w->WriteSLEB128(-kPointerSize); 1749 1750 // The RBP 1751 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); 1752 w->WriteULEB128(AMD64_RBP); 1753 w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset); 1754 1755 // Last location described by this entry. 1756 w->Write<uint8_t>(DW_CFA_SET_LOC); 1757 w->Write<uint64_t>(desc_->CodeEnd()); 1758 } 1759 1760 1761 bool UnwindInfoSection::WriteBodyInternal(Writer* w) { 1762 uint32_t cie_position = WriteCIE(w); 1763 WriteFDE(w, cie_position); 1764 return true; 1765 } 1766 1767 1768 #endif // V8_TARGET_ARCH_X64 1769 1770 static void CreateDWARFSections(CodeDescription* desc, 1771 Zone* zone, 1772 DebugObject* obj) { 1773 if (desc->IsLineInfoAvailable()) { 1774 obj->AddSection(new(zone) DebugInfoSection(desc)); 1775 obj->AddSection(new(zone) DebugAbbrevSection(desc)); 1776 obj->AddSection(new(zone) DebugLineSection(desc)); 1777 } 1778 #if V8_TARGET_ARCH_X64 1779 obj->AddSection(new(zone) UnwindInfoSection(desc)); 1780 #endif 1781 } 1782 1783 1784 // ------------------------------------------------------------------- 1785 // Binary GDB JIT Interface as described in 1786 // http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html 1787 extern "C" { 1788 typedef enum { 1789 JIT_NOACTION = 0, 1790 JIT_REGISTER_FN, 1791 JIT_UNREGISTER_FN 1792 } JITAction; 1793 1794 struct JITCodeEntry { 1795 JITCodeEntry* next_; 1796 JITCodeEntry* prev_; 1797 Address symfile_addr_; 1798 uint64_t symfile_size_; 1799 }; 1800 1801 struct JITDescriptor { 1802 uint32_t version_; 1803 uint32_t action_flag_; 1804 JITCodeEntry* relevant_entry_; 1805 JITCodeEntry* first_entry_; 1806 }; 1807 1808 // GDB will place breakpoint into this function. 1809 // To prevent GCC from inlining or removing it we place noinline attribute 1810 // and inline assembler statement inside. 1811 void __attribute__((noinline)) __jit_debug_register_code() { 1812 __asm__(""); 1813 } 1814 1815 // GDB will inspect contents of this descriptor. 1816 // Static initialization is necessary to prevent GDB from seeing 1817 // uninitialized descriptor. 1818 JITDescriptor __jit_debug_descriptor = { 1, 0, 0, 0 }; 1819 1820 #ifdef OBJECT_PRINT 1821 void __gdb_print_v8_object(Object* object) { 1822 object->Print(); 1823 PrintF(stdout, "\n"); 1824 } 1825 #endif 1826 } 1827 1828 1829 static JITCodeEntry* CreateCodeEntry(Address symfile_addr, 1830 uintptr_t symfile_size) { 1831 JITCodeEntry* entry = static_cast<JITCodeEntry*>( 1832 malloc(sizeof(JITCodeEntry) + symfile_size)); 1833 1834 entry->symfile_addr_ = reinterpret_cast<Address>(entry + 1); 1835 entry->symfile_size_ = symfile_size; 1836 MemCopy(entry->symfile_addr_, symfile_addr, symfile_size); 1837 1838 entry->prev_ = entry->next_ = NULL; 1839 1840 return entry; 1841 } 1842 1843 1844 static void DestroyCodeEntry(JITCodeEntry* entry) { 1845 free(entry); 1846 } 1847 1848 1849 static void RegisterCodeEntry(JITCodeEntry* entry, 1850 bool dump_if_enabled, 1851 const char* name_hint) { 1852 #if defined(DEBUG) && !V8_OS_WIN 1853 static int file_num = 0; 1854 if (FLAG_gdbjit_dump && dump_if_enabled) { 1855 static const int kMaxFileNameSize = 64; 1856 static const char* kElfFilePrefix = "/tmp/elfdump"; 1857 static const char* kObjFileExt = ".o"; 1858 char file_name[64]; 1859 1860 SNPrintF(Vector<char>(file_name, kMaxFileNameSize), 1861 "%s%s%d%s", 1862 kElfFilePrefix, 1863 (name_hint != NULL) ? name_hint : "", 1864 file_num++, 1865 kObjFileExt); 1866 WriteBytes(file_name, entry->symfile_addr_, entry->symfile_size_); 1867 } 1868 #endif 1869 1870 entry->next_ = __jit_debug_descriptor.first_entry_; 1871 if (entry->next_ != NULL) entry->next_->prev_ = entry; 1872 __jit_debug_descriptor.first_entry_ = 1873 __jit_debug_descriptor.relevant_entry_ = entry; 1874 1875 __jit_debug_descriptor.action_flag_ = JIT_REGISTER_FN; 1876 __jit_debug_register_code(); 1877 } 1878 1879 1880 static void UnregisterCodeEntry(JITCodeEntry* entry) { 1881 if (entry->prev_ != NULL) { 1882 entry->prev_->next_ = entry->next_; 1883 } else { 1884 __jit_debug_descriptor.first_entry_ = entry->next_; 1885 } 1886 1887 if (entry->next_ != NULL) { 1888 entry->next_->prev_ = entry->prev_; 1889 } 1890 1891 __jit_debug_descriptor.relevant_entry_ = entry; 1892 __jit_debug_descriptor.action_flag_ = JIT_UNREGISTER_FN; 1893 __jit_debug_register_code(); 1894 } 1895 1896 1897 static JITCodeEntry* CreateELFObject(CodeDescription* desc, Isolate* isolate) { 1898 #ifdef __MACH_O 1899 Zone zone(isolate); 1900 MachO mach_o(&zone); 1901 Writer w(&mach_o); 1902 1903 mach_o.AddSection(new(&zone) MachOTextSection(kCodeAlignment, 1904 desc->CodeStart(), 1905 desc->CodeSize())); 1906 1907 CreateDWARFSections(desc, &zone, &mach_o); 1908 1909 mach_o.Write(&w, desc->CodeStart(), desc->CodeSize()); 1910 #else 1911 Zone zone(isolate); 1912 ELF elf(&zone); 1913 Writer w(&elf); 1914 1915 int text_section_index = elf.AddSection( 1916 new(&zone) FullHeaderELFSection( 1917 ".text", 1918 ELFSection::TYPE_NOBITS, 1919 kCodeAlignment, 1920 desc->CodeStart(), 1921 0, 1922 desc->CodeSize(), 1923 ELFSection::FLAG_ALLOC | ELFSection::FLAG_EXEC)); 1924 1925 CreateSymbolsTable(desc, &zone, &elf, text_section_index); 1926 1927 CreateDWARFSections(desc, &zone, &elf); 1928 1929 elf.Write(&w); 1930 #endif 1931 1932 return CreateCodeEntry(w.buffer(), w.position()); 1933 } 1934 1935 1936 static bool SameCodeObjects(void* key1, void* key2) { 1937 return key1 == key2; 1938 } 1939 1940 1941 static HashMap* GetEntries() { 1942 static HashMap* entries = NULL; 1943 if (entries == NULL) { 1944 entries = new HashMap(&SameCodeObjects); 1945 } 1946 return entries; 1947 } 1948 1949 1950 static uint32_t HashForCodeObject(Code* code) { 1951 static const uintptr_t kGoldenRatio = 2654435761u; 1952 uintptr_t hash = reinterpret_cast<uintptr_t>(code->address()); 1953 return static_cast<uint32_t>((hash >> kCodeAlignmentBits) * kGoldenRatio); 1954 } 1955 1956 1957 static const intptr_t kLineInfoTag = 0x1; 1958 1959 1960 static bool IsLineInfoTagged(void* ptr) { 1961 return 0 != (reinterpret_cast<intptr_t>(ptr) & kLineInfoTag); 1962 } 1963 1964 1965 static void* TagLineInfo(GDBJITLineInfo* ptr) { 1966 return reinterpret_cast<void*>( 1967 reinterpret_cast<intptr_t>(ptr) | kLineInfoTag); 1968 } 1969 1970 1971 static GDBJITLineInfo* UntagLineInfo(void* ptr) { 1972 return reinterpret_cast<GDBJITLineInfo*>( 1973 reinterpret_cast<intptr_t>(ptr) & ~kLineInfoTag); 1974 } 1975 1976 1977 void GDBJITInterface::AddCode(Handle<Name> name, 1978 Handle<Script> script, 1979 Handle<Code> code, 1980 CompilationInfo* info) { 1981 if (!FLAG_gdbjit) return; 1982 1983 Script::InitLineEnds(script); 1984 1985 if (!name.is_null() && name->IsString()) { 1986 SmartArrayPointer<char> name_cstring = 1987 Handle<String>::cast(name)->ToCString(DISALLOW_NULLS); 1988 AddCode(name_cstring.get(), *code, GDBJITInterface::FUNCTION, *script, 1989 info); 1990 } else { 1991 AddCode("", *code, GDBJITInterface::FUNCTION, *script, info); 1992 } 1993 } 1994 1995 1996 static void AddUnwindInfo(CodeDescription* desc) { 1997 #if V8_TARGET_ARCH_X64 1998 if (desc->tag() == GDBJITInterface::FUNCTION) { 1999 // To avoid propagating unwinding information through 2000 // compilation pipeline we use an approximation. 2001 // For most use cases this should not affect usability. 2002 static const int kFramePointerPushOffset = 1; 2003 static const int kFramePointerSetOffset = 4; 2004 static const int kFramePointerPopOffset = -3; 2005 2006 uintptr_t frame_pointer_push_address = 2007 desc->CodeStart() + kFramePointerPushOffset; 2008 2009 uintptr_t frame_pointer_set_address = 2010 desc->CodeStart() + kFramePointerSetOffset; 2011 2012 uintptr_t frame_pointer_pop_address = 2013 desc->CodeEnd() + kFramePointerPopOffset; 2014 2015 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_PUSH, 2016 frame_pointer_push_address); 2017 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_SET, 2018 frame_pointer_set_address); 2019 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_POP, 2020 frame_pointer_pop_address); 2021 } else { 2022 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_PUSH, 2023 desc->CodeStart()); 2024 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_SET, 2025 desc->CodeStart()); 2026 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_POP, 2027 desc->CodeEnd()); 2028 } 2029 #endif // V8_TARGET_ARCH_X64 2030 } 2031 2032 2033 static LazyMutex mutex = LAZY_MUTEX_INITIALIZER; 2034 2035 2036 void GDBJITInterface::AddCode(const char* name, 2037 Code* code, 2038 GDBJITInterface::CodeTag tag, 2039 Script* script, 2040 CompilationInfo* info) { 2041 if (!FLAG_gdbjit) return; 2042 2043 LockGuard<Mutex> lock_guard(mutex.Pointer()); 2044 DisallowHeapAllocation no_gc; 2045 2046 HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true); 2047 if (e->value != NULL && !IsLineInfoTagged(e->value)) return; 2048 2049 GDBJITLineInfo* lineinfo = UntagLineInfo(e->value); 2050 CodeDescription code_desc(name, 2051 code, 2052 script != NULL ? Handle<Script>(script) 2053 : Handle<Script>(), 2054 lineinfo, 2055 tag, 2056 info); 2057 2058 if (!FLAG_gdbjit_full && !code_desc.IsLineInfoAvailable()) { 2059 delete lineinfo; 2060 GetEntries()->Remove(code, HashForCodeObject(code)); 2061 return; 2062 } 2063 2064 AddUnwindInfo(&code_desc); 2065 Isolate* isolate = code->GetIsolate(); 2066 JITCodeEntry* entry = CreateELFObject(&code_desc, isolate); 2067 ASSERT(!IsLineInfoTagged(entry)); 2068 2069 delete lineinfo; 2070 e->value = entry; 2071 2072 const char* name_hint = NULL; 2073 bool should_dump = false; 2074 if (FLAG_gdbjit_dump) { 2075 if (strlen(FLAG_gdbjit_dump_filter) == 0) { 2076 name_hint = name; 2077 should_dump = true; 2078 } else if (name != NULL) { 2079 name_hint = strstr(name, FLAG_gdbjit_dump_filter); 2080 should_dump = (name_hint != NULL); 2081 } 2082 } 2083 RegisterCodeEntry(entry, should_dump, name_hint); 2084 } 2085 2086 2087 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag, 2088 const char* name, 2089 Code* code) { 2090 if (!FLAG_gdbjit) return; 2091 2092 EmbeddedVector<char, 256> buffer; 2093 StringBuilder builder(buffer.start(), buffer.length()); 2094 2095 builder.AddString(Tag2String(tag)); 2096 if ((name != NULL) && (*name != '\0')) { 2097 builder.AddString(": "); 2098 builder.AddString(name); 2099 } else { 2100 builder.AddFormatted(": code object %p", static_cast<void*>(code)); 2101 } 2102 2103 AddCode(builder.Finalize(), code, tag, NULL, NULL); 2104 } 2105 2106 2107 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag, 2108 Name* name, 2109 Code* code) { 2110 if (!FLAG_gdbjit) return; 2111 if (name != NULL && name->IsString()) { 2112 AddCode(tag, String::cast(name)->ToCString(DISALLOW_NULLS).get(), code); 2113 } else { 2114 AddCode(tag, "", code); 2115 } 2116 } 2117 2118 2119 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag, Code* code) { 2120 if (!FLAG_gdbjit) return; 2121 2122 AddCode(tag, "", code); 2123 } 2124 2125 2126 void GDBJITInterface::RemoveCode(Code* code) { 2127 if (!FLAG_gdbjit) return; 2128 2129 LockGuard<Mutex> lock_guard(mutex.Pointer()); 2130 HashMap::Entry* e = GetEntries()->Lookup(code, 2131 HashForCodeObject(code), 2132 false); 2133 if (e == NULL) return; 2134 2135 if (IsLineInfoTagged(e->value)) { 2136 delete UntagLineInfo(e->value); 2137 } else { 2138 JITCodeEntry* entry = static_cast<JITCodeEntry*>(e->value); 2139 UnregisterCodeEntry(entry); 2140 DestroyCodeEntry(entry); 2141 } 2142 e->value = NULL; 2143 GetEntries()->Remove(code, HashForCodeObject(code)); 2144 } 2145 2146 2147 void GDBJITInterface::RemoveCodeRange(Address start, Address end) { 2148 HashMap* entries = GetEntries(); 2149 Zone zone(Isolate::Current()); 2150 ZoneList<Code*> dead_codes(1, &zone); 2151 2152 for (HashMap::Entry* e = entries->Start(); e != NULL; e = entries->Next(e)) { 2153 Code* code = reinterpret_cast<Code*>(e->key); 2154 if (code->address() >= start && code->address() < end) { 2155 dead_codes.Add(code, &zone); 2156 } 2157 } 2158 2159 for (int i = 0; i < dead_codes.length(); i++) { 2160 RemoveCode(dead_codes.at(i)); 2161 } 2162 } 2163 2164 2165 void GDBJITInterface::RegisterDetailedLineInfo(Code* code, 2166 GDBJITLineInfo* line_info) { 2167 LockGuard<Mutex> lock_guard(mutex.Pointer()); 2168 ASSERT(!IsLineInfoTagged(line_info)); 2169 HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true); 2170 ASSERT(e->value == NULL); 2171 e->value = TagLineInfo(line_info); 2172 } 2173 2174 2175 } } // namespace v8::internal 2176 #endif 2177