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

Unified Diff: src/gdb-jit.cc

Issue 6995161: Extend gdb-jit support (OSX/locals+parameters/prettyprint) (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/gdb-jit.h ('K') | « src/gdb-jit.h ('k') | tools/gdb-v8-support.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gdb-jit.cc
diff --git a/src/gdb-jit.cc b/src/gdb-jit.cc
index b4992a7f52680e0d766e6b8befa5ca31b6ec607b..32988d7833345e3e8747fa8792853e18370cdaa4 100644
--- a/src/gdb-jit.cc
+++ b/src/gdb-jit.cc
@@ -34,16 +34,37 @@
#include "global-handles.h"
#include "messages.h"
#include "natives.h"
+#include "scopeinfo.h"
+
+#ifdef __APPLE__
+#define __MACH_O
+#define SECTION_BASE MachOSection
+#define OBJ_FORMAT MachO
+#else
+#define __ELF
+#define SECTION_BASE ELFSection
+#define OBJ_FORMAT ELF
+#endif
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 I don't think we are using macros for anything lik
zarko 2011/06/27 22:24:29 Done (though I have kept the __MACH_O/__ELF define
namespace v8 {
namespace internal {
class ELF;
+class MachO;
class Writer BASE_EMBEDDED {
public:
explicit Writer(ELF* elf)
: elf_(elf),
+ mach_o_(0),
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 Instead of duplicating code and members replace el
zarko 2011/06/27 22:24:29 Done.
+ position_(0),
+ capacity_(1024),
+ buffer_(reinterpret_cast<byte*>(malloc(capacity_))) {
+ }
+
+ explicit Writer(MachO* mach_o)
+ : elf_(0),
+ mach_o_(mach_o),
position_(0),
capacity_(1024),
buffer_(reinterpret_cast<byte*>(malloc(capacity_))) {
@@ -112,7 +133,9 @@ class Writer BASE_EMBEDDED {
}
}
- ELF* elf() { return elf_; }
+ ELF* elf() { ASSERT(elf_ != 0); return elf_; }
+
+ MachO* mach_o() { ASSERT(mach_o_ != 0); return mach_o_; }
byte* buffer() { return buffer_; }
@@ -166,6 +189,7 @@ class Writer BASE_EMBEDDED {
}
ELF* elf_;
+ MachO* mach_o_;
uintptr_t position_;
uintptr_t capacity_;
byte* buffer_;
@@ -173,6 +197,91 @@ class Writer BASE_EMBEDDED {
class StringTable;
+class MachOSection : public ZoneObject {
+ public:
+ struct Header {
+ char sectname[16];
+ char segname[16];
+#if defined(V8_TARGET_ARCH_IA32)
+ uint32_t addr;
+ uint32_t size;
+#else
+ uint64_t addr;
+ uint64_t size;
+#endif
+ uint32_t offset;
+ uint32_t align;
+ uint32_t reloff;
+ uint32_t nreloc;
+ uint32_t flags;
+ uint32_t reserved1;
+ uint32_t reserved2;
+ };
+
+ enum Type {
+ S_REGULAR = 0x0u,
+ S_ATTR_COALESCED = 0xbu,
+ S_ATTR_SOME_INSTRUCTIONS = 0x400u,
+ S_ATTR_DEBUG = 0x02000000u,
+ S_ATTR_PURE_INSTRUCTIONS = 0x80000000u
+ };
+
+ MachOSection(const char* name,
+ const char* segment,
+ uintptr_t align,
+ uint32_t flags)
+ : name_(name),
+ segment_(segment),
+ align_(align),
+ flags_(flags) {
+ ASSERT(IsPowerOf2(align));
+ if (align_ != 0) {
+ align_ = WhichPowerOf2(align_);
+ }
+ }
+
+ virtual ~MachOSection() { }
+
+ virtual void PopulateHeader(Writer::Slot<Header> header) {
+ header->addr = 0;
+ header->size = 0;
+ header->offset = 0;
+ header->align = align_;
+ header->reloff = 0;
+ header->nreloc = 0;
+ header->flags = flags_;
+ header->reserved1 = 0;
+ header->reserved2 = 0;
+ memset(header->sectname, 0, 16);
+ memset(header->segname, 0, 16);
+ ASSERT(strlen(name_) < 16);
+ ASSERT(strlen(segment_) < 16);
+ strcpy(header->sectname, name_);
+ strcpy(header->segname, segment_);
+ }
+
+ virtual void WriteBody(Writer::Slot<Header> header, Writer* writer) {
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 Seems to be shared between ELFSection and MachOSec
zarko 2011/06/27 22:24:29 Done.
+ uintptr_t start = writer->position();
+ if (WriteBody(writer)) {
+ uintptr_t end = writer->position();
+ header->offset = start;
+ header->addr = 0;
+ header->size = end - start;
+ }
+ }
+
+ virtual bool WriteBody(Writer* writer) {
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 Ditto.
zarko 2011/06/27 22:24:29 Done.
+ return false;
+ }
+
+ private:
+ const char* name_;
+ const char* segment_;
+ uintptr_t align_;
+ uint32_t flags_;
+};
+
+
class ELFSection : public ZoneObject {
public:
struct Header {
@@ -252,7 +361,6 @@ class ELFSection : public ZoneObject {
header->entry_size = 0;
}
-
private:
const char* name_;
Type type_;
@@ -261,6 +369,33 @@ class ELFSection : public ZoneObject {
};
+class MachOTextSection : public MachOSection {
+ public:
+ MachOTextSection(uintptr_t align,
+ uintptr_t addr,
+ uintptr_t size)
+ : MachOSection("__text",
+ "__TEXT",
+ align,
+ MachOSection::S_REGULAR |
+ MachOSection::S_ATTR_SOME_INSTRUCTIONS |
+ MachOSection::S_ATTR_PURE_INSTRUCTIONS),
+ addr_(addr),
+ size_(size) { }
+
+ protected:
+ virtual void PopulateHeader(Writer::Slot<Header> header) {
+ MachOSection::PopulateHeader(header);
+ header->addr = addr_;
+ header->size = size_;
+ }
+
+ private:
+ uintptr_t addr_;
+ uintptr_t size_;
+};
+
+
class FullHeaderELFSection : public ELFSection {
public:
FullHeaderELFSection(const char* name,
@@ -351,6 +486,113 @@ void ELFSection::PopulateHeader(Writer::Slot<ELFSection::Header> header,
}
+class MachO BASE_EMBEDDED {
+ public:
+ MachO() : sections_(6) { }
+
+ uint32_t AddSection(MachOSection* section) {
+ sections_.Add(section);
+ return sections_.length() - 1;
+ }
+
+ void Write(Writer* w, uintptr_t code_start, uintptr_t code_size);
+
+ private:
+ struct MachOHeader {
+ uint32_t magic;
+ uint32_t cputype;
+ uint32_t cpusubtype;
+ uint32_t filetype;
+ uint32_t ncmds;
+ uint32_t sizeofcmds;
+ uint32_t flags;
+#if defined(V8_TARGET_ARCH_X64)
+ uint32_t reserved;
+#endif
+ };
+
+ struct MachOSegmentCommand {
+ uint32_t cmd;
+ uint32_t cmdsize;
+ char segname[16];
+#if defined(V8_TARGET_ARCH_IA32)
+ uint32_t vmaddr;
+ uint32_t vmsize;
+ uint32_t fileoff;
+ uint32_t filesize;
+#else
+ uint64_t vmaddr;
+ uint64_t vmsize;
+ uint64_t fileoff;
+ uint64_t filesize;
+#endif
+ uint32_t maxprot;
+ uint32_t initprot;
+ uint32_t nsects;
+ uint32_t flags;
+ };
+
+ enum MachOLoadCommandCmd {
+ LC_SEGMENT_32 = 0x00000001u,
+ LC_SEGMENT_64 = 0x00000019u
+ };
+
+ ZoneList<MachOSection*> sections_;
+};
+
+
+void MachO::Write(Writer* w,
+ uintptr_t code_start,
+ uintptr_t code_size) {
+ ASSERT(w->position() == 0);
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 Can you split this method into several like it is
zarko 2011/06/27 22:24:29 Done.
+ Writer::Slot<MachOHeader> header = w->CreateSlotHere<MachOHeader>();
+#if defined(V8_TARGET_ARCH_IA32)
+ header->magic = 0xFEEDFACEu;
+ header->cputype = 7; // i386
+ header->cpusubtype = 3; // CPU_SUBTYPE_I386_ALL
+#elif defined(V8_TARGET_ARCH_X64)
+ header->magic = 0xFEEDFACFu;
+ header->cputype = 7 | 0x01000000; // i386 | 64-bit ABI
+ header->cpusubtype = 3; // CPU_SUBTYPE_I386_ALL
+ header->reserved = 0;
+#else
+#error Unsupported target architecture.
+#endif
+ header->filetype = 0x1; // MH_OBJECT
+ header->ncmds = 1;
+ header->sizeofcmds = 0;
+ header->flags = 0;
+ uintptr_t load_command_start = w->position();
+ Writer::Slot<MachOSegmentCommand> cmd =
+ w->CreateSlotHere<MachOSegmentCommand>();
+#if defined(V8_TARGET_ARCH_IA32)
+ cmd->cmd = LC_SEGMENT_32;
+#else
+ cmd->cmd = LC_SEGMENT_64;
+#endif
+ cmd->vmaddr = code_start;
+ cmd->vmsize = code_size;
+ cmd->fileoff = 0;
+ cmd->filesize = 0;
+ cmd->maxprot = 7;
+ cmd->initprot = 7;
+ cmd->flags = 0;
+ cmd->nsects = sections_.length();
+ memset(cmd->segname, 0, 16);
+ cmd->cmdsize = sizeof(MachOSegmentCommand) + sizeof(MachOSection::Header) *
+ cmd->nsects;
+ Writer::Slot<MachOSection::Header> headers =
+ w->CreateSlotsHere<MachOSection::Header>(sections_.length());
+ cmd->fileoff = w->position();
+ header->sizeofcmds = w->position() - load_command_start;
+ for (int section = 0; section < sections_.length(); ++section) {
+ sections_[section]->PopulateHeader(headers.at(section));
+ sections_[section]->WriteBody(headers.at(section), w);
+ }
+ cmd->filesize = w->position() - (uintptr_t)cmd->fileoff;
+}
+
+
class ELF BASE_EMBEDDED {
public:
ELF() : sections_(6) {
@@ -657,12 +899,14 @@ class CodeDescription BASE_EMBEDDED {
Code* code,
Handle<Script> script,
GDBJITLineInfo* lineinfo,
- GDBJITInterface::CodeTag tag)
+ GDBJITInterface::CodeTag tag,
+ CompilationInfo* info)
: name_(name),
code_(code),
script_(script),
lineinfo_(lineinfo),
- tag_(tag) {
+ tag_(tag),
+ info_(info) {
}
const char* name() const {
@@ -677,6 +921,14 @@ class CodeDescription BASE_EMBEDDED {
return tag_;
}
+ CompilationInfo* info() const {
+ return info_;
+ }
+
+ bool IsInfoAvailable() const {
+ return info_ != NULL;
+ }
+
uintptr_t CodeStart() const {
return reinterpret_cast<uintptr_t>(code_->instruction_start());
}
@@ -724,12 +976,13 @@ class CodeDescription BASE_EMBEDDED {
Handle<Script> script_;
GDBJITLineInfo* lineinfo_;
GDBJITInterface::CodeTag tag_;
+ CompilationInfo* info_;
#ifdef V8_TARGET_ARCH_X64
uintptr_t stack_state_start_addresses_[STACK_STATE_MAX];
#endif
};
-
+#ifdef __ELF
static void CreateSymbolsTable(CodeDescription* desc,
ELF* elf,
int text_section_index) {
@@ -754,14 +1007,40 @@ static void CreateSymbolsTable(CodeDescription* desc,
ELFSymbol::TYPE_FUNC,
text_section_index));
}
+#endif
-class DebugInfoSection : public ELFSection {
+class DebugInfoSection : public SECTION_BASE {
public:
explicit DebugInfoSection(CodeDescription* desc)
- : ELFSection(".debug_info", TYPE_PROGBITS, 1), desc_(desc) { }
+#ifdef __ELF
+ : ELFSection(".debug_info", TYPE_PROGBITS, 1),
+#else
+ : MachOSection("__debug_info", "__DWARF", 1,
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 one argument per line.
zarko 2011/06/27 22:24:29 Done.
+ MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG),
+#endif
+ desc_(desc) { }
+
+ // DWARF2 standard
+ enum DWARF2LocationOp {
+ DW_OP_reg0 = 0x50,
+ DW_OP_reg1 = 0x51,
+ DW_OP_reg2 = 0x52,
+ DW_OP_reg3 = 0x53,
+ DW_OP_reg4 = 0x54,
+ DW_OP_reg5 = 0x55,
+ DW_OP_reg6 = 0x56,
+ DW_OP_reg7 = 0x57,
+ DW_OP_fbreg = 0x91 // 1 param: SLEB128 offset
+ };
+
+ enum DWARF2Encoding {
+ DW_ATE_ADDRESS = 0x1,
+ DW_ATE_SIGNED = 0x5
+ };
bool WriteBody(Writer* w) {
+ uintptr_t cu_start = w->position();
Writer::Slot<uint32_t> size = w->CreateSlotHere<uint32_t>();
uintptr_t start = w->position();
w->Write<uint16_t>(2); // DWARF version.
@@ -773,6 +1052,125 @@ class DebugInfoSection : public ELFSection {
w->Write<intptr_t>(desc_->CodeStart());
w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize());
w->Write<uint32_t>(0);
+
+ uint32_t ty_offset = static_cast<uint32_t>(w->position() - cu_start);
+ w->WriteULEB128(3);
+ w->Write<uint8_t>(kPointerSize);
+ w->WriteString("v8value");
+
+ if (desc_->IsInfoAvailable()) {
+ CompilationInfo* info = desc_->info();
+ ScopeInfo<FreeStoreAllocationPolicy> scope_info(info->scope());
+ w->WriteULEB128(2);
+ w->WriteString(desc_->name());
+ w->Write<intptr_t>(desc_->CodeStart());
+ w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize());
+ Writer::Slot<uint32_t> fb_block_size = w->CreateSlotHere<uint32_t>();
+ uintptr_t fb_block_start = w->position();
+#if defined(V8_TARGET_ARCH_IA32)
+ w->Write<uint8_t>(DW_OP_reg5); // The frame pointer's here on ia32
+#elif defined(V8_TARGET_ARCH_X64)
+ w->Write<uint8_t>(DW_OP_reg6); // and here on x64.
+#else
+#error Unsupported target architecture.
+#endif
+ fb_block_size.set(static_cast<uint32_t>(w->position() - fb_block_start));
+
+ int params = scope_info.number_of_parameters();
+ int slots = scope_info.number_of_stack_slots();
+ int context_slots = scope_info.number_of_context_slots();
+ // The real slot ID is internal_slots + context_slot_id.
+ int internal_slots = Context::MIN_CONTEXT_SLOTS;
+ int locals = scope_info.NumberOfLocals();
+ int current_abbreviation = 4;
+
+ for (int param = 0; param < params; ++param) {
+ w->WriteULEB128(current_abbreviation++);
+ w->WriteString(
+ *scope_info.parameter_name(param)->ToCString(DISALLOW_NULLS));
+ w->Write<uint32_t>(ty_offset);
+ Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
+ uintptr_t block_start = w->position();
+ w->Write<uint8_t>(DW_OP_fbreg);
+ w->WriteSLEB128(
+ JavaScriptFrameConstants::kLastParameterOffset +
+ kPointerSize * (params - param - 1));
+ block_size.set(static_cast<uint32_t>(w->position() - block_start));
+ }
+
+ EmbeddedVector<char, 256> buffer;
+ StringBuilder builder(buffer.start(), buffer.length());
+
+ for (int slot = 0; slot < slots; ++slot) {
+ w->WriteULEB128(current_abbreviation++);
+ builder.Reset();
+ builder.AddFormatted("slot%d", slot);
+ w->WriteString(builder.Finalize());
+ }
+
+ // See contexts.h for more information.
+ ASSERT(Context::MIN_CONTEXT_SLOTS == 5);
+ ASSERT(Context::CLOSURE_INDEX == 0);
+ ASSERT(Context::FCONTEXT_INDEX == 1);
+ ASSERT(Context::PREVIOUS_INDEX == 2);
+ ASSERT(Context::EXTENSION_INDEX == 3);
+ ASSERT(Context::GLOBAL_INDEX == 4);
+ w->WriteULEB128(current_abbreviation++);
+ w->WriteString(".closure");
+ w->WriteULEB128(current_abbreviation++);
+ w->WriteString(".fcontext");
+ w->WriteULEB128(current_abbreviation++);
+ w->WriteString(".previous");
+ w->WriteULEB128(current_abbreviation++);
+ w->WriteString(".extension");
+ w->WriteULEB128(current_abbreviation++);
+ w->WriteString(".global");
+
+ for (int context_slot = 0; context_slot < context_slots;
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 for(x; y; z)
zarko 2011/06/27 22:24:29 Done.
+ ++context_slot) {
+ w->WriteULEB128(current_abbreviation++);
+ builder.Reset();
+ builder.AddFormatted("context_slot%d", context_slot + internal_slots);
+ w->WriteString(builder.Finalize());
+ }
+
+ for (int local = 0; local < locals; ++local) {
+ w->WriteULEB128(current_abbreviation++);
+ w->WriteString(
+ *scope_info.LocalName(local)->ToCString(DISALLOW_NULLS));
+ w->Write<uint32_t>(ty_offset);
+ Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
+ uintptr_t block_start = w->position();
+ w->Write<uint8_t>(DW_OP_fbreg);
+ w->WriteSLEB128(
+ JavaScriptFrameConstants::kLocal0Offset -
+ kPointerSize * local);
+ block_size.set(static_cast<uint32_t>(w->position() - block_start));
+ }
+
+ {
+ w->WriteULEB128(current_abbreviation++);
+ w->WriteString("__function");
+ w->Write<uint32_t>(ty_offset);
+ Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
+ uintptr_t block_start = w->position();
+ w->Write<uint8_t>(DW_OP_fbreg);
+ w->WriteSLEB128(JavaScriptFrameConstants::kFunctionOffset);
+ block_size.set(static_cast<uint32_t>(w->position() - block_start));
+ }
+
+ {
+ w->WriteULEB128(current_abbreviation++);
+ w->WriteString("__context");
+ w->Write<uint32_t>(ty_offset);
+ Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
+ uintptr_t block_start = w->position();
+ w->Write<uint8_t>(DW_OP_fbreg);
+ w->WriteSLEB128(StandardFrameConstants::kContextOffset);
+ block_size.set(static_cast<uint32_t>(w->position() - block_start));
+ }
+ }
+
size.set(static_cast<uint32_t>(w->position() - start));
return true;
}
@@ -782,13 +1180,26 @@ class DebugInfoSection : public ELFSection {
};
-class DebugAbbrevSection : public ELFSection {
+class DebugAbbrevSection : public SECTION_BASE {
public:
- DebugAbbrevSection() : ELFSection(".debug_abbrev", TYPE_PROGBITS, 1) { }
+ explicit DebugAbbrevSection(CodeDescription* desc)
+#ifdef __ELF
+ : ELFSection(".debug_abbrev", TYPE_PROGBITS, 1),
+#else
+ : MachOSection("__debug_abbrev", "__DWARF", 1,
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 Argument per line
zarko 2011/06/27 22:24:29 Done.
+ MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG),
+#endif
+ desc_(desc) { }
// DWARF2 standard, figure 14.
enum DWARF2Tags {
- DW_TAG_COMPILE_UNIT = 0x11
+ DW_TAG_FORMAL_PARAMETER = 0x05,
+ DW_TAG_POINTER_TYPE = 0xf,
+ DW_TAG_COMPILE_UNIT = 0x11,
+ DW_TAG_STRUCTURE_TYPE = 0x13,
+ DW_TAG_BASE_TYPE = 0x24,
+ DW_TAG_SUBPROGRAM = 0x2e,
+ DW_TAG_VARIABLE = 0x34
};
// DWARF2 standard, figure 16.
@@ -799,23 +1210,35 @@ class DebugAbbrevSection : public ELFSection {
// DWARF standard, figure 17.
enum DWARF2Attribute {
+ DW_AT_LOCATION = 0x2,
DW_AT_NAME = 0x3,
+ DW_AT_BYTE_SIZE = 0xb,
DW_AT_STMT_LIST = 0x10,
DW_AT_LOW_PC = 0x11,
- DW_AT_HIGH_PC = 0x12
+ DW_AT_HIGH_PC = 0x12,
+ DW_AT_ENCODING = 0x3e,
+ DW_AT_FRAME_BASE = 0x40,
+ DW_AT_TYPE = 0x49
};
// DWARF2 standard, figure 19.
enum DWARF2AttributeForm {
DW_FORM_ADDR = 0x1,
+ DW_FORM_BLOCK4 = 0x4,
DW_FORM_STRING = 0x8,
- DW_FORM_DATA4 = 0x6
+ DW_FORM_DATA4 = 0x6,
+ DW_FORM_BLOCK = 0x9,
+ DW_FORM_DATA1 = 0xb,
+ DW_FORM_FLAG = 0xc,
+ DW_FORM_REF4 = 0x13
};
bool WriteBody(Writer* w) {
+ bool extra_info = desc_->IsInfoAvailable();
+ ASSERT(desc_->IsLineInfoAvailable());
w->WriteULEB128(1);
w->WriteULEB128(DW_TAG_COMPILE_UNIT);
- w->Write<uint8_t>(DW_CHILDREN_NO);
+ w->Write<uint8_t>(extra_info ? DW_CHILDREN_YES : DW_CHILDREN_NO);
w->WriteULEB128(DW_AT_NAME);
w->WriteULEB128(DW_FORM_STRING);
w->WriteULEB128(DW_AT_LOW_PC);
@@ -826,16 +1249,157 @@ class DebugAbbrevSection : public ELFSection {
w->WriteULEB128(DW_FORM_DATA4);
w->WriteULEB128(0);
w->WriteULEB128(0);
- w->WriteULEB128(0);
+
+ if (extra_info) {
+ CompilationInfo* info = desc_->info();
+ ScopeInfo<FreeStoreAllocationPolicy> scope_info(info->scope());
+ int params = scope_info.number_of_parameters();
+ int slots = scope_info.number_of_stack_slots();
+ int context_slots = scope_info.number_of_context_slots();
+ // The real slot ID is internal_slots + context_slot_id.
+ int internal_slots = Context::MIN_CONTEXT_SLOTS;
+ int locals = scope_info.NumberOfLocals();
+ int total_children =
+ params + slots + context_slots + internal_slots + locals + 2;
+
+ // The extra duplication below seems to be necessary to keep
+ // gdb from getting upset on OSX.
+
+ w->WriteULEB128(2); // Abbreviation code.
+ w->WriteULEB128(DW_TAG_SUBPROGRAM);
+ w->Write<uint8_t>(
+ total_children != 0 ? DW_CHILDREN_YES : DW_CHILDREN_NO);
+ w->WriteULEB128(DW_AT_NAME);
+ w->WriteULEB128(DW_FORM_STRING);
+ w->WriteULEB128(DW_AT_LOW_PC);
+ w->WriteULEB128(DW_FORM_ADDR);
+ w->WriteULEB128(DW_AT_HIGH_PC);
+ w->WriteULEB128(DW_FORM_ADDR);
+ w->WriteULEB128(DW_AT_FRAME_BASE);
+ w->WriteULEB128(DW_FORM_BLOCK4);
+ w->WriteULEB128(0);
+ w->WriteULEB128(0);
+
+ w->WriteULEB128(3);
+ w->WriteULEB128(DW_TAG_STRUCTURE_TYPE);
+ w->Write<uint8_t>(DW_CHILDREN_NO);
+ w->WriteULEB128(DW_AT_BYTE_SIZE);
+ w->WriteULEB128(DW_FORM_DATA1);
+ w->WriteULEB128(DW_AT_NAME);
+ w->WriteULEB128(DW_FORM_STRING);
+ w->WriteULEB128(0);
+ w->WriteULEB128(0);
+
+ int current_abbreviation = 4;
Vyacheslav Egorov (Chromium) 2011/06/23 11:28:37 Move it to the beginning of the function and use i
zarko 2011/06/27 22:24:29 Done.
+ for (int param = 0; param < params; ++param) {
+ w->WriteULEB128(current_abbreviation++);
+ w->WriteULEB128(DW_TAG_FORMAL_PARAMETER);
+ w->Write<uint8_t>(DW_CHILDREN_NO);
+ w->WriteULEB128(DW_AT_NAME);
+ w->WriteULEB128(DW_FORM_STRING);
+ w->WriteULEB128(DW_AT_TYPE);
+ w->WriteULEB128(DW_FORM_REF4);
+ w->WriteULEB128(DW_AT_LOCATION);
+ w->WriteULEB128(DW_FORM_BLOCK4);
+ w->WriteULEB128(0);
+ w->WriteULEB128(0);
+ }
+
+ for (int slot = 0; slot < slots; ++slot) {
+ w->WriteULEB128(current_abbreviation++);
+ w->WriteULEB128(DW_TAG_VARIABLE);
+ w->Write<uint8_t>(DW_CHILDREN_NO);
+ w->WriteULEB128(DW_AT_NAME);
+ w->WriteULEB128(DW_FORM_STRING);
+ w->WriteULEB128(0);
+ w->WriteULEB128(0);
+ }
+
+ for (int context_slot = 0; context_slot < context_slots;
Vyacheslav Egorov (Chromium) 2011/06/23 11:28:37 for(x; y; z)
zarko 2011/06/27 22:24:29 Done.
+ ++context_slot) {
+ w->WriteULEB128(current_abbreviation++);
Vyacheslav Egorov (Chromium) 2011/06/23 11:28:37 Seems to be duplicated. Extract to a method?
+ w->WriteULEB128(DW_TAG_VARIABLE);
+ w->Write<uint8_t>(DW_CHILDREN_NO);
+ w->WriteULEB128(DW_AT_NAME);
+ w->WriteULEB128(DW_FORM_STRING);
+ w->WriteULEB128(0);
+ w->WriteULEB128(0);
+ }
+
+ for (int internal_slot = 0; internal_slot < internal_slots;
Vyacheslav Egorov (Chromium) 2011/06/23 11:28:37 for(x; y; z)
zarko 2011/06/27 22:24:29 Done.
+ ++internal_slot) {
+ w->WriteULEB128(current_abbreviation++);
Vyacheslav Egorov (Chromium) 2011/06/23 11:28:37 Seems to be duplicated. Extract to a method? Mayb
+ w->WriteULEB128(DW_TAG_VARIABLE);
+ w->Write<uint8_t>(DW_CHILDREN_NO);
+ w->WriteULEB128(DW_AT_NAME);
+ w->WriteULEB128(DW_FORM_STRING);
+ w->WriteULEB128(0);
+ w->WriteULEB128(0);
+ }
+
+ for (int local = 0; local < locals; ++local) {
+ w->WriteULEB128(current_abbreviation++);
Vyacheslav Egorov (Chromium) 2011/06/23 11:28:37 Partially duplicated. If possible try to unify wit
+ w->WriteULEB128(DW_TAG_VARIABLE);
+ w->Write<uint8_t>(DW_CHILDREN_NO);
+ w->WriteULEB128(DW_AT_NAME);
+ w->WriteULEB128(DW_FORM_STRING);
+ w->WriteULEB128(DW_AT_TYPE);
+ w->WriteULEB128(DW_FORM_REF4);
+ w->WriteULEB128(DW_AT_LOCATION);
+ w->WriteULEB128(DW_FORM_BLOCK4);
+ w->WriteULEB128(0);
+ w->WriteULEB128(0);
+ }
+
+ // The function.
+ w->WriteULEB128(current_abbreviation++);
+ w->WriteULEB128(DW_TAG_VARIABLE);
+ w->Write<uint8_t>(DW_CHILDREN_NO);
+ w->WriteULEB128(DW_AT_NAME);
+ w->WriteULEB128(DW_FORM_STRING);
+ w->WriteULEB128(DW_AT_TYPE);
+ w->WriteULEB128(DW_FORM_REF4);
+ w->WriteULEB128(DW_AT_LOCATION);
+ w->WriteULEB128(DW_FORM_BLOCK4);
+ w->WriteULEB128(0);
+ w->WriteULEB128(0);
+
+ // The context.
+ w->WriteULEB128(current_abbreviation++);
Vyacheslav Egorov (Chromium) 2011/06/23 11:28:37 Duplicated?
+ w->WriteULEB128(DW_TAG_VARIABLE);
+ w->Write<uint8_t>(DW_CHILDREN_NO);
+ w->WriteULEB128(DW_AT_NAME);
+ w->WriteULEB128(DW_FORM_STRING);
+ w->WriteULEB128(DW_AT_TYPE);
+ w->WriteULEB128(DW_FORM_REF4);
+ w->WriteULEB128(DW_AT_LOCATION);
+ w->WriteULEB128(DW_FORM_BLOCK4);
+ w->WriteULEB128(0);
+ w->WriteULEB128(0);
+
+ if (total_children != 0) {
+ w->WriteULEB128(0); // Terminate the sibling list.
+ }
+ }
+
+ w->WriteULEB128(0); // Terminate the table.
return true;
}
+
+ private:
+ CodeDescription* desc_;
};
-class DebugLineSection : public ELFSection {
+class DebugLineSection : public SECTION_BASE {
public:
explicit DebugLineSection(CodeDescription* desc)
+#ifdef __ELF
: ELFSection(".debug_line", TYPE_PROGBITS, 1),
+#else
+ : MachOSection("__debug_line", "__DWARF", 1,
+ MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG),
+#endif
desc_(desc) { }
// DWARF2 standard, figure 34.
@@ -992,8 +1556,7 @@ class DebugLineSection : public ELFSection {
#ifdef V8_TARGET_ARCH_X64
-
-class UnwindInfoSection : public ELFSection {
+class UnwindInfoSection : public SECTION_BASE {
public:
explicit UnwindInfoSection(CodeDescription *desc);
virtual bool WriteBody(Writer *w);
@@ -1079,8 +1642,13 @@ void UnwindInfoSection::WriteLength(Writer *w,
UnwindInfoSection::UnwindInfoSection(CodeDescription *desc)
- : ELFSection(".eh_frame", TYPE_X86_64_UNWIND, 1), desc_(desc)
-{ }
+#ifdef __ELF
+ : ELFSection(".eh_frame", TYPE_X86_64_UNWIND, 1),
+#else
+ : MachOSection("__eh_frame", "__TEXT", sizeof(uintptr_t),
+ MachOSection::S_REGULAR),
+#endif
+ desc_(desc) { }
int UnwindInfoSection::WriteCIE(Writer *w) {
Writer::Slot<uint32_t> cie_length_slot = w->CreateSlotHere<uint32_t>();
@@ -1212,15 +1780,14 @@ bool UnwindInfoSection::WriteBody(Writer *w) {
#endif // V8_TARGET_ARCH_X64
-
-static void CreateDWARFSections(CodeDescription* desc, ELF* elf) {
+static void CreateDWARFSections(CodeDescription* desc, OBJ_FORMAT* obj) {
if (desc->IsLineInfoAvailable()) {
- elf->AddSection(new DebugInfoSection(desc));
- elf->AddSection(new DebugAbbrevSection);
- elf->AddSection(new DebugLineSection(desc));
+ obj->AddSection(new DebugInfoSection(desc));
+ obj->AddSection(new DebugAbbrevSection(desc));
+ obj->AddSection(new DebugLineSection(desc));
}
#ifdef V8_TARGET_ARCH_X64
- elf->AddSection(new UnwindInfoSection(desc));
+ obj->AddSection(new UnwindInfoSection(desc));
#endif
}
@@ -1260,6 +1827,13 @@ extern "C" {
// Static initialization is necessary to prevent GDB from seeing
// uninitialized descriptor.
JITDescriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
+
+#ifdef OBJECT_PRINT
+ void __gdb_print_v8_object(MaybeObject* object) {
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 Frankly speaking I don't see any reason to add thi
zarko 2011/06/27 22:24:29 gdb was having some trouble finding the symbol for
+ object->Print();
+ fprintf(stdout, "\n");
+ }
+#endif
}
@@ -1283,17 +1857,20 @@ static void DestroyCodeEntry(JITCodeEntry* entry) {
}
-static void RegisterCodeEntry(JITCodeEntry* entry) {
+static void RegisterCodeEntry(JITCodeEntry* entry,
+ bool dump_if_enabled,
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 something with indentation.
zarko 2011/06/27 22:24:29 Done.
+ const char* name_hint) {
#if defined(DEBUG) && !defined(WIN32)
static int file_num = 0;
- if (FLAG_gdbjit_dump) {
+ if (FLAG_gdbjit_dump && dump_if_enabled) {
static const int kMaxFileNameSize = 64;
static const char* kElfFilePrefix = "/tmp/elfdump";
static const char* kObjFileExt = ".o";
char file_name[64];
- OS::SNPrintF(Vector<char>(file_name, kMaxFileNameSize), "%s%d%s",
- kElfFilePrefix, file_num++, kObjFileExt);
+ OS::SNPrintF(Vector<char>(file_name, kMaxFileNameSize), "%s%s%d%s",
Vyacheslav Egorov (Chromium) 2011/06/23 11:14:47 One argument per line. (somehow I missed this pla
zarko 2011/06/27 22:24:29 Done.
+ kElfFilePrefix, (name_hint != NULL) ? name_hint : "",
+ file_num++, kObjFileExt);
WriteBytes(file_name, entry->symfile_addr_, entry->symfile_size_);
}
#endif
@@ -1327,7 +1904,18 @@ static void UnregisterCodeEntry(JITCodeEntry* entry) {
static JITCodeEntry* CreateELFObject(CodeDescription* desc) {
ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
+#ifdef __MACH_O
+ MachO mach_o;
+ Writer w(&mach_o);
+
+ mach_o.AddSection(new MachOTextSection(kCodeAlignment,
+ desc->CodeStart(),
+ desc->CodeSize()));
+
+ CreateDWARFSections(desc, &mach_o);
+ mach_o.Write(&w, desc->CodeStart(), desc->CodeSize());
+#else
ELF elf;
Writer w(&elf);
@@ -1345,6 +1933,7 @@ static JITCodeEntry* CreateELFObject(CodeDescription* desc) {
CreateDWARFSections(desc, &elf);
elf.Write(&w);
+#endif
return CreateCodeEntry(w.buffer(), w.position());
}
@@ -1393,7 +1982,8 @@ static GDBJITLineInfo* UntagLineInfo(void* ptr) {
void GDBJITInterface::AddCode(Handle<String> name,
Handle<Script> script,
- Handle<Code> code) {
+ Handle<Code> code,
+ CompilationInfo* info) {
if (!FLAG_gdbjit) return;
// Force initialization of line_ends array.
@@ -1401,9 +1991,9 @@ void GDBJITInterface::AddCode(Handle<String> name,
if (!name.is_null()) {
SmartPointer<char> name_cstring = name->ToCString(DISALLOW_NULLS);
- AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script);
+ AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script, info);
} else {
- AddCode("", *code, GDBJITInterface::FUNCTION, *script);
+ AddCode("", *code, GDBJITInterface::FUNCTION, *script, info);
}
}
@@ -1450,7 +2040,8 @@ Mutex* GDBJITInterface::mutex_ = OS::CreateMutex();
void GDBJITInterface::AddCode(const char* name,
Code* code,
GDBJITInterface::CodeTag tag,
- Script* script) {
+ Script* script,
+ CompilationInfo* info) {
if (!FLAG_gdbjit) return;
ScopedLock lock(mutex_);
@@ -1465,7 +2056,8 @@ void GDBJITInterface::AddCode(const char* name,
script != NULL ? Handle<Script>(script)
: Handle<Script>(),
lineinfo,
- tag);
+ tag,
+ info);
if (!FLAG_gdbjit_full && !code_desc.IsLineInfoAvailable()) {
delete lineinfo;
@@ -1480,7 +2072,18 @@ void GDBJITInterface::AddCode(const char* name,
delete lineinfo;
e->value = entry;
- RegisterCodeEntry(entry);
+ const char* name_hint = NULL;
+ bool should_dump = false;
+ if (FLAG_gdbjit_dump) {
+ if (strlen(FLAG_gdbjit_dump_filter) == 0) {
+ name_hint = name;
+ should_dump = true;
+ } else if (name != NULL) {
+ name_hint = strstr(name, FLAG_gdbjit_dump_filter);
+ should_dump = (name_hint != NULL);
+ }
+ }
+ RegisterCodeEntry(entry, should_dump, name_hint);
}
« src/gdb-jit.h ('K') | « src/gdb-jit.h ('k') | tools/gdb-v8-support.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698