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

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