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