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