Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(566)

Side by Side Diff: src/gdb-jit.cc

Issue 6250104: GDBJIT: emit .eh_frame section on x64. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/gdb-jit.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 TYPE_STRTAB = 3, 194 TYPE_STRTAB = 3,
195 TYPE_RELA = 4, 195 TYPE_RELA = 4,
196 TYPE_HASH = 5, 196 TYPE_HASH = 5,
197 TYPE_DYNAMIC = 6, 197 TYPE_DYNAMIC = 6,
198 TYPE_NOTE = 7, 198 TYPE_NOTE = 7,
199 TYPE_NOBITS = 8, 199 TYPE_NOBITS = 8,
200 TYPE_REL = 9, 200 TYPE_REL = 9,
201 TYPE_SHLIB = 10, 201 TYPE_SHLIB = 10,
202 TYPE_DYNSYM = 11, 202 TYPE_DYNSYM = 11,
203 TYPE_LOPROC = 0x70000000, 203 TYPE_LOPROC = 0x70000000,
204 TYPE_X86_64_UNWIND = 0x70000001,
204 TYPE_HIPROC = 0x7fffffff, 205 TYPE_HIPROC = 0x7fffffff,
205 TYPE_LOUSER = 0x80000000, 206 TYPE_LOUSER = 0x80000000,
206 TYPE_HIUSER = 0xffffffff 207 TYPE_HIUSER = 0xffffffff
207 }; 208 };
208 209
209 enum Flags { 210 enum Flags {
210 FLAG_WRITE = 1, 211 FLAG_WRITE = 1,
211 FLAG_ALLOC = 2, 212 FLAG_ALLOC = 2,
212 FLAG_EXEC = 4 213 FLAG_EXEC = 4
213 }; 214 };
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 } 633 }
633 } 634 }
634 635
635 ZoneList<ELFSymbol> locals_; 636 ZoneList<ELFSymbol> locals_;
636 ZoneList<ELFSymbol> globals_; 637 ZoneList<ELFSymbol> globals_;
637 }; 638 };
638 639
639 640
640 class CodeDescription BASE_EMBEDDED { 641 class CodeDescription BASE_EMBEDDED {
641 public: 642 public:
643
644 #ifdef V8_TARGET_ARCH_X64
645 enum StackState {
646 POST_RBP_PUSH,
647 POST_RBP_SET,
648 POST_RBP_POP,
649 STACK_STATE_MAX
650 };
651 #endif
652
642 CodeDescription(const char* name, 653 CodeDescription(const char* name,
643 Code* code, 654 Code* code,
644 Handle<Script> script, 655 Handle<Script> script,
645 GDBJITLineInfo* lineinfo) 656 GDBJITLineInfo* lineinfo,
646 : name_(name), code_(code), script_(script), lineinfo_(lineinfo) 657 GDBJITInterface::CodeTag tag)
658 : name_(name),
659 code_(code),
Erik Corry 2011/02/02 13:10:25 Indentation
660 script_(script),
661 lineinfo_(lineinfo),
662 tag_(tag)
647 { } 663 { }
648 664
649 const char* code_name() const { 665 const char* name() const {
650 return name_; 666 return name_;
651 } 667 }
652 668
653 uintptr_t code_size() const { 669 GDBJITLineInfo* lineinfo() const {
654 return code_->instruction_end() - code_->instruction_start(); 670 return lineinfo_;
655 } 671 }
656 672
657 uintptr_t code_start() const { 673 GDBJITInterface::CodeTag tag() const {
658 return (uintptr_t)code_->instruction_start(); 674 return tag_;
659 } 675 }
660 676
661 bool is_line_info_available() { 677 uintptr_t CodeStart() const {
Erik Corry 2011/02/02 13:10:25 Why can't these return Address?
678 return reinterpret_cast<uintptr_t>(code_->instruction_start());
679 }
680
681 uintptr_t CodeEnd() const {
682 return reinterpret_cast<uintptr_t>(code_->instruction_end());
683 }
684
685 uintptr_t CodeSize() const {
686 return CodeEnd() - CodeStart();
687 }
688
689 bool IsLineInfoAvailable() {
662 return !script_.is_null() && 690 return !script_.is_null() &&
663 script_->source()->IsString() && 691 script_->source()->IsString() &&
664 script_->HasValidSource() && 692 script_->HasValidSource() &&
665 script_->name()->IsString() && 693 script_->name()->IsString() &&
666 lineinfo_ != NULL; 694 lineinfo_ != NULL;
667 } 695 }
668 696
669 GDBJITLineInfo* lineinfo() const { return lineinfo_; } 697 #ifdef V8_TARGET_ARCH_X64
698 uintptr_t GetStackStateStartAddress(StackState state) const {
699 ASSERT(state < STACK_STATE_MAX);
700 return stack_state_start_addresses_[state];
701 }
670 702
671 SmartPointer<char> filename() { 703 void SetStackStateStartAddress(StackState state, uintptr_t addr) {
704 ASSERT(state < STACK_STATE_MAX);
705 stack_state_start_addresses_[state] = addr;
706 }
707 #endif
708
709 SmartPointer<char> GetFilename() {
672 return String::cast(script_->name())->ToCString(); 710 return String::cast(script_->name())->ToCString();
673 } 711 }
674 712
675 int GetScriptLineNumber(int pos) { 713 int GetScriptLineNumber(int pos) {
676 return GetScriptLineNumberSafe(script_, pos) + 1; 714 return GetScriptLineNumberSafe(script_, pos) + 1;
677 } 715 }
678 716
717
679 private: 718 private:
680 const char* name_; 719 const char* name_;
681 Code* code_; 720 Code* code_;
682 Handle<Script> script_; 721 Handle<Script> script_;
683 GDBJITLineInfo* lineinfo_; 722 GDBJITLineInfo* lineinfo_;
723 GDBJITInterface::CodeTag tag_;
724 #ifdef V8_TARGET_ARCH_X64
725 uintptr_t stack_state_start_addresses_[STACK_STATE_MAX];
726 #endif
684 }; 727 };
685 728
686 729
687 static void CreateSymbolsTable(CodeDescription* desc, 730 static void CreateSymbolsTable(CodeDescription* desc,
688 ELF* elf, 731 ELF* elf,
689 int text_section_index) { 732 int text_section_index) {
690 ELFSymbolTable* symtab = new ELFSymbolTable(".symtab"); 733 ELFSymbolTable* symtab = new ELFSymbolTable(".symtab");
691 StringTable* strtab = new StringTable(".strtab"); 734 StringTable* strtab = new StringTable(".strtab");
692 735
693 // Symbol table should be followed by the linked string table. 736 // Symbol table should be followed by the linked string table.
694 elf->AddSection(symtab); 737 elf->AddSection(symtab);
695 elf->AddSection(strtab); 738 elf->AddSection(strtab);
696 739
697 symtab->Add(ELFSymbol("V8 Code", 740 symtab->Add(ELFSymbol("V8 Code",
698 0, 741 0,
699 0, 742 0,
700 ELFSymbol::BIND_LOCAL, 743 ELFSymbol::BIND_LOCAL,
701 ELFSymbol::TYPE_FILE, 744 ELFSymbol::TYPE_FILE,
702 ELFSection::INDEX_ABSOLUTE)); 745 ELFSection::INDEX_ABSOLUTE));
703 746
704 symtab->Add(ELFSymbol(desc->code_name(), 747 symtab->Add(ELFSymbol(desc->name(),
705 0, 748 0,
706 desc->code_size(), 749 desc->CodeSize(),
707 ELFSymbol::BIND_GLOBAL, 750 ELFSymbol::BIND_GLOBAL,
708 ELFSymbol::TYPE_FUNC, 751 ELFSymbol::TYPE_FUNC,
709 text_section_index)); 752 text_section_index));
710 } 753 }
711 754
712 755
713 class DebugInfoSection : public ELFSection { 756 class DebugInfoSection : public ELFSection {
714 public: 757 public:
715 explicit DebugInfoSection(CodeDescription* desc) 758 explicit DebugInfoSection(CodeDescription* desc)
716 : ELFSection(".debug_info", TYPE_PROGBITS, 1), desc_(desc) { } 759 : ELFSection(".debug_info", TYPE_PROGBITS, 1), desc_(desc) { }
717 760
718 bool WriteBody(Writer* w) { 761 bool WriteBody(Writer* w) {
719 Writer::Slot<uint32_t> size = w->CreateSlotHere<uint32_t>(); 762 Writer::Slot<uint32_t> size = w->CreateSlotHere<uint32_t>();
720 uintptr_t start = w->position(); 763 uintptr_t start = w->position();
721 w->Write<uint16_t>(2); // DWARF version. 764 w->Write<uint16_t>(2); // DWARF version.
722 w->Write<uint32_t>(0); // Abbreviation table offset. 765 w->Write<uint32_t>(0); // Abbreviation table offset.
723 w->Write<uint8_t>(sizeof(intptr_t)); 766 w->Write<uint8_t>(sizeof(intptr_t));
724 767
725 w->WriteULEB128(1); // Abbreviation code. 768 w->WriteULEB128(1); // Abbreviation code.
726 w->WriteString(*desc_->filename()); 769 w->WriteString(*desc_->GetFilename());
727 w->Write<intptr_t>(desc_->code_start()); 770 w->Write<intptr_t>(desc_->CodeStart());
Erik Corry 2011/02/02 13:10:25 w->Write<Address>(...
728 w->Write<intptr_t>(desc_->code_start() + desc_->code_size()); 771 w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize());
729 w->Write<uint32_t>(0); 772 w->Write<uint32_t>(0);
730 size.set(static_cast<uint32_t>(w->position() - start)); 773 size.set(static_cast<uint32_t>(w->position() - start));
731 return true; 774 return true;
732 } 775 }
733 776
734 private: 777 private:
735 CodeDescription* desc_; 778 CodeDescription* desc_;
736 }; 779 };
737 780
738 781
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
822 w->Write<int8_t>(0); // Field line_base. 865 w->Write<int8_t>(0); // Field line_base.
823 w->Write<uint8_t>(2); // Field line_range. 866 w->Write<uint8_t>(2); // Field line_range.
824 w->Write<uint8_t>(DW_LNS_NEGATE_STMT + 1); // Field opcode_base. 867 w->Write<uint8_t>(DW_LNS_NEGATE_STMT + 1); // Field opcode_base.
825 w->Write<uint8_t>(0); // DW_LNS_COPY operands count. 868 w->Write<uint8_t>(0); // DW_LNS_COPY operands count.
826 w->Write<uint8_t>(1); // DW_LNS_ADVANCE_PC operands count. 869 w->Write<uint8_t>(1); // DW_LNS_ADVANCE_PC operands count.
827 w->Write<uint8_t>(1); // DW_LNS_ADVANCE_LINE operands count. 870 w->Write<uint8_t>(1); // DW_LNS_ADVANCE_LINE operands count.
828 w->Write<uint8_t>(1); // DW_LNS_SET_FILE operands count. 871 w->Write<uint8_t>(1); // DW_LNS_SET_FILE operands count.
829 w->Write<uint8_t>(1); // DW_LNS_SET_COLUMN operands count. 872 w->Write<uint8_t>(1); // DW_LNS_SET_COLUMN operands count.
830 w->Write<uint8_t>(0); // DW_LNS_NEGATE_STMT operands count. 873 w->Write<uint8_t>(0); // DW_LNS_NEGATE_STMT operands count.
831 w->Write<uint8_t>(0); // Empty include_directories sequence. 874 w->Write<uint8_t>(0); // Empty include_directories sequence.
832 w->WriteString(*desc_->filename()); // File name. 875 w->WriteString(*desc_->GetFilename()); // File name.
833 w->WriteULEB128(0); // Current directory. 876 w->WriteULEB128(0); // Current directory.
834 w->WriteULEB128(0); // Unknown modification time. 877 w->WriteULEB128(0); // Unknown modification time.
835 w->WriteULEB128(0); // Unknown file size. 878 w->WriteULEB128(0); // Unknown file size.
836 w->Write<uint8_t>(0); 879 w->Write<uint8_t>(0);
837 prologue_length.set(static_cast<uint32_t>(w->position() - prologue_start)); 880 prologue_length.set(static_cast<uint32_t>(w->position() - prologue_start));
838 881
839 WriteExtendedOpcode(w, DW_LNE_SET_ADDRESS, sizeof(intptr_t)); 882 WriteExtendedOpcode(w, DW_LNE_SET_ADDRESS, sizeof(intptr_t));
840 w->Write<intptr_t>(desc_->code_start()); 883 w->Write<intptr_t>(desc_->CodeStart());
841 884
842 intptr_t pc = 0; 885 intptr_t pc = 0;
843 intptr_t line = 1; 886 intptr_t line = 1;
844 bool is_statement = true; 887 bool is_statement = true;
845 888
846 List<GDBJITLineInfo::PCInfo>* pc_info = desc_->lineinfo()->pc_info(); 889 List<GDBJITLineInfo::PCInfo>* pc_info = desc_->lineinfo()->pc_info();
847 pc_info->Sort(&ComparePCInfo); 890 pc_info->Sort(&ComparePCInfo);
848 for (int i = 0; i < pc_info->length(); i++) { 891 for (int i = 0; i < pc_info->length(); i++) {
849 GDBJITLineInfo::PCInfo* info = &pc_info->at(i); 892 GDBJITLineInfo::PCInfo* info = &pc_info->at(i);
850 uintptr_t pc_diff = info->pc_ - pc; 893 uintptr_t pc_diff = info->pc_ - pc;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 return +1; 936 return +1;
894 } else { 937 } else {
895 return -1; 938 return -1;
896 } 939 }
897 } 940 }
898 941
899 CodeDescription* desc_; 942 CodeDescription* desc_;
900 }; 943 };
901 944
902 945
946 #ifdef V8_TARGET_ARCH_X64
947
948
949 class UnwindInfoSection : public ELFSection {
950 public:
951 explicit UnwindInfoSection(CodeDescription *desc);
952 virtual bool WriteBody(Writer *w);
953
954 int WriteCIE(Writer *w);
955 void WriteFDE(Writer *w, int);
956
957 void WriteFDEStateOnEntry(Writer *w);
958 void WriteFDEStateAfterRBPPush(Writer *w);
959 void WriteFDEStateAfterRBPSet(Writer *w);
960 void WriteFDEStateAfterRBPPop(Writer *w);
961
962 void WriteLength(Writer *w, Writer::Slot<uint32_t> &, int);
963
964 private:
965 CodeDescription *desc_;
966
967 // DWARF3 Specification, Table 7.23
968 enum CFIInstructions {
969 DW_CFA_ADVANCE_LOC = 0X40,
Erik Corry 2011/02/02 13:10:25 We use a small x everywhere in V8, so we should do
970 DW_CFA_OFFSET = 0X80,
971 DW_CFA_RESTORE = 0XC0,
972 DW_CFA_NOP = 0X00,
973 DW_CFA_SET_LOC = 0X01,
974 DW_CFA_ADVANCE_LOC1 = 0X02,
975 DW_CFA_ADVANCE_LOC2 = 0X03,
976 DW_CFA_ADVANCE_LOC4 = 0X04,
977 DW_CFA_OFFSET_EXTENDED = 0X05,
978 DW_CFA_RESTORE_EXTENDED = 0X06,
979 DW_CFA_UNDEFINED = 0X07,
980 DW_CFA_SAME_VALUE = 0X08,
981 DW_CFA_REGISTER = 0X09,
982 DW_CFA_REMEMBER_STATE = 0X0A,
983 DW_CFA_RESTORE_STATE = 0X0B,
984 DW_CFA_DEF_CFA = 0X0C,
985 DW_CFA_DEF_CFA_REGISTER = 0X0D,
986 DW_CFA_DEF_CFA_OFFSET = 0X0E,
987
988 DW_CFA_DEF_CFA_EXPRESSION = 0X0F,
989 DW_CFA_EXPRESSION = 0X10,
990 DW_CFA_OFFSET_EXTENDED_SF = 0X11,
991 DW_CFA_DEF_CFA_SF = 0X12,
992 DW_CFA_DEF_CFA_OFFSET_SF = 0X13,
993 DW_CFA_VAL_OFFSET = 0X14,
994 DW_CFA_VAL_OFFSET_SF = 0X15,
995 DW_CFA_VAL_EXPRESSION = 0X16
996 };
997
998 // System V ABI, AMD64 Supplement, Version 0.99.5, Figure 3.36
999 enum RegisterMapping {
1000 // Only the relevant ones have been added to reduce clutter.
1001 AMD64_RBP = 6,
1002 AMD64_RSP = 7,
1003 AMD64_RA = 16
1004 };
1005
1006 enum CFIConstants {
1007 CIE_ID = 0,
1008 CIE_VERSION = 1,
1009 CODE_ALIGN_FACTOR = 1,
1010 DATA_ALIGN_FACTOR = 1,
1011 RETURN_ADDRESS_REGISTER = AMD64_RA
1012 };
1013 };
1014
1015
1016 void UnwindInfoSection::WriteLength(Writer *w,
1017 Writer::Slot<uint32_t> &length_slot,
1018 int initial_position) {
1019 uint32_t align = (w->position() - initial_position) % kPointerSize;
1020
1021 if (align != 0) {
1022 for (uint32_t i = 0; i < (kPointerSize - align); i++)
Erik Corry 2011/02/02 13:10:25 Missing {} on multiline for statement.
1023 w->Write<uint8_t>(DW_CFA_NOP);
1024 }
1025
1026 ASSERT((w->position() - initial_position) % kPointerSize == 0);
1027 length_slot.set(w->position() - initial_position);
1028 }
1029
1030
1031 UnwindInfoSection::UnwindInfoSection(CodeDescription *desc)
1032 : ELFSection(".eh_frame", TYPE_X86_64_UNWIND, 1), desc_(desc)
1033 { }
1034
1035 int UnwindInfoSection::WriteCIE(Writer *w) {
1036 Writer::Slot<uint32_t> cie_length_slot = w->CreateSlotHere<uint32_t>();
1037 uint32_t cie_position = w->position();
1038
1039 // Write out the CIE header. Currently no 'common instructions' are
1040 // emitted onto the CIE; every FDE has its own set of instructions.
1041
1042 w->Write<uint32_t>(CIE_ID);
1043 w->Write<uint8_t>(CIE_VERSION);
1044 w->Write<uint8_t>(0); // Null augmentation string.
1045 w->WriteSLEB128(CODE_ALIGN_FACTOR);
1046 w->WriteSLEB128(DATA_ALIGN_FACTOR);
1047 w->Write<uint8_t>(RETURN_ADDRESS_REGISTER);
1048
1049 WriteLength(w, cie_length_slot, cie_position);
1050
1051 return cie_position;
1052 }
1053
1054
1055 void UnwindInfoSection::WriteFDE(Writer *w, int cie_position) {
1056 // The only FDE for this function. The CFA is the current RBP.
1057 Writer::Slot<uint32_t> fde_length_slot = w->CreateSlotHere<uint32_t>();
1058 int fde_position = w->position();
1059 w->Write<int32_t>(fde_position - cie_position + 4);
1060
1061 w->Write<uintptr_t>(desc_->CodeStart());
1062 w->Write<uintptr_t>(desc_->CodeSize());
1063
1064 WriteFDEStateOnEntry(w);
1065 WriteFDEStateAfterRBPPush(w);
1066 WriteFDEStateAfterRBPSet(w);
1067 WriteFDEStateAfterRBPPop(w);
1068
1069 WriteLength(w, fde_length_slot, fde_position);
1070 }
1071
1072
1073 void UnwindInfoSection::WriteFDEStateOnEntry(Writer *w) {
1074 // The first state, just after the control has been transferred to the the
1075 // function.
1076
1077 // RBP for this function will be the value of RSP after pushing the RBP
1078 // for the previous function. The previous RBP has not been pushed yet.
1079 w->Write<uint8_t>(DW_CFA_DEF_CFA_SF);
1080 w->WriteULEB128(AMD64_RSP);
1081 w->WriteSLEB128(-kPointerSize);
1082
1083 // The RA is stored at location CFA + kCallerPCOffset. This is an invariant,
1084 // and hence omitted from the next states.
1085 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED);
1086 w->WriteULEB128(AMD64_RA);
1087 w->WriteSLEB128(StandardFrameConstants::kCallerPCOffset);
1088
1089 // The RBP of the previous function is still in RBP.
1090 w->Write<uint8_t>(DW_CFA_SAME_VALUE);
1091 w->WriteULEB128(AMD64_RBP);
1092
1093 // Last location described by this entry.
1094 w->Write<uint8_t>(DW_CFA_SET_LOC);
1095 w->Write<uint64_t>(
1096 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_PUSH));
1097 }
1098
1099
1100 void UnwindInfoSection::WriteFDEStateAfterRBPPush(Writer *w) {
1101 // The second state, just after RBP has been pushed.
1102
1103 // RBP / CFA for this function is now the current RSP, so just set the
1104 // offset from the previous rule (from -8) to 0.
1105 w->Write<uint8_t>(DW_CFA_DEF_CFA_OFFSET);
1106 w->WriteULEB128(0);
1107
1108 // The previous RBP is stored at CFA + kCallerFPOffset. This is an invariant
1109 // in this and the next state, and hence omitted in the next state.
1110 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED);
1111 w->WriteULEB128(AMD64_RBP);
1112 w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset);
1113
1114 // Last location described by this entry.
1115 w->Write<uint8_t>(DW_CFA_SET_LOC);
1116 w->Write<uint64_t>(
1117 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_SET));
1118 }
1119
1120
1121 void UnwindInfoSection::WriteFDEStateAfterRBPSet(Writer *w) {
1122 // The third state, after the RBP has been set.
1123
1124 // The CFA can now directly be set to RBP.
1125 w->Write<uint8_t>(DW_CFA_DEF_CFA);
1126 w->WriteULEB128(AMD64_RBP);
1127 w->WriteULEB128(0);
1128
1129 // Last location described by this entry.
1130 w->Write<uint8_t>(DW_CFA_SET_LOC);
1131 w->Write<uint64_t>(
1132 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_POP));
1133 }
1134
1135
1136 void UnwindInfoSection::WriteFDEStateAfterRBPPop(Writer *w) {
1137 // The fourth (final) state. The RBP has been popped (just before issuing a
1138 // return).
1139
1140 // The CFA can is now calculated in the same way as in the first state.
1141 w->Write<uint8_t>(DW_CFA_DEF_CFA_SF);
1142 w->WriteULEB128(AMD64_RSP);
1143 w->WriteSLEB128(-kPointerSize);
1144
1145 // The RBP
1146 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED);
1147 w->WriteULEB128(AMD64_RBP);
1148 w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset);
1149
1150 // Last location described by this entry.
1151 w->Write<uint8_t>(DW_CFA_SET_LOC);
1152 w->Write<uint64_t>(desc_->CodeEnd());
1153 }
1154
1155
1156 bool UnwindInfoSection::WriteBody(Writer *w) {
1157 uint32_t cie_position = WriteCIE(w);
1158 WriteFDE(w, cie_position);
1159 return true;
1160 }
1161
1162
1163 #endif // V8_TARGET_ARCH_X64
1164
1165
903 static void CreateDWARFSections(CodeDescription* desc, ELF* elf) { 1166 static void CreateDWARFSections(CodeDescription* desc, ELF* elf) {
904 if (desc->is_line_info_available()) { 1167 if (desc->IsLineInfoAvailable()) {
905 elf->AddSection(new DebugInfoSection(desc)); 1168 elf->AddSection(new DebugInfoSection(desc));
906 elf->AddSection(new DebugAbbrevSection); 1169 elf->AddSection(new DebugAbbrevSection);
907 elf->AddSection(new DebugLineSection(desc)); 1170 elf->AddSection(new DebugLineSection(desc));
908 } 1171 }
909 } 1172 #ifdef V8_TARGET_ARCH_X64
910 1173 elf->AddSection(new UnwindInfoSection(desc));
911 1174 #endif
1175 }
1176
1177
912 // ------------------------------------------------------------------- 1178 // -------------------------------------------------------------------
913 // Binary GDB JIT Interface as described in 1179 // Binary GDB JIT Interface as described in
914 // http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html 1180 // http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html
915 extern "C" { 1181 extern "C" {
916 typedef enum { 1182 typedef enum {
917 JIT_NOACTION = 0, 1183 JIT_NOACTION = 0,
918 JIT_REGISTER_FN, 1184 JIT_REGISTER_FN,
919 JIT_UNREGISTER_FN 1185 JIT_UNREGISTER_FN
920 } JITAction; 1186 } JITAction;
921 1187
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
998 static JITCodeEntry* CreateELFObject(CodeDescription* desc) { 1264 static JITCodeEntry* CreateELFObject(CodeDescription* desc) {
999 ZoneScope zone_scope(DELETE_ON_EXIT); 1265 ZoneScope zone_scope(DELETE_ON_EXIT);
1000 1266
1001 ELF elf; 1267 ELF elf;
1002 Writer w(&elf); 1268 Writer w(&elf);
1003 1269
1004 int text_section_index = elf.AddSection( 1270 int text_section_index = elf.AddSection(
1005 new FullHeaderELFSection(".text", 1271 new FullHeaderELFSection(".text",
1006 ELFSection::TYPE_NOBITS, 1272 ELFSection::TYPE_NOBITS,
1007 kCodeAlignment, 1273 kCodeAlignment,
1008 desc->code_start(), 1274 desc->CodeStart(),
1009 0, 1275 0,
1010 desc->code_size(), 1276 desc->CodeSize(),
1011 ELFSection::FLAG_ALLOC | ELFSection::FLAG_EXEC)); 1277 ELFSection::FLAG_ALLOC | ELFSection::FLAG_EXEC));
1012 1278
1013 CreateSymbolsTable(desc, &elf, text_section_index); 1279 CreateSymbolsTable(desc, &elf, text_section_index);
1014 1280
1015 CreateDWARFSections(desc, &elf); 1281 CreateDWARFSections(desc, &elf);
1016 1282
1017 elf.Write(&w); 1283 elf.Write(&w);
1018 1284
1019 return CreateCodeEntry(w.buffer(), w.position()); 1285 return CreateCodeEntry(w.buffer(), w.position());
1020 } 1286 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1058 void GDBJITInterface::AddCode(Handle<String> name, 1324 void GDBJITInterface::AddCode(Handle<String> name,
1059 Handle<Script> script, 1325 Handle<Script> script,
1060 Handle<Code> code) { 1326 Handle<Code> code) {
1061 if (!FLAG_gdbjit) return; 1327 if (!FLAG_gdbjit) return;
1062 1328
1063 // Force initialization of line_ends array. 1329 // Force initialization of line_ends array.
1064 GetScriptLineNumber(script, 0); 1330 GetScriptLineNumber(script, 0);
1065 1331
1066 if (!name.is_null()) { 1332 if (!name.is_null()) {
1067 SmartPointer<char> name_cstring = name->ToCString(DISALLOW_NULLS); 1333 SmartPointer<char> name_cstring = name->ToCString(DISALLOW_NULLS);
1068 AddCode(*name_cstring, *code, *script); 1334 AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script);
1069 } else { 1335 } else {
1070 AddCode("", *code, *script); 1336 AddCode("", *code, GDBJITInterface::FUNCTION, *script);
1071 } 1337 }
1072 } 1338 }
1073 1339
1340 static void AddUnwindInfo(CodeDescription *desc) {
1341 #ifdef V8_TARGET_ARCH_X64
1342 if (desc->tag() == GDBJITInterface::FUNCTION) {
1343 // To avoid propagating unwinding information through
1344 // compilation pipeline we rely on constant offsets as
1345 // function prologue and epilogue are the same for all
Erik Corry 2011/02/02 13:10:25 we rely on ... are the same -> we rely on ... bein
1346 // code objects generated by the full code generator.
1347 static const int kFramePointerPushOffset = 1;
1348 static const int kFramePointerSetOffset = 4;
1349 static const int kFramePointerPopOffset = -3;
1350
1351 uintptr_t frame_pointer_push_address =
1352 desc->CodeStart() + kFramePointerPushOffset;
1353
1354 uintptr_t frame_pointer_set_address =
1355 desc->CodeStart() + kFramePointerSetOffset;
1356
1357 uintptr_t frame_pointer_pop_address =
1358 desc->CodeEnd() + kFramePointerPopOffset;
1359
1360 #ifdef DEBUG
1361 static const uint8_t kFramePointerPushInstruction = 0x48; // push ebp
1362 static const uint16_t kFramePointerSetInstruction = 0x5756; // mov ebp, esp
1363 static const uint8_t kFramePointerPopInstruction = 0xBE; // pop ebp
1364
1365 ASSERT(*reinterpret_cast<uint8_t*>(frame_pointer_push_address) ==
1366 kFramePointerPushInstruction);
1367 ASSERT(*reinterpret_cast<uint16_t*>(frame_pointer_set_address) ==
1368 kFramePointerSetInstruction);
1369 ASSERT(*reinterpret_cast<uint8_t*>(frame_pointer_pop_address) ==
1370 kFramePointerPopInstruction);
1371 #endif
1372
1373 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_PUSH,
1374 frame_pointer_push_address);
1375 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_SET,
1376 frame_pointer_set_address);
1377 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_POP,
1378 frame_pointer_pop_address);
1379 } else {
1380 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_PUSH,
1381 desc->CodeStart());
1382 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_SET,
1383 desc->CodeStart());
1384 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_POP,
1385 desc->CodeEnd());
1386 }
1387 #endif // V8_TARGET_ARCH_X64
1388 }
1389
1074 1390
1075 void GDBJITInterface::AddCode(const char* name, 1391 void GDBJITInterface::AddCode(const char* name,
1076 Code* code, 1392 Code* code,
1393 GDBJITInterface::CodeTag tag,
1077 Script* script) { 1394 Script* script) {
1078 if (!FLAG_gdbjit) return; 1395 if (!FLAG_gdbjit) return;
1079 AssertNoAllocation no_gc; 1396 AssertNoAllocation no_gc;
1080 1397
1081 HashMap::Entry* e = entries.Lookup(code, HashForCodeObject(code), true); 1398 HashMap::Entry* e = entries.Lookup(code, HashForCodeObject(code), true);
1082 if (e->value != NULL && !IsLineInfoTagged(e->value)) return; 1399 if (e->value != NULL && !IsLineInfoTagged(e->value)) return;
1083 1400
1084 GDBJITLineInfo* lineinfo = UntagLineInfo(e->value); 1401 GDBJITLineInfo* lineinfo = UntagLineInfo(e->value);
1085 CodeDescription code_desc(name, 1402 CodeDescription code_desc(name,
1086 code, 1403 code,
1087 script != NULL ? Handle<Script>(script) 1404 script != NULL ? Handle<Script>(script)
1088 : Handle<Script>(), 1405 : Handle<Script>(),
1089 lineinfo); 1406 lineinfo,
1407 tag);
1090 1408
1091 if (!FLAG_gdbjit_full && !code_desc.is_line_info_available()) { 1409 if (!FLAG_gdbjit_full && !code_desc.IsLineInfoAvailable()) {
1092 delete lineinfo; 1410 delete lineinfo;
1093 entries.Remove(code, HashForCodeObject(code)); 1411 entries.Remove(code, HashForCodeObject(code));
1094 return; 1412 return;
1095 } 1413 }
1096 1414
1415 AddUnwindInfo(&code_desc);
1097 JITCodeEntry* entry = CreateELFObject(&code_desc); 1416 JITCodeEntry* entry = CreateELFObject(&code_desc);
1098 ASSERT(!IsLineInfoTagged(entry)); 1417 ASSERT(!IsLineInfoTagged(entry));
1099 1418
1100 delete lineinfo; 1419 delete lineinfo;
1101 e->value = entry; 1420 e->value = entry;
1102 1421
1103 RegisterCodeEntry(entry); 1422 RegisterCodeEntry(entry);
1104 } 1423 }
1105 1424
1106 1425
1107 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag, 1426 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag,
1108 const char* name, 1427 const char* name,
1109 Code* code) { 1428 Code* code) {
1110 if (!FLAG_gdbjit) return; 1429 if (!FLAG_gdbjit) return;
1111 1430
1112 EmbeddedVector<char, 256> buffer; 1431 EmbeddedVector<char, 256> buffer;
1113 StringBuilder builder(buffer.start(), buffer.length()); 1432 StringBuilder builder(buffer.start(), buffer.length());
1114 1433
1115 builder.AddString(Tag2String(tag)); 1434 builder.AddString(Tag2String(tag));
1116 if ((name != NULL) && (*name != '\0')) { 1435 if ((name != NULL) && (*name != '\0')) {
1117 builder.AddString(": "); 1436 builder.AddString(": ");
1118 builder.AddString(name); 1437 builder.AddString(name);
1119 } else { 1438 } else {
1120 builder.AddFormatted(": code object %p", static_cast<void*>(code)); 1439 builder.AddFormatted(": code object %p", static_cast<void*>(code));
1121 } 1440 }
1122 1441
1123 AddCode(builder.Finalize(), code); 1442 AddCode(builder.Finalize(), code, tag);
1124 } 1443 }
1125 1444
1126 1445
1127 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag, 1446 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag,
1128 String* name, 1447 String* name,
1129 Code* code) { 1448 Code* code) {
1130 if (!FLAG_gdbjit) return; 1449 if (!FLAG_gdbjit) return;
1131 AddCode(tag, name != NULL ? *name->ToCString(DISALLOW_NULLS) : NULL, code); 1450 AddCode(tag, name != NULL ? *name->ToCString(DISALLOW_NULLS) : NULL, code);
1132 } 1451 }
1133 1452
(...skipping 27 matching lines...) Expand all
1161 GDBJITLineInfo* line_info) { 1480 GDBJITLineInfo* line_info) {
1162 ASSERT(!IsLineInfoTagged(line_info)); 1481 ASSERT(!IsLineInfoTagged(line_info));
1163 HashMap::Entry* e = entries.Lookup(code, HashForCodeObject(code), true); 1482 HashMap::Entry* e = entries.Lookup(code, HashForCodeObject(code), true);
1164 ASSERT(e->value == NULL); 1483 ASSERT(e->value == NULL);
1165 e->value = TagLineInfo(line_info); 1484 e->value = TagLineInfo(line_info);
1166 } 1485 }
1167 1486
1168 1487
1169 } } // namespace v8::internal 1488 } } // namespace v8::internal
1170 #endif 1489 #endif
OLDNEW
« no previous file with comments | « src/gdb-jit.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698