Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / v8 / src / gdb-jit.cc
1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifdef ENABLE_GDB_JIT_INTERFACE
6 #include "src/v8.h"
7
8 #include "src/base/platform/platform.h"
9 #include "src/bootstrapper.h"
10 #include "src/compiler.h"
11 #include "src/frames-inl.h"
12 #include "src/frames.h"
13 #include "src/gdb-jit.h"
14 #include "src/global-handles.h"
15 #include "src/messages.h"
16 #include "src/natives.h"
17 #include "src/ostreams.h"
18 #include "src/scopes.h"
19
20 namespace v8 {
21 namespace internal {
22
23 #ifdef __APPLE__
24 #define __MACH_O
25 class MachO;
26 class MachOSection;
27 typedef MachO DebugObject;
28 typedef MachOSection DebugSection;
29 #else
30 #define __ELF
31 class ELF;
32 class ELFSection;
33 typedef ELF DebugObject;
34 typedef ELFSection DebugSection;
35 #endif
36
37 class Writer BASE_EMBEDDED {
38  public:
39   explicit Writer(DebugObject* debug_object)
40       : debug_object_(debug_object),
41         position_(0),
42         capacity_(1024),
43         buffer_(reinterpret_cast<byte*>(malloc(capacity_))) {
44   }
45
46   ~Writer() {
47     free(buffer_);
48   }
49
50   uintptr_t position() const {
51     return position_;
52   }
53
54   template<typename T>
55   class Slot {
56    public:
57     Slot(Writer* w, uintptr_t offset) : w_(w), offset_(offset) { }
58
59     T* operator-> () {
60       return w_->RawSlotAt<T>(offset_);
61     }
62
63     void set(const T& value) {
64       *w_->RawSlotAt<T>(offset_) = value;
65     }
66
67     Slot<T> at(int i) {
68       return Slot<T>(w_, offset_ + sizeof(T) * i);
69     }
70
71    private:
72     Writer* w_;
73     uintptr_t offset_;
74   };
75
76   template<typename T>
77   void Write(const T& val) {
78     Ensure(position_ + sizeof(T));
79     *RawSlotAt<T>(position_) = val;
80     position_ += sizeof(T);
81   }
82
83   template<typename T>
84   Slot<T> SlotAt(uintptr_t offset) {
85     Ensure(offset + sizeof(T));
86     return Slot<T>(this, offset);
87   }
88
89   template<typename T>
90   Slot<T> CreateSlotHere() {
91     return CreateSlotsHere<T>(1);
92   }
93
94   template<typename T>
95   Slot<T> CreateSlotsHere(uint32_t count) {
96     uintptr_t slot_position = position_;
97     position_ += sizeof(T) * count;
98     Ensure(position_);
99     return SlotAt<T>(slot_position);
100   }
101
102   void Ensure(uintptr_t pos) {
103     if (capacity_ < pos) {
104       while (capacity_ < pos) capacity_ *= 2;
105       buffer_ = reinterpret_cast<byte*>(realloc(buffer_, capacity_));
106     }
107   }
108
109   DebugObject* debug_object() { return debug_object_; }
110
111   byte* buffer() { return buffer_; }
112
113   void Align(uintptr_t align) {
114     uintptr_t delta = position_ % align;
115     if (delta == 0) return;
116     uintptr_t padding = align - delta;
117     Ensure(position_ += padding);
118     DCHECK((position_ % align) == 0);
119   }
120
121   void WriteULEB128(uintptr_t value) {
122     do {
123       uint8_t byte = value & 0x7F;
124       value >>= 7;
125       if (value != 0) byte |= 0x80;
126       Write<uint8_t>(byte);
127     } while (value != 0);
128   }
129
130   void WriteSLEB128(intptr_t value) {
131     bool more = true;
132     while (more) {
133       int8_t byte = value & 0x7F;
134       bool byte_sign = byte & 0x40;
135       value >>= 7;
136
137       if ((value == 0 && !byte_sign) || (value == -1 && byte_sign)) {
138         more = false;
139       } else {
140         byte |= 0x80;
141       }
142
143       Write<int8_t>(byte);
144     }
145   }
146
147   void WriteString(const char* str) {
148     do {
149       Write<char>(*str);
150     } while (*str++);
151   }
152
153  private:
154   template<typename T> friend class Slot;
155
156   template<typename T>
157   T* RawSlotAt(uintptr_t offset) {
158     DCHECK(offset < capacity_ && offset + sizeof(T) <= capacity_);
159     return reinterpret_cast<T*>(&buffer_[offset]);
160   }
161
162   DebugObject* debug_object_;
163   uintptr_t position_;
164   uintptr_t capacity_;
165   byte* buffer_;
166 };
167
168 class ELFStringTable;
169
170 template<typename THeader>
171 class DebugSectionBase : public ZoneObject {
172  public:
173   virtual ~DebugSectionBase() { }
174
175   virtual void WriteBody(Writer::Slot<THeader> header, Writer* writer) {
176     uintptr_t start = writer->position();
177     if (WriteBodyInternal(writer)) {
178       uintptr_t end = writer->position();
179       header->offset = start;
180 #if defined(__MACH_O)
181       header->addr = 0;
182 #endif
183       header->size = end - start;
184     }
185   }
186
187   virtual bool WriteBodyInternal(Writer* writer) {
188     return false;
189   }
190
191   typedef THeader Header;
192 };
193
194
195 struct MachOSectionHeader {
196   char sectname[16];
197   char segname[16];
198 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87
199   uint32_t addr;
200   uint32_t size;
201 #else
202   uint64_t addr;
203   uint64_t size;
204 #endif
205   uint32_t offset;
206   uint32_t align;
207   uint32_t reloff;
208   uint32_t nreloc;
209   uint32_t flags;
210   uint32_t reserved1;
211   uint32_t reserved2;
212 };
213
214
215 class MachOSection : public DebugSectionBase<MachOSectionHeader> {
216  public:
217   enum Type {
218     S_REGULAR = 0x0u,
219     S_ATTR_COALESCED = 0xbu,
220     S_ATTR_SOME_INSTRUCTIONS = 0x400u,
221     S_ATTR_DEBUG = 0x02000000u,
222     S_ATTR_PURE_INSTRUCTIONS = 0x80000000u
223   };
224
225   MachOSection(const char* name,
226                const char* segment,
227                uintptr_t align,
228                uint32_t flags)
229     : name_(name),
230       segment_(segment),
231       align_(align),
232       flags_(flags) {
233     if (align_ != 0) {
234       DCHECK(IsPowerOf2(align));
235       align_ = WhichPowerOf2(align_);
236     }
237   }
238
239   virtual ~MachOSection() { }
240
241   virtual void PopulateHeader(Writer::Slot<Header> header) {
242     header->addr = 0;
243     header->size = 0;
244     header->offset = 0;
245     header->align = align_;
246     header->reloff = 0;
247     header->nreloc = 0;
248     header->flags = flags_;
249     header->reserved1 = 0;
250     header->reserved2 = 0;
251     memset(header->sectname, 0, sizeof(header->sectname));
252     memset(header->segname, 0, sizeof(header->segname));
253     DCHECK(strlen(name_) < sizeof(header->sectname));
254     DCHECK(strlen(segment_) < sizeof(header->segname));
255     strncpy(header->sectname, name_, sizeof(header->sectname));
256     strncpy(header->segname, segment_, sizeof(header->segname));
257   }
258
259  private:
260   const char* name_;
261   const char* segment_;
262   uintptr_t align_;
263   uint32_t flags_;
264 };
265
266
267 struct ELFSectionHeader {
268   uint32_t name;
269   uint32_t type;
270   uintptr_t flags;
271   uintptr_t address;
272   uintptr_t offset;
273   uintptr_t size;
274   uint32_t link;
275   uint32_t info;
276   uintptr_t alignment;
277   uintptr_t entry_size;
278 };
279
280
281 #if defined(__ELF)
282 class ELFSection : public DebugSectionBase<ELFSectionHeader> {
283  public:
284   enum Type {
285     TYPE_NULL = 0,
286     TYPE_PROGBITS = 1,
287     TYPE_SYMTAB = 2,
288     TYPE_STRTAB = 3,
289     TYPE_RELA = 4,
290     TYPE_HASH = 5,
291     TYPE_DYNAMIC = 6,
292     TYPE_NOTE = 7,
293     TYPE_NOBITS = 8,
294     TYPE_REL = 9,
295     TYPE_SHLIB = 10,
296     TYPE_DYNSYM = 11,
297     TYPE_LOPROC = 0x70000000,
298     TYPE_X86_64_UNWIND = 0x70000001,
299     TYPE_HIPROC = 0x7fffffff,
300     TYPE_LOUSER = 0x80000000,
301     TYPE_HIUSER = 0xffffffff
302   };
303
304   enum Flags {
305     FLAG_WRITE = 1,
306     FLAG_ALLOC = 2,
307     FLAG_EXEC = 4
308   };
309
310   enum SpecialIndexes {
311     INDEX_ABSOLUTE = 0xfff1
312   };
313
314   ELFSection(const char* name, Type type, uintptr_t align)
315       : name_(name), type_(type), align_(align) { }
316
317   virtual ~ELFSection() { }
318
319   void PopulateHeader(Writer::Slot<Header> header, ELFStringTable* strtab);
320
321   virtual void WriteBody(Writer::Slot<Header> header, Writer* w) {
322     uintptr_t start = w->position();
323     if (WriteBodyInternal(w)) {
324       uintptr_t end = w->position();
325       header->offset = start;
326       header->size = end - start;
327     }
328   }
329
330   virtual bool WriteBodyInternal(Writer* w) {
331     return false;
332   }
333
334   uint16_t index() const { return index_; }
335   void set_index(uint16_t index) { index_ = index; }
336
337  protected:
338   virtual void PopulateHeader(Writer::Slot<Header> header) {
339     header->flags = 0;
340     header->address = 0;
341     header->offset = 0;
342     header->size = 0;
343     header->link = 0;
344     header->info = 0;
345     header->entry_size = 0;
346   }
347
348  private:
349   const char* name_;
350   Type type_;
351   uintptr_t align_;
352   uint16_t index_;
353 };
354 #endif  // defined(__ELF)
355
356
357 #if defined(__MACH_O)
358 class MachOTextSection : public MachOSection {
359  public:
360   MachOTextSection(uintptr_t align,
361                    uintptr_t addr,
362                    uintptr_t size)
363       : MachOSection("__text",
364                      "__TEXT",
365                      align,
366                      MachOSection::S_REGULAR |
367                          MachOSection::S_ATTR_SOME_INSTRUCTIONS |
368                          MachOSection::S_ATTR_PURE_INSTRUCTIONS),
369         addr_(addr),
370         size_(size) { }
371
372  protected:
373   virtual void PopulateHeader(Writer::Slot<Header> header) {
374     MachOSection::PopulateHeader(header);
375     header->addr = addr_;
376     header->size = size_;
377   }
378
379  private:
380   uintptr_t addr_;
381   uintptr_t size_;
382 };
383 #endif  // defined(__MACH_O)
384
385
386 #if defined(__ELF)
387 class FullHeaderELFSection : public ELFSection {
388  public:
389   FullHeaderELFSection(const char* name,
390                        Type type,
391                        uintptr_t align,
392                        uintptr_t addr,
393                        uintptr_t offset,
394                        uintptr_t size,
395                        uintptr_t flags)
396       : ELFSection(name, type, align),
397         addr_(addr),
398         offset_(offset),
399         size_(size),
400         flags_(flags) { }
401
402  protected:
403   virtual void PopulateHeader(Writer::Slot<Header> header) {
404     ELFSection::PopulateHeader(header);
405     header->address = addr_;
406     header->offset = offset_;
407     header->size = size_;
408     header->flags = flags_;
409   }
410
411  private:
412   uintptr_t addr_;
413   uintptr_t offset_;
414   uintptr_t size_;
415   uintptr_t flags_;
416 };
417
418
419 class ELFStringTable : public ELFSection {
420  public:
421   explicit ELFStringTable(const char* name)
422       : ELFSection(name, TYPE_STRTAB, 1), writer_(NULL), offset_(0), size_(0) {
423   }
424
425   uintptr_t Add(const char* str) {
426     if (*str == '\0') return 0;
427
428     uintptr_t offset = size_;
429     WriteString(str);
430     return offset;
431   }
432
433   void AttachWriter(Writer* w) {
434     writer_ = w;
435     offset_ = writer_->position();
436
437     // First entry in the string table should be an empty string.
438     WriteString("");
439   }
440
441   void DetachWriter() {
442     writer_ = NULL;
443   }
444
445   virtual void WriteBody(Writer::Slot<Header> header, Writer* w) {
446     DCHECK(writer_ == NULL);
447     header->offset = offset_;
448     header->size = size_;
449   }
450
451  private:
452   void WriteString(const char* str) {
453     uintptr_t written = 0;
454     do {
455       writer_->Write(*str);
456       written++;
457     } while (*str++);
458     size_ += written;
459   }
460
461   Writer* writer_;
462
463   uintptr_t offset_;
464   uintptr_t size_;
465 };
466
467
468 void ELFSection::PopulateHeader(Writer::Slot<ELFSection::Header> header,
469                                 ELFStringTable* strtab) {
470   header->name = strtab->Add(name_);
471   header->type = type_;
472   header->alignment = align_;
473   PopulateHeader(header);
474 }
475 #endif  // defined(__ELF)
476
477
478 #if defined(__MACH_O)
479 class MachO BASE_EMBEDDED {
480  public:
481   explicit MachO(Zone* zone) : zone_(zone), sections_(6, zone) { }
482
483   uint32_t AddSection(MachOSection* section) {
484     sections_.Add(section, zone_);
485     return sections_.length() - 1;
486   }
487
488   void Write(Writer* w, uintptr_t code_start, uintptr_t code_size) {
489     Writer::Slot<MachOHeader> header = WriteHeader(w);
490     uintptr_t load_command_start = w->position();
491     Writer::Slot<MachOSegmentCommand> cmd = WriteSegmentCommand(w,
492                                                                 code_start,
493                                                                 code_size);
494     WriteSections(w, cmd, header, load_command_start);
495   }
496
497  private:
498   struct MachOHeader {
499     uint32_t magic;
500     uint32_t cputype;
501     uint32_t cpusubtype;
502     uint32_t filetype;
503     uint32_t ncmds;
504     uint32_t sizeofcmds;
505     uint32_t flags;
506 #if V8_TARGET_ARCH_X64
507     uint32_t reserved;
508 #endif
509   };
510
511   struct MachOSegmentCommand {
512     uint32_t cmd;
513     uint32_t cmdsize;
514     char segname[16];
515 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87
516     uint32_t vmaddr;
517     uint32_t vmsize;
518     uint32_t fileoff;
519     uint32_t filesize;
520 #else
521     uint64_t vmaddr;
522     uint64_t vmsize;
523     uint64_t fileoff;
524     uint64_t filesize;
525 #endif
526     uint32_t maxprot;
527     uint32_t initprot;
528     uint32_t nsects;
529     uint32_t flags;
530   };
531
532   enum MachOLoadCommandCmd {
533     LC_SEGMENT_32 = 0x00000001u,
534     LC_SEGMENT_64 = 0x00000019u
535   };
536
537
538   Writer::Slot<MachOHeader> WriteHeader(Writer* w) {
539     DCHECK(w->position() == 0);
540     Writer::Slot<MachOHeader> header = w->CreateSlotHere<MachOHeader>();
541 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87
542     header->magic = 0xFEEDFACEu;
543     header->cputype = 7;  // i386
544     header->cpusubtype = 3;  // CPU_SUBTYPE_I386_ALL
545 #elif V8_TARGET_ARCH_X64
546     header->magic = 0xFEEDFACFu;
547     header->cputype = 7 | 0x01000000;  // i386 | 64-bit ABI
548     header->cpusubtype = 3;  // CPU_SUBTYPE_I386_ALL
549     header->reserved = 0;
550 #else
551 #error Unsupported target architecture.
552 #endif
553     header->filetype = 0x1;  // MH_OBJECT
554     header->ncmds = 1;
555     header->sizeofcmds = 0;
556     header->flags = 0;
557     return header;
558   }
559
560
561   Writer::Slot<MachOSegmentCommand> WriteSegmentCommand(Writer* w,
562                                                         uintptr_t code_start,
563                                                         uintptr_t code_size) {
564     Writer::Slot<MachOSegmentCommand> cmd =
565         w->CreateSlotHere<MachOSegmentCommand>();
566 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87
567     cmd->cmd = LC_SEGMENT_32;
568 #else
569     cmd->cmd = LC_SEGMENT_64;
570 #endif
571     cmd->vmaddr = code_start;
572     cmd->vmsize = code_size;
573     cmd->fileoff = 0;
574     cmd->filesize = 0;
575     cmd->maxprot = 7;
576     cmd->initprot = 7;
577     cmd->flags = 0;
578     cmd->nsects = sections_.length();
579     memset(cmd->segname, 0, 16);
580     cmd->cmdsize = sizeof(MachOSegmentCommand) + sizeof(MachOSection::Header) *
581         cmd->nsects;
582     return cmd;
583   }
584
585
586   void WriteSections(Writer* w,
587                      Writer::Slot<MachOSegmentCommand> cmd,
588                      Writer::Slot<MachOHeader> header,
589                      uintptr_t load_command_start) {
590     Writer::Slot<MachOSection::Header> headers =
591         w->CreateSlotsHere<MachOSection::Header>(sections_.length());
592     cmd->fileoff = w->position();
593     header->sizeofcmds = w->position() - load_command_start;
594     for (int section = 0; section < sections_.length(); ++section) {
595       sections_[section]->PopulateHeader(headers.at(section));
596       sections_[section]->WriteBody(headers.at(section), w);
597     }
598     cmd->filesize = w->position() - (uintptr_t)cmd->fileoff;
599   }
600
601   Zone* zone_;
602   ZoneList<MachOSection*> sections_;
603 };
604 #endif  // defined(__MACH_O)
605
606
607 #if defined(__ELF)
608 class ELF BASE_EMBEDDED {
609  public:
610   explicit ELF(Zone* zone) : zone_(zone), sections_(6, zone) {
611     sections_.Add(new(zone) ELFSection("", ELFSection::TYPE_NULL, 0), zone);
612     sections_.Add(new(zone) ELFStringTable(".shstrtab"), zone);
613   }
614
615   void Write(Writer* w) {
616     WriteHeader(w);
617     WriteSectionTable(w);
618     WriteSections(w);
619   }
620
621   ELFSection* SectionAt(uint32_t index) {
622     return sections_[index];
623   }
624
625   uint32_t AddSection(ELFSection* section) {
626     sections_.Add(section, zone_);
627     section->set_index(sections_.length() - 1);
628     return sections_.length() - 1;
629   }
630
631  private:
632   struct ELFHeader {
633     uint8_t ident[16];
634     uint16_t type;
635     uint16_t machine;
636     uint32_t version;
637     uintptr_t entry;
638     uintptr_t pht_offset;
639     uintptr_t sht_offset;
640     uint32_t flags;
641     uint16_t header_size;
642     uint16_t pht_entry_size;
643     uint16_t pht_entry_num;
644     uint16_t sht_entry_size;
645     uint16_t sht_entry_num;
646     uint16_t sht_strtab_index;
647   };
648
649
650   void WriteHeader(Writer* w) {
651     DCHECK(w->position() == 0);
652     Writer::Slot<ELFHeader> header = w->CreateSlotHere<ELFHeader>();
653 #if (V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X87 || \
654      (V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT))
655     const uint8_t ident[16] =
656         { 0x7f, 'E', 'L', 'F', 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
657 #elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_64_BIT
658     const uint8_t ident[16] =
659         { 0x7f, 'E', 'L', 'F', 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
660 #else
661 #error Unsupported target architecture.
662 #endif
663     memcpy(header->ident, ident, 16);
664     header->type = 1;
665 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87
666     header->machine = 3;
667 #elif V8_TARGET_ARCH_X64
668     // Processor identification value for x64 is 62 as defined in
669     //    System V ABI, AMD64 Supplement
670     //    http://www.x86-64.org/documentation/abi.pdf
671     header->machine = 62;
672 #elif V8_TARGET_ARCH_ARM
673     // Set to EM_ARM, defined as 40, in "ARM ELF File Format" at
674     // infocenter.arm.com/help/topic/com.arm.doc.dui0101a/DUI0101A_Elf.pdf
675     header->machine = 40;
676 #else
677 #error Unsupported target architecture.
678 #endif
679     header->version = 1;
680     header->entry = 0;
681     header->pht_offset = 0;
682     header->sht_offset = sizeof(ELFHeader);  // Section table follows header.
683     header->flags = 0;
684     header->header_size = sizeof(ELFHeader);
685     header->pht_entry_size = 0;
686     header->pht_entry_num = 0;
687     header->sht_entry_size = sizeof(ELFSection::Header);
688     header->sht_entry_num = sections_.length();
689     header->sht_strtab_index = 1;
690   }
691
692   void WriteSectionTable(Writer* w) {
693     // Section headers table immediately follows file header.
694     DCHECK(w->position() == sizeof(ELFHeader));
695
696     Writer::Slot<ELFSection::Header> headers =
697         w->CreateSlotsHere<ELFSection::Header>(sections_.length());
698
699     // String table for section table is the first section.
700     ELFStringTable* strtab = static_cast<ELFStringTable*>(SectionAt(1));
701     strtab->AttachWriter(w);
702     for (int i = 0, length = sections_.length();
703          i < length;
704          i++) {
705       sections_[i]->PopulateHeader(headers.at(i), strtab);
706     }
707     strtab->DetachWriter();
708   }
709
710   int SectionHeaderPosition(uint32_t section_index) {
711     return sizeof(ELFHeader) + sizeof(ELFSection::Header) * section_index;
712   }
713
714   void WriteSections(Writer* w) {
715     Writer::Slot<ELFSection::Header> headers =
716         w->SlotAt<ELFSection::Header>(sizeof(ELFHeader));
717
718     for (int i = 0, length = sections_.length();
719          i < length;
720          i++) {
721       sections_[i]->WriteBody(headers.at(i), w);
722     }
723   }
724
725   Zone* zone_;
726   ZoneList<ELFSection*> sections_;
727 };
728
729
730 class ELFSymbol BASE_EMBEDDED {
731  public:
732   enum Type {
733     TYPE_NOTYPE = 0,
734     TYPE_OBJECT = 1,
735     TYPE_FUNC = 2,
736     TYPE_SECTION = 3,
737     TYPE_FILE = 4,
738     TYPE_LOPROC = 13,
739     TYPE_HIPROC = 15
740   };
741
742   enum Binding {
743     BIND_LOCAL = 0,
744     BIND_GLOBAL = 1,
745     BIND_WEAK = 2,
746     BIND_LOPROC = 13,
747     BIND_HIPROC = 15
748   };
749
750   ELFSymbol(const char* name,
751             uintptr_t value,
752             uintptr_t size,
753             Binding binding,
754             Type type,
755             uint16_t section)
756       : name(name),
757         value(value),
758         size(size),
759         info((binding << 4) | type),
760         other(0),
761         section(section) {
762   }
763
764   Binding binding() const {
765     return static_cast<Binding>(info >> 4);
766   }
767 #if (V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X87 || \
768      (V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT))
769   struct SerializedLayout {
770     SerializedLayout(uint32_t name,
771                      uintptr_t value,
772                      uintptr_t size,
773                      Binding binding,
774                      Type type,
775                      uint16_t section)
776         : name(name),
777           value(value),
778           size(size),
779           info((binding << 4) | type),
780           other(0),
781           section(section) {
782     }
783
784     uint32_t name;
785     uintptr_t value;
786     uintptr_t size;
787     uint8_t info;
788     uint8_t other;
789     uint16_t section;
790   };
791 #elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_64_BIT
792   struct SerializedLayout {
793     SerializedLayout(uint32_t name,
794                      uintptr_t value,
795                      uintptr_t size,
796                      Binding binding,
797                      Type type,
798                      uint16_t section)
799         : name(name),
800           info((binding << 4) | type),
801           other(0),
802           section(section),
803           value(value),
804           size(size) {
805     }
806
807     uint32_t name;
808     uint8_t info;
809     uint8_t other;
810     uint16_t section;
811     uintptr_t value;
812     uintptr_t size;
813   };
814 #endif
815
816   void Write(Writer::Slot<SerializedLayout> s, ELFStringTable* t) {
817     // Convert symbol names from strings to indexes in the string table.
818     s->name = t->Add(name);
819     s->value = value;
820     s->size = size;
821     s->info = info;
822     s->other = other;
823     s->section = section;
824   }
825
826  private:
827   const char* name;
828   uintptr_t value;
829   uintptr_t size;
830   uint8_t info;
831   uint8_t other;
832   uint16_t section;
833 };
834
835
836 class ELFSymbolTable : public ELFSection {
837  public:
838   ELFSymbolTable(const char* name, Zone* zone)
839       : ELFSection(name, TYPE_SYMTAB, sizeof(uintptr_t)),
840         locals_(1, zone),
841         globals_(1, zone) {
842   }
843
844   virtual void WriteBody(Writer::Slot<Header> header, Writer* w) {
845     w->Align(header->alignment);
846     int total_symbols = locals_.length() + globals_.length() + 1;
847     header->offset = w->position();
848
849     Writer::Slot<ELFSymbol::SerializedLayout> symbols =
850         w->CreateSlotsHere<ELFSymbol::SerializedLayout>(total_symbols);
851
852     header->size = w->position() - header->offset;
853
854     // String table for this symbol table should follow it in the section table.
855     ELFStringTable* strtab =
856         static_cast<ELFStringTable*>(w->debug_object()->SectionAt(index() + 1));
857     strtab->AttachWriter(w);
858     symbols.at(0).set(ELFSymbol::SerializedLayout(0,
859                                                   0,
860                                                   0,
861                                                   ELFSymbol::BIND_LOCAL,
862                                                   ELFSymbol::TYPE_NOTYPE,
863                                                   0));
864     WriteSymbolsList(&locals_, symbols.at(1), strtab);
865     WriteSymbolsList(&globals_, symbols.at(locals_.length() + 1), strtab);
866     strtab->DetachWriter();
867   }
868
869   void Add(const ELFSymbol& symbol, Zone* zone) {
870     if (symbol.binding() == ELFSymbol::BIND_LOCAL) {
871       locals_.Add(symbol, zone);
872     } else {
873       globals_.Add(symbol, zone);
874     }
875   }
876
877  protected:
878   virtual void PopulateHeader(Writer::Slot<Header> header) {
879     ELFSection::PopulateHeader(header);
880     // We are assuming that string table will follow symbol table.
881     header->link = index() + 1;
882     header->info = locals_.length() + 1;
883     header->entry_size = sizeof(ELFSymbol::SerializedLayout);
884   }
885
886  private:
887   void WriteSymbolsList(const ZoneList<ELFSymbol>* src,
888                         Writer::Slot<ELFSymbol::SerializedLayout> dst,
889                         ELFStringTable* strtab) {
890     for (int i = 0, len = src->length();
891          i < len;
892          i++) {
893       src->at(i).Write(dst.at(i), strtab);
894     }
895   }
896
897   ZoneList<ELFSymbol> locals_;
898   ZoneList<ELFSymbol> globals_;
899 };
900 #endif  // defined(__ELF)
901
902
903 class LineInfo : public Malloced {
904  public:
905   LineInfo() : pc_info_(10) {}
906
907   void SetPosition(intptr_t pc, int pos, bool is_statement) {
908     AddPCInfo(PCInfo(pc, pos, is_statement));
909   }
910
911   struct PCInfo {
912     PCInfo(intptr_t pc, int pos, bool is_statement)
913         : pc_(pc), pos_(pos), is_statement_(is_statement) {}
914
915     intptr_t pc_;
916     int pos_;
917     bool is_statement_;
918   };
919
920   List<PCInfo>* pc_info() { return &pc_info_; }
921
922  private:
923   void AddPCInfo(const PCInfo& pc_info) { pc_info_.Add(pc_info); }
924
925   List<PCInfo> pc_info_;
926 };
927
928
929 class CodeDescription BASE_EMBEDDED {
930  public:
931 #if V8_TARGET_ARCH_X64
932   enum StackState {
933     POST_RBP_PUSH,
934     POST_RBP_SET,
935     POST_RBP_POP,
936     STACK_STATE_MAX
937   };
938 #endif
939
940   CodeDescription(const char* name, Code* code, Handle<Script> script,
941                   LineInfo* lineinfo, GDBJITInterface::CodeTag tag,
942                   CompilationInfo* info)
943       : name_(name),
944         code_(code),
945         script_(script),
946         lineinfo_(lineinfo),
947         tag_(tag),
948         info_(info) {}
949
950   const char* name() const {
951     return name_;
952   }
953
954   LineInfo* lineinfo() const { return lineinfo_; }
955
956   GDBJITInterface::CodeTag tag() const {
957     return tag_;
958   }
959
960   CompilationInfo* info() const {
961     return info_;
962   }
963
964   bool IsInfoAvailable() const {
965     return info_ != NULL;
966   }
967
968   uintptr_t CodeStart() const {
969     return reinterpret_cast<uintptr_t>(code_->instruction_start());
970   }
971
972   uintptr_t CodeEnd() const {
973     return reinterpret_cast<uintptr_t>(code_->instruction_end());
974   }
975
976   uintptr_t CodeSize() const {
977     return CodeEnd() - CodeStart();
978   }
979
980   bool IsLineInfoAvailable() {
981     return !script_.is_null() &&
982         script_->source()->IsString() &&
983         script_->HasValidSource() &&
984         script_->name()->IsString() &&
985         lineinfo_ != NULL;
986   }
987
988 #if V8_TARGET_ARCH_X64
989   uintptr_t GetStackStateStartAddress(StackState state) const {
990     DCHECK(state < STACK_STATE_MAX);
991     return stack_state_start_addresses_[state];
992   }
993
994   void SetStackStateStartAddress(StackState state, uintptr_t addr) {
995     DCHECK(state < STACK_STATE_MAX);
996     stack_state_start_addresses_[state] = addr;
997   }
998 #endif
999
1000   SmartArrayPointer<char> GetFilename() {
1001     return String::cast(script_->name())->ToCString();
1002   }
1003
1004   int GetScriptLineNumber(int pos) {
1005     return script_->GetLineNumber(pos) + 1;
1006   }
1007
1008
1009  private:
1010   const char* name_;
1011   Code* code_;
1012   Handle<Script> script_;
1013   LineInfo* lineinfo_;
1014   GDBJITInterface::CodeTag tag_;
1015   CompilationInfo* info_;
1016 #if V8_TARGET_ARCH_X64
1017   uintptr_t stack_state_start_addresses_[STACK_STATE_MAX];
1018 #endif
1019 };
1020
1021 #if defined(__ELF)
1022 static void CreateSymbolsTable(CodeDescription* desc,
1023                                Zone* zone,
1024                                ELF* elf,
1025                                int text_section_index) {
1026   ELFSymbolTable* symtab = new(zone) ELFSymbolTable(".symtab", zone);
1027   ELFStringTable* strtab = new(zone) ELFStringTable(".strtab");
1028
1029   // Symbol table should be followed by the linked string table.
1030   elf->AddSection(symtab);
1031   elf->AddSection(strtab);
1032
1033   symtab->Add(ELFSymbol("V8 Code",
1034                         0,
1035                         0,
1036                         ELFSymbol::BIND_LOCAL,
1037                         ELFSymbol::TYPE_FILE,
1038                         ELFSection::INDEX_ABSOLUTE),
1039               zone);
1040
1041   symtab->Add(ELFSymbol(desc->name(),
1042                         0,
1043                         desc->CodeSize(),
1044                         ELFSymbol::BIND_GLOBAL,
1045                         ELFSymbol::TYPE_FUNC,
1046                         text_section_index),
1047               zone);
1048 }
1049 #endif  // defined(__ELF)
1050
1051
1052 class DebugInfoSection : public DebugSection {
1053  public:
1054   explicit DebugInfoSection(CodeDescription* desc)
1055 #if defined(__ELF)
1056       : ELFSection(".debug_info", TYPE_PROGBITS, 1),
1057 #else
1058       : MachOSection("__debug_info",
1059                      "__DWARF",
1060                      1,
1061                      MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG),
1062 #endif
1063         desc_(desc) { }
1064
1065   // DWARF2 standard
1066   enum DWARF2LocationOp {
1067     DW_OP_reg0 = 0x50,
1068     DW_OP_reg1 = 0x51,
1069     DW_OP_reg2 = 0x52,
1070     DW_OP_reg3 = 0x53,
1071     DW_OP_reg4 = 0x54,
1072     DW_OP_reg5 = 0x55,
1073     DW_OP_reg6 = 0x56,
1074     DW_OP_reg7 = 0x57,
1075     DW_OP_fbreg = 0x91  // 1 param: SLEB128 offset
1076   };
1077
1078   enum DWARF2Encoding {
1079     DW_ATE_ADDRESS = 0x1,
1080     DW_ATE_SIGNED = 0x5
1081   };
1082
1083   bool WriteBodyInternal(Writer* w) {
1084     uintptr_t cu_start = w->position();
1085     Writer::Slot<uint32_t> size = w->CreateSlotHere<uint32_t>();
1086     uintptr_t start = w->position();
1087     w->Write<uint16_t>(2);  // DWARF version.
1088     w->Write<uint32_t>(0);  // Abbreviation table offset.
1089     w->Write<uint8_t>(sizeof(intptr_t));
1090
1091     w->WriteULEB128(1);  // Abbreviation code.
1092     w->WriteString(desc_->GetFilename().get());
1093     w->Write<intptr_t>(desc_->CodeStart());
1094     w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize());
1095     w->Write<uint32_t>(0);
1096
1097     uint32_t ty_offset = static_cast<uint32_t>(w->position() - cu_start);
1098     w->WriteULEB128(3);
1099     w->Write<uint8_t>(kPointerSize);
1100     w->WriteString("v8value");
1101
1102     if (desc_->IsInfoAvailable()) {
1103       Scope* scope = desc_->info()->scope();
1104       w->WriteULEB128(2);
1105       w->WriteString(desc_->name());
1106       w->Write<intptr_t>(desc_->CodeStart());
1107       w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize());
1108       Writer::Slot<uint32_t> fb_block_size = w->CreateSlotHere<uint32_t>();
1109       uintptr_t fb_block_start = w->position();
1110 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87
1111       w->Write<uint8_t>(DW_OP_reg5);  // The frame pointer's here on ia32
1112 #elif V8_TARGET_ARCH_X64
1113       w->Write<uint8_t>(DW_OP_reg6);  // and here on x64.
1114 #elif V8_TARGET_ARCH_ARM
1115       UNIMPLEMENTED();
1116 #elif V8_TARGET_ARCH_MIPS
1117       UNIMPLEMENTED();
1118 #elif V8_TARGET_ARCH_MIPS64
1119       UNIMPLEMENTED();
1120 #else
1121 #error Unsupported target architecture.
1122 #endif
1123       fb_block_size.set(static_cast<uint32_t>(w->position() - fb_block_start));
1124
1125       int params = scope->num_parameters();
1126       int slots = scope->num_stack_slots();
1127       int context_slots = scope->ContextLocalCount();
1128       // The real slot ID is internal_slots + context_slot_id.
1129       int internal_slots = Context::MIN_CONTEXT_SLOTS;
1130       int locals = scope->StackLocalCount();
1131       int current_abbreviation = 4;
1132
1133       for (int param = 0; param < params; ++param) {
1134         w->WriteULEB128(current_abbreviation++);
1135         w->WriteString(
1136             scope->parameter(param)->name()->ToCString(DISALLOW_NULLS).get());
1137         w->Write<uint32_t>(ty_offset);
1138         Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
1139         uintptr_t block_start = w->position();
1140         w->Write<uint8_t>(DW_OP_fbreg);
1141         w->WriteSLEB128(
1142           JavaScriptFrameConstants::kLastParameterOffset +
1143               kPointerSize * (params - param - 1));
1144         block_size.set(static_cast<uint32_t>(w->position() - block_start));
1145       }
1146
1147       EmbeddedVector<char, 256> buffer;
1148       StringBuilder builder(buffer.start(), buffer.length());
1149
1150       for (int slot = 0; slot < slots; ++slot) {
1151         w->WriteULEB128(current_abbreviation++);
1152         builder.Reset();
1153         builder.AddFormatted("slot%d", slot);
1154         w->WriteString(builder.Finalize());
1155       }
1156
1157       // See contexts.h for more information.
1158       DCHECK(Context::MIN_CONTEXT_SLOTS == 4);
1159       DCHECK(Context::CLOSURE_INDEX == 0);
1160       DCHECK(Context::PREVIOUS_INDEX == 1);
1161       DCHECK(Context::EXTENSION_INDEX == 2);
1162       DCHECK(Context::GLOBAL_OBJECT_INDEX == 3);
1163       w->WriteULEB128(current_abbreviation++);
1164       w->WriteString(".closure");
1165       w->WriteULEB128(current_abbreviation++);
1166       w->WriteString(".previous");
1167       w->WriteULEB128(current_abbreviation++);
1168       w->WriteString(".extension");
1169       w->WriteULEB128(current_abbreviation++);
1170       w->WriteString(".global");
1171
1172       for (int context_slot = 0;
1173            context_slot < context_slots;
1174            ++context_slot) {
1175         w->WriteULEB128(current_abbreviation++);
1176         builder.Reset();
1177         builder.AddFormatted("context_slot%d", context_slot + internal_slots);
1178         w->WriteString(builder.Finalize());
1179       }
1180
1181       ZoneList<Variable*> stack_locals(locals, scope->zone());
1182       ZoneList<Variable*> context_locals(context_slots, scope->zone());
1183       scope->CollectStackAndContextLocals(&stack_locals, &context_locals);
1184       for (int local = 0; local < locals; ++local) {
1185         w->WriteULEB128(current_abbreviation++);
1186         w->WriteString(
1187             stack_locals[local]->name()->ToCString(DISALLOW_NULLS).get());
1188         w->Write<uint32_t>(ty_offset);
1189         Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
1190         uintptr_t block_start = w->position();
1191         w->Write<uint8_t>(DW_OP_fbreg);
1192         w->WriteSLEB128(
1193           JavaScriptFrameConstants::kLocal0Offset -
1194               kPointerSize * local);
1195         block_size.set(static_cast<uint32_t>(w->position() - block_start));
1196       }
1197
1198       {
1199         w->WriteULEB128(current_abbreviation++);
1200         w->WriteString("__function");
1201         w->Write<uint32_t>(ty_offset);
1202         Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
1203         uintptr_t block_start = w->position();
1204         w->Write<uint8_t>(DW_OP_fbreg);
1205         w->WriteSLEB128(JavaScriptFrameConstants::kFunctionOffset);
1206         block_size.set(static_cast<uint32_t>(w->position() - block_start));
1207       }
1208
1209       {
1210         w->WriteULEB128(current_abbreviation++);
1211         w->WriteString("__context");
1212         w->Write<uint32_t>(ty_offset);
1213         Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
1214         uintptr_t block_start = w->position();
1215         w->Write<uint8_t>(DW_OP_fbreg);
1216         w->WriteSLEB128(StandardFrameConstants::kContextOffset);
1217         block_size.set(static_cast<uint32_t>(w->position() - block_start));
1218       }
1219
1220       w->WriteULEB128(0);  // Terminate the sub program.
1221     }
1222
1223     w->WriteULEB128(0);  // Terminate the compile unit.
1224     size.set(static_cast<uint32_t>(w->position() - start));
1225     return true;
1226   }
1227
1228  private:
1229   CodeDescription* desc_;
1230 };
1231
1232
1233 class DebugAbbrevSection : public DebugSection {
1234  public:
1235   explicit DebugAbbrevSection(CodeDescription* desc)
1236 #ifdef __ELF
1237       : ELFSection(".debug_abbrev", TYPE_PROGBITS, 1),
1238 #else
1239       : MachOSection("__debug_abbrev",
1240                      "__DWARF",
1241                      1,
1242                      MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG),
1243 #endif
1244         desc_(desc) { }
1245
1246   // DWARF2 standard, figure 14.
1247   enum DWARF2Tags {
1248     DW_TAG_FORMAL_PARAMETER = 0x05,
1249     DW_TAG_POINTER_TYPE = 0xf,
1250     DW_TAG_COMPILE_UNIT = 0x11,
1251     DW_TAG_STRUCTURE_TYPE = 0x13,
1252     DW_TAG_BASE_TYPE = 0x24,
1253     DW_TAG_SUBPROGRAM = 0x2e,
1254     DW_TAG_VARIABLE = 0x34
1255   };
1256
1257   // DWARF2 standard, figure 16.
1258   enum DWARF2ChildrenDetermination {
1259     DW_CHILDREN_NO = 0,
1260     DW_CHILDREN_YES = 1
1261   };
1262
1263   // DWARF standard, figure 17.
1264   enum DWARF2Attribute {
1265     DW_AT_LOCATION = 0x2,
1266     DW_AT_NAME = 0x3,
1267     DW_AT_BYTE_SIZE = 0xb,
1268     DW_AT_STMT_LIST = 0x10,
1269     DW_AT_LOW_PC = 0x11,
1270     DW_AT_HIGH_PC = 0x12,
1271     DW_AT_ENCODING = 0x3e,
1272     DW_AT_FRAME_BASE = 0x40,
1273     DW_AT_TYPE = 0x49
1274   };
1275
1276   // DWARF2 standard, figure 19.
1277   enum DWARF2AttributeForm {
1278     DW_FORM_ADDR = 0x1,
1279     DW_FORM_BLOCK4 = 0x4,
1280     DW_FORM_STRING = 0x8,
1281     DW_FORM_DATA4 = 0x6,
1282     DW_FORM_BLOCK = 0x9,
1283     DW_FORM_DATA1 = 0xb,
1284     DW_FORM_FLAG = 0xc,
1285     DW_FORM_REF4 = 0x13
1286   };
1287
1288   void WriteVariableAbbreviation(Writer* w,
1289                                  int abbreviation_code,
1290                                  bool has_value,
1291                                  bool is_parameter) {
1292     w->WriteULEB128(abbreviation_code);
1293     w->WriteULEB128(is_parameter ? DW_TAG_FORMAL_PARAMETER : DW_TAG_VARIABLE);
1294     w->Write<uint8_t>(DW_CHILDREN_NO);
1295     w->WriteULEB128(DW_AT_NAME);
1296     w->WriteULEB128(DW_FORM_STRING);
1297     if (has_value) {
1298       w->WriteULEB128(DW_AT_TYPE);
1299       w->WriteULEB128(DW_FORM_REF4);
1300       w->WriteULEB128(DW_AT_LOCATION);
1301       w->WriteULEB128(DW_FORM_BLOCK4);
1302     }
1303     w->WriteULEB128(0);
1304     w->WriteULEB128(0);
1305   }
1306
1307   bool WriteBodyInternal(Writer* w) {
1308     int current_abbreviation = 1;
1309     bool extra_info = desc_->IsInfoAvailable();
1310     DCHECK(desc_->IsLineInfoAvailable());
1311     w->WriteULEB128(current_abbreviation++);
1312     w->WriteULEB128(DW_TAG_COMPILE_UNIT);
1313     w->Write<uint8_t>(extra_info ? DW_CHILDREN_YES : DW_CHILDREN_NO);
1314     w->WriteULEB128(DW_AT_NAME);
1315     w->WriteULEB128(DW_FORM_STRING);
1316     w->WriteULEB128(DW_AT_LOW_PC);
1317     w->WriteULEB128(DW_FORM_ADDR);
1318     w->WriteULEB128(DW_AT_HIGH_PC);
1319     w->WriteULEB128(DW_FORM_ADDR);
1320     w->WriteULEB128(DW_AT_STMT_LIST);
1321     w->WriteULEB128(DW_FORM_DATA4);
1322     w->WriteULEB128(0);
1323     w->WriteULEB128(0);
1324
1325     if (extra_info) {
1326       Scope* scope = desc_->info()->scope();
1327       int params = scope->num_parameters();
1328       int slots = scope->num_stack_slots();
1329       int context_slots = scope->ContextLocalCount();
1330       // The real slot ID is internal_slots + context_slot_id.
1331       int internal_slots = Context::MIN_CONTEXT_SLOTS;
1332       int locals = scope->StackLocalCount();
1333       // Total children is params + slots + context_slots + internal_slots +
1334       // locals + 2 (__function and __context).
1335
1336       // The extra duplication below seems to be necessary to keep
1337       // gdb from getting upset on OSX.
1338       w->WriteULEB128(current_abbreviation++);  // Abbreviation code.
1339       w->WriteULEB128(DW_TAG_SUBPROGRAM);
1340       w->Write<uint8_t>(DW_CHILDREN_YES);
1341       w->WriteULEB128(DW_AT_NAME);
1342       w->WriteULEB128(DW_FORM_STRING);
1343       w->WriteULEB128(DW_AT_LOW_PC);
1344       w->WriteULEB128(DW_FORM_ADDR);
1345       w->WriteULEB128(DW_AT_HIGH_PC);
1346       w->WriteULEB128(DW_FORM_ADDR);
1347       w->WriteULEB128(DW_AT_FRAME_BASE);
1348       w->WriteULEB128(DW_FORM_BLOCK4);
1349       w->WriteULEB128(0);
1350       w->WriteULEB128(0);
1351
1352       w->WriteULEB128(current_abbreviation++);
1353       w->WriteULEB128(DW_TAG_STRUCTURE_TYPE);
1354       w->Write<uint8_t>(DW_CHILDREN_NO);
1355       w->WriteULEB128(DW_AT_BYTE_SIZE);
1356       w->WriteULEB128(DW_FORM_DATA1);
1357       w->WriteULEB128(DW_AT_NAME);
1358       w->WriteULEB128(DW_FORM_STRING);
1359       w->WriteULEB128(0);
1360       w->WriteULEB128(0);
1361
1362       for (int param = 0; param < params; ++param) {
1363         WriteVariableAbbreviation(w, current_abbreviation++, true, true);
1364       }
1365
1366       for (int slot = 0; slot < slots; ++slot) {
1367         WriteVariableAbbreviation(w, current_abbreviation++, false, false);
1368       }
1369
1370       for (int internal_slot = 0;
1371            internal_slot < internal_slots;
1372            ++internal_slot) {
1373         WriteVariableAbbreviation(w, current_abbreviation++, false, false);
1374       }
1375
1376       for (int context_slot = 0;
1377            context_slot < context_slots;
1378            ++context_slot) {
1379         WriteVariableAbbreviation(w, current_abbreviation++, false, false);
1380       }
1381
1382       for (int local = 0; local < locals; ++local) {
1383         WriteVariableAbbreviation(w, current_abbreviation++, true, false);
1384       }
1385
1386       // The function.
1387       WriteVariableAbbreviation(w, current_abbreviation++, true, false);
1388
1389       // The context.
1390       WriteVariableAbbreviation(w, current_abbreviation++, true, false);
1391
1392       w->WriteULEB128(0);  // Terminate the sibling list.
1393     }
1394
1395     w->WriteULEB128(0);  // Terminate the table.
1396     return true;
1397   }
1398
1399  private:
1400   CodeDescription* desc_;
1401 };
1402
1403
1404 class DebugLineSection : public DebugSection {
1405  public:
1406   explicit DebugLineSection(CodeDescription* desc)
1407 #ifdef __ELF
1408       : ELFSection(".debug_line", TYPE_PROGBITS, 1),
1409 #else
1410       : MachOSection("__debug_line",
1411                      "__DWARF",
1412                      1,
1413                      MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG),
1414 #endif
1415         desc_(desc) { }
1416
1417   // DWARF2 standard, figure 34.
1418   enum DWARF2Opcodes {
1419     DW_LNS_COPY = 1,
1420     DW_LNS_ADVANCE_PC = 2,
1421     DW_LNS_ADVANCE_LINE = 3,
1422     DW_LNS_SET_FILE = 4,
1423     DW_LNS_SET_COLUMN = 5,
1424     DW_LNS_NEGATE_STMT = 6
1425   };
1426
1427   // DWARF2 standard, figure 35.
1428   enum DWARF2ExtendedOpcode {
1429     DW_LNE_END_SEQUENCE = 1,
1430     DW_LNE_SET_ADDRESS = 2,
1431     DW_LNE_DEFINE_FILE = 3
1432   };
1433
1434   bool WriteBodyInternal(Writer* w) {
1435     // Write prologue.
1436     Writer::Slot<uint32_t> total_length = w->CreateSlotHere<uint32_t>();
1437     uintptr_t start = w->position();
1438
1439     // Used for special opcodes
1440     const int8_t line_base = 1;
1441     const uint8_t line_range = 7;
1442     const int8_t max_line_incr = (line_base + line_range - 1);
1443     const uint8_t opcode_base = DW_LNS_NEGATE_STMT + 1;
1444
1445     w->Write<uint16_t>(2);  // Field version.
1446     Writer::Slot<uint32_t> prologue_length = w->CreateSlotHere<uint32_t>();
1447     uintptr_t prologue_start = w->position();
1448     w->Write<uint8_t>(1);  // Field minimum_instruction_length.
1449     w->Write<uint8_t>(1);  // Field default_is_stmt.
1450     w->Write<int8_t>(line_base);  // Field line_base.
1451     w->Write<uint8_t>(line_range);  // Field line_range.
1452     w->Write<uint8_t>(opcode_base);  // Field opcode_base.
1453     w->Write<uint8_t>(0);  // DW_LNS_COPY operands count.
1454     w->Write<uint8_t>(1);  // DW_LNS_ADVANCE_PC operands count.
1455     w->Write<uint8_t>(1);  // DW_LNS_ADVANCE_LINE operands count.
1456     w->Write<uint8_t>(1);  // DW_LNS_SET_FILE operands count.
1457     w->Write<uint8_t>(1);  // DW_LNS_SET_COLUMN operands count.
1458     w->Write<uint8_t>(0);  // DW_LNS_NEGATE_STMT operands count.
1459     w->Write<uint8_t>(0);  // Empty include_directories sequence.
1460     w->WriteString(desc_->GetFilename().get());  // File name.
1461     w->WriteULEB128(0);  // Current directory.
1462     w->WriteULEB128(0);  // Unknown modification time.
1463     w->WriteULEB128(0);  // Unknown file size.
1464     w->Write<uint8_t>(0);
1465     prologue_length.set(static_cast<uint32_t>(w->position() - prologue_start));
1466
1467     WriteExtendedOpcode(w, DW_LNE_SET_ADDRESS, sizeof(intptr_t));
1468     w->Write<intptr_t>(desc_->CodeStart());
1469     w->Write<uint8_t>(DW_LNS_COPY);
1470
1471     intptr_t pc = 0;
1472     intptr_t line = 1;
1473     bool is_statement = true;
1474
1475     List<LineInfo::PCInfo>* pc_info = desc_->lineinfo()->pc_info();
1476     pc_info->Sort(&ComparePCInfo);
1477
1478     int pc_info_length = pc_info->length();
1479     for (int i = 0; i < pc_info_length; i++) {
1480       LineInfo::PCInfo* info = &pc_info->at(i);
1481       DCHECK(info->pc_ >= pc);
1482
1483       // Reduce bloating in the debug line table by removing duplicate line
1484       // entries (per DWARF2 standard).
1485       intptr_t  new_line = desc_->GetScriptLineNumber(info->pos_);
1486       if (new_line == line) {
1487         continue;
1488       }
1489
1490       // Mark statement boundaries.  For a better debugging experience, mark
1491       // the last pc address in the function as a statement (e.g. "}"), so that
1492       // a user can see the result of the last line executed in the function,
1493       // should control reach the end.
1494       if ((i+1) == pc_info_length) {
1495         if (!is_statement) {
1496           w->Write<uint8_t>(DW_LNS_NEGATE_STMT);
1497         }
1498       } else if (is_statement != info->is_statement_) {
1499         w->Write<uint8_t>(DW_LNS_NEGATE_STMT);
1500         is_statement = !is_statement;
1501       }
1502
1503       // Generate special opcodes, if possible.  This results in more compact
1504       // debug line tables.  See the DWARF 2.0 standard to learn more about
1505       // special opcodes.
1506       uintptr_t pc_diff = info->pc_ - pc;
1507       intptr_t line_diff = new_line - line;
1508
1509       // Compute special opcode (see DWARF 2.0 standard)
1510       intptr_t special_opcode = (line_diff - line_base) +
1511                                 (line_range * pc_diff) + opcode_base;
1512
1513       // If special_opcode is less than or equal to 255, it can be used as a
1514       // special opcode.  If line_diff is larger than the max line increment
1515       // allowed for a special opcode, or if line_diff is less than the minimum
1516       // line that can be added to the line register (i.e. line_base), then
1517       // special_opcode can't be used.
1518       if ((special_opcode >= opcode_base) && (special_opcode <= 255) &&
1519           (line_diff <= max_line_incr) && (line_diff >= line_base)) {
1520         w->Write<uint8_t>(special_opcode);
1521       } else {
1522         w->Write<uint8_t>(DW_LNS_ADVANCE_PC);
1523         w->WriteSLEB128(pc_diff);
1524         w->Write<uint8_t>(DW_LNS_ADVANCE_LINE);
1525         w->WriteSLEB128(line_diff);
1526         w->Write<uint8_t>(DW_LNS_COPY);
1527       }
1528
1529       // Increment the pc and line operands.
1530       pc += pc_diff;
1531       line += line_diff;
1532     }
1533     // Advance the pc to the end of the routine, since the end sequence opcode
1534     // requires this.
1535     w->Write<uint8_t>(DW_LNS_ADVANCE_PC);
1536     w->WriteSLEB128(desc_->CodeSize() - pc);
1537     WriteExtendedOpcode(w, DW_LNE_END_SEQUENCE, 0);
1538     total_length.set(static_cast<uint32_t>(w->position() - start));
1539     return true;
1540   }
1541
1542  private:
1543   void WriteExtendedOpcode(Writer* w,
1544                            DWARF2ExtendedOpcode op,
1545                            size_t operands_size) {
1546     w->Write<uint8_t>(0);
1547     w->WriteULEB128(operands_size + 1);
1548     w->Write<uint8_t>(op);
1549   }
1550
1551   static int ComparePCInfo(const LineInfo::PCInfo* a,
1552                            const LineInfo::PCInfo* b) {
1553     if (a->pc_ == b->pc_) {
1554       if (a->is_statement_ != b->is_statement_) {
1555         return b->is_statement_ ? +1 : -1;
1556       }
1557       return 0;
1558     } else if (a->pc_ > b->pc_) {
1559       return +1;
1560     } else {
1561       return -1;
1562     }
1563   }
1564
1565   CodeDescription* desc_;
1566 };
1567
1568
1569 #if V8_TARGET_ARCH_X64
1570
1571 class UnwindInfoSection : public DebugSection {
1572  public:
1573   explicit UnwindInfoSection(CodeDescription* desc);
1574   virtual bool WriteBodyInternal(Writer* w);
1575
1576   int WriteCIE(Writer* w);
1577   void WriteFDE(Writer* w, int);
1578
1579   void WriteFDEStateOnEntry(Writer* w);
1580   void WriteFDEStateAfterRBPPush(Writer* w);
1581   void WriteFDEStateAfterRBPSet(Writer* w);
1582   void WriteFDEStateAfterRBPPop(Writer* w);
1583
1584   void WriteLength(Writer* w,
1585                    Writer::Slot<uint32_t>* length_slot,
1586                    int initial_position);
1587
1588  private:
1589   CodeDescription* desc_;
1590
1591   // DWARF3 Specification, Table 7.23
1592   enum CFIInstructions {
1593     DW_CFA_ADVANCE_LOC = 0x40,
1594     DW_CFA_OFFSET = 0x80,
1595     DW_CFA_RESTORE = 0xC0,
1596     DW_CFA_NOP = 0x00,
1597     DW_CFA_SET_LOC = 0x01,
1598     DW_CFA_ADVANCE_LOC1 = 0x02,
1599     DW_CFA_ADVANCE_LOC2 = 0x03,
1600     DW_CFA_ADVANCE_LOC4 = 0x04,
1601     DW_CFA_OFFSET_EXTENDED = 0x05,
1602     DW_CFA_RESTORE_EXTENDED = 0x06,
1603     DW_CFA_UNDEFINED = 0x07,
1604     DW_CFA_SAME_VALUE = 0x08,
1605     DW_CFA_REGISTER = 0x09,
1606     DW_CFA_REMEMBER_STATE = 0x0A,
1607     DW_CFA_RESTORE_STATE = 0x0B,
1608     DW_CFA_DEF_CFA = 0x0C,
1609     DW_CFA_DEF_CFA_REGISTER = 0x0D,
1610     DW_CFA_DEF_CFA_OFFSET = 0x0E,
1611
1612     DW_CFA_DEF_CFA_EXPRESSION = 0x0F,
1613     DW_CFA_EXPRESSION = 0x10,
1614     DW_CFA_OFFSET_EXTENDED_SF = 0x11,
1615     DW_CFA_DEF_CFA_SF = 0x12,
1616     DW_CFA_DEF_CFA_OFFSET_SF = 0x13,
1617     DW_CFA_VAL_OFFSET = 0x14,
1618     DW_CFA_VAL_OFFSET_SF = 0x15,
1619     DW_CFA_VAL_EXPRESSION = 0x16
1620   };
1621
1622   // System V ABI, AMD64 Supplement, Version 0.99.5, Figure 3.36
1623   enum RegisterMapping {
1624     // Only the relevant ones have been added to reduce clutter.
1625     AMD64_RBP = 6,
1626     AMD64_RSP = 7,
1627     AMD64_RA = 16
1628   };
1629
1630   enum CFIConstants {
1631     CIE_ID = 0,
1632     CIE_VERSION = 1,
1633     CODE_ALIGN_FACTOR = 1,
1634     DATA_ALIGN_FACTOR = 1,
1635     RETURN_ADDRESS_REGISTER = AMD64_RA
1636   };
1637 };
1638
1639
1640 void UnwindInfoSection::WriteLength(Writer* w,
1641                                     Writer::Slot<uint32_t>* length_slot,
1642                                     int initial_position) {
1643   uint32_t align = (w->position() - initial_position) % kPointerSize;
1644
1645   if (align != 0) {
1646     for (uint32_t i = 0; i < (kPointerSize - align); i++) {
1647       w->Write<uint8_t>(DW_CFA_NOP);
1648     }
1649   }
1650
1651   DCHECK((w->position() - initial_position) % kPointerSize == 0);
1652   length_slot->set(w->position() - initial_position);
1653 }
1654
1655
1656 UnwindInfoSection::UnwindInfoSection(CodeDescription* desc)
1657 #ifdef __ELF
1658     : ELFSection(".eh_frame", TYPE_X86_64_UNWIND, 1),
1659 #else
1660     : MachOSection("__eh_frame", "__TEXT", sizeof(uintptr_t),
1661                    MachOSection::S_REGULAR),
1662 #endif
1663       desc_(desc) { }
1664
1665 int UnwindInfoSection::WriteCIE(Writer* w) {
1666   Writer::Slot<uint32_t> cie_length_slot = w->CreateSlotHere<uint32_t>();
1667   uint32_t cie_position = w->position();
1668
1669   // Write out the CIE header. Currently no 'common instructions' are
1670   // emitted onto the CIE; every FDE has its own set of instructions.
1671
1672   w->Write<uint32_t>(CIE_ID);
1673   w->Write<uint8_t>(CIE_VERSION);
1674   w->Write<uint8_t>(0);  // Null augmentation string.
1675   w->WriteSLEB128(CODE_ALIGN_FACTOR);
1676   w->WriteSLEB128(DATA_ALIGN_FACTOR);
1677   w->Write<uint8_t>(RETURN_ADDRESS_REGISTER);
1678
1679   WriteLength(w, &cie_length_slot, cie_position);
1680
1681   return cie_position;
1682 }
1683
1684
1685 void UnwindInfoSection::WriteFDE(Writer* w, int cie_position) {
1686   // The only FDE for this function. The CFA is the current RBP.
1687   Writer::Slot<uint32_t> fde_length_slot = w->CreateSlotHere<uint32_t>();
1688   int fde_position = w->position();
1689   w->Write<int32_t>(fde_position - cie_position + 4);
1690
1691   w->Write<uintptr_t>(desc_->CodeStart());
1692   w->Write<uintptr_t>(desc_->CodeSize());
1693
1694   WriteFDEStateOnEntry(w);
1695   WriteFDEStateAfterRBPPush(w);
1696   WriteFDEStateAfterRBPSet(w);
1697   WriteFDEStateAfterRBPPop(w);
1698
1699   WriteLength(w, &fde_length_slot, fde_position);
1700 }
1701
1702
1703 void UnwindInfoSection::WriteFDEStateOnEntry(Writer* w) {
1704   // The first state, just after the control has been transferred to the the
1705   // function.
1706
1707   // RBP for this function will be the value of RSP after pushing the RBP
1708   // for the previous function. The previous RBP has not been pushed yet.
1709   w->Write<uint8_t>(DW_CFA_DEF_CFA_SF);
1710   w->WriteULEB128(AMD64_RSP);
1711   w->WriteSLEB128(-kPointerSize);
1712
1713   // The RA is stored at location CFA + kCallerPCOffset. This is an invariant,
1714   // and hence omitted from the next states.
1715   w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED);
1716   w->WriteULEB128(AMD64_RA);
1717   w->WriteSLEB128(StandardFrameConstants::kCallerPCOffset);
1718
1719   // The RBP of the previous function is still in RBP.
1720   w->Write<uint8_t>(DW_CFA_SAME_VALUE);
1721   w->WriteULEB128(AMD64_RBP);
1722
1723   // Last location described by this entry.
1724   w->Write<uint8_t>(DW_CFA_SET_LOC);
1725   w->Write<uint64_t>(
1726       desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_PUSH));
1727 }
1728
1729
1730 void UnwindInfoSection::WriteFDEStateAfterRBPPush(Writer* w) {
1731   // The second state, just after RBP has been pushed.
1732
1733   // RBP / CFA for this function is now the current RSP, so just set the
1734   // offset from the previous rule (from -8) to 0.
1735   w->Write<uint8_t>(DW_CFA_DEF_CFA_OFFSET);
1736   w->WriteULEB128(0);
1737
1738   // The previous RBP is stored at CFA + kCallerFPOffset. This is an invariant
1739   // in this and the next state, and hence omitted in the next state.
1740   w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED);
1741   w->WriteULEB128(AMD64_RBP);
1742   w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset);
1743
1744   // Last location described by this entry.
1745   w->Write<uint8_t>(DW_CFA_SET_LOC);
1746   w->Write<uint64_t>(
1747       desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_SET));
1748 }
1749
1750
1751 void UnwindInfoSection::WriteFDEStateAfterRBPSet(Writer* w) {
1752   // The third state, after the RBP has been set.
1753
1754   // The CFA can now directly be set to RBP.
1755   w->Write<uint8_t>(DW_CFA_DEF_CFA);
1756   w->WriteULEB128(AMD64_RBP);
1757   w->WriteULEB128(0);
1758
1759   // Last location described by this entry.
1760   w->Write<uint8_t>(DW_CFA_SET_LOC);
1761   w->Write<uint64_t>(
1762       desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_POP));
1763 }
1764
1765
1766 void UnwindInfoSection::WriteFDEStateAfterRBPPop(Writer* w) {
1767   // The fourth (final) state. The RBP has been popped (just before issuing a
1768   // return).
1769
1770   // The CFA can is now calculated in the same way as in the first state.
1771   w->Write<uint8_t>(DW_CFA_DEF_CFA_SF);
1772   w->WriteULEB128(AMD64_RSP);
1773   w->WriteSLEB128(-kPointerSize);
1774
1775   // The RBP
1776   w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED);
1777   w->WriteULEB128(AMD64_RBP);
1778   w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset);
1779
1780   // Last location described by this entry.
1781   w->Write<uint8_t>(DW_CFA_SET_LOC);
1782   w->Write<uint64_t>(desc_->CodeEnd());
1783 }
1784
1785
1786 bool UnwindInfoSection::WriteBodyInternal(Writer* w) {
1787   uint32_t cie_position = WriteCIE(w);
1788   WriteFDE(w, cie_position);
1789   return true;
1790 }
1791
1792
1793 #endif  // V8_TARGET_ARCH_X64
1794
1795 static void CreateDWARFSections(CodeDescription* desc,
1796                                 Zone* zone,
1797                                 DebugObject* obj) {
1798   if (desc->IsLineInfoAvailable()) {
1799     obj->AddSection(new(zone) DebugInfoSection(desc));
1800     obj->AddSection(new(zone) DebugAbbrevSection(desc));
1801     obj->AddSection(new(zone) DebugLineSection(desc));
1802   }
1803 #if V8_TARGET_ARCH_X64
1804   obj->AddSection(new(zone) UnwindInfoSection(desc));
1805 #endif
1806 }
1807
1808
1809 // -------------------------------------------------------------------
1810 // Binary GDB JIT Interface as described in
1811 //   http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html
1812 extern "C" {
1813   typedef enum {
1814     JIT_NOACTION = 0,
1815     JIT_REGISTER_FN,
1816     JIT_UNREGISTER_FN
1817   } JITAction;
1818
1819   struct JITCodeEntry {
1820     JITCodeEntry* next_;
1821     JITCodeEntry* prev_;
1822     Address symfile_addr_;
1823     uint64_t symfile_size_;
1824   };
1825
1826   struct JITDescriptor {
1827     uint32_t version_;
1828     uint32_t action_flag_;
1829     JITCodeEntry* relevant_entry_;
1830     JITCodeEntry* first_entry_;
1831   };
1832
1833   // GDB will place breakpoint into this function.
1834   // To prevent GCC from inlining or removing it we place noinline attribute
1835   // and inline assembler statement inside.
1836   void __attribute__((noinline)) __jit_debug_register_code() {
1837     __asm__("");
1838   }
1839
1840   // GDB will inspect contents of this descriptor.
1841   // Static initialization is necessary to prevent GDB from seeing
1842   // uninitialized descriptor.
1843   JITDescriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
1844
1845 #ifdef OBJECT_PRINT
1846   void __gdb_print_v8_object(Object* object) {
1847     OFStream os(stdout);
1848     object->Print(os);
1849     os << flush;
1850   }
1851 #endif
1852 }
1853
1854
1855 static JITCodeEntry* CreateCodeEntry(Address symfile_addr,
1856                                      uintptr_t symfile_size) {
1857   JITCodeEntry* entry = static_cast<JITCodeEntry*>(
1858       malloc(sizeof(JITCodeEntry) + symfile_size));
1859
1860   entry->symfile_addr_ = reinterpret_cast<Address>(entry + 1);
1861   entry->symfile_size_ = symfile_size;
1862   MemCopy(entry->symfile_addr_, symfile_addr, symfile_size);
1863
1864   entry->prev_ = entry->next_ = NULL;
1865
1866   return entry;
1867 }
1868
1869
1870 static void DestroyCodeEntry(JITCodeEntry* entry) {
1871   free(entry);
1872 }
1873
1874
1875 static void RegisterCodeEntry(JITCodeEntry* entry,
1876                               bool dump_if_enabled,
1877                               const char* name_hint) {
1878 #if defined(DEBUG) && !V8_OS_WIN
1879   static int file_num = 0;
1880   if (FLAG_gdbjit_dump && dump_if_enabled) {
1881     static const int kMaxFileNameSize = 64;
1882     static const char* kElfFilePrefix = "/tmp/elfdump";
1883     static const char* kObjFileExt = ".o";
1884     char file_name[64];
1885
1886     SNPrintF(Vector<char>(file_name, kMaxFileNameSize),
1887              "%s%s%d%s",
1888              kElfFilePrefix,
1889              (name_hint != NULL) ? name_hint : "",
1890              file_num++,
1891              kObjFileExt);
1892     WriteBytes(file_name, entry->symfile_addr_, entry->symfile_size_);
1893   }
1894 #endif
1895
1896   entry->next_ = __jit_debug_descriptor.first_entry_;
1897   if (entry->next_ != NULL) entry->next_->prev_ = entry;
1898   __jit_debug_descriptor.first_entry_ =
1899       __jit_debug_descriptor.relevant_entry_ = entry;
1900
1901   __jit_debug_descriptor.action_flag_ = JIT_REGISTER_FN;
1902   __jit_debug_register_code();
1903 }
1904
1905
1906 static void UnregisterCodeEntry(JITCodeEntry* entry) {
1907   if (entry->prev_ != NULL) {
1908     entry->prev_->next_ = entry->next_;
1909   } else {
1910     __jit_debug_descriptor.first_entry_ = entry->next_;
1911   }
1912
1913   if (entry->next_ != NULL) {
1914     entry->next_->prev_ = entry->prev_;
1915   }
1916
1917   __jit_debug_descriptor.relevant_entry_ = entry;
1918   __jit_debug_descriptor.action_flag_ = JIT_UNREGISTER_FN;
1919   __jit_debug_register_code();
1920 }
1921
1922
1923 static JITCodeEntry* CreateELFObject(CodeDescription* desc, Isolate* isolate) {
1924 #ifdef __MACH_O
1925   Zone zone(isolate);
1926   MachO mach_o(&zone);
1927   Writer w(&mach_o);
1928
1929   mach_o.AddSection(new(&zone) MachOTextSection(kCodeAlignment,
1930                                                 desc->CodeStart(),
1931                                                 desc->CodeSize()));
1932
1933   CreateDWARFSections(desc, &zone, &mach_o);
1934
1935   mach_o.Write(&w, desc->CodeStart(), desc->CodeSize());
1936 #else
1937   Zone zone(isolate);
1938   ELF elf(&zone);
1939   Writer w(&elf);
1940
1941   int text_section_index = elf.AddSection(
1942       new(&zone) FullHeaderELFSection(
1943           ".text",
1944           ELFSection::TYPE_NOBITS,
1945           kCodeAlignment,
1946           desc->CodeStart(),
1947           0,
1948           desc->CodeSize(),
1949           ELFSection::FLAG_ALLOC | ELFSection::FLAG_EXEC));
1950
1951   CreateSymbolsTable(desc, &zone, &elf, text_section_index);
1952
1953   CreateDWARFSections(desc, &zone, &elf);
1954
1955   elf.Write(&w);
1956 #endif
1957
1958   return CreateCodeEntry(w.buffer(), w.position());
1959 }
1960
1961
1962 static bool SameCodeObjects(void* key1, void* key2) {
1963   return key1 == key2;
1964 }
1965
1966
1967 static HashMap* GetEntries() {
1968   static HashMap* entries = NULL;
1969   if (entries == NULL) {
1970     entries = new HashMap(&SameCodeObjects);
1971   }
1972   return entries;
1973 }
1974
1975
1976 static uint32_t HashForCodeObject(Code* code) {
1977   static const uintptr_t kGoldenRatio = 2654435761u;
1978   uintptr_t hash = reinterpret_cast<uintptr_t>(code->address());
1979   return static_cast<uint32_t>((hash >> kCodeAlignmentBits) * kGoldenRatio);
1980 }
1981
1982
1983 static const intptr_t kLineInfoTag = 0x1;
1984
1985
1986 static bool IsLineInfoTagged(void* ptr) {
1987   return 0 != (reinterpret_cast<intptr_t>(ptr) & kLineInfoTag);
1988 }
1989
1990
1991 static void* TagLineInfo(LineInfo* ptr) {
1992   return reinterpret_cast<void*>(
1993       reinterpret_cast<intptr_t>(ptr) | kLineInfoTag);
1994 }
1995
1996
1997 static LineInfo* UntagLineInfo(void* ptr) {
1998   return reinterpret_cast<LineInfo*>(reinterpret_cast<intptr_t>(ptr) &
1999                                      ~kLineInfoTag);
2000 }
2001
2002
2003 void GDBJITInterface::AddCode(Handle<Name> name,
2004                               Handle<Script> script,
2005                               Handle<Code> code,
2006                               CompilationInfo* info) {
2007   if (!FLAG_gdbjit) return;
2008
2009   Script::InitLineEnds(script);
2010
2011   if (!name.is_null() && name->IsString()) {
2012     SmartArrayPointer<char> name_cstring =
2013         Handle<String>::cast(name)->ToCString(DISALLOW_NULLS);
2014     AddCode(name_cstring.get(), *code, GDBJITInterface::FUNCTION, *script,
2015             info);
2016   } else {
2017     AddCode("", *code, GDBJITInterface::FUNCTION, *script, info);
2018   }
2019 }
2020
2021
2022 static void AddUnwindInfo(CodeDescription* desc) {
2023 #if V8_TARGET_ARCH_X64
2024   if (desc->tag() == GDBJITInterface::FUNCTION) {
2025     // To avoid propagating unwinding information through
2026     // compilation pipeline we use an approximation.
2027     // For most use cases this should not affect usability.
2028     static const int kFramePointerPushOffset = 1;
2029     static const int kFramePointerSetOffset = 4;
2030     static const int kFramePointerPopOffset = -3;
2031
2032     uintptr_t frame_pointer_push_address =
2033         desc->CodeStart() + kFramePointerPushOffset;
2034
2035     uintptr_t frame_pointer_set_address =
2036         desc->CodeStart() + kFramePointerSetOffset;
2037
2038     uintptr_t frame_pointer_pop_address =
2039         desc->CodeEnd() + kFramePointerPopOffset;
2040
2041     desc->SetStackStateStartAddress(CodeDescription::POST_RBP_PUSH,
2042                                     frame_pointer_push_address);
2043     desc->SetStackStateStartAddress(CodeDescription::POST_RBP_SET,
2044                                     frame_pointer_set_address);
2045     desc->SetStackStateStartAddress(CodeDescription::POST_RBP_POP,
2046                                     frame_pointer_pop_address);
2047   } else {
2048     desc->SetStackStateStartAddress(CodeDescription::POST_RBP_PUSH,
2049                                     desc->CodeStart());
2050     desc->SetStackStateStartAddress(CodeDescription::POST_RBP_SET,
2051                                     desc->CodeStart());
2052     desc->SetStackStateStartAddress(CodeDescription::POST_RBP_POP,
2053                                     desc->CodeEnd());
2054   }
2055 #endif  // V8_TARGET_ARCH_X64
2056 }
2057
2058
2059 static base::LazyMutex mutex = LAZY_MUTEX_INITIALIZER;
2060
2061
2062 void GDBJITInterface::AddCode(const char* name,
2063                               Code* code,
2064                               GDBJITInterface::CodeTag tag,
2065                               Script* script,
2066                               CompilationInfo* info) {
2067   base::LockGuard<base::Mutex> lock_guard(mutex.Pointer());
2068   DisallowHeapAllocation no_gc;
2069
2070   HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true);
2071   if (e->value != NULL && !IsLineInfoTagged(e->value)) return;
2072
2073   LineInfo* lineinfo = UntagLineInfo(e->value);
2074   CodeDescription code_desc(name,
2075                             code,
2076                             script != NULL ? Handle<Script>(script)
2077                                            : Handle<Script>(),
2078                             lineinfo,
2079                             tag,
2080                             info);
2081
2082   if (!FLAG_gdbjit_full && !code_desc.IsLineInfoAvailable()) {
2083     delete lineinfo;
2084     GetEntries()->Remove(code, HashForCodeObject(code));
2085     return;
2086   }
2087
2088   AddUnwindInfo(&code_desc);
2089   Isolate* isolate = code->GetIsolate();
2090   JITCodeEntry* entry = CreateELFObject(&code_desc, isolate);
2091   DCHECK(!IsLineInfoTagged(entry));
2092
2093   delete lineinfo;
2094   e->value = entry;
2095
2096   const char* name_hint = NULL;
2097   bool should_dump = false;
2098   if (FLAG_gdbjit_dump) {
2099     if (strlen(FLAG_gdbjit_dump_filter) == 0) {
2100       name_hint = name;
2101       should_dump = true;
2102     } else if (name != NULL) {
2103       name_hint = strstr(name, FLAG_gdbjit_dump_filter);
2104       should_dump = (name_hint != NULL);
2105     }
2106   }
2107   RegisterCodeEntry(entry, should_dump, name_hint);
2108 }
2109
2110
2111 void GDBJITInterface::RemoveCode(Code* code) {
2112   if (!FLAG_gdbjit) return;
2113
2114   base::LockGuard<base::Mutex> lock_guard(mutex.Pointer());
2115   HashMap::Entry* e = GetEntries()->Lookup(code,
2116                                            HashForCodeObject(code),
2117                                            false);
2118   if (e == NULL) return;
2119
2120   if (IsLineInfoTagged(e->value)) {
2121     delete UntagLineInfo(e->value);
2122   } else {
2123     JITCodeEntry* entry = static_cast<JITCodeEntry*>(e->value);
2124     UnregisterCodeEntry(entry);
2125     DestroyCodeEntry(entry);
2126   }
2127   e->value = NULL;
2128   GetEntries()->Remove(code, HashForCodeObject(code));
2129 }
2130
2131
2132 void GDBJITInterface::RemoveCodeRange(Address start, Address end) {
2133   HashMap* entries = GetEntries();
2134   Zone zone(Isolate::Current());
2135   ZoneList<Code*> dead_codes(1, &zone);
2136
2137   for (HashMap::Entry* e = entries->Start(); e != NULL; e = entries->Next(e)) {
2138     Code* code = reinterpret_cast<Code*>(e->key);
2139     if (code->address() >= start && code->address() < end) {
2140       dead_codes.Add(code, &zone);
2141     }
2142   }
2143
2144   for (int i = 0; i < dead_codes.length(); i++) {
2145     RemoveCode(dead_codes.at(i));
2146   }
2147 }
2148
2149
2150 static void RegisterDetailedLineInfo(Code* code, LineInfo* line_info) {
2151   base::LockGuard<base::Mutex> lock_guard(mutex.Pointer());
2152   DCHECK(!IsLineInfoTagged(line_info));
2153   HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true);
2154   DCHECK(e->value == NULL);
2155   e->value = TagLineInfo(line_info);
2156 }
2157
2158
2159 void GDBJITInterface::EventHandler(const v8::JitCodeEvent* event) {
2160   if (!FLAG_gdbjit) return;
2161   switch (event->type) {
2162     case v8::JitCodeEvent::CODE_ADDED: {
2163       Code* code = Code::GetCodeFromTargetAddress(
2164           reinterpret_cast<Address>(event->code_start));
2165       if (code->kind() == Code::OPTIMIZED_FUNCTION ||
2166           code->kind() == Code::FUNCTION) {
2167         break;
2168       }
2169       EmbeddedVector<char, 256> buffer;
2170       StringBuilder builder(buffer.start(), buffer.length());
2171       builder.AddSubstring(event->name.str, static_cast<int>(event->name.len));
2172       AddCode(builder.Finalize(), code, NON_FUNCTION, NULL, NULL);
2173       break;
2174     }
2175     case v8::JitCodeEvent::CODE_MOVED:
2176       break;
2177     case v8::JitCodeEvent::CODE_REMOVED: {
2178       Code* code = Code::GetCodeFromTargetAddress(
2179           reinterpret_cast<Address>(event->code_start));
2180       RemoveCode(code);
2181       break;
2182     }
2183     case v8::JitCodeEvent::CODE_ADD_LINE_POS_INFO: {
2184       LineInfo* line_info = reinterpret_cast<LineInfo*>(event->user_data);
2185       line_info->SetPosition(static_cast<intptr_t>(event->line_info.offset),
2186                              static_cast<int>(event->line_info.pos),
2187                              event->line_info.position_type ==
2188                                  v8::JitCodeEvent::STATEMENT_POSITION);
2189       break;
2190     }
2191     case v8::JitCodeEvent::CODE_START_LINE_INFO_RECORDING: {
2192       v8::JitCodeEvent* mutable_event = const_cast<v8::JitCodeEvent*>(event);
2193       mutable_event->user_data = new LineInfo();
2194       break;
2195     }
2196     case v8::JitCodeEvent::CODE_END_LINE_INFO_RECORDING: {
2197       LineInfo* line_info = reinterpret_cast<LineInfo*>(event->user_data);
2198       Code* code = Code::GetCodeFromTargetAddress(
2199           reinterpret_cast<Address>(event->code_start));
2200       RegisterDetailedLineInfo(code, line_info);
2201       break;
2202     }
2203   }
2204 }
2205
2206
2207 } }  // namespace v8::internal
2208 #endif