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