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