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 "natives.h" 37 38 namespace v8 { 39 namespace internal { 40 41 class ELF; 42 43 class Writer BASE_EMBEDDED { 44 public: 45 explicit Writer(ELF* elf) 46 : elf_(elf), 47 position_(0), 48 capacity_(1024), 49 buffer_(reinterpret_cast<byte*>(malloc(capacity_))) { 50 } 51 52 ~Writer() { 53 free(buffer_); 54 } 55 56 uintptr_t position() const { 57 return position_; 58 } 59 60 template<typename T> 61 class Slot { 62 public: 63 Slot(Writer* w, uintptr_t offset) : w_(w), offset_(offset) { } 64 65 T* operator-> () { 66 return w_->RawSlotAt<T>(offset_); 67 } 68 69 void set(const T& value) { 70 *w_->RawSlotAt<T>(offset_) = value; 71 } 72 73 Slot<T> at(int i) { 74 return Slot<T>(w_, offset_ + sizeof(T) * i); 75 } 76 77 private: 78 Writer* w_; 79 uintptr_t offset_; 80 }; 81 82 template<typename T> 83 void Write(const T& val) { 84 Ensure(position_ + sizeof(T)); 85 *RawSlotAt<T>(position_) = val; 86 position_ += sizeof(T); 87 } 88 89 template<typename T> 90 Slot<T> SlotAt(uintptr_t offset) { 91 Ensure(offset + sizeof(T)); 92 return Slot<T>(this, offset); 93 } 94 95 template<typename T> 96 Slot<T> CreateSlotHere() { 97 return CreateSlotsHere<T>(1); 98 } 99 100 template<typename T> 101 Slot<T> CreateSlotsHere(uint32_t count) { 102 uintptr_t slot_position = position_; 103 position_ += sizeof(T) * count; 104 Ensure(position_); 105 return SlotAt<T>(slot_position); 106 } 107 108 void Ensure(uintptr_t pos) { 109 if (capacity_ < pos) { 110 while (capacity_ < pos) capacity_ *= 2; 111 buffer_ = reinterpret_cast<byte*>(realloc(buffer_, capacity_)); 112 } 113 } 114 115 ELF* elf() { return elf_; } 116 117 byte* buffer() { return buffer_; } 118 119 void Align(uintptr_t align) { 120 uintptr_t delta = position_ % align; 121 if (delta == 0) return; 122 uintptr_t padding = align - delta; 123 Ensure(position_ += padding); 124 ASSERT((position_ % align) == 0); 125 } 126 127 void WriteULEB128(uintptr_t value) { 128 do { 129 uint8_t byte = value & 0x7F; 130 value >>= 7; 131 if (value != 0) byte |= 0x80; 132 Write<uint8_t>(byte); 133 } while (value != 0); 134 } 135 136 void WriteSLEB128(intptr_t value) { 137 bool more = true; 138 while (more) { 139 int8_t byte = value & 0x7F; 140 bool byte_sign = byte & 0x40; 141 value >>= 7; 142 143 if ((value == 0 && !byte_sign) || (value == -1 && byte_sign)) { 144 more = false; 145 } else { 146 byte |= 0x80; 147 } 148 149 Write<int8_t>(byte); 150 } 151 } 152 153 void WriteString(const char* str) { 154 do { 155 Write<char>(*str); 156 } while (*str++); 157 } 158 159 private: 160 template<typename T> friend class Slot; 161 162 template<typename T> 163 T* RawSlotAt(uintptr_t offset) { 164 ASSERT(offset < capacity_ && offset + sizeof(T) <= capacity_); 165 return reinterpret_cast<T*>(&buffer_[offset]); 166 } 167 168 ELF* elf_; 169 uintptr_t position_; 170 uintptr_t capacity_; 171 byte* buffer_; 172 }; 173 174 class StringTable; 175 176 class ELFSection : public ZoneObject { 177 public: 178 struct Header { 179 uint32_t name; 180 uint32_t type; 181 uintptr_t flags; 182 uintptr_t address; 183 uintptr_t offset; 184 uintptr_t size; 185 uint32_t link; 186 uint32_t info; 187 uintptr_t alignment; 188 uintptr_t entry_size; 189 }; 190 191 enum Type { 192 TYPE_NULL = 0, 193 TYPE_PROGBITS = 1, 194 TYPE_SYMTAB = 2, 195 TYPE_STRTAB = 3, 196 TYPE_RELA = 4, 197 TYPE_HASH = 5, 198 TYPE_DYNAMIC = 6, 199 TYPE_NOTE = 7, 200 TYPE_NOBITS = 8, 201 TYPE_REL = 9, 202 TYPE_SHLIB = 10, 203 TYPE_DYNSYM = 11, 204 TYPE_LOPROC = 0x70000000, 205 TYPE_X86_64_UNWIND = 0x70000001, 206 TYPE_HIPROC = 0x7fffffff, 207 TYPE_LOUSER = 0x80000000, 208 TYPE_HIUSER = 0xffffffff 209 }; 210 211 enum Flags { 212 FLAG_WRITE = 1, 213 FLAG_ALLOC = 2, 214 FLAG_EXEC = 4 215 }; 216 217 enum SpecialIndexes { 218 INDEX_ABSOLUTE = 0xfff1 219 }; 220 221 ELFSection(const char* name, Type type, uintptr_t align) 222 : name_(name), type_(type), align_(align) { } 223 224 virtual ~ELFSection() { } 225 226 void PopulateHeader(Writer::Slot<Header> header, StringTable* strtab); 227 228 virtual void WriteBody(Writer::Slot<Header> header, Writer* w) { 229 uintptr_t start = w->position(); 230 if (WriteBody(w)) { 231 uintptr_t end = w->position(); 232 header->offset = start; 233 header->size = end - start; 234 } 235 } 236 237 virtual bool WriteBody(Writer* w) { 238 return false; 239 } 240 241 uint16_t index() const { return index_; } 242 void set_index(uint16_t index) { index_ = index; } 243 244 protected: 245 virtual void PopulateHeader(Writer::Slot<Header> header) { 246 header->flags = 0; 247 header->address = 0; 248 header->offset = 0; 249 header->size = 0; 250 header->link = 0; 251 header->info = 0; 252 header->entry_size = 0; 253 } 254 255 256 private: 257 const char* name_; 258 Type type_; 259 uintptr_t align_; 260 uint16_t index_; 261 }; 262 263 264 class FullHeaderELFSection : public ELFSection { 265 public: 266 FullHeaderELFSection(const char* name, 267 Type type, 268 uintptr_t align, 269 uintptr_t addr, 270 uintptr_t offset, 271 uintptr_t size, 272 uintptr_t flags) 273 : ELFSection(name, type, align), 274 addr_(addr), 275 offset_(offset), 276 size_(size), 277 flags_(flags) { } 278 279 protected: 280 virtual void PopulateHeader(Writer::Slot<Header> header) { 281 ELFSection::PopulateHeader(header); 282 header->address = addr_; 283 header->offset = offset_; 284 header->size = size_; 285 header->flags = flags_; 286 } 287 288 private: 289 uintptr_t addr_; 290 uintptr_t offset_; 291 uintptr_t size_; 292 uintptr_t flags_; 293 }; 294 295 296 class StringTable : public ELFSection { 297 public: 298 explicit StringTable(const char* name) 299 : ELFSection(name, TYPE_STRTAB, 1), writer_(NULL), offset_(0), size_(0) { 300 } 301 302 uintptr_t Add(const char* str) { 303 if (*str == '\0') return 0; 304 305 uintptr_t offset = size_; 306 WriteString(str); 307 return offset; 308 } 309 310 void AttachWriter(Writer* w) { 311 writer_ = w; 312 offset_ = writer_->position(); 313 314 // First entry in the string table should be an empty string. 315 WriteString(""); 316 } 317 318 void DetachWriter() { 319 writer_ = NULL; 320 } 321 322 virtual void WriteBody(Writer::Slot<Header> header, Writer* w) { 323 ASSERT(writer_ == NULL); 324 header->offset = offset_; 325 header->size = size_; 326 } 327 328 private: 329 void WriteString(const char* str) { 330 uintptr_t written = 0; 331 do { 332 writer_->Write(*str); 333 written++; 334 } while (*str++); 335 size_ += written; 336 } 337 338 Writer* writer_; 339 340 uintptr_t offset_; 341 uintptr_t size_; 342 }; 343 344 345 void ELFSection::PopulateHeader(Writer::Slot<ELFSection::Header> header, 346 StringTable* strtab) { 347 header->name = strtab->Add(name_); 348 header->type = type_; 349 header->alignment = align_; 350 PopulateHeader(header); 351 } 352 353 354 class ELF BASE_EMBEDDED { 355 public: 356 ELF() : sections_(6) { 357 sections_.Add(new ELFSection("", ELFSection::TYPE_NULL, 0)); 358 sections_.Add(new StringTable(".shstrtab")); 359 } 360 361 void Write(Writer* w) { 362 WriteHeader(w); 363 WriteSectionTable(w); 364 WriteSections(w); 365 } 366 367 ELFSection* SectionAt(uint32_t index) { 368 return sections_[index]; 369 } 370 371 uint32_t AddSection(ELFSection* section) { 372 sections_.Add(section); 373 section->set_index(sections_.length() - 1); 374 return sections_.length() - 1; 375 } 376 377 private: 378 struct ELFHeader { 379 uint8_t ident[16]; 380 uint16_t type; 381 uint16_t machine; 382 uint32_t version; 383 uintptr_t entry; 384 uintptr_t pht_offset; 385 uintptr_t sht_offset; 386 uint32_t flags; 387 uint16_t header_size; 388 uint16_t pht_entry_size; 389 uint16_t pht_entry_num; 390 uint16_t sht_entry_size; 391 uint16_t sht_entry_num; 392 uint16_t sht_strtab_index; 393 }; 394 395 396 void WriteHeader(Writer* w) { 397 ASSERT(w->position() == 0); 398 Writer::Slot<ELFHeader> header = w->CreateSlotHere<ELFHeader>(); 399 #if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_ARM) 400 const uint8_t ident[16] = 401 { 0x7f, 'E', 'L', 'F', 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 402 #elif defined(V8_TARGET_ARCH_X64) 403 const uint8_t ident[16] = 404 { 0x7f, 'E', 'L', 'F', 2, 1, 1, 0, 0, 0 , 0, 0, 0, 0, 0, 0}; 405 #else 406 #error Unsupported target architecture. 407 #endif 408 memcpy(header->ident, ident, 16); 409 header->type = 1; 410 #if defined(V8_TARGET_ARCH_IA32) 411 header->machine = 3; 412 #elif defined(V8_TARGET_ARCH_X64) 413 // Processor identification value for x64 is 62 as defined in 414 // System V ABI, AMD64 Supplement 415 // http://www.x86-64.org/documentation/abi.pdf 416 header->machine = 62; 417 #elif defined(V8_TARGET_ARCH_ARM) 418 // Set to EM_ARM, defined as 40, in "ARM ELF File Format" at 419 // infocenter.arm.com/help/topic/com.arm.doc.dui0101a/DUI0101A_Elf.pdf 420 header->machine = 40; 421 #else 422 #error Unsupported target architecture. 423 #endif 424 header->version = 1; 425 header->entry = 0; 426 header->pht_offset = 0; 427 header->sht_offset = sizeof(ELFHeader); // Section table follows header. 428 header->flags = 0; 429 header->header_size = sizeof(ELFHeader); 430 header->pht_entry_size = 0; 431 header->pht_entry_num = 0; 432 header->sht_entry_size = sizeof(ELFSection::Header); 433 header->sht_entry_num = sections_.length(); 434 header->sht_strtab_index = 1; 435 } 436 437 void WriteSectionTable(Writer* w) { 438 // Section headers table immediately follows file header. 439 ASSERT(w->position() == sizeof(ELFHeader)); 440 441 Writer::Slot<ELFSection::Header> headers = 442 w->CreateSlotsHere<ELFSection::Header>(sections_.length()); 443 444 // String table for section table is the first section. 445 StringTable* strtab = static_cast<StringTable*>(SectionAt(1)); 446 strtab->AttachWriter(w); 447 for (int i = 0, length = sections_.length(); 448 i < length; 449 i++) { 450 sections_[i]->PopulateHeader(headers.at(i), strtab); 451 } 452 strtab->DetachWriter(); 453 } 454 455 int SectionHeaderPosition(uint32_t section_index) { 456 return sizeof(ELFHeader) + sizeof(ELFSection::Header) * section_index; 457 } 458 459 void WriteSections(Writer* w) { 460 Writer::Slot<ELFSection::Header> headers = 461 w->SlotAt<ELFSection::Header>(sizeof(ELFHeader)); 462 463 for (int i = 0, length = sections_.length(); 464 i < length; 465 i++) { 466 sections_[i]->WriteBody(headers.at(i), w); 467 } 468 } 469 470 ZoneList<ELFSection*> sections_; 471 }; 472 473 474 class ELFSymbol BASE_EMBEDDED { 475 public: 476 enum Type { 477 TYPE_NOTYPE = 0, 478 TYPE_OBJECT = 1, 479 TYPE_FUNC = 2, 480 TYPE_SECTION = 3, 481 TYPE_FILE = 4, 482 TYPE_LOPROC = 13, 483 TYPE_HIPROC = 15 484 }; 485 486 enum Binding { 487 BIND_LOCAL = 0, 488 BIND_GLOBAL = 1, 489 BIND_WEAK = 2, 490 BIND_LOPROC = 13, 491 BIND_HIPROC = 15 492 }; 493 494 ELFSymbol(const char* name, 495 uintptr_t value, 496 uintptr_t size, 497 Binding binding, 498 Type type, 499 uint16_t section) 500 : name(name), 501 value(value), 502 size(size), 503 info((binding << 4) | type), 504 other(0), 505 section(section) { 506 } 507 508 Binding binding() const { 509 return static_cast<Binding>(info >> 4); 510 } 511 #if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_ARM) 512 struct SerializedLayout { 513 SerializedLayout(uint32_t name, 514 uintptr_t value, 515 uintptr_t size, 516 Binding binding, 517 Type type, 518 uint16_t section) 519 : name(name), 520 value(value), 521 size(size), 522 info((binding << 4) | type), 523 other(0), 524 section(section) { 525 } 526 527 uint32_t name; 528 uintptr_t value; 529 uintptr_t size; 530 uint8_t info; 531 uint8_t other; 532 uint16_t section; 533 }; 534 #elif defined(V8_TARGET_ARCH_X64) 535 struct SerializedLayout { 536 SerializedLayout(uint32_t name, 537 uintptr_t value, 538 uintptr_t size, 539 Binding binding, 540 Type type, 541 uint16_t section) 542 : name(name), 543 info((binding << 4) | type), 544 other(0), 545 section(section), 546 value(value), 547 size(size) { 548 } 549 550 uint32_t name; 551 uint8_t info; 552 uint8_t other; 553 uint16_t section; 554 uintptr_t value; 555 uintptr_t size; 556 }; 557 #endif 558 559 void Write(Writer::Slot<SerializedLayout> s, StringTable* t) { 560 // Convert symbol names from strings to indexes in the string table. 561 s->name = t->Add(name); 562 s->value = value; 563 s->size = size; 564 s->info = info; 565 s->other = other; 566 s->section = section; 567 } 568 569 private: 570 const char* name; 571 uintptr_t value; 572 uintptr_t size; 573 uint8_t info; 574 uint8_t other; 575 uint16_t section; 576 }; 577 578 579 class ELFSymbolTable : public ELFSection { 580 public: 581 explicit ELFSymbolTable(const char* name) 582 : ELFSection(name, TYPE_SYMTAB, sizeof(uintptr_t)), 583 locals_(1), 584 globals_(1) { 585 } 586 587 virtual void WriteBody(Writer::Slot<Header> header, Writer* w) { 588 w->Align(header->alignment); 589 int total_symbols = locals_.length() + globals_.length() + 1; 590 header->offset = w->position(); 591 592 Writer::Slot<ELFSymbol::SerializedLayout> symbols = 593 w->CreateSlotsHere<ELFSymbol::SerializedLayout>(total_symbols); 594 595 header->size = w->position() - header->offset; 596 597 // String table for this symbol table should follow it in the section table. 598 StringTable* strtab = 599 static_cast<StringTable*>(w->elf()->SectionAt(index() + 1)); 600 strtab->AttachWriter(w); 601 symbols.at(0).set(ELFSymbol::SerializedLayout(0, 602 0, 603 0, 604 ELFSymbol::BIND_LOCAL, 605 ELFSymbol::TYPE_NOTYPE, 606 0)); 607 WriteSymbolsList(&locals_, symbols.at(1), strtab); 608 WriteSymbolsList(&globals_, symbols.at(locals_.length() + 1), strtab); 609 strtab->DetachWriter(); 610 } 611 612 void Add(const ELFSymbol& symbol) { 613 if (symbol.binding() == ELFSymbol::BIND_LOCAL) { 614 locals_.Add(symbol); 615 } else { 616 globals_.Add(symbol); 617 } 618 } 619 620 protected: 621 virtual void PopulateHeader(Writer::Slot<Header> header) { 622 ELFSection::PopulateHeader(header); 623 // We are assuming that string table will follow symbol table. 624 header->link = index() + 1; 625 header->info = locals_.length() + 1; 626 header->entry_size = sizeof(ELFSymbol::SerializedLayout); 627 } 628 629 private: 630 void WriteSymbolsList(const ZoneList<ELFSymbol>* src, 631 Writer::Slot<ELFSymbol::SerializedLayout> dst, 632 StringTable* strtab) { 633 for (int i = 0, len = src->length(); 634 i < len; 635 i++) { 636 src->at(i).Write(dst.at(i), strtab); 637 } 638 } 639 640 ZoneList<ELFSymbol> locals_; 641 ZoneList<ELFSymbol> globals_; 642 }; 643 644 645 class CodeDescription BASE_EMBEDDED { 646 public: 647 648 #ifdef V8_TARGET_ARCH_X64 649 enum StackState { 650 POST_RBP_PUSH, 651 POST_RBP_SET, 652 POST_RBP_POP, 653 STACK_STATE_MAX 654 }; 655 #endif 656 657 CodeDescription(const char* name, 658 Code* code, 659 Handle<Script> script, 660 GDBJITLineInfo* lineinfo, 661 GDBJITInterface::CodeTag tag) 662 : name_(name), 663 code_(code), 664 script_(script), 665 lineinfo_(lineinfo), 666 tag_(tag) { 667 } 668 669 const char* name() const { 670 return name_; 671 } 672 673 GDBJITLineInfo* lineinfo() const { 674 return lineinfo_; 675 } 676 677 GDBJITInterface::CodeTag tag() const { 678 return tag_; 679 } 680 681 uintptr_t CodeStart() const { 682 return reinterpret_cast<uintptr_t>(code_->instruction_start()); 683 } 684 685 uintptr_t CodeEnd() const { 686 return reinterpret_cast<uintptr_t>(code_->instruction_end()); 687 } 688 689 uintptr_t CodeSize() const { 690 return CodeEnd() - CodeStart(); 691 } 692 693 bool IsLineInfoAvailable() { 694 return !script_.is_null() && 695 script_->source()->IsString() && 696 script_->HasValidSource() && 697 script_->name()->IsString() && 698 lineinfo_ != NULL; 699 } 700 701 #ifdef V8_TARGET_ARCH_X64 702 uintptr_t GetStackStateStartAddress(StackState state) const { 703 ASSERT(state < STACK_STATE_MAX); 704 return stack_state_start_addresses_[state]; 705 } 706 707 void SetStackStateStartAddress(StackState state, uintptr_t addr) { 708 ASSERT(state < STACK_STATE_MAX); 709 stack_state_start_addresses_[state] = addr; 710 } 711 #endif 712 713 SmartPointer<char> GetFilename() { 714 return String::cast(script_->name())->ToCString(); 715 } 716 717 int GetScriptLineNumber(int pos) { 718 return GetScriptLineNumberSafe(script_, pos) + 1; 719 } 720 721 722 private: 723 const char* name_; 724 Code* code_; 725 Handle<Script> script_; 726 GDBJITLineInfo* lineinfo_; 727 GDBJITInterface::CodeTag tag_; 728 #ifdef V8_TARGET_ARCH_X64 729 uintptr_t stack_state_start_addresses_[STACK_STATE_MAX]; 730 #endif 731 }; 732 733 734 static void CreateSymbolsTable(CodeDescription* desc, 735 ELF* elf, 736 int text_section_index) { 737 ELFSymbolTable* symtab = new ELFSymbolTable(".symtab"); 738 StringTable* strtab = new StringTable(".strtab"); 739 740 // Symbol table should be followed by the linked string table. 741 elf->AddSection(symtab); 742 elf->AddSection(strtab); 743 744 symtab->Add(ELFSymbol("V8 Code", 745 0, 746 0, 747 ELFSymbol::BIND_LOCAL, 748 ELFSymbol::TYPE_FILE, 749 ELFSection::INDEX_ABSOLUTE)); 750 751 symtab->Add(ELFSymbol(desc->name(), 752 0, 753 desc->CodeSize(), 754 ELFSymbol::BIND_GLOBAL, 755 ELFSymbol::TYPE_FUNC, 756 text_section_index)); 757 } 758 759 760 class DebugInfoSection : public ELFSection { 761 public: 762 explicit DebugInfoSection(CodeDescription* desc) 763 : ELFSection(".debug_info", TYPE_PROGBITS, 1), desc_(desc) { } 764 765 bool WriteBody(Writer* w) { 766 Writer::Slot<uint32_t> size = w->CreateSlotHere<uint32_t>(); 767 uintptr_t start = w->position(); 768 w->Write<uint16_t>(2); // DWARF version. 769 w->Write<uint32_t>(0); // Abbreviation table offset. 770 w->Write<uint8_t>(sizeof(intptr_t)); 771 772 w->WriteULEB128(1); // Abbreviation code. 773 w->WriteString(*desc_->GetFilename()); 774 w->Write<intptr_t>(desc_->CodeStart()); 775 w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize()); 776 w->Write<uint32_t>(0); 777 size.set(static_cast<uint32_t>(w->position() - start)); 778 return true; 779 } 780 781 private: 782 CodeDescription* desc_; 783 }; 784 785 786 class DebugAbbrevSection : public ELFSection { 787 public: 788 DebugAbbrevSection() : ELFSection(".debug_abbrev", TYPE_PROGBITS, 1) { } 789 790 // DWARF2 standard, figure 14. 791 enum DWARF2Tags { 792 DW_TAG_COMPILE_UNIT = 0x11 793 }; 794 795 // DWARF2 standard, figure 16. 796 enum DWARF2ChildrenDetermination { 797 DW_CHILDREN_NO = 0, 798 DW_CHILDREN_YES = 1 799 }; 800 801 // DWARF standard, figure 17. 802 enum DWARF2Attribute { 803 DW_AT_NAME = 0x3, 804 DW_AT_STMT_LIST = 0x10, 805 DW_AT_LOW_PC = 0x11, 806 DW_AT_HIGH_PC = 0x12 807 }; 808 809 // DWARF2 standard, figure 19. 810 enum DWARF2AttributeForm { 811 DW_FORM_ADDR = 0x1, 812 DW_FORM_STRING = 0x8, 813 DW_FORM_DATA4 = 0x6 814 }; 815 816 bool WriteBody(Writer* w) { 817 w->WriteULEB128(1); 818 w->WriteULEB128(DW_TAG_COMPILE_UNIT); 819 w->Write<uint8_t>(DW_CHILDREN_NO); 820 w->WriteULEB128(DW_AT_NAME); 821 w->WriteULEB128(DW_FORM_STRING); 822 w->WriteULEB128(DW_AT_LOW_PC); 823 w->WriteULEB128(DW_FORM_ADDR); 824 w->WriteULEB128(DW_AT_HIGH_PC); 825 w->WriteULEB128(DW_FORM_ADDR); 826 w->WriteULEB128(DW_AT_STMT_LIST); 827 w->WriteULEB128(DW_FORM_DATA4); 828 w->WriteULEB128(0); 829 w->WriteULEB128(0); 830 w->WriteULEB128(0); 831 return true; 832 } 833 }; 834 835 836 class DebugLineSection : public ELFSection { 837 public: 838 explicit DebugLineSection(CodeDescription* desc) 839 : ELFSection(".debug_line", TYPE_PROGBITS, 1), 840 desc_(desc) { } 841 842 // DWARF2 standard, figure 34. 843 enum DWARF2Opcodes { 844 DW_LNS_COPY = 1, 845 DW_LNS_ADVANCE_PC = 2, 846 DW_LNS_ADVANCE_LINE = 3, 847 DW_LNS_SET_FILE = 4, 848 DW_LNS_SET_COLUMN = 5, 849 DW_LNS_NEGATE_STMT = 6 850 }; 851 852 // DWARF2 standard, figure 35. 853 enum DWARF2ExtendedOpcode { 854 DW_LNE_END_SEQUENCE = 1, 855 DW_LNE_SET_ADDRESS = 2, 856 DW_LNE_DEFINE_FILE = 3 857 }; 858 859 bool WriteBody(Writer* w) { 860 // Write prologue. 861 Writer::Slot<uint32_t> total_length = w->CreateSlotHere<uint32_t>(); 862 uintptr_t start = w->position(); 863 864 // Used for special opcodes 865 const int8_t line_base = 1; 866 const uint8_t line_range = 7; 867 const int8_t max_line_incr = (line_base + line_range - 1); 868 const uint8_t opcode_base = DW_LNS_NEGATE_STMT + 1; 869 870 w->Write<uint16_t>(2); // Field version. 871 Writer::Slot<uint32_t> prologue_length = w->CreateSlotHere<uint32_t>(); 872 uintptr_t prologue_start = w->position(); 873 w->Write<uint8_t>(1); // Field minimum_instruction_length. 874 w->Write<uint8_t>(1); // Field default_is_stmt. 875 w->Write<int8_t>(line_base); // Field line_base. 876 w->Write<uint8_t>(line_range); // Field line_range. 877 w->Write<uint8_t>(opcode_base); // Field opcode_base. 878 w->Write<uint8_t>(0); // DW_LNS_COPY operands count. 879 w->Write<uint8_t>(1); // DW_LNS_ADVANCE_PC operands count. 880 w->Write<uint8_t>(1); // DW_LNS_ADVANCE_LINE operands count. 881 w->Write<uint8_t>(1); // DW_LNS_SET_FILE operands count. 882 w->Write<uint8_t>(1); // DW_LNS_SET_COLUMN operands count. 883 w->Write<uint8_t>(0); // DW_LNS_NEGATE_STMT operands count. 884 w->Write<uint8_t>(0); // Empty include_directories sequence. 885 w->WriteString(*desc_->GetFilename()); // File name. 886 w->WriteULEB128(0); // Current directory. 887 w->WriteULEB128(0); // Unknown modification time. 888 w->WriteULEB128(0); // Unknown file size. 889 w->Write<uint8_t>(0); 890 prologue_length.set(static_cast<uint32_t>(w->position() - prologue_start)); 891 892 WriteExtendedOpcode(w, DW_LNE_SET_ADDRESS, sizeof(intptr_t)); 893 w->Write<intptr_t>(desc_->CodeStart()); 894 w->Write<uint8_t>(DW_LNS_COPY); 895 896 intptr_t pc = 0; 897 intptr_t line = 1; 898 bool is_statement = true; 899 900 List<GDBJITLineInfo::PCInfo>* pc_info = desc_->lineinfo()->pc_info(); 901 pc_info->Sort(&ComparePCInfo); 902 903 int pc_info_length = pc_info->length(); 904 for (int i = 0; i < pc_info_length; i++) { 905 GDBJITLineInfo::PCInfo* info = &pc_info->at(i); 906 ASSERT(info->pc_ >= pc); 907 908 // Reduce bloating in the debug line table by removing duplicate line 909 // entries (per DWARF2 standard). 910 intptr_t new_line = desc_->GetScriptLineNumber(info->pos_); 911 if (new_line == line) { 912 continue; 913 } 914 915 // Mark statement boundaries. For a better debugging experience, mark 916 // the last pc address in the function as a statement (e.g. "}"), so that 917 // a user can see the result of the last line executed in the function, 918 // should control reach the end. 919 if ((i+1) == pc_info_length) { 920 if (!is_statement) { 921 w->Write<uint8_t>(DW_LNS_NEGATE_STMT); 922 } 923 } else if (is_statement != info->is_statement_) { 924 w->Write<uint8_t>(DW_LNS_NEGATE_STMT); 925 is_statement = !is_statement; 926 } 927 928 // Generate special opcodes, if possible. This results in more compact 929 // debug line tables. See the DWARF 2.0 standard to learn more about 930 // special opcodes. 931 uintptr_t pc_diff = info->pc_ - pc; 932 intptr_t line_diff = new_line - line; 933 934 // Compute special opcode (see DWARF 2.0 standard) 935 intptr_t special_opcode = (line_diff - line_base) + 936 (line_range * pc_diff) + opcode_base; 937 938 // If special_opcode is less than or equal to 255, it can be used as a 939 // special opcode. If line_diff is larger than the max line increment 940 // allowed for a special opcode, or if line_diff is less than the minimum 941 // line that can be added to the line register (i.e. line_base), then 942 // special_opcode can't be used. 943 if ((special_opcode >= opcode_base) && (special_opcode <= 255) && 944 (line_diff <= max_line_incr) && (line_diff >= line_base)) { 945 w->Write<uint8_t>(special_opcode); 946 } else { 947 w->Write<uint8_t>(DW_LNS_ADVANCE_PC); 948 w->WriteSLEB128(pc_diff); 949 w->Write<uint8_t>(DW_LNS_ADVANCE_LINE); 950 w->WriteSLEB128(line_diff); 951 w->Write<uint8_t>(DW_LNS_COPY); 952 } 953 954 // Increment the pc and line operands. 955 pc += pc_diff; 956 line += line_diff; 957 } 958 // Advance the pc to the end of the routine, since the end sequence opcode 959 // requires this. 960 w->Write<uint8_t>(DW_LNS_ADVANCE_PC); 961 w->WriteSLEB128(desc_->CodeSize() - pc); 962 WriteExtendedOpcode(w, DW_LNE_END_SEQUENCE, 0); 963 total_length.set(static_cast<uint32_t>(w->position() - start)); 964 return true; 965 } 966 967 private: 968 void WriteExtendedOpcode(Writer* w, 969 DWARF2ExtendedOpcode op, 970 size_t operands_size) { 971 w->Write<uint8_t>(0); 972 w->WriteULEB128(operands_size + 1); 973 w->Write<uint8_t>(op); 974 } 975 976 static int ComparePCInfo(const GDBJITLineInfo::PCInfo* a, 977 const GDBJITLineInfo::PCInfo* b) { 978 if (a->pc_ == b->pc_) { 979 if (a->is_statement_ != b->is_statement_) { 980 return b->is_statement_ ? +1 : -1; 981 } 982 return 0; 983 } else if (a->pc_ > b->pc_) { 984 return +1; 985 } else { 986 return -1; 987 } 988 } 989 990 CodeDescription* desc_; 991 }; 992 993 994 #ifdef V8_TARGET_ARCH_X64 995 996 997 class UnwindInfoSection : public ELFSection { 998 public: 999 explicit UnwindInfoSection(CodeDescription *desc); 1000 virtual bool WriteBody(Writer *w); 1001 1002 int WriteCIE(Writer *w); 1003 void WriteFDE(Writer *w, int); 1004 1005 void WriteFDEStateOnEntry(Writer *w); 1006 void WriteFDEStateAfterRBPPush(Writer *w); 1007 void WriteFDEStateAfterRBPSet(Writer *w); 1008 void WriteFDEStateAfterRBPPop(Writer *w); 1009 1010 void WriteLength(Writer *w, 1011 Writer::Slot<uint32_t>* length_slot, 1012 int initial_position); 1013 1014 private: 1015 CodeDescription *desc_; 1016 1017 // DWARF3 Specification, Table 7.23 1018 enum CFIInstructions { 1019 DW_CFA_ADVANCE_LOC = 0x40, 1020 DW_CFA_OFFSET = 0x80, 1021 DW_CFA_RESTORE = 0xC0, 1022 DW_CFA_NOP = 0x00, 1023 DW_CFA_SET_LOC = 0x01, 1024 DW_CFA_ADVANCE_LOC1 = 0x02, 1025 DW_CFA_ADVANCE_LOC2 = 0x03, 1026 DW_CFA_ADVANCE_LOC4 = 0x04, 1027 DW_CFA_OFFSET_EXTENDED = 0x05, 1028 DW_CFA_RESTORE_EXTENDED = 0x06, 1029 DW_CFA_UNDEFINED = 0x07, 1030 DW_CFA_SAME_VALUE = 0x08, 1031 DW_CFA_REGISTER = 0x09, 1032 DW_CFA_REMEMBER_STATE = 0x0A, 1033 DW_CFA_RESTORE_STATE = 0x0B, 1034 DW_CFA_DEF_CFA = 0x0C, 1035 DW_CFA_DEF_CFA_REGISTER = 0x0D, 1036 DW_CFA_DEF_CFA_OFFSET = 0x0E, 1037 1038 DW_CFA_DEF_CFA_EXPRESSION = 0x0F, 1039 DW_CFA_EXPRESSION = 0x10, 1040 DW_CFA_OFFSET_EXTENDED_SF = 0x11, 1041 DW_CFA_DEF_CFA_SF = 0x12, 1042 DW_CFA_DEF_CFA_OFFSET_SF = 0x13, 1043 DW_CFA_VAL_OFFSET = 0x14, 1044 DW_CFA_VAL_OFFSET_SF = 0x15, 1045 DW_CFA_VAL_EXPRESSION = 0x16 1046 }; 1047 1048 // System V ABI, AMD64 Supplement, Version 0.99.5, Figure 3.36 1049 enum RegisterMapping { 1050 // Only the relevant ones have been added to reduce clutter. 1051 AMD64_RBP = 6, 1052 AMD64_RSP = 7, 1053 AMD64_RA = 16 1054 }; 1055 1056 enum CFIConstants { 1057 CIE_ID = 0, 1058 CIE_VERSION = 1, 1059 CODE_ALIGN_FACTOR = 1, 1060 DATA_ALIGN_FACTOR = 1, 1061 RETURN_ADDRESS_REGISTER = AMD64_RA 1062 }; 1063 }; 1064 1065 1066 void UnwindInfoSection::WriteLength(Writer *w, 1067 Writer::Slot<uint32_t>* length_slot, 1068 int initial_position) { 1069 uint32_t align = (w->position() - initial_position) % kPointerSize; 1070 1071 if (align != 0) { 1072 for (uint32_t i = 0; i < (kPointerSize - align); i++) { 1073 w->Write<uint8_t>(DW_CFA_NOP); 1074 } 1075 } 1076 1077 ASSERT((w->position() - initial_position) % kPointerSize == 0); 1078 length_slot->set(w->position() - initial_position); 1079 } 1080 1081 1082 UnwindInfoSection::UnwindInfoSection(CodeDescription *desc) 1083 : ELFSection(".eh_frame", TYPE_X86_64_UNWIND, 1), desc_(desc) 1084 { } 1085 1086 int UnwindInfoSection::WriteCIE(Writer *w) { 1087 Writer::Slot<uint32_t> cie_length_slot = w->CreateSlotHere<uint32_t>(); 1088 uint32_t cie_position = w->position(); 1089 1090 // Write out the CIE header. Currently no 'common instructions' are 1091 // emitted onto the CIE; every FDE has its own set of instructions. 1092 1093 w->Write<uint32_t>(CIE_ID); 1094 w->Write<uint8_t>(CIE_VERSION); 1095 w->Write<uint8_t>(0); // Null augmentation string. 1096 w->WriteSLEB128(CODE_ALIGN_FACTOR); 1097 w->WriteSLEB128(DATA_ALIGN_FACTOR); 1098 w->Write<uint8_t>(RETURN_ADDRESS_REGISTER); 1099 1100 WriteLength(w, &cie_length_slot, cie_position); 1101 1102 return cie_position; 1103 } 1104 1105 1106 void UnwindInfoSection::WriteFDE(Writer *w, int cie_position) { 1107 // The only FDE for this function. The CFA is the current RBP. 1108 Writer::Slot<uint32_t> fde_length_slot = w->CreateSlotHere<uint32_t>(); 1109 int fde_position = w->position(); 1110 w->Write<int32_t>(fde_position - cie_position + 4); 1111 1112 w->Write<uintptr_t>(desc_->CodeStart()); 1113 w->Write<uintptr_t>(desc_->CodeSize()); 1114 1115 WriteFDEStateOnEntry(w); 1116 WriteFDEStateAfterRBPPush(w); 1117 WriteFDEStateAfterRBPSet(w); 1118 WriteFDEStateAfterRBPPop(w); 1119 1120 WriteLength(w, &fde_length_slot, fde_position); 1121 } 1122 1123 1124 void UnwindInfoSection::WriteFDEStateOnEntry(Writer *w) { 1125 // The first state, just after the control has been transferred to the the 1126 // function. 1127 1128 // RBP for this function will be the value of RSP after pushing the RBP 1129 // for the previous function. The previous RBP has not been pushed yet. 1130 w->Write<uint8_t>(DW_CFA_DEF_CFA_SF); 1131 w->WriteULEB128(AMD64_RSP); 1132 w->WriteSLEB128(-kPointerSize); 1133 1134 // The RA is stored at location CFA + kCallerPCOffset. This is an invariant, 1135 // and hence omitted from the next states. 1136 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); 1137 w->WriteULEB128(AMD64_RA); 1138 w->WriteSLEB128(StandardFrameConstants::kCallerPCOffset); 1139 1140 // The RBP of the previous function is still in RBP. 1141 w->Write<uint8_t>(DW_CFA_SAME_VALUE); 1142 w->WriteULEB128(AMD64_RBP); 1143 1144 // Last location described by this entry. 1145 w->Write<uint8_t>(DW_CFA_SET_LOC); 1146 w->Write<uint64_t>( 1147 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_PUSH)); 1148 } 1149 1150 1151 void UnwindInfoSection::WriteFDEStateAfterRBPPush(Writer *w) { 1152 // The second state, just after RBP has been pushed. 1153 1154 // RBP / CFA for this function is now the current RSP, so just set the 1155 // offset from the previous rule (from -8) to 0. 1156 w->Write<uint8_t>(DW_CFA_DEF_CFA_OFFSET); 1157 w->WriteULEB128(0); 1158 1159 // The previous RBP is stored at CFA + kCallerFPOffset. This is an invariant 1160 // in this and the next state, and hence omitted in the next state. 1161 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); 1162 w->WriteULEB128(AMD64_RBP); 1163 w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset); 1164 1165 // Last location described by this entry. 1166 w->Write<uint8_t>(DW_CFA_SET_LOC); 1167 w->Write<uint64_t>( 1168 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_SET)); 1169 } 1170 1171 1172 void UnwindInfoSection::WriteFDEStateAfterRBPSet(Writer *w) { 1173 // The third state, after the RBP has been set. 1174 1175 // The CFA can now directly be set to RBP. 1176 w->Write<uint8_t>(DW_CFA_DEF_CFA); 1177 w->WriteULEB128(AMD64_RBP); 1178 w->WriteULEB128(0); 1179 1180 // Last location described by this entry. 1181 w->Write<uint8_t>(DW_CFA_SET_LOC); 1182 w->Write<uint64_t>( 1183 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_POP)); 1184 } 1185 1186 1187 void UnwindInfoSection::WriteFDEStateAfterRBPPop(Writer *w) { 1188 // The fourth (final) state. The RBP has been popped (just before issuing a 1189 // return). 1190 1191 // The CFA can is now calculated in the same way as in the first state. 1192 w->Write<uint8_t>(DW_CFA_DEF_CFA_SF); 1193 w->WriteULEB128(AMD64_RSP); 1194 w->WriteSLEB128(-kPointerSize); 1195 1196 // The RBP 1197 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); 1198 w->WriteULEB128(AMD64_RBP); 1199 w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset); 1200 1201 // Last location described by this entry. 1202 w->Write<uint8_t>(DW_CFA_SET_LOC); 1203 w->Write<uint64_t>(desc_->CodeEnd()); 1204 } 1205 1206 1207 bool UnwindInfoSection::WriteBody(Writer *w) { 1208 uint32_t cie_position = WriteCIE(w); 1209 WriteFDE(w, cie_position); 1210 return true; 1211 } 1212 1213 1214 #endif // V8_TARGET_ARCH_X64 1215 1216 1217 static void CreateDWARFSections(CodeDescription* desc, ELF* elf) { 1218 if (desc->IsLineInfoAvailable()) { 1219 elf->AddSection(new DebugInfoSection(desc)); 1220 elf->AddSection(new DebugAbbrevSection); 1221 elf->AddSection(new DebugLineSection(desc)); 1222 } 1223 #ifdef V8_TARGET_ARCH_X64 1224 elf->AddSection(new UnwindInfoSection(desc)); 1225 #endif 1226 } 1227 1228 1229 // ------------------------------------------------------------------- 1230 // Binary GDB JIT Interface as described in 1231 // http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html 1232 extern "C" { 1233 typedef enum { 1234 JIT_NOACTION = 0, 1235 JIT_REGISTER_FN, 1236 JIT_UNREGISTER_FN 1237 } JITAction; 1238 1239 struct JITCodeEntry { 1240 JITCodeEntry* next_; 1241 JITCodeEntry* prev_; 1242 Address symfile_addr_; 1243 uint64_t symfile_size_; 1244 }; 1245 1246 struct JITDescriptor { 1247 uint32_t version_; 1248 uint32_t action_flag_; 1249 JITCodeEntry *relevant_entry_; 1250 JITCodeEntry *first_entry_; 1251 }; 1252 1253 // GDB will place breakpoint into this function. 1254 // To prevent GCC from inlining or removing it we place noinline attribute 1255 // and inline assembler statement inside. 1256 void __attribute__((noinline)) __jit_debug_register_code() { 1257 __asm__(""); 1258 } 1259 1260 // GDB will inspect contents of this descriptor. 1261 // Static initialization is necessary to prevent GDB from seeing 1262 // uninitialized descriptor. 1263 JITDescriptor __jit_debug_descriptor = { 1, 0, 0, 0 }; 1264 } 1265 1266 1267 static JITCodeEntry* CreateCodeEntry(Address symfile_addr, 1268 uintptr_t symfile_size) { 1269 JITCodeEntry* entry = static_cast<JITCodeEntry*>( 1270 malloc(sizeof(JITCodeEntry) + symfile_size)); 1271 1272 entry->symfile_addr_ = reinterpret_cast<Address>(entry + 1); 1273 entry->symfile_size_ = symfile_size; 1274 memcpy(entry->symfile_addr_, symfile_addr, symfile_size); 1275 1276 entry->prev_ = entry->next_ = NULL; 1277 1278 return entry; 1279 } 1280 1281 1282 static void DestroyCodeEntry(JITCodeEntry* entry) { 1283 free(entry); 1284 } 1285 1286 1287 static void RegisterCodeEntry(JITCodeEntry* entry) { 1288 #if defined(DEBUG) && !defined(WIN32) 1289 static int file_num = 0; 1290 if (FLAG_gdbjit_dump) { 1291 static const int kMaxFileNameSize = 64; 1292 static const char* kElfFilePrefix = "/tmp/elfdump"; 1293 static const char* kObjFileExt = ".o"; 1294 char file_name[64]; 1295 1296 OS::SNPrintF(Vector<char>(file_name, kMaxFileNameSize), "%s%d%s", 1297 kElfFilePrefix, file_num++, kObjFileExt); 1298 WriteBytes(file_name, entry->symfile_addr_, entry->symfile_size_); 1299 } 1300 #endif 1301 1302 entry->next_ = __jit_debug_descriptor.first_entry_; 1303 if (entry->next_ != NULL) entry->next_->prev_ = entry; 1304 __jit_debug_descriptor.first_entry_ = 1305 __jit_debug_descriptor.relevant_entry_ = entry; 1306 1307 __jit_debug_descriptor.action_flag_ = JIT_REGISTER_FN; 1308 __jit_debug_register_code(); 1309 } 1310 1311 1312 static void UnregisterCodeEntry(JITCodeEntry* entry) { 1313 if (entry->prev_ != NULL) { 1314 entry->prev_->next_ = entry->next_; 1315 } else { 1316 __jit_debug_descriptor.first_entry_ = entry->next_; 1317 } 1318 1319 if (entry->next_ != NULL) { 1320 entry->next_->prev_ = entry->prev_; 1321 } 1322 1323 __jit_debug_descriptor.relevant_entry_ = entry; 1324 __jit_debug_descriptor.action_flag_ = JIT_UNREGISTER_FN; 1325 __jit_debug_register_code(); 1326 } 1327 1328 1329 static JITCodeEntry* CreateELFObject(CodeDescription* desc) { 1330 ZoneScope zone_scope(DELETE_ON_EXIT); 1331 1332 ELF elf; 1333 Writer w(&elf); 1334 1335 int text_section_index = elf.AddSection( 1336 new FullHeaderELFSection(".text", 1337 ELFSection::TYPE_NOBITS, 1338 kCodeAlignment, 1339 desc->CodeStart(), 1340 0, 1341 desc->CodeSize(), 1342 ELFSection::FLAG_ALLOC | ELFSection::FLAG_EXEC)); 1343 1344 CreateSymbolsTable(desc, &elf, text_section_index); 1345 1346 CreateDWARFSections(desc, &elf); 1347 1348 elf.Write(&w); 1349 1350 return CreateCodeEntry(w.buffer(), w.position()); 1351 } 1352 1353 1354 static bool SameCodeObjects(void* key1, void* key2) { 1355 return key1 == key2; 1356 } 1357 1358 1359 static HashMap* GetEntries() { 1360 static HashMap* entries = NULL; 1361 if (entries == NULL) { 1362 entries = new HashMap(&SameCodeObjects); 1363 } 1364 return entries; 1365 } 1366 1367 1368 static uint32_t HashForCodeObject(Code* code) { 1369 static const uintptr_t kGoldenRatio = 2654435761u; 1370 uintptr_t hash = reinterpret_cast<uintptr_t>(code->address()); 1371 return static_cast<uint32_t>((hash >> kCodeAlignmentBits) * kGoldenRatio); 1372 } 1373 1374 1375 static const intptr_t kLineInfoTag = 0x1; 1376 1377 1378 static bool IsLineInfoTagged(void* ptr) { 1379 return 0 != (reinterpret_cast<intptr_t>(ptr) & kLineInfoTag); 1380 } 1381 1382 1383 static void* TagLineInfo(GDBJITLineInfo* ptr) { 1384 return reinterpret_cast<void*>( 1385 reinterpret_cast<intptr_t>(ptr) | kLineInfoTag); 1386 } 1387 1388 1389 static GDBJITLineInfo* UntagLineInfo(void* ptr) { 1390 return reinterpret_cast<GDBJITLineInfo*>( 1391 reinterpret_cast<intptr_t>(ptr) & ~kLineInfoTag); 1392 } 1393 1394 1395 void GDBJITInterface::AddCode(Handle<String> name, 1396 Handle<Script> script, 1397 Handle<Code> code) { 1398 if (!FLAG_gdbjit) return; 1399 1400 // Force initialization of line_ends array. 1401 GetScriptLineNumber(script, 0); 1402 1403 if (!name.is_null()) { 1404 SmartPointer<char> name_cstring = name->ToCString(DISALLOW_NULLS); 1405 AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script); 1406 } else { 1407 AddCode("", *code, GDBJITInterface::FUNCTION, *script); 1408 } 1409 } 1410 1411 static void AddUnwindInfo(CodeDescription *desc) { 1412 #ifdef V8_TARGET_ARCH_X64 1413 if (desc->tag() == GDBJITInterface::FUNCTION) { 1414 // To avoid propagating unwinding information through 1415 // compilation pipeline we use an approximation. 1416 // For most use cases this should not affect usability. 1417 static const int kFramePointerPushOffset = 1; 1418 static const int kFramePointerSetOffset = 4; 1419 static const int kFramePointerPopOffset = -3; 1420 1421 uintptr_t frame_pointer_push_address = 1422 desc->CodeStart() + kFramePointerPushOffset; 1423 1424 uintptr_t frame_pointer_set_address = 1425 desc->CodeStart() + kFramePointerSetOffset; 1426 1427 uintptr_t frame_pointer_pop_address = 1428 desc->CodeEnd() + kFramePointerPopOffset; 1429 1430 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_PUSH, 1431 frame_pointer_push_address); 1432 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_SET, 1433 frame_pointer_set_address); 1434 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_POP, 1435 frame_pointer_pop_address); 1436 } else { 1437 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_PUSH, 1438 desc->CodeStart()); 1439 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_SET, 1440 desc->CodeStart()); 1441 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_POP, 1442 desc->CodeEnd()); 1443 } 1444 #endif // V8_TARGET_ARCH_X64 1445 } 1446 1447 1448 Mutex* GDBJITInterface::mutex_ = OS::CreateMutex(); 1449 1450 1451 void GDBJITInterface::AddCode(const char* name, 1452 Code* code, 1453 GDBJITInterface::CodeTag tag, 1454 Script* script) { 1455 if (!FLAG_gdbjit) return; 1456 1457 ScopedLock lock(mutex_); 1458 AssertNoAllocation no_gc; 1459 1460 HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true); 1461 if (e->value != NULL && !IsLineInfoTagged(e->value)) return; 1462 1463 GDBJITLineInfo* lineinfo = UntagLineInfo(e->value); 1464 CodeDescription code_desc(name, 1465 code, 1466 script != NULL ? Handle<Script>(script) 1467 : Handle<Script>(), 1468 lineinfo, 1469 tag); 1470 1471 if (!FLAG_gdbjit_full && !code_desc.IsLineInfoAvailable()) { 1472 delete lineinfo; 1473 GetEntries()->Remove(code, HashForCodeObject(code)); 1474 return; 1475 } 1476 1477 AddUnwindInfo(&code_desc); 1478 JITCodeEntry* entry = CreateELFObject(&code_desc); 1479 ASSERT(!IsLineInfoTagged(entry)); 1480 1481 delete lineinfo; 1482 e->value = entry; 1483 1484 RegisterCodeEntry(entry); 1485 } 1486 1487 1488 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag, 1489 const char* name, 1490 Code* code) { 1491 if (!FLAG_gdbjit) return; 1492 1493 EmbeddedVector<char, 256> buffer; 1494 StringBuilder builder(buffer.start(), buffer.length()); 1495 1496 builder.AddString(Tag2String(tag)); 1497 if ((name != NULL) && (*name != '\0')) { 1498 builder.AddString(": "); 1499 builder.AddString(name); 1500 } else { 1501 builder.AddFormatted(": code object %p", static_cast<void*>(code)); 1502 } 1503 1504 AddCode(builder.Finalize(), code, tag); 1505 } 1506 1507 1508 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag, 1509 String* name, 1510 Code* code) { 1511 if (!FLAG_gdbjit) return; 1512 AddCode(tag, name != NULL ? *name->ToCString(DISALLOW_NULLS) : NULL, code); 1513 } 1514 1515 1516 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag, Code* code) { 1517 if (!FLAG_gdbjit) return; 1518 1519 AddCode(tag, "", code); 1520 } 1521 1522 1523 void GDBJITInterface::RemoveCode(Code* code) { 1524 if (!FLAG_gdbjit) return; 1525 1526 ScopedLock lock(mutex_); 1527 HashMap::Entry* e = GetEntries()->Lookup(code, 1528 HashForCodeObject(code), 1529 false); 1530 if (e == NULL) return; 1531 1532 if (IsLineInfoTagged(e->value)) { 1533 delete UntagLineInfo(e->value); 1534 } else { 1535 JITCodeEntry* entry = static_cast<JITCodeEntry*>(e->value); 1536 UnregisterCodeEntry(entry); 1537 DestroyCodeEntry(entry); 1538 } 1539 e->value = NULL; 1540 GetEntries()->Remove(code, HashForCodeObject(code)); 1541 } 1542 1543 1544 void GDBJITInterface::RegisterDetailedLineInfo(Code* code, 1545 GDBJITLineInfo* line_info) { 1546 ScopedLock lock(mutex_); 1547 ASSERT(!IsLineInfoTagged(line_info)); 1548 HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true); 1549 ASSERT(e->value == NULL); 1550 e->value = TagLineInfo(line_info); 1551 } 1552 1553 1554 } } // namespace v8::internal 1555 #endif 1556