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

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

Issue 6995161: Extend gdb-jit support (OSX/locals+parameters/prettyprint) (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Created 9 years, 6 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
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 16 matching lines...) Expand all
27 27
28 #ifdef ENABLE_GDB_JIT_INTERFACE 28 #ifdef ENABLE_GDB_JIT_INTERFACE
29 #include "v8.h" 29 #include "v8.h"
30 #include "gdb-jit.h" 30 #include "gdb-jit.h"
31 31
32 #include "bootstrapper.h" 32 #include "bootstrapper.h"
33 #include "compiler.h" 33 #include "compiler.h"
34 #include "global-handles.h" 34 #include "global-handles.h"
35 #include "messages.h" 35 #include "messages.h"
36 #include "natives.h" 36 #include "natives.h"
37 #include "scopeinfo.h"
38
39 #ifdef __APPLE__
40 #define __MACH_O
41 #define SECTION_BASE MachOSection
42 #define OBJ_FORMAT MachO
43 #else
44 #define __ELF
45 #define SECTION_BASE ELFSection
46 #define OBJ_FORMAT ELF
47 #endif
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 I don't think we are using macros for anything lik
zarko 2011/06/27 22:24:29 Done (though I have kept the __MACH_O/__ELF define
37 48
38 namespace v8 { 49 namespace v8 {
39 namespace internal { 50 namespace internal {
40 51
41 class ELF; 52 class ELF;
53 class MachO;
42 54
43 class Writer BASE_EMBEDDED { 55 class Writer BASE_EMBEDDED {
44 public: 56 public:
45 explicit Writer(ELF* elf) 57 explicit Writer(ELF* elf)
46 : elf_(elf), 58 : elf_(elf),
59 mach_o_(0),
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 Instead of duplicating code and members replace el
zarko 2011/06/27 22:24:29 Done.
47 position_(0), 60 position_(0),
48 capacity_(1024), 61 capacity_(1024),
49 buffer_(reinterpret_cast<byte*>(malloc(capacity_))) { 62 buffer_(reinterpret_cast<byte*>(malloc(capacity_))) {
63 }
64
65 explicit Writer(MachO* mach_o)
66 : elf_(0),
67 mach_o_(mach_o),
68 position_(0),
69 capacity_(1024),
70 buffer_(reinterpret_cast<byte*>(malloc(capacity_))) {
50 } 71 }
51 72
52 ~Writer() { 73 ~Writer() {
53 free(buffer_); 74 free(buffer_);
54 } 75 }
55 76
56 uintptr_t position() const { 77 uintptr_t position() const {
57 return position_; 78 return position_;
58 } 79 }
59 80
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 return SlotAt<T>(slot_position); 126 return SlotAt<T>(slot_position);
106 } 127 }
107 128
108 void Ensure(uintptr_t pos) { 129 void Ensure(uintptr_t pos) {
109 if (capacity_ < pos) { 130 if (capacity_ < pos) {
110 while (capacity_ < pos) capacity_ *= 2; 131 while (capacity_ < pos) capacity_ *= 2;
111 buffer_ = reinterpret_cast<byte*>(realloc(buffer_, capacity_)); 132 buffer_ = reinterpret_cast<byte*>(realloc(buffer_, capacity_));
112 } 133 }
113 } 134 }
114 135
115 ELF* elf() { return elf_; } 136 ELF* elf() { ASSERT(elf_ != 0); return elf_; }
137
138 MachO* mach_o() { ASSERT(mach_o_ != 0); return mach_o_; }
116 139
117 byte* buffer() { return buffer_; } 140 byte* buffer() { return buffer_; }
118 141
119 void Align(uintptr_t align) { 142 void Align(uintptr_t align) {
120 uintptr_t delta = position_ % align; 143 uintptr_t delta = position_ % align;
121 if (delta == 0) return; 144 if (delta == 0) return;
122 uintptr_t padding = align - delta; 145 uintptr_t padding = align - delta;
123 Ensure(position_ += padding); 146 Ensure(position_ += padding);
124 ASSERT((position_ % align) == 0); 147 ASSERT((position_ % align) == 0);
125 } 148 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 private: 182 private:
160 template<typename T> friend class Slot; 183 template<typename T> friend class Slot;
161 184
162 template<typename T> 185 template<typename T>
163 T* RawSlotAt(uintptr_t offset) { 186 T* RawSlotAt(uintptr_t offset) {
164 ASSERT(offset < capacity_ && offset + sizeof(T) <= capacity_); 187 ASSERT(offset < capacity_ && offset + sizeof(T) <= capacity_);
165 return reinterpret_cast<T*>(&buffer_[offset]); 188 return reinterpret_cast<T*>(&buffer_[offset]);
166 } 189 }
167 190
168 ELF* elf_; 191 ELF* elf_;
192 MachO* mach_o_;
169 uintptr_t position_; 193 uintptr_t position_;
170 uintptr_t capacity_; 194 uintptr_t capacity_;
171 byte* buffer_; 195 byte* buffer_;
172 }; 196 };
173 197
174 class StringTable; 198 class StringTable;
175 199
200 class MachOSection : public ZoneObject {
201 public:
202 struct Header {
203 char sectname[16];
204 char segname[16];
205 #if defined(V8_TARGET_ARCH_IA32)
206 uint32_t addr;
207 uint32_t size;
208 #else
209 uint64_t addr;
210 uint64_t size;
211 #endif
212 uint32_t offset;
213 uint32_t align;
214 uint32_t reloff;
215 uint32_t nreloc;
216 uint32_t flags;
217 uint32_t reserved1;
218 uint32_t reserved2;
219 };
220
221 enum Type {
222 S_REGULAR = 0x0u,
223 S_ATTR_COALESCED = 0xbu,
224 S_ATTR_SOME_INSTRUCTIONS = 0x400u,
225 S_ATTR_DEBUG = 0x02000000u,
226 S_ATTR_PURE_INSTRUCTIONS = 0x80000000u
227 };
228
229 MachOSection(const char* name,
230 const char* segment,
231 uintptr_t align,
232 uint32_t flags)
233 : name_(name),
234 segment_(segment),
235 align_(align),
236 flags_(flags) {
237 ASSERT(IsPowerOf2(align));
238 if (align_ != 0) {
239 align_ = WhichPowerOf2(align_);
240 }
241 }
242
243 virtual ~MachOSection() { }
244
245 virtual void PopulateHeader(Writer::Slot<Header> header) {
246 header->addr = 0;
247 header->size = 0;
248 header->offset = 0;
249 header->align = align_;
250 header->reloff = 0;
251 header->nreloc = 0;
252 header->flags = flags_;
253 header->reserved1 = 0;
254 header->reserved2 = 0;
255 memset(header->sectname, 0, 16);
256 memset(header->segname, 0, 16);
257 ASSERT(strlen(name_) < 16);
258 ASSERT(strlen(segment_) < 16);
259 strcpy(header->sectname, name_);
260 strcpy(header->segname, segment_);
261 }
262
263 virtual void WriteBody(Writer::Slot<Header> header, Writer* writer) {
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 Seems to be shared between ELFSection and MachOSec
zarko 2011/06/27 22:24:29 Done.
264 uintptr_t start = writer->position();
265 if (WriteBody(writer)) {
266 uintptr_t end = writer->position();
267 header->offset = start;
268 header->addr = 0;
269 header->size = end - start;
270 }
271 }
272
273 virtual bool WriteBody(Writer* writer) {
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 Ditto.
zarko 2011/06/27 22:24:29 Done.
274 return false;
275 }
276
277 private:
278 const char* name_;
279 const char* segment_;
280 uintptr_t align_;
281 uint32_t flags_;
282 };
283
284
176 class ELFSection : public ZoneObject { 285 class ELFSection : public ZoneObject {
177 public: 286 public:
178 struct Header { 287 struct Header {
179 uint32_t name; 288 uint32_t name;
180 uint32_t type; 289 uint32_t type;
181 uintptr_t flags; 290 uintptr_t flags;
182 uintptr_t address; 291 uintptr_t address;
183 uintptr_t offset; 292 uintptr_t offset;
184 uintptr_t size; 293 uintptr_t size;
185 uint32_t link; 294 uint32_t link;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 virtual void PopulateHeader(Writer::Slot<Header> header) { 354 virtual void PopulateHeader(Writer::Slot<Header> header) {
246 header->flags = 0; 355 header->flags = 0;
247 header->address = 0; 356 header->address = 0;
248 header->offset = 0; 357 header->offset = 0;
249 header->size = 0; 358 header->size = 0;
250 header->link = 0; 359 header->link = 0;
251 header->info = 0; 360 header->info = 0;
252 header->entry_size = 0; 361 header->entry_size = 0;
253 } 362 }
254 363
255
256 private: 364 private:
257 const char* name_; 365 const char* name_;
258 Type type_; 366 Type type_;
259 uintptr_t align_; 367 uintptr_t align_;
260 uint16_t index_; 368 uint16_t index_;
261 }; 369 };
262 370
263 371
372 class MachOTextSection : public MachOSection {
373 public:
374 MachOTextSection(uintptr_t align,
375 uintptr_t addr,
376 uintptr_t size)
377 : MachOSection("__text",
378 "__TEXT",
379 align,
380 MachOSection::S_REGULAR |
381 MachOSection::S_ATTR_SOME_INSTRUCTIONS |
382 MachOSection::S_ATTR_PURE_INSTRUCTIONS),
383 addr_(addr),
384 size_(size) { }
385
386 protected:
387 virtual void PopulateHeader(Writer::Slot<Header> header) {
388 MachOSection::PopulateHeader(header);
389 header->addr = addr_;
390 header->size = size_;
391 }
392
393 private:
394 uintptr_t addr_;
395 uintptr_t size_;
396 };
397
398
264 class FullHeaderELFSection : public ELFSection { 399 class FullHeaderELFSection : public ELFSection {
265 public: 400 public:
266 FullHeaderELFSection(const char* name, 401 FullHeaderELFSection(const char* name,
267 Type type, 402 Type type,
268 uintptr_t align, 403 uintptr_t align,
269 uintptr_t addr, 404 uintptr_t addr,
270 uintptr_t offset, 405 uintptr_t offset,
271 uintptr_t size, 406 uintptr_t size,
272 uintptr_t flags) 407 uintptr_t flags)
273 : ELFSection(name, type, align), 408 : ELFSection(name, type, align),
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 479
345 void ELFSection::PopulateHeader(Writer::Slot<ELFSection::Header> header, 480 void ELFSection::PopulateHeader(Writer::Slot<ELFSection::Header> header,
346 StringTable* strtab) { 481 StringTable* strtab) {
347 header->name = strtab->Add(name_); 482 header->name = strtab->Add(name_);
348 header->type = type_; 483 header->type = type_;
349 header->alignment = align_; 484 header->alignment = align_;
350 PopulateHeader(header); 485 PopulateHeader(header);
351 } 486 }
352 487
353 488
489 class MachO BASE_EMBEDDED {
490 public:
491 MachO() : sections_(6) { }
492
493 uint32_t AddSection(MachOSection* section) {
494 sections_.Add(section);
495 return sections_.length() - 1;
496 }
497
498 void Write(Writer* w, uintptr_t code_start, uintptr_t code_size);
499
500 private:
501 struct MachOHeader {
502 uint32_t magic;
503 uint32_t cputype;
504 uint32_t cpusubtype;
505 uint32_t filetype;
506 uint32_t ncmds;
507 uint32_t sizeofcmds;
508 uint32_t flags;
509 #if defined(V8_TARGET_ARCH_X64)
510 uint32_t reserved;
511 #endif
512 };
513
514 struct MachOSegmentCommand {
515 uint32_t cmd;
516 uint32_t cmdsize;
517 char segname[16];
518 #if defined(V8_TARGET_ARCH_IA32)
519 uint32_t vmaddr;
520 uint32_t vmsize;
521 uint32_t fileoff;
522 uint32_t filesize;
523 #else
524 uint64_t vmaddr;
525 uint64_t vmsize;
526 uint64_t fileoff;
527 uint64_t filesize;
528 #endif
529 uint32_t maxprot;
530 uint32_t initprot;
531 uint32_t nsects;
532 uint32_t flags;
533 };
534
535 enum MachOLoadCommandCmd {
536 LC_SEGMENT_32 = 0x00000001u,
537 LC_SEGMENT_64 = 0x00000019u
538 };
539
540 ZoneList<MachOSection*> sections_;
541 };
542
543
544 void MachO::Write(Writer* w,
545 uintptr_t code_start,
546 uintptr_t code_size) {
547 ASSERT(w->position() == 0);
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 Can you split this method into several like it is
zarko 2011/06/27 22:24:29 Done.
548 Writer::Slot<MachOHeader> header = w->CreateSlotHere<MachOHeader>();
549 #if defined(V8_TARGET_ARCH_IA32)
550 header->magic = 0xFEEDFACEu;
551 header->cputype = 7; // i386
552 header->cpusubtype = 3; // CPU_SUBTYPE_I386_ALL
553 #elif defined(V8_TARGET_ARCH_X64)
554 header->magic = 0xFEEDFACFu;
555 header->cputype = 7 | 0x01000000; // i386 | 64-bit ABI
556 header->cpusubtype = 3; // CPU_SUBTYPE_I386_ALL
557 header->reserved = 0;
558 #else
559 #error Unsupported target architecture.
560 #endif
561 header->filetype = 0x1; // MH_OBJECT
562 header->ncmds = 1;
563 header->sizeofcmds = 0;
564 header->flags = 0;
565 uintptr_t load_command_start = w->position();
566 Writer::Slot<MachOSegmentCommand> cmd =
567 w->CreateSlotHere<MachOSegmentCommand>();
568 #if defined(V8_TARGET_ARCH_IA32)
569 cmd->cmd = LC_SEGMENT_32;
570 #else
571 cmd->cmd = LC_SEGMENT_64;
572 #endif
573 cmd->vmaddr = code_start;
574 cmd->vmsize = code_size;
575 cmd->fileoff = 0;
576 cmd->filesize = 0;
577 cmd->maxprot = 7;
578 cmd->initprot = 7;
579 cmd->flags = 0;
580 cmd->nsects = sections_.length();
581 memset(cmd->segname, 0, 16);
582 cmd->cmdsize = sizeof(MachOSegmentCommand) + sizeof(MachOSection::Header) *
583 cmd->nsects;
584 Writer::Slot<MachOSection::Header> headers =
585 w->CreateSlotsHere<MachOSection::Header>(sections_.length());
586 cmd->fileoff = w->position();
587 header->sizeofcmds = w->position() - load_command_start;
588 for (int section = 0; section < sections_.length(); ++section) {
589 sections_[section]->PopulateHeader(headers.at(section));
590 sections_[section]->WriteBody(headers.at(section), w);
591 }
592 cmd->filesize = w->position() - (uintptr_t)cmd->fileoff;
593 }
594
595
354 class ELF BASE_EMBEDDED { 596 class ELF BASE_EMBEDDED {
355 public: 597 public:
356 ELF() : sections_(6) { 598 ELF() : sections_(6) {
357 sections_.Add(new ELFSection("", ELFSection::TYPE_NULL, 0)); 599 sections_.Add(new ELFSection("", ELFSection::TYPE_NULL, 0));
358 sections_.Add(new StringTable(".shstrtab")); 600 sections_.Add(new StringTable(".shstrtab"));
359 } 601 }
360 602
361 void Write(Writer* w) { 603 void Write(Writer* w) {
362 WriteHeader(w); 604 WriteHeader(w);
363 WriteSectionTable(w); 605 WriteSectionTable(w);
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 POST_RBP_SET, 892 POST_RBP_SET,
651 POST_RBP_POP, 893 POST_RBP_POP,
652 STACK_STATE_MAX 894 STACK_STATE_MAX
653 }; 895 };
654 #endif 896 #endif
655 897
656 CodeDescription(const char* name, 898 CodeDescription(const char* name,
657 Code* code, 899 Code* code,
658 Handle<Script> script, 900 Handle<Script> script,
659 GDBJITLineInfo* lineinfo, 901 GDBJITLineInfo* lineinfo,
660 GDBJITInterface::CodeTag tag) 902 GDBJITInterface::CodeTag tag,
903 CompilationInfo* info)
661 : name_(name), 904 : name_(name),
662 code_(code), 905 code_(code),
663 script_(script), 906 script_(script),
664 lineinfo_(lineinfo), 907 lineinfo_(lineinfo),
665 tag_(tag) { 908 tag_(tag),
909 info_(info) {
666 } 910 }
667 911
668 const char* name() const { 912 const char* name() const {
669 return name_; 913 return name_;
670 } 914 }
671 915
672 GDBJITLineInfo* lineinfo() const { 916 GDBJITLineInfo* lineinfo() const {
673 return lineinfo_; 917 return lineinfo_;
674 } 918 }
675 919
676 GDBJITInterface::CodeTag tag() const { 920 GDBJITInterface::CodeTag tag() const {
677 return tag_; 921 return tag_;
678 } 922 }
679 923
924 CompilationInfo* info() const {
925 return info_;
926 }
927
928 bool IsInfoAvailable() const {
929 return info_ != NULL;
930 }
931
680 uintptr_t CodeStart() const { 932 uintptr_t CodeStart() const {
681 return reinterpret_cast<uintptr_t>(code_->instruction_start()); 933 return reinterpret_cast<uintptr_t>(code_->instruction_start());
682 } 934 }
683 935
684 uintptr_t CodeEnd() const { 936 uintptr_t CodeEnd() const {
685 return reinterpret_cast<uintptr_t>(code_->instruction_end()); 937 return reinterpret_cast<uintptr_t>(code_->instruction_end());
686 } 938 }
687 939
688 uintptr_t CodeSize() const { 940 uintptr_t CodeSize() const {
689 return CodeEnd() - CodeStart(); 941 return CodeEnd() - CodeStart();
(...skipping 27 matching lines...) Expand all
717 return GetScriptLineNumberSafe(script_, pos) + 1; 969 return GetScriptLineNumberSafe(script_, pos) + 1;
718 } 970 }
719 971
720 972
721 private: 973 private:
722 const char* name_; 974 const char* name_;
723 Code* code_; 975 Code* code_;
724 Handle<Script> script_; 976 Handle<Script> script_;
725 GDBJITLineInfo* lineinfo_; 977 GDBJITLineInfo* lineinfo_;
726 GDBJITInterface::CodeTag tag_; 978 GDBJITInterface::CodeTag tag_;
979 CompilationInfo* info_;
727 #ifdef V8_TARGET_ARCH_X64 980 #ifdef V8_TARGET_ARCH_X64
728 uintptr_t stack_state_start_addresses_[STACK_STATE_MAX]; 981 uintptr_t stack_state_start_addresses_[STACK_STATE_MAX];
729 #endif 982 #endif
730 }; 983 };
731 984
732 985 #ifdef __ELF
733 static void CreateSymbolsTable(CodeDescription* desc, 986 static void CreateSymbolsTable(CodeDescription* desc,
734 ELF* elf, 987 ELF* elf,
735 int text_section_index) { 988 int text_section_index) {
736 ELFSymbolTable* symtab = new ELFSymbolTable(".symtab"); 989 ELFSymbolTable* symtab = new ELFSymbolTable(".symtab");
737 StringTable* strtab = new StringTable(".strtab"); 990 StringTable* strtab = new StringTable(".strtab");
738 991
739 // Symbol table should be followed by the linked string table. 992 // Symbol table should be followed by the linked string table.
740 elf->AddSection(symtab); 993 elf->AddSection(symtab);
741 elf->AddSection(strtab); 994 elf->AddSection(strtab);
742 995
743 symtab->Add(ELFSymbol("V8 Code", 996 symtab->Add(ELFSymbol("V8 Code",
744 0, 997 0,
745 0, 998 0,
746 ELFSymbol::BIND_LOCAL, 999 ELFSymbol::BIND_LOCAL,
747 ELFSymbol::TYPE_FILE, 1000 ELFSymbol::TYPE_FILE,
748 ELFSection::INDEX_ABSOLUTE)); 1001 ELFSection::INDEX_ABSOLUTE));
749 1002
750 symtab->Add(ELFSymbol(desc->name(), 1003 symtab->Add(ELFSymbol(desc->name(),
751 0, 1004 0,
752 desc->CodeSize(), 1005 desc->CodeSize(),
753 ELFSymbol::BIND_GLOBAL, 1006 ELFSymbol::BIND_GLOBAL,
754 ELFSymbol::TYPE_FUNC, 1007 ELFSymbol::TYPE_FUNC,
755 text_section_index)); 1008 text_section_index));
756 } 1009 }
1010 #endif
757 1011
758 1012
759 class DebugInfoSection : public ELFSection { 1013 class DebugInfoSection : public SECTION_BASE {
760 public: 1014 public:
761 explicit DebugInfoSection(CodeDescription* desc) 1015 explicit DebugInfoSection(CodeDescription* desc)
762 : ELFSection(".debug_info", TYPE_PROGBITS, 1), desc_(desc) { } 1016 #ifdef __ELF
1017 : ELFSection(".debug_info", TYPE_PROGBITS, 1),
1018 #else
1019 : MachOSection("__debug_info", "__DWARF", 1,
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 one argument per line.
zarko 2011/06/27 22:24:29 Done.
1020 MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG),
1021 #endif
1022 desc_(desc) { }
1023
1024 // DWARF2 standard
1025 enum DWARF2LocationOp {
1026 DW_OP_reg0 = 0x50,
1027 DW_OP_reg1 = 0x51,
1028 DW_OP_reg2 = 0x52,
1029 DW_OP_reg3 = 0x53,
1030 DW_OP_reg4 = 0x54,
1031 DW_OP_reg5 = 0x55,
1032 DW_OP_reg6 = 0x56,
1033 DW_OP_reg7 = 0x57,
1034 DW_OP_fbreg = 0x91 // 1 param: SLEB128 offset
1035 };
1036
1037 enum DWARF2Encoding {
1038 DW_ATE_ADDRESS = 0x1,
1039 DW_ATE_SIGNED = 0x5
1040 };
763 1041
764 bool WriteBody(Writer* w) { 1042 bool WriteBody(Writer* w) {
1043 uintptr_t cu_start = w->position();
765 Writer::Slot<uint32_t> size = w->CreateSlotHere<uint32_t>(); 1044 Writer::Slot<uint32_t> size = w->CreateSlotHere<uint32_t>();
766 uintptr_t start = w->position(); 1045 uintptr_t start = w->position();
767 w->Write<uint16_t>(2); // DWARF version. 1046 w->Write<uint16_t>(2); // DWARF version.
768 w->Write<uint32_t>(0); // Abbreviation table offset. 1047 w->Write<uint32_t>(0); // Abbreviation table offset.
769 w->Write<uint8_t>(sizeof(intptr_t)); 1048 w->Write<uint8_t>(sizeof(intptr_t));
770 1049
771 w->WriteULEB128(1); // Abbreviation code. 1050 w->WriteULEB128(1); // Abbreviation code.
772 w->WriteString(*desc_->GetFilename()); 1051 w->WriteString(*desc_->GetFilename());
773 w->Write<intptr_t>(desc_->CodeStart()); 1052 w->Write<intptr_t>(desc_->CodeStart());
774 w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize()); 1053 w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize());
775 w->Write<uint32_t>(0); 1054 w->Write<uint32_t>(0);
1055
1056 uint32_t ty_offset = static_cast<uint32_t>(w->position() - cu_start);
1057 w->WriteULEB128(3);
1058 w->Write<uint8_t>(kPointerSize);
1059 w->WriteString("v8value");
1060
1061 if (desc_->IsInfoAvailable()) {
1062 CompilationInfo* info = desc_->info();
1063 ScopeInfo<FreeStoreAllocationPolicy> scope_info(info->scope());
1064 w->WriteULEB128(2);
1065 w->WriteString(desc_->name());
1066 w->Write<intptr_t>(desc_->CodeStart());
1067 w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize());
1068 Writer::Slot<uint32_t> fb_block_size = w->CreateSlotHere<uint32_t>();
1069 uintptr_t fb_block_start = w->position();
1070 #if defined(V8_TARGET_ARCH_IA32)
1071 w->Write<uint8_t>(DW_OP_reg5); // The frame pointer's here on ia32
1072 #elif defined(V8_TARGET_ARCH_X64)
1073 w->Write<uint8_t>(DW_OP_reg6); // and here on x64.
1074 #else
1075 #error Unsupported target architecture.
1076 #endif
1077 fb_block_size.set(static_cast<uint32_t>(w->position() - fb_block_start));
1078
1079 int params = scope_info.number_of_parameters();
1080 int slots = scope_info.number_of_stack_slots();
1081 int context_slots = scope_info.number_of_context_slots();
1082 // The real slot ID is internal_slots + context_slot_id.
1083 int internal_slots = Context::MIN_CONTEXT_SLOTS;
1084 int locals = scope_info.NumberOfLocals();
1085 int current_abbreviation = 4;
1086
1087 for (int param = 0; param < params; ++param) {
1088 w->WriteULEB128(current_abbreviation++);
1089 w->WriteString(
1090 *scope_info.parameter_name(param)->ToCString(DISALLOW_NULLS));
1091 w->Write<uint32_t>(ty_offset);
1092 Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
1093 uintptr_t block_start = w->position();
1094 w->Write<uint8_t>(DW_OP_fbreg);
1095 w->WriteSLEB128(
1096 JavaScriptFrameConstants::kLastParameterOffset +
1097 kPointerSize * (params - param - 1));
1098 block_size.set(static_cast<uint32_t>(w->position() - block_start));
1099 }
1100
1101 EmbeddedVector<char, 256> buffer;
1102 StringBuilder builder(buffer.start(), buffer.length());
1103
1104 for (int slot = 0; slot < slots; ++slot) {
1105 w->WriteULEB128(current_abbreviation++);
1106 builder.Reset();
1107 builder.AddFormatted("slot%d", slot);
1108 w->WriteString(builder.Finalize());
1109 }
1110
1111 // See contexts.h for more information.
1112 ASSERT(Context::MIN_CONTEXT_SLOTS == 5);
1113 ASSERT(Context::CLOSURE_INDEX == 0);
1114 ASSERT(Context::FCONTEXT_INDEX == 1);
1115 ASSERT(Context::PREVIOUS_INDEX == 2);
1116 ASSERT(Context::EXTENSION_INDEX == 3);
1117 ASSERT(Context::GLOBAL_INDEX == 4);
1118 w->WriteULEB128(current_abbreviation++);
1119 w->WriteString(".closure");
1120 w->WriteULEB128(current_abbreviation++);
1121 w->WriteString(".fcontext");
1122 w->WriteULEB128(current_abbreviation++);
1123 w->WriteString(".previous");
1124 w->WriteULEB128(current_abbreviation++);
1125 w->WriteString(".extension");
1126 w->WriteULEB128(current_abbreviation++);
1127 w->WriteString(".global");
1128
1129 for (int context_slot = 0; context_slot < context_slots;
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 for(x; y; z)
zarko 2011/06/27 22:24:29 Done.
1130 ++context_slot) {
1131 w->WriteULEB128(current_abbreviation++);
1132 builder.Reset();
1133 builder.AddFormatted("context_slot%d", context_slot + internal_slots);
1134 w->WriteString(builder.Finalize());
1135 }
1136
1137 for (int local = 0; local < locals; ++local) {
1138 w->WriteULEB128(current_abbreviation++);
1139 w->WriteString(
1140 *scope_info.LocalName(local)->ToCString(DISALLOW_NULLS));
1141 w->Write<uint32_t>(ty_offset);
1142 Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
1143 uintptr_t block_start = w->position();
1144 w->Write<uint8_t>(DW_OP_fbreg);
1145 w->WriteSLEB128(
1146 JavaScriptFrameConstants::kLocal0Offset -
1147 kPointerSize * local);
1148 block_size.set(static_cast<uint32_t>(w->position() - block_start));
1149 }
1150
1151 {
1152 w->WriteULEB128(current_abbreviation++);
1153 w->WriteString("__function");
1154 w->Write<uint32_t>(ty_offset);
1155 Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
1156 uintptr_t block_start = w->position();
1157 w->Write<uint8_t>(DW_OP_fbreg);
1158 w->WriteSLEB128(JavaScriptFrameConstants::kFunctionOffset);
1159 block_size.set(static_cast<uint32_t>(w->position() - block_start));
1160 }
1161
1162 {
1163 w->WriteULEB128(current_abbreviation++);
1164 w->WriteString("__context");
1165 w->Write<uint32_t>(ty_offset);
1166 Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
1167 uintptr_t block_start = w->position();
1168 w->Write<uint8_t>(DW_OP_fbreg);
1169 w->WriteSLEB128(StandardFrameConstants::kContextOffset);
1170 block_size.set(static_cast<uint32_t>(w->position() - block_start));
1171 }
1172 }
1173
776 size.set(static_cast<uint32_t>(w->position() - start)); 1174 size.set(static_cast<uint32_t>(w->position() - start));
777 return true; 1175 return true;
778 } 1176 }
779 1177
780 private: 1178 private:
781 CodeDescription* desc_; 1179 CodeDescription* desc_;
782 }; 1180 };
783 1181
784 1182
785 class DebugAbbrevSection : public ELFSection { 1183 class DebugAbbrevSection : public SECTION_BASE {
786 public: 1184 public:
787 DebugAbbrevSection() : ELFSection(".debug_abbrev", TYPE_PROGBITS, 1) { } 1185 explicit DebugAbbrevSection(CodeDescription* desc)
1186 #ifdef __ELF
1187 : ELFSection(".debug_abbrev", TYPE_PROGBITS, 1),
1188 #else
1189 : MachOSection("__debug_abbrev", "__DWARF", 1,
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 Argument per line
zarko 2011/06/27 22:24:29 Done.
1190 MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG),
1191 #endif
1192 desc_(desc) { }
788 1193
789 // DWARF2 standard, figure 14. 1194 // DWARF2 standard, figure 14.
790 enum DWARF2Tags { 1195 enum DWARF2Tags {
791 DW_TAG_COMPILE_UNIT = 0x11 1196 DW_TAG_FORMAL_PARAMETER = 0x05,
1197 DW_TAG_POINTER_TYPE = 0xf,
1198 DW_TAG_COMPILE_UNIT = 0x11,
1199 DW_TAG_STRUCTURE_TYPE = 0x13,
1200 DW_TAG_BASE_TYPE = 0x24,
1201 DW_TAG_SUBPROGRAM = 0x2e,
1202 DW_TAG_VARIABLE = 0x34
792 }; 1203 };
793 1204
794 // DWARF2 standard, figure 16. 1205 // DWARF2 standard, figure 16.
795 enum DWARF2ChildrenDetermination { 1206 enum DWARF2ChildrenDetermination {
796 DW_CHILDREN_NO = 0, 1207 DW_CHILDREN_NO = 0,
797 DW_CHILDREN_YES = 1 1208 DW_CHILDREN_YES = 1
798 }; 1209 };
799 1210
800 // DWARF standard, figure 17. 1211 // DWARF standard, figure 17.
801 enum DWARF2Attribute { 1212 enum DWARF2Attribute {
1213 DW_AT_LOCATION = 0x2,
802 DW_AT_NAME = 0x3, 1214 DW_AT_NAME = 0x3,
1215 DW_AT_BYTE_SIZE = 0xb,
803 DW_AT_STMT_LIST = 0x10, 1216 DW_AT_STMT_LIST = 0x10,
804 DW_AT_LOW_PC = 0x11, 1217 DW_AT_LOW_PC = 0x11,
805 DW_AT_HIGH_PC = 0x12 1218 DW_AT_HIGH_PC = 0x12,
1219 DW_AT_ENCODING = 0x3e,
1220 DW_AT_FRAME_BASE = 0x40,
1221 DW_AT_TYPE = 0x49
806 }; 1222 };
807 1223
808 // DWARF2 standard, figure 19. 1224 // DWARF2 standard, figure 19.
809 enum DWARF2AttributeForm { 1225 enum DWARF2AttributeForm {
810 DW_FORM_ADDR = 0x1, 1226 DW_FORM_ADDR = 0x1,
1227 DW_FORM_BLOCK4 = 0x4,
811 DW_FORM_STRING = 0x8, 1228 DW_FORM_STRING = 0x8,
812 DW_FORM_DATA4 = 0x6 1229 DW_FORM_DATA4 = 0x6,
1230 DW_FORM_BLOCK = 0x9,
1231 DW_FORM_DATA1 = 0xb,
1232 DW_FORM_FLAG = 0xc,
1233 DW_FORM_REF4 = 0x13
813 }; 1234 };
814 1235
815 bool WriteBody(Writer* w) { 1236 bool WriteBody(Writer* w) {
1237 bool extra_info = desc_->IsInfoAvailable();
1238 ASSERT(desc_->IsLineInfoAvailable());
816 w->WriteULEB128(1); 1239 w->WriteULEB128(1);
817 w->WriteULEB128(DW_TAG_COMPILE_UNIT); 1240 w->WriteULEB128(DW_TAG_COMPILE_UNIT);
818 w->Write<uint8_t>(DW_CHILDREN_NO); 1241 w->Write<uint8_t>(extra_info ? DW_CHILDREN_YES : DW_CHILDREN_NO);
819 w->WriteULEB128(DW_AT_NAME); 1242 w->WriteULEB128(DW_AT_NAME);
820 w->WriteULEB128(DW_FORM_STRING); 1243 w->WriteULEB128(DW_FORM_STRING);
821 w->WriteULEB128(DW_AT_LOW_PC); 1244 w->WriteULEB128(DW_AT_LOW_PC);
822 w->WriteULEB128(DW_FORM_ADDR); 1245 w->WriteULEB128(DW_FORM_ADDR);
823 w->WriteULEB128(DW_AT_HIGH_PC); 1246 w->WriteULEB128(DW_AT_HIGH_PC);
824 w->WriteULEB128(DW_FORM_ADDR); 1247 w->WriteULEB128(DW_FORM_ADDR);
825 w->WriteULEB128(DW_AT_STMT_LIST); 1248 w->WriteULEB128(DW_AT_STMT_LIST);
826 w->WriteULEB128(DW_FORM_DATA4); 1249 w->WriteULEB128(DW_FORM_DATA4);
827 w->WriteULEB128(0); 1250 w->WriteULEB128(0);
828 w->WriteULEB128(0); 1251 w->WriteULEB128(0);
829 w->WriteULEB128(0); 1252
1253 if (extra_info) {
1254 CompilationInfo* info = desc_->info();
1255 ScopeInfo<FreeStoreAllocationPolicy> scope_info(info->scope());
1256 int params = scope_info.number_of_parameters();
1257 int slots = scope_info.number_of_stack_slots();
1258 int context_slots = scope_info.number_of_context_slots();
1259 // The real slot ID is internal_slots + context_slot_id.
1260 int internal_slots = Context::MIN_CONTEXT_SLOTS;
1261 int locals = scope_info.NumberOfLocals();
1262 int total_children =
1263 params + slots + context_slots + internal_slots + locals + 2;
1264
1265 // The extra duplication below seems to be necessary to keep
1266 // gdb from getting upset on OSX.
1267
1268 w->WriteULEB128(2); // Abbreviation code.
1269 w->WriteULEB128(DW_TAG_SUBPROGRAM);
1270 w->Write<uint8_t>(
1271 total_children != 0 ? DW_CHILDREN_YES : DW_CHILDREN_NO);
1272 w->WriteULEB128(DW_AT_NAME);
1273 w->WriteULEB128(DW_FORM_STRING);
1274 w->WriteULEB128(DW_AT_LOW_PC);
1275 w->WriteULEB128(DW_FORM_ADDR);
1276 w->WriteULEB128(DW_AT_HIGH_PC);
1277 w->WriteULEB128(DW_FORM_ADDR);
1278 w->WriteULEB128(DW_AT_FRAME_BASE);
1279 w->WriteULEB128(DW_FORM_BLOCK4);
1280 w->WriteULEB128(0);
1281 w->WriteULEB128(0);
1282
1283 w->WriteULEB128(3);
1284 w->WriteULEB128(DW_TAG_STRUCTURE_TYPE);
1285 w->Write<uint8_t>(DW_CHILDREN_NO);
1286 w->WriteULEB128(DW_AT_BYTE_SIZE);
1287 w->WriteULEB128(DW_FORM_DATA1);
1288 w->WriteULEB128(DW_AT_NAME);
1289 w->WriteULEB128(DW_FORM_STRING);
1290 w->WriteULEB128(0);
1291 w->WriteULEB128(0);
1292
1293 int current_abbreviation = 4;
Vyacheslav Egorov (Chromium) 2011/06/23 11:28:37 Move it to the beginning of the function and use i
zarko 2011/06/27 22:24:29 Done.
1294 for (int param = 0; param < params; ++param) {
1295 w->WriteULEB128(current_abbreviation++);
1296 w->WriteULEB128(DW_TAG_FORMAL_PARAMETER);
1297 w->Write<uint8_t>(DW_CHILDREN_NO);
1298 w->WriteULEB128(DW_AT_NAME);
1299 w->WriteULEB128(DW_FORM_STRING);
1300 w->WriteULEB128(DW_AT_TYPE);
1301 w->WriteULEB128(DW_FORM_REF4);
1302 w->WriteULEB128(DW_AT_LOCATION);
1303 w->WriteULEB128(DW_FORM_BLOCK4);
1304 w->WriteULEB128(0);
1305 w->WriteULEB128(0);
1306 }
1307
1308 for (int slot = 0; slot < slots; ++slot) {
1309 w->WriteULEB128(current_abbreviation++);
1310 w->WriteULEB128(DW_TAG_VARIABLE);
1311 w->Write<uint8_t>(DW_CHILDREN_NO);
1312 w->WriteULEB128(DW_AT_NAME);
1313 w->WriteULEB128(DW_FORM_STRING);
1314 w->WriteULEB128(0);
1315 w->WriteULEB128(0);
1316 }
1317
1318 for (int context_slot = 0; context_slot < context_slots;
Vyacheslav Egorov (Chromium) 2011/06/23 11:28:37 for(x; y; z)
zarko 2011/06/27 22:24:29 Done.
1319 ++context_slot) {
1320 w->WriteULEB128(current_abbreviation++);
Vyacheslav Egorov (Chromium) 2011/06/23 11:28:37 Seems to be duplicated. Extract to a method?
1321 w->WriteULEB128(DW_TAG_VARIABLE);
1322 w->Write<uint8_t>(DW_CHILDREN_NO);
1323 w->WriteULEB128(DW_AT_NAME);
1324 w->WriteULEB128(DW_FORM_STRING);
1325 w->WriteULEB128(0);
1326 w->WriteULEB128(0);
1327 }
1328
1329 for (int internal_slot = 0; internal_slot < internal_slots;
Vyacheslav Egorov (Chromium) 2011/06/23 11:28:37 for(x; y; z)
zarko 2011/06/27 22:24:29 Done.
1330 ++internal_slot) {
1331 w->WriteULEB128(current_abbreviation++);
Vyacheslav Egorov (Chromium) 2011/06/23 11:28:37 Seems to be duplicated. Extract to a method? Mayb
1332 w->WriteULEB128(DW_TAG_VARIABLE);
1333 w->Write<uint8_t>(DW_CHILDREN_NO);
1334 w->WriteULEB128(DW_AT_NAME);
1335 w->WriteULEB128(DW_FORM_STRING);
1336 w->WriteULEB128(0);
1337 w->WriteULEB128(0);
1338 }
1339
1340 for (int local = 0; local < locals; ++local) {
1341 w->WriteULEB128(current_abbreviation++);
Vyacheslav Egorov (Chromium) 2011/06/23 11:28:37 Partially duplicated. If possible try to unify wit
1342 w->WriteULEB128(DW_TAG_VARIABLE);
1343 w->Write<uint8_t>(DW_CHILDREN_NO);
1344 w->WriteULEB128(DW_AT_NAME);
1345 w->WriteULEB128(DW_FORM_STRING);
1346 w->WriteULEB128(DW_AT_TYPE);
1347 w->WriteULEB128(DW_FORM_REF4);
1348 w->WriteULEB128(DW_AT_LOCATION);
1349 w->WriteULEB128(DW_FORM_BLOCK4);
1350 w->WriteULEB128(0);
1351 w->WriteULEB128(0);
1352 }
1353
1354 // The function.
1355 w->WriteULEB128(current_abbreviation++);
1356 w->WriteULEB128(DW_TAG_VARIABLE);
1357 w->Write<uint8_t>(DW_CHILDREN_NO);
1358 w->WriteULEB128(DW_AT_NAME);
1359 w->WriteULEB128(DW_FORM_STRING);
1360 w->WriteULEB128(DW_AT_TYPE);
1361 w->WriteULEB128(DW_FORM_REF4);
1362 w->WriteULEB128(DW_AT_LOCATION);
1363 w->WriteULEB128(DW_FORM_BLOCK4);
1364 w->WriteULEB128(0);
1365 w->WriteULEB128(0);
1366
1367 // The context.
1368 w->WriteULEB128(current_abbreviation++);
Vyacheslav Egorov (Chromium) 2011/06/23 11:28:37 Duplicated?
1369 w->WriteULEB128(DW_TAG_VARIABLE);
1370 w->Write<uint8_t>(DW_CHILDREN_NO);
1371 w->WriteULEB128(DW_AT_NAME);
1372 w->WriteULEB128(DW_FORM_STRING);
1373 w->WriteULEB128(DW_AT_TYPE);
1374 w->WriteULEB128(DW_FORM_REF4);
1375 w->WriteULEB128(DW_AT_LOCATION);
1376 w->WriteULEB128(DW_FORM_BLOCK4);
1377 w->WriteULEB128(0);
1378 w->WriteULEB128(0);
1379
1380 if (total_children != 0) {
1381 w->WriteULEB128(0); // Terminate the sibling list.
1382 }
1383 }
1384
1385 w->WriteULEB128(0); // Terminate the table.
830 return true; 1386 return true;
831 } 1387 }
1388
1389 private:
1390 CodeDescription* desc_;
832 }; 1391 };
833 1392
834 1393
835 class DebugLineSection : public ELFSection { 1394 class DebugLineSection : public SECTION_BASE {
836 public: 1395 public:
837 explicit DebugLineSection(CodeDescription* desc) 1396 explicit DebugLineSection(CodeDescription* desc)
1397 #ifdef __ELF
838 : ELFSection(".debug_line", TYPE_PROGBITS, 1), 1398 : ELFSection(".debug_line", TYPE_PROGBITS, 1),
1399 #else
1400 : MachOSection("__debug_line", "__DWARF", 1,
1401 MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG),
1402 #endif
839 desc_(desc) { } 1403 desc_(desc) { }
840 1404
841 // DWARF2 standard, figure 34. 1405 // DWARF2 standard, figure 34.
842 enum DWARF2Opcodes { 1406 enum DWARF2Opcodes {
843 DW_LNS_COPY = 1, 1407 DW_LNS_COPY = 1,
844 DW_LNS_ADVANCE_PC = 2, 1408 DW_LNS_ADVANCE_PC = 2,
845 DW_LNS_ADVANCE_LINE = 3, 1409 DW_LNS_ADVANCE_LINE = 3,
846 DW_LNS_SET_FILE = 4, 1410 DW_LNS_SET_FILE = 4,
847 DW_LNS_SET_COLUMN = 5, 1411 DW_LNS_SET_COLUMN = 5,
848 DW_LNS_NEGATE_STMT = 6 1412 DW_LNS_NEGATE_STMT = 6
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 return -1; 1549 return -1;
986 } 1550 }
987 } 1551 }
988 1552
989 CodeDescription* desc_; 1553 CodeDescription* desc_;
990 }; 1554 };
991 1555
992 1556
993 #ifdef V8_TARGET_ARCH_X64 1557 #ifdef V8_TARGET_ARCH_X64
994 1558
995 1559 class UnwindInfoSection : public SECTION_BASE {
996 class UnwindInfoSection : public ELFSection {
997 public: 1560 public:
998 explicit UnwindInfoSection(CodeDescription *desc); 1561 explicit UnwindInfoSection(CodeDescription *desc);
999 virtual bool WriteBody(Writer *w); 1562 virtual bool WriteBody(Writer *w);
1000 1563
1001 int WriteCIE(Writer *w); 1564 int WriteCIE(Writer *w);
1002 void WriteFDE(Writer *w, int); 1565 void WriteFDE(Writer *w, int);
1003 1566
1004 void WriteFDEStateOnEntry(Writer *w); 1567 void WriteFDEStateOnEntry(Writer *w);
1005 void WriteFDEStateAfterRBPPush(Writer *w); 1568 void WriteFDEStateAfterRBPPush(Writer *w);
1006 void WriteFDEStateAfterRBPSet(Writer *w); 1569 void WriteFDEStateAfterRBPSet(Writer *w);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1072 w->Write<uint8_t>(DW_CFA_NOP); 1635 w->Write<uint8_t>(DW_CFA_NOP);
1073 } 1636 }
1074 } 1637 }
1075 1638
1076 ASSERT((w->position() - initial_position) % kPointerSize == 0); 1639 ASSERT((w->position() - initial_position) % kPointerSize == 0);
1077 length_slot->set(w->position() - initial_position); 1640 length_slot->set(w->position() - initial_position);
1078 } 1641 }
1079 1642
1080 1643
1081 UnwindInfoSection::UnwindInfoSection(CodeDescription *desc) 1644 UnwindInfoSection::UnwindInfoSection(CodeDescription *desc)
1082 : ELFSection(".eh_frame", TYPE_X86_64_UNWIND, 1), desc_(desc) 1645 #ifdef __ELF
1083 { } 1646 : ELFSection(".eh_frame", TYPE_X86_64_UNWIND, 1),
1647 #else
1648 : MachOSection("__eh_frame", "__TEXT", sizeof(uintptr_t),
1649 MachOSection::S_REGULAR),
1650 #endif
1651 desc_(desc) { }
1084 1652
1085 int UnwindInfoSection::WriteCIE(Writer *w) { 1653 int UnwindInfoSection::WriteCIE(Writer *w) {
1086 Writer::Slot<uint32_t> cie_length_slot = w->CreateSlotHere<uint32_t>(); 1654 Writer::Slot<uint32_t> cie_length_slot = w->CreateSlotHere<uint32_t>();
1087 uint32_t cie_position = w->position(); 1655 uint32_t cie_position = w->position();
1088 1656
1089 // Write out the CIE header. Currently no 'common instructions' are 1657 // Write out the CIE header. Currently no 'common instructions' are
1090 // emitted onto the CIE; every FDE has its own set of instructions. 1658 // emitted onto the CIE; every FDE has its own set of instructions.
1091 1659
1092 w->Write<uint32_t>(CIE_ID); 1660 w->Write<uint32_t>(CIE_ID);
1093 w->Write<uint8_t>(CIE_VERSION); 1661 w->Write<uint8_t>(CIE_VERSION);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1205 1773
1206 bool UnwindInfoSection::WriteBody(Writer *w) { 1774 bool UnwindInfoSection::WriteBody(Writer *w) {
1207 uint32_t cie_position = WriteCIE(w); 1775 uint32_t cie_position = WriteCIE(w);
1208 WriteFDE(w, cie_position); 1776 WriteFDE(w, cie_position);
1209 return true; 1777 return true;
1210 } 1778 }
1211 1779
1212 1780
1213 #endif // V8_TARGET_ARCH_X64 1781 #endif // V8_TARGET_ARCH_X64
1214 1782
1215 1783 static void CreateDWARFSections(CodeDescription* desc, OBJ_FORMAT* obj) {
1216 static void CreateDWARFSections(CodeDescription* desc, ELF* elf) {
1217 if (desc->IsLineInfoAvailable()) { 1784 if (desc->IsLineInfoAvailable()) {
1218 elf->AddSection(new DebugInfoSection(desc)); 1785 obj->AddSection(new DebugInfoSection(desc));
1219 elf->AddSection(new DebugAbbrevSection); 1786 obj->AddSection(new DebugAbbrevSection(desc));
1220 elf->AddSection(new DebugLineSection(desc)); 1787 obj->AddSection(new DebugLineSection(desc));
1221 } 1788 }
1222 #ifdef V8_TARGET_ARCH_X64 1789 #ifdef V8_TARGET_ARCH_X64
1223 elf->AddSection(new UnwindInfoSection(desc)); 1790 obj->AddSection(new UnwindInfoSection(desc));
1224 #endif 1791 #endif
1225 } 1792 }
1226 1793
1227 1794
1228 // ------------------------------------------------------------------- 1795 // -------------------------------------------------------------------
1229 // Binary GDB JIT Interface as described in 1796 // Binary GDB JIT Interface as described in
1230 // http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html 1797 // http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html
1231 extern "C" { 1798 extern "C" {
1232 typedef enum { 1799 typedef enum {
1233 JIT_NOACTION = 0, 1800 JIT_NOACTION = 0,
(...skipping 19 matching lines...) Expand all
1253 // To prevent GCC from inlining or removing it we place noinline attribute 1820 // To prevent GCC from inlining or removing it we place noinline attribute
1254 // and inline assembler statement inside. 1821 // and inline assembler statement inside.
1255 void __attribute__((noinline)) __jit_debug_register_code() { 1822 void __attribute__((noinline)) __jit_debug_register_code() {
1256 __asm__(""); 1823 __asm__("");
1257 } 1824 }
1258 1825
1259 // GDB will inspect contents of this descriptor. 1826 // GDB will inspect contents of this descriptor.
1260 // Static initialization is necessary to prevent GDB from seeing 1827 // Static initialization is necessary to prevent GDB from seeing
1261 // uninitialized descriptor. 1828 // uninitialized descriptor.
1262 JITDescriptor __jit_debug_descriptor = { 1, 0, 0, 0 }; 1829 JITDescriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
1830
1831 #ifdef OBJECT_PRINT
1832 void __gdb_print_v8_object(MaybeObject* object) {
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 Frankly speaking I don't see any reason to add thi
zarko 2011/06/27 22:24:29 gdb was having some trouble finding the symbol for
1833 object->Print();
1834 fprintf(stdout, "\n");
1835 }
1836 #endif
1263 } 1837 }
1264 1838
1265 1839
1266 static JITCodeEntry* CreateCodeEntry(Address symfile_addr, 1840 static JITCodeEntry* CreateCodeEntry(Address symfile_addr,
1267 uintptr_t symfile_size) { 1841 uintptr_t symfile_size) {
1268 JITCodeEntry* entry = static_cast<JITCodeEntry*>( 1842 JITCodeEntry* entry = static_cast<JITCodeEntry*>(
1269 malloc(sizeof(JITCodeEntry) + symfile_size)); 1843 malloc(sizeof(JITCodeEntry) + symfile_size));
1270 1844
1271 entry->symfile_addr_ = reinterpret_cast<Address>(entry + 1); 1845 entry->symfile_addr_ = reinterpret_cast<Address>(entry + 1);
1272 entry->symfile_size_ = symfile_size; 1846 entry->symfile_size_ = symfile_size;
1273 memcpy(entry->symfile_addr_, symfile_addr, symfile_size); 1847 memcpy(entry->symfile_addr_, symfile_addr, symfile_size);
1274 1848
1275 entry->prev_ = entry->next_ = NULL; 1849 entry->prev_ = entry->next_ = NULL;
1276 1850
1277 return entry; 1851 return entry;
1278 } 1852 }
1279 1853
1280 1854
1281 static void DestroyCodeEntry(JITCodeEntry* entry) { 1855 static void DestroyCodeEntry(JITCodeEntry* entry) {
1282 free(entry); 1856 free(entry);
1283 } 1857 }
1284 1858
1285 1859
1286 static void RegisterCodeEntry(JITCodeEntry* entry) { 1860 static void RegisterCodeEntry(JITCodeEntry* entry,
1861 bool dump_if_enabled,
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 something with indentation.
zarko 2011/06/27 22:24:29 Done.
1862 const char* name_hint) {
1287 #if defined(DEBUG) && !defined(WIN32) 1863 #if defined(DEBUG) && !defined(WIN32)
1288 static int file_num = 0; 1864 static int file_num = 0;
1289 if (FLAG_gdbjit_dump) { 1865 if (FLAG_gdbjit_dump && dump_if_enabled) {
1290 static const int kMaxFileNameSize = 64; 1866 static const int kMaxFileNameSize = 64;
1291 static const char* kElfFilePrefix = "/tmp/elfdump"; 1867 static const char* kElfFilePrefix = "/tmp/elfdump";
1292 static const char* kObjFileExt = ".o"; 1868 static const char* kObjFileExt = ".o";
1293 char file_name[64]; 1869 char file_name[64];
1294 1870
1295 OS::SNPrintF(Vector<char>(file_name, kMaxFileNameSize), "%s%d%s", 1871 OS::SNPrintF(Vector<char>(file_name, kMaxFileNameSize), "%s%s%d%s",
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 One argument per line. (somehow I missed this pla
zarko 2011/06/27 22:24:29 Done.
1296 kElfFilePrefix, file_num++, kObjFileExt); 1872 kElfFilePrefix, (name_hint != NULL) ? name_hint : "",
1873 file_num++, kObjFileExt);
1297 WriteBytes(file_name, entry->symfile_addr_, entry->symfile_size_); 1874 WriteBytes(file_name, entry->symfile_addr_, entry->symfile_size_);
1298 } 1875 }
1299 #endif 1876 #endif
1300 1877
1301 entry->next_ = __jit_debug_descriptor.first_entry_; 1878 entry->next_ = __jit_debug_descriptor.first_entry_;
1302 if (entry->next_ != NULL) entry->next_->prev_ = entry; 1879 if (entry->next_ != NULL) entry->next_->prev_ = entry;
1303 __jit_debug_descriptor.first_entry_ = 1880 __jit_debug_descriptor.first_entry_ =
1304 __jit_debug_descriptor.relevant_entry_ = entry; 1881 __jit_debug_descriptor.relevant_entry_ = entry;
1305 1882
1306 __jit_debug_descriptor.action_flag_ = JIT_REGISTER_FN; 1883 __jit_debug_descriptor.action_flag_ = JIT_REGISTER_FN;
(...skipping 13 matching lines...) Expand all
1320 } 1897 }
1321 1898
1322 __jit_debug_descriptor.relevant_entry_ = entry; 1899 __jit_debug_descriptor.relevant_entry_ = entry;
1323 __jit_debug_descriptor.action_flag_ = JIT_UNREGISTER_FN; 1900 __jit_debug_descriptor.action_flag_ = JIT_UNREGISTER_FN;
1324 __jit_debug_register_code(); 1901 __jit_debug_register_code();
1325 } 1902 }
1326 1903
1327 1904
1328 static JITCodeEntry* CreateELFObject(CodeDescription* desc) { 1905 static JITCodeEntry* CreateELFObject(CodeDescription* desc) {
1329 ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT); 1906 ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
1907 #ifdef __MACH_O
1908 MachO mach_o;
1909 Writer w(&mach_o);
1330 1910
1911 mach_o.AddSection(new MachOTextSection(kCodeAlignment,
1912 desc->CodeStart(),
1913 desc->CodeSize()));
1914
1915 CreateDWARFSections(desc, &mach_o);
1916
1917 mach_o.Write(&w, desc->CodeStart(), desc->CodeSize());
1918 #else
1331 ELF elf; 1919 ELF elf;
1332 Writer w(&elf); 1920 Writer w(&elf);
1333 1921
1334 int text_section_index = elf.AddSection( 1922 int text_section_index = elf.AddSection(
1335 new FullHeaderELFSection(".text", 1923 new FullHeaderELFSection(".text",
1336 ELFSection::TYPE_NOBITS, 1924 ELFSection::TYPE_NOBITS,
1337 kCodeAlignment, 1925 kCodeAlignment,
1338 desc->CodeStart(), 1926 desc->CodeStart(),
1339 0, 1927 0,
1340 desc->CodeSize(), 1928 desc->CodeSize(),
1341 ELFSection::FLAG_ALLOC | ELFSection::FLAG_EXEC)); 1929 ELFSection::FLAG_ALLOC | ELFSection::FLAG_EXEC));
1342 1930
1343 CreateSymbolsTable(desc, &elf, text_section_index); 1931 CreateSymbolsTable(desc, &elf, text_section_index);
1344 1932
1345 CreateDWARFSections(desc, &elf); 1933 CreateDWARFSections(desc, &elf);
1346 1934
1347 elf.Write(&w); 1935 elf.Write(&w);
1936 #endif
1348 1937
1349 return CreateCodeEntry(w.buffer(), w.position()); 1938 return CreateCodeEntry(w.buffer(), w.position());
1350 } 1939 }
1351 1940
1352 1941
1353 static bool SameCodeObjects(void* key1, void* key2) { 1942 static bool SameCodeObjects(void* key1, void* key2) {
1354 return key1 == key2; 1943 return key1 == key2;
1355 } 1944 }
1356 1945
1357 1946
(...skipping 28 matching lines...) Expand all
1386 1975
1387 1976
1388 static GDBJITLineInfo* UntagLineInfo(void* ptr) { 1977 static GDBJITLineInfo* UntagLineInfo(void* ptr) {
1389 return reinterpret_cast<GDBJITLineInfo*>( 1978 return reinterpret_cast<GDBJITLineInfo*>(
1390 reinterpret_cast<intptr_t>(ptr) & ~kLineInfoTag); 1979 reinterpret_cast<intptr_t>(ptr) & ~kLineInfoTag);
1391 } 1980 }
1392 1981
1393 1982
1394 void GDBJITInterface::AddCode(Handle<String> name, 1983 void GDBJITInterface::AddCode(Handle<String> name,
1395 Handle<Script> script, 1984 Handle<Script> script,
1396 Handle<Code> code) { 1985 Handle<Code> code,
1986 CompilationInfo* info) {
1397 if (!FLAG_gdbjit) return; 1987 if (!FLAG_gdbjit) return;
1398 1988
1399 // Force initialization of line_ends array. 1989 // Force initialization of line_ends array.
1400 GetScriptLineNumber(script, 0); 1990 GetScriptLineNumber(script, 0);
1401 1991
1402 if (!name.is_null()) { 1992 if (!name.is_null()) {
1403 SmartPointer<char> name_cstring = name->ToCString(DISALLOW_NULLS); 1993 SmartPointer<char> name_cstring = name->ToCString(DISALLOW_NULLS);
1404 AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script); 1994 AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script, info);
1405 } else { 1995 } else {
1406 AddCode("", *code, GDBJITInterface::FUNCTION, *script); 1996 AddCode("", *code, GDBJITInterface::FUNCTION, *script, info);
1407 } 1997 }
1408 } 1998 }
1409 1999
1410 static void AddUnwindInfo(CodeDescription *desc) { 2000 static void AddUnwindInfo(CodeDescription *desc) {
1411 #ifdef V8_TARGET_ARCH_X64 2001 #ifdef V8_TARGET_ARCH_X64
1412 if (desc->tag() == GDBJITInterface::FUNCTION) { 2002 if (desc->tag() == GDBJITInterface::FUNCTION) {
1413 // To avoid propagating unwinding information through 2003 // To avoid propagating unwinding information through
1414 // compilation pipeline we use an approximation. 2004 // compilation pipeline we use an approximation.
1415 // For most use cases this should not affect usability. 2005 // For most use cases this should not affect usability.
1416 static const int kFramePointerPushOffset = 1; 2006 static const int kFramePointerPushOffset = 1;
(...skipping 26 matching lines...) Expand all
1443 #endif // V8_TARGET_ARCH_X64 2033 #endif // V8_TARGET_ARCH_X64
1444 } 2034 }
1445 2035
1446 2036
1447 Mutex* GDBJITInterface::mutex_ = OS::CreateMutex(); 2037 Mutex* GDBJITInterface::mutex_ = OS::CreateMutex();
1448 2038
1449 2039
1450 void GDBJITInterface::AddCode(const char* name, 2040 void GDBJITInterface::AddCode(const char* name,
1451 Code* code, 2041 Code* code,
1452 GDBJITInterface::CodeTag tag, 2042 GDBJITInterface::CodeTag tag,
1453 Script* script) { 2043 Script* script,
2044 CompilationInfo* info) {
1454 if (!FLAG_gdbjit) return; 2045 if (!FLAG_gdbjit) return;
1455 2046
1456 ScopedLock lock(mutex_); 2047 ScopedLock lock(mutex_);
1457 AssertNoAllocation no_gc; 2048 AssertNoAllocation no_gc;
1458 2049
1459 HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true); 2050 HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true);
1460 if (e->value != NULL && !IsLineInfoTagged(e->value)) return; 2051 if (e->value != NULL && !IsLineInfoTagged(e->value)) return;
1461 2052
1462 GDBJITLineInfo* lineinfo = UntagLineInfo(e->value); 2053 GDBJITLineInfo* lineinfo = UntagLineInfo(e->value);
1463 CodeDescription code_desc(name, 2054 CodeDescription code_desc(name,
1464 code, 2055 code,
1465 script != NULL ? Handle<Script>(script) 2056 script != NULL ? Handle<Script>(script)
1466 : Handle<Script>(), 2057 : Handle<Script>(),
1467 lineinfo, 2058 lineinfo,
1468 tag); 2059 tag,
2060 info);
1469 2061
1470 if (!FLAG_gdbjit_full && !code_desc.IsLineInfoAvailable()) { 2062 if (!FLAG_gdbjit_full && !code_desc.IsLineInfoAvailable()) {
1471 delete lineinfo; 2063 delete lineinfo;
1472 GetEntries()->Remove(code, HashForCodeObject(code)); 2064 GetEntries()->Remove(code, HashForCodeObject(code));
1473 return; 2065 return;
1474 } 2066 }
1475 2067
1476 AddUnwindInfo(&code_desc); 2068 AddUnwindInfo(&code_desc);
1477 JITCodeEntry* entry = CreateELFObject(&code_desc); 2069 JITCodeEntry* entry = CreateELFObject(&code_desc);
1478 ASSERT(!IsLineInfoTagged(entry)); 2070 ASSERT(!IsLineInfoTagged(entry));
1479 2071
1480 delete lineinfo; 2072 delete lineinfo;
1481 e->value = entry; 2073 e->value = entry;
1482 2074
1483 RegisterCodeEntry(entry); 2075 const char* name_hint = NULL;
2076 bool should_dump = false;
2077 if (FLAG_gdbjit_dump) {
2078 if (strlen(FLAG_gdbjit_dump_filter) == 0) {
2079 name_hint = name;
2080 should_dump = true;
2081 } else if (name != NULL) {
2082 name_hint = strstr(name, FLAG_gdbjit_dump_filter);
2083 should_dump = (name_hint != NULL);
2084 }
2085 }
2086 RegisterCodeEntry(entry, should_dump, name_hint);
1484 } 2087 }
1485 2088
1486 2089
1487 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag, 2090 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag,
1488 const char* name, 2091 const char* name,
1489 Code* code) { 2092 Code* code) {
1490 if (!FLAG_gdbjit) return; 2093 if (!FLAG_gdbjit) return;
1491 2094
1492 EmbeddedVector<char, 256> buffer; 2095 EmbeddedVector<char, 256> buffer;
1493 StringBuilder builder(buffer.start(), buffer.length()); 2096 StringBuilder builder(buffer.start(), buffer.length());
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1545 ScopedLock lock(mutex_); 2148 ScopedLock lock(mutex_);
1546 ASSERT(!IsLineInfoTagged(line_info)); 2149 ASSERT(!IsLineInfoTagged(line_info));
1547 HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true); 2150 HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true);
1548 ASSERT(e->value == NULL); 2151 ASSERT(e->value == NULL);
1549 e->value = TagLineInfo(line_info); 2152 e->value = TagLineInfo(line_info);
1550 } 2153 }
1551 2154
1552 2155
1553 } } // namespace v8::internal 2156 } } // namespace v8::internal
1554 #endif 2157 #endif
OLDNEW
« src/gdb-jit.h ('K') | « src/gdb-jit.h ('k') | tools/gdb-v8-support.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698