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