OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 return false; | 210 return false; |
211 } | 211 } |
212 | 212 |
213 typedef THeader Header; | 213 typedef THeader Header; |
214 }; | 214 }; |
215 | 215 |
216 | 216 |
217 struct MachOSectionHeader { | 217 struct MachOSectionHeader { |
218 char sectname[16]; | 218 char sectname[16]; |
219 char segname[16]; | 219 char segname[16]; |
220 #if defined(V8_TARGET_ARCH_IA32) | 220 #if V8_TARGET_ARCH_IA32 |
221 uint32_t addr; | 221 uint32_t addr; |
222 uint32_t size; | 222 uint32_t size; |
223 #else | 223 #else |
224 uint64_t addr; | 224 uint64_t addr; |
225 uint64_t size; | 225 uint64_t size; |
226 #endif | 226 #endif |
227 uint32_t offset; | 227 uint32_t offset; |
228 uint32_t align; | 228 uint32_t align; |
229 uint32_t reloff; | 229 uint32_t reloff; |
230 uint32_t nreloc; | 230 uint32_t nreloc; |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 header->type = type_; | 493 header->type = type_; |
494 header->alignment = align_; | 494 header->alignment = align_; |
495 PopulateHeader(header); | 495 PopulateHeader(header); |
496 } | 496 } |
497 #endif // defined(__ELF) | 497 #endif // defined(__ELF) |
498 | 498 |
499 | 499 |
500 #if defined(__MACH_O) | 500 #if defined(__MACH_O) |
501 class MachO BASE_EMBEDDED { | 501 class MachO BASE_EMBEDDED { |
502 public: | 502 public: |
503 MachO() : sections_(6) { } | 503 explicit MachO(Zone* zone) : zone_(zone), sections_(6, zone) { } |
504 | 504 |
505 uint32_t AddSection(MachOSection* section) { | 505 uint32_t AddSection(MachOSection* section) { |
506 sections_.Add(section); | 506 sections_.Add(section, zone_); |
507 return sections_.length() - 1; | 507 return sections_.length() - 1; |
508 } | 508 } |
509 | 509 |
510 void Write(Writer* w, uintptr_t code_start, uintptr_t code_size) { | 510 void Write(Writer* w, uintptr_t code_start, uintptr_t code_size) { |
511 Writer::Slot<MachOHeader> header = WriteHeader(w); | 511 Writer::Slot<MachOHeader> header = WriteHeader(w); |
512 uintptr_t load_command_start = w->position(); | 512 uintptr_t load_command_start = w->position(); |
513 Writer::Slot<MachOSegmentCommand> cmd = WriteSegmentCommand(w, | 513 Writer::Slot<MachOSegmentCommand> cmd = WriteSegmentCommand(w, |
514 code_start, | 514 code_start, |
515 code_size); | 515 code_size); |
516 WriteSections(w, cmd, header, load_command_start); | 516 WriteSections(w, cmd, header, load_command_start); |
517 } | 517 } |
518 | 518 |
519 private: | 519 private: |
520 struct MachOHeader { | 520 struct MachOHeader { |
521 uint32_t magic; | 521 uint32_t magic; |
522 uint32_t cputype; | 522 uint32_t cputype; |
523 uint32_t cpusubtype; | 523 uint32_t cpusubtype; |
524 uint32_t filetype; | 524 uint32_t filetype; |
525 uint32_t ncmds; | 525 uint32_t ncmds; |
526 uint32_t sizeofcmds; | 526 uint32_t sizeofcmds; |
527 uint32_t flags; | 527 uint32_t flags; |
528 #if defined(V8_TARGET_ARCH_X64) | 528 #if V8_TARGET_ARCH_X64 |
529 uint32_t reserved; | 529 uint32_t reserved; |
530 #endif | 530 #endif |
531 }; | 531 }; |
532 | 532 |
533 struct MachOSegmentCommand { | 533 struct MachOSegmentCommand { |
534 uint32_t cmd; | 534 uint32_t cmd; |
535 uint32_t cmdsize; | 535 uint32_t cmdsize; |
536 char segname[16]; | 536 char segname[16]; |
537 #if defined(V8_TARGET_ARCH_IA32) | 537 #if V8_TARGET_ARCH_IA32 |
538 uint32_t vmaddr; | 538 uint32_t vmaddr; |
539 uint32_t vmsize; | 539 uint32_t vmsize; |
540 uint32_t fileoff; | 540 uint32_t fileoff; |
541 uint32_t filesize; | 541 uint32_t filesize; |
542 #else | 542 #else |
543 uint64_t vmaddr; | 543 uint64_t vmaddr; |
544 uint64_t vmsize; | 544 uint64_t vmsize; |
545 uint64_t fileoff; | 545 uint64_t fileoff; |
546 uint64_t filesize; | 546 uint64_t filesize; |
547 #endif | 547 #endif |
548 uint32_t maxprot; | 548 uint32_t maxprot; |
549 uint32_t initprot; | 549 uint32_t initprot; |
550 uint32_t nsects; | 550 uint32_t nsects; |
551 uint32_t flags; | 551 uint32_t flags; |
552 }; | 552 }; |
553 | 553 |
554 enum MachOLoadCommandCmd { | 554 enum MachOLoadCommandCmd { |
555 LC_SEGMENT_32 = 0x00000001u, | 555 LC_SEGMENT_32 = 0x00000001u, |
556 LC_SEGMENT_64 = 0x00000019u | 556 LC_SEGMENT_64 = 0x00000019u |
557 }; | 557 }; |
558 | 558 |
559 | 559 |
560 Writer::Slot<MachOHeader> WriteHeader(Writer* w) { | 560 Writer::Slot<MachOHeader> WriteHeader(Writer* w) { |
561 ASSERT(w->position() == 0); | 561 ASSERT(w->position() == 0); |
562 Writer::Slot<MachOHeader> header = w->CreateSlotHere<MachOHeader>(); | 562 Writer::Slot<MachOHeader> header = w->CreateSlotHere<MachOHeader>(); |
563 #if defined(V8_TARGET_ARCH_IA32) | 563 #if V8_TARGET_ARCH_IA32 |
564 header->magic = 0xFEEDFACEu; | 564 header->magic = 0xFEEDFACEu; |
565 header->cputype = 7; // i386 | 565 header->cputype = 7; // i386 |
566 header->cpusubtype = 3; // CPU_SUBTYPE_I386_ALL | 566 header->cpusubtype = 3; // CPU_SUBTYPE_I386_ALL |
567 #elif defined(V8_TARGET_ARCH_X64) | 567 #elif V8_TARGET_ARCH_X64 |
568 header->magic = 0xFEEDFACFu; | 568 header->magic = 0xFEEDFACFu; |
569 header->cputype = 7 | 0x01000000; // i386 | 64-bit ABI | 569 header->cputype = 7 | 0x01000000; // i386 | 64-bit ABI |
570 header->cpusubtype = 3; // CPU_SUBTYPE_I386_ALL | 570 header->cpusubtype = 3; // CPU_SUBTYPE_I386_ALL |
571 header->reserved = 0; | 571 header->reserved = 0; |
572 #else | 572 #else |
573 #error Unsupported target architecture. | 573 #error Unsupported target architecture. |
574 #endif | 574 #endif |
575 header->filetype = 0x1; // MH_OBJECT | 575 header->filetype = 0x1; // MH_OBJECT |
576 header->ncmds = 1; | 576 header->ncmds = 1; |
577 header->sizeofcmds = 0; | 577 header->sizeofcmds = 0; |
578 header->flags = 0; | 578 header->flags = 0; |
579 return header; | 579 return header; |
580 } | 580 } |
581 | 581 |
582 | 582 |
583 Writer::Slot<MachOSegmentCommand> WriteSegmentCommand(Writer* w, | 583 Writer::Slot<MachOSegmentCommand> WriteSegmentCommand(Writer* w, |
584 uintptr_t code_start, | 584 uintptr_t code_start, |
585 uintptr_t code_size) { | 585 uintptr_t code_size) { |
586 Writer::Slot<MachOSegmentCommand> cmd = | 586 Writer::Slot<MachOSegmentCommand> cmd = |
587 w->CreateSlotHere<MachOSegmentCommand>(); | 587 w->CreateSlotHere<MachOSegmentCommand>(); |
588 #if defined(V8_TARGET_ARCH_IA32) | 588 #if V8_TARGET_ARCH_IA32 |
589 cmd->cmd = LC_SEGMENT_32; | 589 cmd->cmd = LC_SEGMENT_32; |
590 #else | 590 #else |
591 cmd->cmd = LC_SEGMENT_64; | 591 cmd->cmd = LC_SEGMENT_64; |
592 #endif | 592 #endif |
593 cmd->vmaddr = code_start; | 593 cmd->vmaddr = code_start; |
594 cmd->vmsize = code_size; | 594 cmd->vmsize = code_size; |
595 cmd->fileoff = 0; | 595 cmd->fileoff = 0; |
596 cmd->filesize = 0; | 596 cmd->filesize = 0; |
597 cmd->maxprot = 7; | 597 cmd->maxprot = 7; |
598 cmd->initprot = 7; | 598 cmd->initprot = 7; |
(...skipping 14 matching lines...) Expand all Loading... |
613 w->CreateSlotsHere<MachOSection::Header>(sections_.length()); | 613 w->CreateSlotsHere<MachOSection::Header>(sections_.length()); |
614 cmd->fileoff = w->position(); | 614 cmd->fileoff = w->position(); |
615 header->sizeofcmds = w->position() - load_command_start; | 615 header->sizeofcmds = w->position() - load_command_start; |
616 for (int section = 0; section < sections_.length(); ++section) { | 616 for (int section = 0; section < sections_.length(); ++section) { |
617 sections_[section]->PopulateHeader(headers.at(section)); | 617 sections_[section]->PopulateHeader(headers.at(section)); |
618 sections_[section]->WriteBody(headers.at(section), w); | 618 sections_[section]->WriteBody(headers.at(section), w); |
619 } | 619 } |
620 cmd->filesize = w->position() - (uintptr_t)cmd->fileoff; | 620 cmd->filesize = w->position() - (uintptr_t)cmd->fileoff; |
621 } | 621 } |
622 | 622 |
623 | 623 Zone* zone_; |
624 ZoneList<MachOSection*> sections_; | 624 ZoneList<MachOSection*> sections_; |
625 }; | 625 }; |
626 #endif // defined(__MACH_O) | 626 #endif // defined(__MACH_O) |
627 | 627 |
628 | 628 |
629 #if defined(__ELF) | 629 #if defined(__ELF) |
630 class ELF BASE_EMBEDDED { | 630 class ELF BASE_EMBEDDED { |
631 public: | 631 public: |
632 explicit ELF(Zone* zone) : sections_(6, zone) { | 632 explicit ELF(Zone* zone) : zone_(zone), sections_(6, zone) { |
633 sections_.Add(new(zone) ELFSection("", ELFSection::TYPE_NULL, 0), zone); | 633 sections_.Add(new(zone) ELFSection("", ELFSection::TYPE_NULL, 0), zone); |
634 sections_.Add(new(zone) ELFStringTable(".shstrtab"), zone); | 634 sections_.Add(new(zone) ELFStringTable(".shstrtab"), zone); |
635 } | 635 } |
636 | 636 |
637 void Write(Writer* w) { | 637 void Write(Writer* w) { |
638 WriteHeader(w); | 638 WriteHeader(w); |
639 WriteSectionTable(w); | 639 WriteSectionTable(w); |
640 WriteSections(w); | 640 WriteSections(w); |
641 } | 641 } |
642 | 642 |
643 ELFSection* SectionAt(uint32_t index) { | 643 ELFSection* SectionAt(uint32_t index) { |
644 return sections_[index]; | 644 return sections_[index]; |
645 } | 645 } |
646 | 646 |
647 uint32_t AddSection(ELFSection* section, Zone* zone) { | 647 uint32_t AddSection(ELFSection* section) { |
648 sections_.Add(section, zone); | 648 sections_.Add(section, zone_); |
649 section->set_index(sections_.length() - 1); | 649 section->set_index(sections_.length() - 1); |
650 return sections_.length() - 1; | 650 return sections_.length() - 1; |
651 } | 651 } |
652 | 652 |
653 private: | 653 private: |
654 struct ELFHeader { | 654 struct ELFHeader { |
655 uint8_t ident[16]; | 655 uint8_t ident[16]; |
656 uint16_t type; | 656 uint16_t type; |
657 uint16_t machine; | 657 uint16_t machine; |
658 uint32_t version; | 658 uint32_t version; |
659 uintptr_t entry; | 659 uintptr_t entry; |
660 uintptr_t pht_offset; | 660 uintptr_t pht_offset; |
661 uintptr_t sht_offset; | 661 uintptr_t sht_offset; |
662 uint32_t flags; | 662 uint32_t flags; |
663 uint16_t header_size; | 663 uint16_t header_size; |
664 uint16_t pht_entry_size; | 664 uint16_t pht_entry_size; |
665 uint16_t pht_entry_num; | 665 uint16_t pht_entry_num; |
666 uint16_t sht_entry_size; | 666 uint16_t sht_entry_size; |
667 uint16_t sht_entry_num; | 667 uint16_t sht_entry_num; |
668 uint16_t sht_strtab_index; | 668 uint16_t sht_strtab_index; |
669 }; | 669 }; |
670 | 670 |
671 | 671 |
672 void WriteHeader(Writer* w) { | 672 void WriteHeader(Writer* w) { |
673 ASSERT(w->position() == 0); | 673 ASSERT(w->position() == 0); |
674 Writer::Slot<ELFHeader> header = w->CreateSlotHere<ELFHeader>(); | 674 Writer::Slot<ELFHeader> header = w->CreateSlotHere<ELFHeader>(); |
675 #if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_ARM) | 675 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM |
676 const uint8_t ident[16] = | 676 const uint8_t ident[16] = |
677 { 0x7f, 'E', 'L', 'F', 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | 677 { 0x7f, 'E', 'L', 'F', 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}; |
678 #elif defined(V8_TARGET_ARCH_X64) | 678 #elif V8_TARGET_ARCH_X64 |
679 const uint8_t ident[16] = | 679 const uint8_t ident[16] = |
680 { 0x7f, 'E', 'L', 'F', 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | 680 { 0x7f, 'E', 'L', 'F', 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}; |
681 #else | 681 #else |
682 #error Unsupported target architecture. | 682 #error Unsupported target architecture. |
683 #endif | 683 #endif |
684 OS::MemCopy(header->ident, ident, 16); | 684 OS::MemCopy(header->ident, ident, 16); |
685 header->type = 1; | 685 header->type = 1; |
686 #if defined(V8_TARGET_ARCH_IA32) | 686 #if V8_TARGET_ARCH_IA32 |
687 header->machine = 3; | 687 header->machine = 3; |
688 #elif defined(V8_TARGET_ARCH_X64) | 688 #elif V8_TARGET_ARCH_X64 |
689 // Processor identification value for x64 is 62 as defined in | 689 // Processor identification value for x64 is 62 as defined in |
690 // System V ABI, AMD64 Supplement | 690 // System V ABI, AMD64 Supplement |
691 // http://www.x86-64.org/documentation/abi.pdf | 691 // http://www.x86-64.org/documentation/abi.pdf |
692 header->machine = 62; | 692 header->machine = 62; |
693 #elif defined(V8_TARGET_ARCH_ARM) | 693 #elif V8_TARGET_ARCH_ARM |
694 // Set to EM_ARM, defined as 40, in "ARM ELF File Format" at | 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 | 695 // infocenter.arm.com/help/topic/com.arm.doc.dui0101a/DUI0101A_Elf.pdf |
696 header->machine = 40; | 696 header->machine = 40; |
697 #else | 697 #else |
698 #error Unsupported target architecture. | 698 #error Unsupported target architecture. |
699 #endif | 699 #endif |
700 header->version = 1; | 700 header->version = 1; |
701 header->entry = 0; | 701 header->entry = 0; |
702 header->pht_offset = 0; | 702 header->pht_offset = 0; |
703 header->sht_offset = sizeof(ELFHeader); // Section table follows header. | 703 header->sht_offset = sizeof(ELFHeader); // Section table follows header. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
736 Writer::Slot<ELFSection::Header> headers = | 736 Writer::Slot<ELFSection::Header> headers = |
737 w->SlotAt<ELFSection::Header>(sizeof(ELFHeader)); | 737 w->SlotAt<ELFSection::Header>(sizeof(ELFHeader)); |
738 | 738 |
739 for (int i = 0, length = sections_.length(); | 739 for (int i = 0, length = sections_.length(); |
740 i < length; | 740 i < length; |
741 i++) { | 741 i++) { |
742 sections_[i]->WriteBody(headers.at(i), w); | 742 sections_[i]->WriteBody(headers.at(i), w); |
743 } | 743 } |
744 } | 744 } |
745 | 745 |
| 746 Zone* zone_; |
746 ZoneList<ELFSection*> sections_; | 747 ZoneList<ELFSection*> sections_; |
747 }; | 748 }; |
748 | 749 |
749 | 750 |
750 class ELFSymbol BASE_EMBEDDED { | 751 class ELFSymbol BASE_EMBEDDED { |
751 public: | 752 public: |
752 enum Type { | 753 enum Type { |
753 TYPE_NOTYPE = 0, | 754 TYPE_NOTYPE = 0, |
754 TYPE_OBJECT = 1, | 755 TYPE_OBJECT = 1, |
755 TYPE_FUNC = 2, | 756 TYPE_FUNC = 2, |
(...skipping 21 matching lines...) Expand all Loading... |
777 value(value), | 778 value(value), |
778 size(size), | 779 size(size), |
779 info((binding << 4) | type), | 780 info((binding << 4) | type), |
780 other(0), | 781 other(0), |
781 section(section) { | 782 section(section) { |
782 } | 783 } |
783 | 784 |
784 Binding binding() const { | 785 Binding binding() const { |
785 return static_cast<Binding>(info >> 4); | 786 return static_cast<Binding>(info >> 4); |
786 } | 787 } |
787 #if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_ARM) | 788 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM |
788 struct SerializedLayout { | 789 struct SerializedLayout { |
789 SerializedLayout(uint32_t name, | 790 SerializedLayout(uint32_t name, |
790 uintptr_t value, | 791 uintptr_t value, |
791 uintptr_t size, | 792 uintptr_t size, |
792 Binding binding, | 793 Binding binding, |
793 Type type, | 794 Type type, |
794 uint16_t section) | 795 uint16_t section) |
795 : name(name), | 796 : name(name), |
796 value(value), | 797 value(value), |
797 size(size), | 798 size(size), |
798 info((binding << 4) | type), | 799 info((binding << 4) | type), |
799 other(0), | 800 other(0), |
800 section(section) { | 801 section(section) { |
801 } | 802 } |
802 | 803 |
803 uint32_t name; | 804 uint32_t name; |
804 uintptr_t value; | 805 uintptr_t value; |
805 uintptr_t size; | 806 uintptr_t size; |
806 uint8_t info; | 807 uint8_t info; |
807 uint8_t other; | 808 uint8_t other; |
808 uint16_t section; | 809 uint16_t section; |
809 }; | 810 }; |
810 #elif defined(V8_TARGET_ARCH_X64) | 811 #elif V8_TARGET_ARCH_X64 |
811 struct SerializedLayout { | 812 struct SerializedLayout { |
812 SerializedLayout(uint32_t name, | 813 SerializedLayout(uint32_t name, |
813 uintptr_t value, | 814 uintptr_t value, |
814 uintptr_t size, | 815 uintptr_t size, |
815 Binding binding, | 816 Binding binding, |
816 Type type, | 817 Type type, |
817 uint16_t section) | 818 uint16_t section) |
818 : name(name), | 819 : name(name), |
819 info((binding << 4) | type), | 820 info((binding << 4) | type), |
820 other(0), | 821 other(0), |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
914 } | 915 } |
915 | 916 |
916 ZoneList<ELFSymbol> locals_; | 917 ZoneList<ELFSymbol> locals_; |
917 ZoneList<ELFSymbol> globals_; | 918 ZoneList<ELFSymbol> globals_; |
918 }; | 919 }; |
919 #endif // defined(__ELF) | 920 #endif // defined(__ELF) |
920 | 921 |
921 | 922 |
922 class CodeDescription BASE_EMBEDDED { | 923 class CodeDescription BASE_EMBEDDED { |
923 public: | 924 public: |
924 #ifdef V8_TARGET_ARCH_X64 | 925 #if V8_TARGET_ARCH_X64 |
925 enum StackState { | 926 enum StackState { |
926 POST_RBP_PUSH, | 927 POST_RBP_PUSH, |
927 POST_RBP_SET, | 928 POST_RBP_SET, |
928 POST_RBP_POP, | 929 POST_RBP_POP, |
929 STACK_STATE_MAX | 930 STACK_STATE_MAX |
930 }; | 931 }; |
931 #endif | 932 #endif |
932 | 933 |
933 CodeDescription(const char* name, | 934 CodeDescription(const char* name, |
934 Code* code, | 935 Code* code, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 } | 978 } |
978 | 979 |
979 bool IsLineInfoAvailable() { | 980 bool IsLineInfoAvailable() { |
980 return !script_.is_null() && | 981 return !script_.is_null() && |
981 script_->source()->IsString() && | 982 script_->source()->IsString() && |
982 script_->HasValidSource() && | 983 script_->HasValidSource() && |
983 script_->name()->IsString() && | 984 script_->name()->IsString() && |
984 lineinfo_ != NULL; | 985 lineinfo_ != NULL; |
985 } | 986 } |
986 | 987 |
987 #ifdef V8_TARGET_ARCH_X64 | 988 #if V8_TARGET_ARCH_X64 |
988 uintptr_t GetStackStateStartAddress(StackState state) const { | 989 uintptr_t GetStackStateStartAddress(StackState state) const { |
989 ASSERT(state < STACK_STATE_MAX); | 990 ASSERT(state < STACK_STATE_MAX); |
990 return stack_state_start_addresses_[state]; | 991 return stack_state_start_addresses_[state]; |
991 } | 992 } |
992 | 993 |
993 void SetStackStateStartAddress(StackState state, uintptr_t addr) { | 994 void SetStackStateStartAddress(StackState state, uintptr_t addr) { |
994 ASSERT(state < STACK_STATE_MAX); | 995 ASSERT(state < STACK_STATE_MAX); |
995 stack_state_start_addresses_[state] = addr; | 996 stack_state_start_addresses_[state] = addr; |
996 } | 997 } |
997 #endif | 998 #endif |
998 | 999 |
999 SmartArrayPointer<char> GetFilename() { | 1000 SmartArrayPointer<char> GetFilename() { |
1000 return String::cast(script_->name())->ToCString(); | 1001 return String::cast(script_->name())->ToCString(); |
1001 } | 1002 } |
1002 | 1003 |
1003 int GetScriptLineNumber(int pos) { | 1004 int GetScriptLineNumber(int pos) { |
1004 return GetScriptLineNumberSafe(script_, pos) + 1; | 1005 return GetScriptLineNumberSafe(script_, pos) + 1; |
1005 } | 1006 } |
1006 | 1007 |
1007 | 1008 |
1008 private: | 1009 private: |
1009 const char* name_; | 1010 const char* name_; |
1010 Code* code_; | 1011 Code* code_; |
1011 Handle<Script> script_; | 1012 Handle<Script> script_; |
1012 GDBJITLineInfo* lineinfo_; | 1013 GDBJITLineInfo* lineinfo_; |
1013 GDBJITInterface::CodeTag tag_; | 1014 GDBJITInterface::CodeTag tag_; |
1014 CompilationInfo* info_; | 1015 CompilationInfo* info_; |
1015 #ifdef V8_TARGET_ARCH_X64 | 1016 #if V8_TARGET_ARCH_X64 |
1016 uintptr_t stack_state_start_addresses_[STACK_STATE_MAX]; | 1017 uintptr_t stack_state_start_addresses_[STACK_STATE_MAX]; |
1017 #endif | 1018 #endif |
1018 }; | 1019 }; |
1019 | 1020 |
1020 #if defined(__ELF) | 1021 #if defined(__ELF) |
1021 static void CreateSymbolsTable(CodeDescription* desc, | 1022 static void CreateSymbolsTable(CodeDescription* desc, |
1022 Zone* zone, | 1023 Zone* zone, |
1023 ELF* elf, | 1024 ELF* elf, |
1024 int text_section_index) { | 1025 int text_section_index) { |
1025 ELFSymbolTable* symtab = new(zone) ELFSymbolTable(".symtab", zone); | 1026 ELFSymbolTable* symtab = new(zone) ELFSymbolTable(".symtab", zone); |
1026 ELFStringTable* strtab = new(zone) ELFStringTable(".strtab"); | 1027 ELFStringTable* strtab = new(zone) ELFStringTable(".strtab"); |
1027 | 1028 |
1028 // Symbol table should be followed by the linked string table. | 1029 // Symbol table should be followed by the linked string table. |
1029 elf->AddSection(symtab, zone); | 1030 elf->AddSection(symtab); |
1030 elf->AddSection(strtab, zone); | 1031 elf->AddSection(strtab); |
1031 | 1032 |
1032 symtab->Add(ELFSymbol("V8 Code", | 1033 symtab->Add(ELFSymbol("V8 Code", |
1033 0, | 1034 0, |
1034 0, | 1035 0, |
1035 ELFSymbol::BIND_LOCAL, | 1036 ELFSymbol::BIND_LOCAL, |
1036 ELFSymbol::TYPE_FILE, | 1037 ELFSymbol::TYPE_FILE, |
1037 ELFSection::INDEX_ABSOLUTE), | 1038 ELFSection::INDEX_ABSOLUTE), |
1038 zone); | 1039 zone); |
1039 | 1040 |
1040 symtab->Add(ELFSymbol(desc->name(), | 1041 symtab->Add(ELFSymbol(desc->name(), |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1099 w->WriteString("v8value"); | 1100 w->WriteString("v8value"); |
1100 | 1101 |
1101 if (desc_->IsInfoAvailable()) { | 1102 if (desc_->IsInfoAvailable()) { |
1102 Scope* scope = desc_->info()->scope(); | 1103 Scope* scope = desc_->info()->scope(); |
1103 w->WriteULEB128(2); | 1104 w->WriteULEB128(2); |
1104 w->WriteString(desc_->name()); | 1105 w->WriteString(desc_->name()); |
1105 w->Write<intptr_t>(desc_->CodeStart()); | 1106 w->Write<intptr_t>(desc_->CodeStart()); |
1106 w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize()); | 1107 w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize()); |
1107 Writer::Slot<uint32_t> fb_block_size = w->CreateSlotHere<uint32_t>(); | 1108 Writer::Slot<uint32_t> fb_block_size = w->CreateSlotHere<uint32_t>(); |
1108 uintptr_t fb_block_start = w->position(); | 1109 uintptr_t fb_block_start = w->position(); |
1109 #if defined(V8_TARGET_ARCH_IA32) | 1110 #if V8_TARGET_ARCH_IA32 |
1110 w->Write<uint8_t>(DW_OP_reg5); // The frame pointer's here on ia32 | 1111 w->Write<uint8_t>(DW_OP_reg5); // The frame pointer's here on ia32 |
1111 #elif defined(V8_TARGET_ARCH_X64) | 1112 #elif V8_TARGET_ARCH_X64 |
1112 w->Write<uint8_t>(DW_OP_reg6); // and here on x64. | 1113 w->Write<uint8_t>(DW_OP_reg6); // and here on x64. |
1113 #elif defined(V8_TARGET_ARCH_ARM) | 1114 #elif V8_TARGET_ARCH_ARM |
1114 UNIMPLEMENTED(); | 1115 UNIMPLEMENTED(); |
1115 #elif defined(V8_TARGET_ARCH_MIPS) | 1116 #elif V8_TARGET_ARCH_MIPS |
1116 UNIMPLEMENTED(); | 1117 UNIMPLEMENTED(); |
1117 #else | 1118 #else |
1118 #error Unsupported target architecture. | 1119 #error Unsupported target architecture. |
1119 #endif | 1120 #endif |
1120 fb_block_size.set(static_cast<uint32_t>(w->position() - fb_block_start)); | 1121 fb_block_size.set(static_cast<uint32_t>(w->position() - fb_block_start)); |
1121 | 1122 |
1122 int params = scope->num_parameters(); | 1123 int params = scope->num_parameters(); |
1123 int slots = scope->num_stack_slots(); | 1124 int slots = scope->num_stack_slots(); |
1124 int context_slots = scope->ContextLocalCount(); | 1125 int context_slots = scope->ContextLocalCount(); |
1125 // The real slot ID is internal_slots + context_slot_id. | 1126 // The real slot ID is internal_slots + context_slot_id. |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1556 return +1; | 1557 return +1; |
1557 } else { | 1558 } else { |
1558 return -1; | 1559 return -1; |
1559 } | 1560 } |
1560 } | 1561 } |
1561 | 1562 |
1562 CodeDescription* desc_; | 1563 CodeDescription* desc_; |
1563 }; | 1564 }; |
1564 | 1565 |
1565 | 1566 |
1566 #ifdef V8_TARGET_ARCH_X64 | 1567 #if V8_TARGET_ARCH_X64 |
1567 | 1568 |
1568 class UnwindInfoSection : public DebugSection { | 1569 class UnwindInfoSection : public DebugSection { |
1569 public: | 1570 public: |
1570 explicit UnwindInfoSection(CodeDescription* desc); | 1571 explicit UnwindInfoSection(CodeDescription* desc); |
1571 virtual bool WriteBodyInternal(Writer* w); | 1572 virtual bool WriteBodyInternal(Writer* w); |
1572 | 1573 |
1573 int WriteCIE(Writer* w); | 1574 int WriteCIE(Writer* w); |
1574 void WriteFDE(Writer* w, int); | 1575 void WriteFDE(Writer* w, int); |
1575 | 1576 |
1576 void WriteFDEStateOnEntry(Writer* w); | 1577 void WriteFDEStateOnEntry(Writer* w); |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1786 return true; | 1787 return true; |
1787 } | 1788 } |
1788 | 1789 |
1789 | 1790 |
1790 #endif // V8_TARGET_ARCH_X64 | 1791 #endif // V8_TARGET_ARCH_X64 |
1791 | 1792 |
1792 static void CreateDWARFSections(CodeDescription* desc, | 1793 static void CreateDWARFSections(CodeDescription* desc, |
1793 Zone* zone, | 1794 Zone* zone, |
1794 DebugObject* obj) { | 1795 DebugObject* obj) { |
1795 if (desc->IsLineInfoAvailable()) { | 1796 if (desc->IsLineInfoAvailable()) { |
1796 obj->AddSection(new(zone) DebugInfoSection(desc), zone); | 1797 obj->AddSection(new(zone) DebugInfoSection(desc)); |
1797 obj->AddSection(new(zone) DebugAbbrevSection(desc), zone); | 1798 obj->AddSection(new(zone) DebugAbbrevSection(desc)); |
1798 obj->AddSection(new(zone) DebugLineSection(desc), zone); | 1799 obj->AddSection(new(zone) DebugLineSection(desc)); |
1799 } | 1800 } |
1800 #ifdef V8_TARGET_ARCH_X64 | 1801 #if V8_TARGET_ARCH_X64 |
1801 obj->AddSection(new(zone) UnwindInfoSection(desc), zone); | 1802 obj->AddSection(new(zone) UnwindInfoSection(desc)); |
1802 #endif | 1803 #endif |
1803 } | 1804 } |
1804 | 1805 |
1805 | 1806 |
1806 // ------------------------------------------------------------------- | 1807 // ------------------------------------------------------------------- |
1807 // Binary GDB JIT Interface as described in | 1808 // Binary GDB JIT Interface as described in |
1808 // http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html | 1809 // http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html |
1809 extern "C" { | 1810 extern "C" { |
1810 typedef enum { | 1811 typedef enum { |
1811 JIT_NOACTION = 0, | 1812 JIT_NOACTION = 0, |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1911 } | 1912 } |
1912 | 1913 |
1913 __jit_debug_descriptor.relevant_entry_ = entry; | 1914 __jit_debug_descriptor.relevant_entry_ = entry; |
1914 __jit_debug_descriptor.action_flag_ = JIT_UNREGISTER_FN; | 1915 __jit_debug_descriptor.action_flag_ = JIT_UNREGISTER_FN; |
1915 __jit_debug_register_code(); | 1916 __jit_debug_register_code(); |
1916 } | 1917 } |
1917 | 1918 |
1918 | 1919 |
1919 static JITCodeEntry* CreateELFObject(CodeDescription* desc, Isolate* isolate) { | 1920 static JITCodeEntry* CreateELFObject(CodeDescription* desc, Isolate* isolate) { |
1920 #ifdef __MACH_O | 1921 #ifdef __MACH_O |
1921 MachO mach_o; | 1922 Zone zone(isolate); |
| 1923 MachO mach_o(&zone); |
1922 Writer w(&mach_o); | 1924 Writer w(&mach_o); |
1923 | 1925 |
1924 mach_o.AddSection(new MachOTextSection(kCodeAlignment, | 1926 mach_o.AddSection(new(&zone) MachOTextSection(kCodeAlignment, |
1925 desc->CodeStart(), | 1927 desc->CodeStart(), |
1926 desc->CodeSize())); | 1928 desc->CodeSize())); |
1927 | 1929 |
1928 CreateDWARFSections(desc, &mach_o); | 1930 CreateDWARFSections(desc, &zone, &mach_o); |
1929 | 1931 |
1930 mach_o.Write(&w, desc->CodeStart(), desc->CodeSize()); | 1932 mach_o.Write(&w, desc->CodeStart(), desc->CodeSize()); |
1931 #else | 1933 #else |
1932 Zone zone(isolate); | 1934 Zone zone(isolate); |
1933 ELF elf(&zone); | 1935 ELF elf(&zone); |
1934 Writer w(&elf); | 1936 Writer w(&elf); |
1935 | 1937 |
1936 int text_section_index = elf.AddSection( | 1938 int text_section_index = elf.AddSection( |
1937 new(&zone) FullHeaderELFSection( | 1939 new(&zone) FullHeaderELFSection( |
1938 ".text", | 1940 ".text", |
1939 ELFSection::TYPE_NOBITS, | 1941 ELFSection::TYPE_NOBITS, |
1940 kCodeAlignment, | 1942 kCodeAlignment, |
1941 desc->CodeStart(), | 1943 desc->CodeStart(), |
1942 0, | 1944 0, |
1943 desc->CodeSize(), | 1945 desc->CodeSize(), |
1944 ELFSection::FLAG_ALLOC | ELFSection::FLAG_EXEC), | 1946 ELFSection::FLAG_ALLOC | ELFSection::FLAG_EXEC)); |
1945 &zone); | |
1946 | 1947 |
1947 CreateSymbolsTable(desc, &zone, &elf, text_section_index); | 1948 CreateSymbolsTable(desc, &zone, &elf, text_section_index); |
1948 | 1949 |
1949 CreateDWARFSections(desc, &zone, &elf); | 1950 CreateDWARFSections(desc, &zone, &elf); |
1950 | 1951 |
1951 elf.Write(&w); | 1952 elf.Write(&w); |
1952 #endif | 1953 #endif |
1953 | 1954 |
1954 return CreateCodeEntry(w.buffer(), w.position()); | 1955 return CreateCodeEntry(w.buffer(), w.position()); |
1955 } | 1956 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2007 | 2008 |
2008 if (!name.is_null() && name->IsString()) { | 2009 if (!name.is_null() && name->IsString()) { |
2009 SmartArrayPointer<char> name_cstring = | 2010 SmartArrayPointer<char> name_cstring = |
2010 Handle<String>::cast(name)->ToCString(DISALLOW_NULLS); | 2011 Handle<String>::cast(name)->ToCString(DISALLOW_NULLS); |
2011 AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script, info); | 2012 AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script, info); |
2012 } else { | 2013 } else { |
2013 AddCode("", *code, GDBJITInterface::FUNCTION, *script, info); | 2014 AddCode("", *code, GDBJITInterface::FUNCTION, *script, info); |
2014 } | 2015 } |
2015 } | 2016 } |
2016 | 2017 |
| 2018 |
2017 static void AddUnwindInfo(CodeDescription* desc) { | 2019 static void AddUnwindInfo(CodeDescription* desc) { |
2018 #ifdef V8_TARGET_ARCH_X64 | 2020 #if V8_TARGET_ARCH_X64 |
2019 if (desc->tag() == GDBJITInterface::FUNCTION) { | 2021 if (desc->tag() == GDBJITInterface::FUNCTION) { |
2020 // To avoid propagating unwinding information through | 2022 // To avoid propagating unwinding information through |
2021 // compilation pipeline we use an approximation. | 2023 // compilation pipeline we use an approximation. |
2022 // For most use cases this should not affect usability. | 2024 // For most use cases this should not affect usability. |
2023 static const int kFramePointerPushOffset = 1; | 2025 static const int kFramePointerPushOffset = 1; |
2024 static const int kFramePointerSetOffset = 4; | 2026 static const int kFramePointerSetOffset = 4; |
2025 static const int kFramePointerPopOffset = -3; | 2027 static const int kFramePointerPopOffset = -3; |
2026 | 2028 |
2027 uintptr_t frame_pointer_push_address = | 2029 uintptr_t frame_pointer_push_address = |
2028 desc->CodeStart() + kFramePointerPushOffset; | 2030 desc->CodeStart() + kFramePointerPushOffset; |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2158 } else { | 2160 } else { |
2159 JITCodeEntry* entry = static_cast<JITCodeEntry*>(e->value); | 2161 JITCodeEntry* entry = static_cast<JITCodeEntry*>(e->value); |
2160 UnregisterCodeEntry(entry); | 2162 UnregisterCodeEntry(entry); |
2161 DestroyCodeEntry(entry); | 2163 DestroyCodeEntry(entry); |
2162 } | 2164 } |
2163 e->value = NULL; | 2165 e->value = NULL; |
2164 GetEntries()->Remove(code, HashForCodeObject(code)); | 2166 GetEntries()->Remove(code, HashForCodeObject(code)); |
2165 } | 2167 } |
2166 | 2168 |
2167 | 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 |
2168 void GDBJITInterface::RegisterDetailedLineInfo(Code* code, | 2188 void GDBJITInterface::RegisterDetailedLineInfo(Code* code, |
2169 GDBJITLineInfo* line_info) { | 2189 GDBJITLineInfo* line_info) { |
2170 ScopedLock lock(mutex.Pointer()); | 2190 ScopedLock lock(mutex.Pointer()); |
2171 ASSERT(!IsLineInfoTagged(line_info)); | 2191 ASSERT(!IsLineInfoTagged(line_info)); |
2172 HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true); | 2192 HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true); |
2173 ASSERT(e->value == NULL); | 2193 ASSERT(e->value == NULL); |
2174 e->value = TagLineInfo(line_info); | 2194 e->value = TagLineInfo(line_info); |
2175 } | 2195 } |
2176 | 2196 |
2177 | 2197 |
2178 } } // namespace v8::internal | 2198 } } // namespace v8::internal |
2179 #endif | 2199 #endif |
OLD | NEW |