1b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch// Copyright 2010 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/gdb-jit.h" 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include <memory> 8f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/bits.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/platform/platform.h" 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/bootstrapper.h" 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/frames-inl.h" 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/frames.h" 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/global-handles.h" 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/messages.h" 16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/objects.h" 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ostreams.h" 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/snapshot/natives.h" 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/splay-tree-inl.h" 20b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 21b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochnamespace v8 { 22b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochnamespace internal { 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace GDBJITInterface { 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef ENABLE_GDB_JIT_INTERFACE 26b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef __APPLE__ 283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define __MACH_O 293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass MachO; 303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass MachOSection; 313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtypedef MachO DebugObject; 323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtypedef MachOSection DebugSection; 333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else 343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#define __ELF 35b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochclass ELF; 363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass ELFSection; 373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtypedef ELF DebugObject; 383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtypedef ELFSection DebugSection; 393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 40b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 41b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochclass Writer BASE_EMBEDDED { 42b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch public: 433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch explicit Writer(DebugObject* debug_object) 443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : debug_object_(debug_object), 45b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch position_(0), 46b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch capacity_(1024), 47b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch buffer_(reinterpret_cast<byte*>(malloc(capacity_))) { 48b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 49b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 50b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ~Writer() { 51b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch free(buffer_); 52b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 53b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 54b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t position() const { 55b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return position_; 56b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 57b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 58b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch template<typename T> 59b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch class Slot { 60b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch public: 61b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Slot(Writer* w, uintptr_t offset) : w_(w), offset_(offset) { } 62b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 63b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch T* operator-> () { 64b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return w_->RawSlotAt<T>(offset_); 65b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 66b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 67b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void set(const T& value) { 68b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch *w_->RawSlotAt<T>(offset_) = value; 69b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 70b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 71b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Slot<T> at(int i) { 72b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return Slot<T>(w_, offset_ + sizeof(T) * i); 73b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 74b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 75b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private: 76b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Writer* w_; 77b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t offset_; 78b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch }; 79b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 80b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch template<typename T> 81b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void Write(const T& val) { 82b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Ensure(position_ + sizeof(T)); 83b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch *RawSlotAt<T>(position_) = val; 84b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch position_ += sizeof(T); 85b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 86b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 87b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch template<typename T> 88b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Slot<T> SlotAt(uintptr_t offset) { 89b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Ensure(offset + sizeof(T)); 90b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return Slot<T>(this, offset); 91b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 92b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 93b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch template<typename T> 94b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Slot<T> CreateSlotHere() { 95b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return CreateSlotsHere<T>(1); 96b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 97b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 98b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch template<typename T> 99b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Slot<T> CreateSlotsHere(uint32_t count) { 100b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t slot_position = position_; 101b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch position_ += sizeof(T) * count; 102b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Ensure(position_); 103b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return SlotAt<T>(slot_position); 104b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 105b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 106b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void Ensure(uintptr_t pos) { 107b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (capacity_ < pos) { 108b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch while (capacity_ < pos) capacity_ *= 2; 109b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch buffer_ = reinterpret_cast<byte*>(realloc(buffer_, capacity_)); 110b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 111b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 112b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DebugObject* debug_object() { return debug_object_; } 114b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 115b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch byte* buffer() { return buffer_; } 116b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 117b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void Align(uintptr_t align) { 118b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t delta = position_ % align; 119b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (delta == 0) return; 120b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t padding = align - delta; 121b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Ensure(position_ += padding); 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((position_ % align) == 0); 123b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 124b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 125b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void WriteULEB128(uintptr_t value) { 126b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch do { 127b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint8_t byte = value & 0x7F; 128b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch value >>= 7; 129b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (value != 0) byte |= 0x80; 130b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Write<uint8_t>(byte); 131b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } while (value != 0); 132b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 133b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 134b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void WriteSLEB128(intptr_t value) { 135b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch bool more = true; 136b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch while (more) { 137b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int8_t byte = value & 0x7F; 138b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch bool byte_sign = byte & 0x40; 139b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch value >>= 7; 140b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 141b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if ((value == 0 && !byte_sign) || (value == -1 && byte_sign)) { 142b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch more = false; 143b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } else { 144b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch byte |= 0x80; 145b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 146b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 147b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Write<int8_t>(byte); 148b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 149b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 150b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 151b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void WriteString(const char* str) { 152b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch do { 153b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Write<char>(*str); 154b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } while (*str++); 155b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 156b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 157b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private: 158b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch template<typename T> friend class Slot; 159b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 160b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch template<typename T> 161b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch T* RawSlotAt(uintptr_t offset) { 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(offset < capacity_ && offset + sizeof(T) <= capacity_); 163b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return reinterpret_cast<T*>(&buffer_[offset]); 164b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 165b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DebugObject* debug_object_; 167b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t position_; 168b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t capacity_; 169b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch byte* buffer_; 170b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}; 171b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ELFStringTable; 173b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochtemplate<typename THeader> 1753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass DebugSectionBase : public ZoneObject { 176b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch public: 1773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual ~DebugSectionBase() { } 1783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual void WriteBody(Writer::Slot<THeader> header, Writer* writer) { 1803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t start = writer->position(); 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (WriteBodyInternal(writer)) { 1823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t end = writer->position(); 183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch header->offset = static_cast<uint32_t>(start); 1843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(__MACH_O) 1853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->addr = 0; 1863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 1873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->size = end - start; 1883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual bool WriteBodyInternal(Writer* writer) { 1923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return false; 1933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch typedef THeader Header; 1963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}; 1973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochstruct MachOSectionHeader { 2003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch char sectname[16]; 2013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch char segname[16]; 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87 2033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t addr; 2043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t size; 2053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else 2063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint64_t addr; 2073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint64_t size; 2083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 2093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t offset; 2103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t align; 2113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t reloff; 2123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t nreloc; 2133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t flags; 2143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t reserved1; 2153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t reserved2; 2163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}; 2173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass MachOSection : public DebugSectionBase<MachOSectionHeader> { 2203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public: 2213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch enum Type { 2223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch S_REGULAR = 0x0u, 2233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch S_ATTR_COALESCED = 0xbu, 2243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch S_ATTR_SOME_INSTRUCTIONS = 0x400u, 2253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch S_ATTR_DEBUG = 0x02000000u, 2263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch S_ATTR_PURE_INSTRUCTIONS = 0x80000000u 227b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch }; 228b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MachOSection(const char* name, const char* segment, uint32_t align, 2303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t flags) 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : name_(name), segment_(segment), align_(align), flags_(flags) { 2323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (align_ != 0) { 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(base::bits::IsPowerOfTwo32(align)); 2343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch align_ = WhichPowerOf2(align_); 2353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual ~MachOSection() { } 2393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual void PopulateHeader(Writer::Slot<Header> header) { 2413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->addr = 0; 2423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->size = 0; 2433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->offset = 0; 2443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->align = align_; 2453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->reloff = 0; 2463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->nreloc = 0; 2473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->flags = flags_; 2483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->reserved1 = 0; 2493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->reserved2 = 0; 2503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch memset(header->sectname, 0, sizeof(header->sectname)); 2513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch memset(header->segname, 0, sizeof(header->segname)); 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(strlen(name_) < sizeof(header->sectname)); 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(strlen(segment_) < sizeof(header->segname)); 2543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch strncpy(header->sectname, name_, sizeof(header->sectname)); 2553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch strncpy(header->segname, segment_, sizeof(header->segname)); 2563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private: 2593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const char* name_; 2603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const char* segment_; 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t align_; 2623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t flags_; 2633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}; 2643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochstruct ELFSectionHeader { 2673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t name; 2683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t type; 2693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t flags; 2703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t address; 2713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t offset; 2723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t size; 2733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t link; 2743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t info; 2753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t alignment; 2763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t entry_size; 2773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}; 2783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 2803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(__ELF) 2813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass ELFSection : public DebugSectionBase<ELFSectionHeader> { 2823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public: 283b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch enum Type { 284b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_NULL = 0, 285b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_PROGBITS = 1, 286b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_SYMTAB = 2, 287b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_STRTAB = 3, 288b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_RELA = 4, 289b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_HASH = 5, 290b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_DYNAMIC = 6, 291b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_NOTE = 7, 292b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_NOBITS = 8, 293b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_REL = 9, 294b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_SHLIB = 10, 295b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_DYNSYM = 11, 296b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_LOPROC = 0x70000000, 2971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block TYPE_X86_64_UNWIND = 0x70000001, 298b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_HIPROC = 0x7fffffff, 299b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_LOUSER = 0x80000000, 300b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_HIUSER = 0xffffffff 301b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch }; 302b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 303b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch enum Flags { 304b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch FLAG_WRITE = 1, 305b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch FLAG_ALLOC = 2, 306b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch FLAG_EXEC = 4 307b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch }; 308b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 309b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch enum SpecialIndexes { 310b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch INDEX_ABSOLUTE = 0xfff1 311b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch }; 312b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 313b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ELFSection(const char* name, Type type, uintptr_t align) 314b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch : name_(name), type_(type), align_(align) { } 315b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 316b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch virtual ~ELFSection() { } 317b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void PopulateHeader(Writer::Slot<Header> header, ELFStringTable* strtab); 319b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 320b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch virtual void WriteBody(Writer::Slot<Header> header, Writer* w) { 321b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t start = w->position(); 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (WriteBodyInternal(w)) { 323b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t end = w->position(); 324b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->offset = start; 325b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->size = end - start; 326b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 327b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 328b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual bool WriteBodyInternal(Writer* w) { 330b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return false; 331b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 332b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 333b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint16_t index() const { return index_; } 334b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void set_index(uint16_t index) { index_ = index; } 335b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 336b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch protected: 337b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch virtual void PopulateHeader(Writer::Slot<Header> header) { 338b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->flags = 0; 339b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->address = 0; 340b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->offset = 0; 341b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->size = 0; 342b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->link = 0; 343b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->info = 0; 344b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->entry_size = 0; 345b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 346b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 347b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private: 348b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch const char* name_; 349b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Type type_; 350b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t align_; 351b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint16_t index_; 352b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}; 3533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif // defined(__ELF) 354b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 355b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 3563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(__MACH_O) 3573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass MachOTextSection : public MachOSection { 3583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public: 359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachOTextSection(uint32_t align, uintptr_t addr, uintptr_t size) 360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : MachOSection("__text", "__TEXT", align, 3613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch MachOSection::S_REGULAR | 3623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch MachOSection::S_ATTR_SOME_INSTRUCTIONS | 3633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch MachOSection::S_ATTR_PURE_INSTRUCTIONS), 3643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch addr_(addr), 365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_(size) {} 3663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch protected: 3683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual void PopulateHeader(Writer::Slot<Header> header) { 3693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch MachOSection::PopulateHeader(header); 3703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->addr = addr_; 3713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->size = size_; 3723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private: 3753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t addr_; 3763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t size_; 3773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}; 3783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif // defined(__MACH_O) 3793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 3813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(__ELF) 382b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochclass FullHeaderELFSection : public ELFSection { 383b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch public: 384b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch FullHeaderELFSection(const char* name, 385b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Type type, 386b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t align, 387b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t addr, 388b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t offset, 389b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t size, 390b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t flags) 391b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch : ELFSection(name, type, align), 392b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch addr_(addr), 393b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch offset_(offset), 394b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch size_(size), 395b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch flags_(flags) { } 396b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 397b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch protected: 398b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch virtual void PopulateHeader(Writer::Slot<Header> header) { 399b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ELFSection::PopulateHeader(header); 400b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->address = addr_; 401b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->offset = offset_; 402b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->size = size_; 403b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->flags = flags_; 404b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 405b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 406b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private: 407b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t addr_; 408b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t offset_; 409b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t size_; 410b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t flags_; 411b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}; 412b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 413b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ELFStringTable : public ELFSection { 415b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch public: 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit ELFStringTable(const char* name) 417b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch : ELFSection(name, TYPE_STRTAB, 1), writer_(NULL), offset_(0), size_(0) { 418b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 419b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 420b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t Add(const char* str) { 421b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (*str == '\0') return 0; 422b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 423b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t offset = size_; 424b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch WriteString(str); 425b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return offset; 426b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 427b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 428b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void AttachWriter(Writer* w) { 429b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch writer_ = w; 430b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch offset_ = writer_->position(); 431b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 432b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // First entry in the string table should be an empty string. 433b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch WriteString(""); 434b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 435b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 436b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void DetachWriter() { 437b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch writer_ = NULL; 438b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 439b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 440b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch virtual void WriteBody(Writer::Slot<Header> header, Writer* w) { 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(writer_ == NULL); 442b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->offset = offset_; 443b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->size = size_; 444b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 445b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 446b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private: 447b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void WriteString(const char* str) { 448b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t written = 0; 449b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch do { 450b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch writer_->Write(*str); 451b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch written++; 452b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } while (*str++); 453b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch size_ += written; 454b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 455b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 456b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Writer* writer_; 457b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 458b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t offset_; 459b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t size_; 460b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}; 461b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 462b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 463b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid ELFSection::PopulateHeader(Writer::Slot<ELFSection::Header> header, 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ELFStringTable* strtab) { 465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch header->name = static_cast<uint32_t>(strtab->Add(name_)); 466b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->type = type_; 467b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->alignment = align_; 468b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch PopulateHeader(header); 469b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch} 4703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif // defined(__ELF) 4713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(__MACH_O) 4743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass MachO BASE_EMBEDDED { 4753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public: 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit MachO(Zone* zone) : zone_(zone), sections_(6, zone) { } 4773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t AddSection(MachOSection* section) { 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sections_.Add(section, zone_); 4803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return sections_.length() - 1; 4813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 4823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void Write(Writer* w, uintptr_t code_start, uintptr_t code_size) { 4843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Writer::Slot<MachOHeader> header = WriteHeader(w); 4853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t load_command_start = w->position(); 4863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Writer::Slot<MachOSegmentCommand> cmd = WriteSegmentCommand(w, 4873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch code_start, 4883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch code_size); 4893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch WriteSections(w, cmd, header, load_command_start); 4903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 4913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private: 4933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch struct MachOHeader { 4943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t magic; 4953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t cputype; 4963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t cpusubtype; 4973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t filetype; 4983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t ncmds; 4993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t sizeofcmds; 5003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t flags; 501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_X64 5023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t reserved; 5033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 5043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch }; 5053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch struct MachOSegmentCommand { 5073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t cmd; 5083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t cmdsize; 5093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch char segname[16]; 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87 5113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t vmaddr; 5123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t vmsize; 5133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t fileoff; 5143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t filesize; 5153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else 5163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint64_t vmaddr; 5173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint64_t vmsize; 5183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint64_t fileoff; 5193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint64_t filesize; 5203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 5213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t maxprot; 5223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t initprot; 5233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t nsects; 5243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t flags; 5253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch }; 5263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch enum MachOLoadCommandCmd { 5283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch LC_SEGMENT_32 = 0x00000001u, 5293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch LC_SEGMENT_64 = 0x00000019u 5303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch }; 5313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Writer::Slot<MachOHeader> WriteHeader(Writer* w) { 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(w->position() == 0); 5353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Writer::Slot<MachOHeader> header = w->CreateSlotHere<MachOHeader>(); 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87 5373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->magic = 0xFEEDFACEu; 5383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->cputype = 7; // i386 5393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->cpusubtype = 3; // CPU_SUBTYPE_I386_ALL 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif V8_TARGET_ARCH_X64 5413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->magic = 0xFEEDFACFu; 5423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->cputype = 7 | 0x01000000; // i386 | 64-bit ABI 5433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->cpusubtype = 3; // CPU_SUBTYPE_I386_ALL 5443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->reserved = 0; 5453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else 5463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#error Unsupported target architecture. 5473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 5483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->filetype = 0x1; // MH_OBJECT 5493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->ncmds = 1; 5503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->sizeofcmds = 0; 5513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch header->flags = 0; 5523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return header; 5533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 554b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 555b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 5563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Writer::Slot<MachOSegmentCommand> WriteSegmentCommand(Writer* w, 5573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t code_start, 5583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t code_size) { 5593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Writer::Slot<MachOSegmentCommand> cmd = 5603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->CreateSlotHere<MachOSegmentCommand>(); 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87 5623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch cmd->cmd = LC_SEGMENT_32; 5633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else 5643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch cmd->cmd = LC_SEGMENT_64; 5653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 5663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch cmd->vmaddr = code_start; 5673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch cmd->vmsize = code_size; 5683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch cmd->fileoff = 0; 5693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch cmd->filesize = 0; 5703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch cmd->maxprot = 7; 5713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch cmd->initprot = 7; 5723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch cmd->flags = 0; 5733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch cmd->nsects = sections_.length(); 5743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch memset(cmd->segname, 0, 16); 5753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch cmd->cmdsize = sizeof(MachOSegmentCommand) + sizeof(MachOSection::Header) * 5763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch cmd->nsects; 5773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return cmd; 5783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void WriteSections(Writer* w, 5823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Writer::Slot<MachOSegmentCommand> cmd, 5833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Writer::Slot<MachOHeader> header, 5843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t load_command_start) { 5853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Writer::Slot<MachOSection::Header> headers = 5863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->CreateSlotsHere<MachOSection::Header>(sections_.length()); 5873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch cmd->fileoff = w->position(); 588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch header->sizeofcmds = 589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<uint32_t>(w->position() - load_command_start); 5903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int section = 0; section < sections_.length(); ++section) { 5913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch sections_[section]->PopulateHeader(headers.at(section)); 5923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch sections_[section]->WriteBody(headers.at(section), w); 5933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch cmd->filesize = w->position() - (uintptr_t)cmd->fileoff; 5953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 5963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone_; 5983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ZoneList<MachOSection*> sections_; 5993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}; 6003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif // defined(__MACH_O) 6013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(__ELF) 604b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochclass ELF BASE_EMBEDDED { 605b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch public: 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit ELF(Zone* zone) : zone_(zone), sections_(6, zone) { 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sections_.Add(new(zone) ELFSection("", ELFSection::TYPE_NULL, 0), zone); 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sections_.Add(new(zone) ELFStringTable(".shstrtab"), zone); 609b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 610b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 611b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void Write(Writer* w) { 612b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch WriteHeader(w); 613b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch WriteSectionTable(w); 614b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch WriteSections(w); 615b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 616b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 617b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ELFSection* SectionAt(uint32_t index) { 618b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return sections_[index]; 619b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 620b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 621b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint32_t AddSection(ELFSection* section) { 622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sections_.Add(section, zone_); 623b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch section->set_index(sections_.length() - 1); 624b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return sections_.length() - 1; 625b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 626b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 627b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private: 628b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch struct ELFHeader { 629b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint8_t ident[16]; 630b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint16_t type; 631b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint16_t machine; 632b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint32_t version; 633b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t entry; 634b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t pht_offset; 635b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t sht_offset; 636b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint32_t flags; 637b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint16_t header_size; 638b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint16_t pht_entry_size; 639b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint16_t pht_entry_num; 640b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint16_t sht_entry_size; 641b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint16_t sht_entry_num; 642b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint16_t sht_strtab_index; 643b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch }; 644b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 645b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 646b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void WriteHeader(Writer* w) { 647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(w->position() == 0); 648b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Writer::Slot<ELFHeader> header = w->CreateSlotHere<ELFHeader>(); 649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if (V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X87 || \ 650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT)) 651b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch const uint8_t ident[16] = 652b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch { 0x7f, 'E', 'L', 'F', 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#elif(V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_64_BIT) || \ 654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (V8_TARGET_ARCH_PPC64 && V8_TARGET_LITTLE_ENDIAN) 655b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch const uint8_t ident[16] = 656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 0x7f, 'E', 'L', 'F', 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#elif V8_TARGET_ARCH_PPC64 && V8_TARGET_BIG_ENDIAN && V8_OS_LINUX 658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const uint8_t ident[16] = {0x7f, 'E', 'L', 'F', 2, 2, 1, 0, 659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 0, 0, 0, 0, 0, 0, 0, 0}; 6603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#elif V8_TARGET_ARCH_S390X 6613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch const uint8_t ident[16] = {0x7f, 'E', 'L', 'F', 2, 2, 1, 3, 6623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 0, 0, 0, 0, 0, 0, 0, 0}; 6633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#elif V8_TARGET_ARCH_S390 6643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch const uint8_t ident[16] = {0x7f, 'E', 'L', 'F', 1, 2, 1, 3, 6653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 0, 0, 0, 0, 0, 0, 0, 0}; 666b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#else 667b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#error Unsupported target architecture. 668b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#endif 669b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch memcpy(header->ident, ident, 16); 670b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->type = 1; 671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87 672b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->machine = 3; 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif V8_TARGET_ARCH_X64 674b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Processor identification value for x64 is 62 as defined in 675b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // System V ABI, AMD64 Supplement 676b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // http://www.x86-64.org/documentation/abi.pdf 677b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->machine = 62; 678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif V8_TARGET_ARCH_ARM 679e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Set to EM_ARM, defined as 40, in "ARM ELF File Format" at 680e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // infocenter.arm.com/help/topic/com.arm.doc.dui0101a/DUI0101A_Elf.pdf 681e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch header->machine = 40; 682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#elif V8_TARGET_ARCH_PPC64 && V8_OS_LINUX 683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Set to EM_PPC64, defined as 21, in Power ABI, 684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Join the next 4 lines, omitting the spaces and double-slashes. 685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // https://www-03.ibm.com/technologyconnect/tgcm/TGCMFileServlet.wss/ 686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // ABI64BitOpenPOWERv1.1_16July2015_pub.pdf? 687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // id=B81AEC1A37F5DAF185257C3E004E8845&linkid=1n0000&c_t= 688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // c9xw7v5dzsj7gt1ifgf4cjbcnskqptmr 689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch header->machine = 21; 6903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#elif V8_TARGET_ARCH_S390 6913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Processor identification value is 22 (EM_S390) as defined in the ABI: 6923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // http://refspecs.linuxbase.org/ELF/zSeries/lzsabi0_s390.html#AEN1691 6933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // http://refspecs.linuxbase.org/ELF/zSeries/lzsabi0_zSeries.html#AEN1599 6943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch header->machine = 22; 695b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#else 696b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#error Unsupported target architecture. 697b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#endif 698b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->version = 1; 699b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->entry = 0; 700b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->pht_offset = 0; 701b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->sht_offset = sizeof(ELFHeader); // Section table follows header. 702b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->flags = 0; 703b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->header_size = sizeof(ELFHeader); 704b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->pht_entry_size = 0; 705b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->pht_entry_num = 0; 706b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->sht_entry_size = sizeof(ELFSection::Header); 707b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->sht_entry_num = sections_.length(); 708b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->sht_strtab_index = 1; 709b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 710b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 711b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void WriteSectionTable(Writer* w) { 712b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Section headers table immediately follows file header. 713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(w->position() == sizeof(ELFHeader)); 714b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 715b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Writer::Slot<ELFSection::Header> headers = 716b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->CreateSlotsHere<ELFSection::Header>(sections_.length()); 717b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 718b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // String table for section table is the first section. 719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ELFStringTable* strtab = static_cast<ELFStringTable*>(SectionAt(1)); 720b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch strtab->AttachWriter(w); 721b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch for (int i = 0, length = sections_.length(); 722b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch i < length; 723b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch i++) { 724b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch sections_[i]->PopulateHeader(headers.at(i), strtab); 725b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 726b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch strtab->DetachWriter(); 727b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 728b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 729b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int SectionHeaderPosition(uint32_t section_index) { 730b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return sizeof(ELFHeader) + sizeof(ELFSection::Header) * section_index; 731b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 732b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 733b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void WriteSections(Writer* w) { 734b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Writer::Slot<ELFSection::Header> headers = 735b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->SlotAt<ELFSection::Header>(sizeof(ELFHeader)); 736b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 737b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch for (int i = 0, length = sections_.length(); 738b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch i < length; 739b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch i++) { 740b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch sections_[i]->WriteBody(headers.at(i), w); 741b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 742b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 743b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone_; 745b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ZoneList<ELFSection*> sections_; 746b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}; 747b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 748b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 749b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochclass ELFSymbol BASE_EMBEDDED { 750b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch public: 751b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch enum Type { 752b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_NOTYPE = 0, 753b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_OBJECT = 1, 754b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_FUNC = 2, 755b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_SECTION = 3, 756b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_FILE = 4, 757b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_LOPROC = 13, 758b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch TYPE_HIPROC = 15 759b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch }; 760b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 761b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch enum Binding { 762b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch BIND_LOCAL = 0, 763b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch BIND_GLOBAL = 1, 764b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch BIND_WEAK = 2, 765b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch BIND_LOPROC = 13, 766b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch BIND_HIPROC = 15 767b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch }; 768b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 769b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ELFSymbol(const char* name, 770b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t value, 771b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t size, 772b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Binding binding, 773b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Type type, 774b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint16_t section) 775b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch : name(name), 776b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch value(value), 777b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch size(size), 778b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch info((binding << 4) | type), 779b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch other(0), 780b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch section(section) { 781b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 782b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 783b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Binding binding() const { 784b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return static_cast<Binding>(info >> 4); 785b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if (V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_X87 || \ 7873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch (V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT) || \ 7883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch (V8_TARGET_ARCH_S390 && V8_TARGET_ARCH_32_BIT)) 789b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch struct SerializedLayout { 790b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch SerializedLayout(uint32_t name, 791b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t value, 792b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t size, 793b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Binding binding, 794b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Type type, 795b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint16_t section) 796b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch : name(name), 797b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch value(value), 798b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch size(size), 799b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch info((binding << 4) | type), 800b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch other(0), 801b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch section(section) { 802b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 803b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 804b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint32_t name; 805b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t value; 806b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t size; 807b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint8_t info; 808b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint8_t other; 809b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint16_t section; 810b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch }; 811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#elif(V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_64_BIT) || \ 8123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch (V8_TARGET_ARCH_PPC64 && V8_OS_LINUX) || V8_TARGET_ARCH_S390X 813b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch struct SerializedLayout { 814b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch SerializedLayout(uint32_t name, 815b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t value, 816b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t size, 817b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Binding binding, 818b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Type type, 819b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint16_t section) 820b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch : name(name), 821b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch info((binding << 4) | type), 822b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch other(0), 823b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch section(section), 824b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch value(value), 825b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch size(size) { 826b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 827b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 828b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint32_t name; 829b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint8_t info; 830b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint8_t other; 831b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint16_t section; 832b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t value; 833b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t size; 834b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch }; 835b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#endif 836b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Write(Writer::Slot<SerializedLayout> s, ELFStringTable* t) { 838b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Convert symbol names from strings to indexes in the string table. 839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch s->name = static_cast<uint32_t>(t->Add(name)); 840b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch s->value = value; 841b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch s->size = size; 842b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch s->info = info; 843b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch s->other = other; 844b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch s->section = section; 845b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 846b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 847b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private: 848b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch const char* name; 849b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t value; 850b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t size; 851b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint8_t info; 852b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint8_t other; 853b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint16_t section; 854b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}; 855b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 856b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 857b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochclass ELFSymbolTable : public ELFSection { 858b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch public: 859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ELFSymbolTable(const char* name, Zone* zone) 860b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch : ELFSection(name, TYPE_SYMTAB, sizeof(uintptr_t)), 861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch locals_(1, zone), 862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch globals_(1, zone) { 863b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 864b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 865b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch virtual void WriteBody(Writer::Slot<Header> header, Writer* w) { 866b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->Align(header->alignment); 867b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int total_symbols = locals_.length() + globals_.length() + 1; 868b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->offset = w->position(); 869b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 870b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Writer::Slot<ELFSymbol::SerializedLayout> symbols = 871b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->CreateSlotsHere<ELFSymbol::SerializedLayout>(total_symbols); 872b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 873b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->size = w->position() - header->offset; 874b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 875b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // String table for this symbol table should follow it in the section table. 876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ELFStringTable* strtab = 877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<ELFStringTable*>(w->debug_object()->SectionAt(index() + 1)); 878b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch strtab->AttachWriter(w); 879b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch symbols.at(0).set(ELFSymbol::SerializedLayout(0, 880b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 0, 881b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 0, 882b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ELFSymbol::BIND_LOCAL, 883b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ELFSymbol::TYPE_NOTYPE, 884b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 0)); 885b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch WriteSymbolsList(&locals_, symbols.at(1), strtab); 886b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch WriteSymbolsList(&globals_, symbols.at(locals_.length() + 1), strtab); 887b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch strtab->DetachWriter(); 888b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 889b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Add(const ELFSymbol& symbol, Zone* zone) { 891b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (symbol.binding() == ELFSymbol::BIND_LOCAL) { 892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch locals_.Add(symbol, zone); 893b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } else { 894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch globals_.Add(symbol, zone); 895b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 896b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 897b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 898b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch protected: 899b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch virtual void PopulateHeader(Writer::Slot<Header> header) { 900b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ELFSection::PopulateHeader(header); 901b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // We are assuming that string table will follow symbol table. 902b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->link = index() + 1; 903b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->info = locals_.length() + 1; 904b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch header->entry_size = sizeof(ELFSymbol::SerializedLayout); 905b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 906b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 907b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private: 908b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void WriteSymbolsList(const ZoneList<ELFSymbol>* src, 909b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Writer::Slot<ELFSymbol::SerializedLayout> dst, 910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ELFStringTable* strtab) { 911b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch for (int i = 0, len = src->length(); 912b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch i < len; 913b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch i++) { 914b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch src->at(i).Write(dst.at(i), strtab); 915b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 916b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 917b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 918b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ZoneList<ELFSymbol> locals_; 919b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ZoneList<ELFSymbol> globals_; 920b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}; 9213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif // defined(__ELF) 922b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 923b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LineInfo : public Malloced { 925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LineInfo() : pc_info_(10) {} 927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetPosition(intptr_t pc, int pos, bool is_statement) { 929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddPCInfo(PCInfo(pc, pos, is_statement)); 930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch struct PCInfo { 933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PCInfo(intptr_t pc, int pos, bool is_statement) 934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : pc_(pc), pos_(pos), is_statement_(is_statement) {} 935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t pc_; 937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int pos_; 938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_statement_; 939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<PCInfo>* pc_info() { return &pc_info_; } 942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddPCInfo(const PCInfo& pc_info) { pc_info_.Add(pc_info); } 945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<PCInfo> pc_info_; 947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 950b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochclass CodeDescription BASE_EMBEDDED { 951b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch public: 952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_X64 9531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block enum StackState { 9541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block POST_RBP_PUSH, 9551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block POST_RBP_SET, 9561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block POST_RBP_POP, 9571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block STACK_STATE_MAX 9581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block }; 9591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#endif 9601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodeDescription(const char* name, Code* code, SharedFunctionInfo* shared, 962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LineInfo* lineinfo) 963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : name_(name), code_(code), shared_info_(shared), lineinfo_(lineinfo) {} 964b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 9651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block const char* name() const { 966b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return name_; 967b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 968b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LineInfo* lineinfo() const { return lineinfo_; } 9701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_function() const { 972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Code::Kind kind = code_->kind(); 973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return kind == Code::FUNCTION || kind == Code::OPTIMIZED_FUNCTION; 9741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 9751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool has_scope_info() const { return shared_info_ != NULL; } 9773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ScopeInfo* scope_info() const { 979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(has_scope_info()); 980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return shared_info_->scope_info(); 9813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 9823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 9831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block uintptr_t CodeStart() const { 9841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return reinterpret_cast<uintptr_t>(code_->instruction_start()); 985b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 986b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 9871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block uintptr_t CodeEnd() const { 9881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return reinterpret_cast<uintptr_t>(code_->instruction_end()); 989b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 990b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 9911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block uintptr_t CodeSize() const { 9921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return CodeEnd() - CodeStart(); 9931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 9941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool has_script() { 996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return shared_info_ != NULL && shared_info_->script()->IsScript(); 997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Script* script() { return Script::cast(shared_info_->script()); } 1000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool IsLineInfoAvailable() { 1002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return has_script() && script()->source()->IsString() && 1003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch script()->HasValidSource() && script()->name()->IsString() && 1004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lineinfo_ != NULL; 1005b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 1006b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_X64 10081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block uintptr_t GetStackStateStartAddress(StackState state) const { 1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(state < STACK_STATE_MAX); 10101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return stack_state_start_addresses_[state]; 10111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 1012b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 10131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block void SetStackStateStartAddress(StackState state, uintptr_t addr) { 1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(state < STACK_STATE_MAX); 10151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block stack_state_start_addresses_[state] = addr; 10161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 10171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#endif 10181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1019f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::unique_ptr<char[]> GetFilename() { 1020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return String::cast(script()->name())->ToCString(); 1021b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 1022b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int GetScriptLineNumber(int pos) { return script()->GetLineNumber(pos) + 1; } 1024b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 10251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1026b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private: 1027b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch const char* name_; 1028b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Code* code_; 1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SharedFunctionInfo* shared_info_; 1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LineInfo* lineinfo_; 1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_X64 10321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block uintptr_t stack_state_start_addresses_[STACK_STATE_MAX]; 10331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#endif 1034b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}; 1035b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 10363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(__ELF) 1037b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochstatic void CreateSymbolsTable(CodeDescription* desc, 1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone, 1039b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ELF* elf, 1040b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int text_section_index) { 1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ELFSymbolTable* symtab = new(zone) ELFSymbolTable(".symtab", zone); 1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ELFStringTable* strtab = new(zone) ELFStringTable(".strtab"); 1043b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1044b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Symbol table should be followed by the linked string table. 1045b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch elf->AddSection(symtab); 1046b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch elf->AddSection(strtab); 1047b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1048b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch symtab->Add(ELFSymbol("V8 Code", 1049b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 0, 1050b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 0, 1051b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ELFSymbol::BIND_LOCAL, 1052b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ELFSymbol::TYPE_FILE, 1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ELFSection::INDEX_ABSOLUTE), 1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zone); 1055b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 10561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block symtab->Add(ELFSymbol(desc->name(), 1057b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 0, 10581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block desc->CodeSize(), 1059b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ELFSymbol::BIND_GLOBAL, 1060b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ELFSymbol::TYPE_FUNC, 1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch text_section_index), 1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zone); 1063b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch} 10643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif // defined(__ELF) 1065b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1066b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 10673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass DebugInfoSection : public DebugSection { 1068b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch public: 1069b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch explicit DebugInfoSection(CodeDescription* desc) 10703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#if defined(__ELF) 10713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : ELFSection(".debug_info", TYPE_PROGBITS, 1), 10723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else 10733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : MachOSection("__debug_info", 10743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "__DWARF", 10753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1, 10763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG), 10773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 10783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch desc_(desc) { } 10793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 10803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // DWARF2 standard 10813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch enum DWARF2LocationOp { 10823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_OP_reg0 = 0x50, 10833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_OP_reg1 = 0x51, 10843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_OP_reg2 = 0x52, 10853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_OP_reg3 = 0x53, 10863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_OP_reg4 = 0x54, 10873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_OP_reg5 = 0x55, 10883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_OP_reg6 = 0x56, 10893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_OP_reg7 = 0x57, 1090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg8 = 0x58, 1091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg9 = 0x59, 1092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg10 = 0x5a, 1093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg11 = 0x5b, 1094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg12 = 0x5c, 1095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg13 = 0x5d, 1096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg14 = 0x5e, 1097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg15 = 0x5f, 1098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg16 = 0x60, 1099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg17 = 0x61, 1100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg18 = 0x62, 1101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg19 = 0x63, 1102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg20 = 0x64, 1103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg21 = 0x65, 1104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg22 = 0x66, 1105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg23 = 0x67, 1106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg24 = 0x68, 1107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg25 = 0x69, 1108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg26 = 0x6a, 1109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg27 = 0x6b, 1110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg28 = 0x6c, 1111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg29 = 0x6d, 1112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg30 = 0x6e, 1113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DW_OP_reg31 = 0x6f, 11143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_OP_fbreg = 0x91 // 1 param: SLEB128 offset 11153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch }; 11163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 11173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch enum DWARF2Encoding { 11183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_ATE_ADDRESS = 0x1, 11193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_ATE_SIGNED = 0x5 11203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch }; 1121b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool WriteBodyInternal(Writer* w) { 11233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t cu_start = w->position(); 1124b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Writer::Slot<uint32_t> size = w->CreateSlotHere<uint32_t>(); 1125b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t start = w->position(); 1126b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->Write<uint16_t>(2); // DWARF version. 1127b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->Write<uint32_t>(0); // Abbreviation table offset. 1128b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->Write<uint8_t>(sizeof(intptr_t)); 1129b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1130b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->WriteULEB128(1); // Abbreviation code. 1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch w->WriteString(desc_->GetFilename().get()); 11321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<intptr_t>(desc_->CodeStart()); 11331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize()); 1134b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->Write<uint32_t>(0); 11353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 11363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t ty_offset = static_cast<uint32_t>(w->position() - cu_start); 11373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(3); 11383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->Write<uint8_t>(kPointerSize); 11393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteString("v8value"); 11403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (desc_->has_scope_info()) { 1142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ScopeInfo* scope = desc_->scope_info(); 11433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(2); 11443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteString(desc_->name()); 11453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->Write<intptr_t>(desc_->CodeStart()); 11463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize()); 11473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Writer::Slot<uint32_t> fb_block_size = w->CreateSlotHere<uint32_t>(); 11483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t fb_block_start = w->position(); 1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87 11503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->Write<uint8_t>(DW_OP_reg5); // The frame pointer's here on ia32 1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif V8_TARGET_ARCH_X64 11523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->Write<uint8_t>(DW_OP_reg6); // and here on x64. 1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif V8_TARGET_ARCH_ARM 1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNIMPLEMENTED(); 1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif V8_TARGET_ARCH_MIPS 1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNIMPLEMENTED(); 1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#elif V8_TARGET_ARCH_MIPS64 1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNIMPLEMENTED(); 1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#elif V8_TARGET_ARCH_PPC64 && V8_OS_LINUX 1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch w->Write<uint8_t>(DW_OP_reg31); // The frame pointer is here on PPC64. 11613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#elif V8_TARGET_ARCH_S390 11623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch w->Write<uint8_t>(DW_OP_reg11); // The frame pointer's here on S390. 11633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else 11643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#error Unsupported target architecture. 11653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 11663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch fb_block_size.set(static_cast<uint32_t>(w->position() - fb_block_start)); 11673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int params = scope->ParameterCount(); 1169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int slots = scope->StackLocalCount(); 1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int context_slots = scope->ContextLocalCount(); 11713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // The real slot ID is internal_slots + context_slot_id. 11723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int internal_slots = Context::MIN_CONTEXT_SLOTS; 1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int locals = scope->StackLocalCount(); 11743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int current_abbreviation = 4; 11753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 11763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int param = 0; param < params; ++param) { 11773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(current_abbreviation++); 11783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteString( 1179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch scope->ParameterName(param)->ToCString(DISALLOW_NULLS).get()); 11803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->Write<uint32_t>(ty_offset); 11813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>(); 11823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t block_start = w->position(); 11833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->Write<uint8_t>(DW_OP_fbreg); 11843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteSLEB128( 11853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch JavaScriptFrameConstants::kLastParameterOffset + 11863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch kPointerSize * (params - param - 1)); 11873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch block_size.set(static_cast<uint32_t>(w->position() - block_start)); 11883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 11893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 11903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch EmbeddedVector<char, 256> buffer; 11913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch StringBuilder builder(buffer.start(), buffer.length()); 11923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 11933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int slot = 0; slot < slots; ++slot) { 11943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(current_abbreviation++); 11953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch builder.Reset(); 11963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch builder.AddFormatted("slot%d", slot); 11973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteString(builder.Finalize()); 11983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 11993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 12003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // See contexts.h for more information. 1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Context::MIN_CONTEXT_SLOTS == 4); 1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Context::CLOSURE_INDEX == 0); 1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Context::PREVIOUS_INDEX == 1); 1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Context::EXTENSION_INDEX == 2); 1205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(Context::NATIVE_CONTEXT_INDEX == 3); 12063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(current_abbreviation++); 12073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteString(".closure"); 12083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(current_abbreviation++); 12093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteString(".previous"); 12103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(current_abbreviation++); 12113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteString(".extension"); 12123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(current_abbreviation++); 1213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch w->WriteString(".native_context"); 12143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 12153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int context_slot = 0; 12163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch context_slot < context_slots; 12173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++context_slot) { 12183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(current_abbreviation++); 12193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch builder.Reset(); 12203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch builder.AddFormatted("context_slot%d", context_slot + internal_slots); 12213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteString(builder.Finalize()); 12223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 12233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 12243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int local = 0; local < locals; ++local) { 12253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(current_abbreviation++); 12263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteString( 1227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch scope->StackLocalName(local)->ToCString(DISALLOW_NULLS).get()); 12283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->Write<uint32_t>(ty_offset); 12293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>(); 12303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t block_start = w->position(); 12313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->Write<uint8_t>(DW_OP_fbreg); 12323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteSLEB128( 12333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch JavaScriptFrameConstants::kLocal0Offset - 12343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch kPointerSize * local); 12353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch block_size.set(static_cast<uint32_t>(w->position() - block_start)); 12363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 12373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 12383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch { 12393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(current_abbreviation++); 12403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteString("__function"); 12413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->Write<uint32_t>(ty_offset); 12423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>(); 12433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t block_start = w->position(); 12443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->Write<uint8_t>(DW_OP_fbreg); 12453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteSLEB128(JavaScriptFrameConstants::kFunctionOffset); 12463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch block_size.set(static_cast<uint32_t>(w->position() - block_start)); 12473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 12483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 12493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch { 12503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(current_abbreviation++); 12513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteString("__context"); 12523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->Write<uint32_t>(ty_offset); 12533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>(); 12543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uintptr_t block_start = w->position(); 12553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->Write<uint8_t>(DW_OP_fbreg); 12563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteSLEB128(StandardFrameConstants::kContextOffset); 12573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch block_size.set(static_cast<uint32_t>(w->position() - block_start)); 12583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch w->WriteULEB128(0); // Terminate the sub program. 12613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 12623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch w->WriteULEB128(0); // Terminate the compile unit. 1264b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch size.set(static_cast<uint32_t>(w->position() - start)); 1265b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return true; 1266b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 1267b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1268b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private: 1269b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch CodeDescription* desc_; 1270b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}; 1271b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1272b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 12733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass DebugAbbrevSection : public DebugSection { 1274b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch public: 12753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch explicit DebugAbbrevSection(CodeDescription* desc) 12763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef __ELF 12773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : ELFSection(".debug_abbrev", TYPE_PROGBITS, 1), 12783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else 12793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : MachOSection("__debug_abbrev", 12803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "__DWARF", 12813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1, 12823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG), 12833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 12843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch desc_(desc) { } 1285b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1286b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // DWARF2 standard, figure 14. 1287b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch enum DWARF2Tags { 12883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_TAG_FORMAL_PARAMETER = 0x05, 12893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_TAG_POINTER_TYPE = 0xf, 12903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_TAG_COMPILE_UNIT = 0x11, 12913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_TAG_STRUCTURE_TYPE = 0x13, 12923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_TAG_BASE_TYPE = 0x24, 12933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_TAG_SUBPROGRAM = 0x2e, 12943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_TAG_VARIABLE = 0x34 1295b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch }; 1296b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1297b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // DWARF2 standard, figure 16. 1298b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch enum DWARF2ChildrenDetermination { 1299b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch DW_CHILDREN_NO = 0, 1300b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch DW_CHILDREN_YES = 1 1301b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch }; 1302b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1303b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // DWARF standard, figure 17. 1304b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch enum DWARF2Attribute { 13053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_AT_LOCATION = 0x2, 1306b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch DW_AT_NAME = 0x3, 13073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_AT_BYTE_SIZE = 0xb, 1308b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch DW_AT_STMT_LIST = 0x10, 1309b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch DW_AT_LOW_PC = 0x11, 13103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_AT_HIGH_PC = 0x12, 13113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_AT_ENCODING = 0x3e, 13123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_AT_FRAME_BASE = 0x40, 13133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_AT_TYPE = 0x49 1314b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch }; 1315b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1316b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // DWARF2 standard, figure 19. 1317b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch enum DWARF2AttributeForm { 1318b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch DW_FORM_ADDR = 0x1, 13193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_FORM_BLOCK4 = 0x4, 1320b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch DW_FORM_STRING = 0x8, 13213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_FORM_DATA4 = 0x6, 13223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_FORM_BLOCK = 0x9, 13233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_FORM_DATA1 = 0xb, 13243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_FORM_FLAG = 0xc, 13253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DW_FORM_REF4 = 0x13 1326b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch }; 1327b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 13283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void WriteVariableAbbreviation(Writer* w, 13293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int abbreviation_code, 13303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool has_value, 13313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool is_parameter) { 13323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(abbreviation_code); 13333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(is_parameter ? DW_TAG_FORMAL_PARAMETER : DW_TAG_VARIABLE); 13343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->Write<uint8_t>(DW_CHILDREN_NO); 13353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(DW_AT_NAME); 13363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(DW_FORM_STRING); 13373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (has_value) { 13383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(DW_AT_TYPE); 13393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(DW_FORM_REF4); 13403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(DW_AT_LOCATION); 13413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(DW_FORM_BLOCK4); 13423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 13433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(0); 13443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(0); 13453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 13463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool WriteBodyInternal(Writer* w) { 13483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int current_abbreviation = 1; 1349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool extra_info = desc_->has_scope_info(); 1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(desc_->IsLineInfoAvailable()); 13513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(current_abbreviation++); 1352b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->WriteULEB128(DW_TAG_COMPILE_UNIT); 13533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->Write<uint8_t>(extra_info ? DW_CHILDREN_YES : DW_CHILDREN_NO); 1354b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->WriteULEB128(DW_AT_NAME); 1355b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->WriteULEB128(DW_FORM_STRING); 1356b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->WriteULEB128(DW_AT_LOW_PC); 1357b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->WriteULEB128(DW_FORM_ADDR); 1358b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->WriteULEB128(DW_AT_HIGH_PC); 1359b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->WriteULEB128(DW_FORM_ADDR); 1360b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->WriteULEB128(DW_AT_STMT_LIST); 1361b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->WriteULEB128(DW_FORM_DATA4); 1362b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->WriteULEB128(0); 1363b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->WriteULEB128(0); 13643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 13653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (extra_info) { 1366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ScopeInfo* scope = desc_->scope_info(); 1367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int params = scope->ParameterCount(); 1368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int slots = scope->StackLocalCount(); 1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int context_slots = scope->ContextLocalCount(); 13703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // The real slot ID is internal_slots + context_slot_id. 13713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int internal_slots = Context::MIN_CONTEXT_SLOTS; 1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int locals = scope->StackLocalCount(); 1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Total children is params + slots + context_slots + internal_slots + 1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // locals + 2 (__function and __context). 13753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 13763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // The extra duplication below seems to be necessary to keep 13773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // gdb from getting upset on OSX. 13783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(current_abbreviation++); // Abbreviation code. 13793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(DW_TAG_SUBPROGRAM); 1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch w->Write<uint8_t>(DW_CHILDREN_YES); 13813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(DW_AT_NAME); 13823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(DW_FORM_STRING); 13833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(DW_AT_LOW_PC); 13843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(DW_FORM_ADDR); 13853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(DW_AT_HIGH_PC); 13863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(DW_FORM_ADDR); 13873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(DW_AT_FRAME_BASE); 13883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(DW_FORM_BLOCK4); 13893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(0); 13903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(0); 13913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 13923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(current_abbreviation++); 13933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(DW_TAG_STRUCTURE_TYPE); 13943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->Write<uint8_t>(DW_CHILDREN_NO); 13953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(DW_AT_BYTE_SIZE); 13963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(DW_FORM_DATA1); 13973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(DW_AT_NAME); 13983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(DW_FORM_STRING); 13993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(0); 14003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(0); 14013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 14023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int param = 0; param < params; ++param) { 14033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch WriteVariableAbbreviation(w, current_abbreviation++, true, true); 14043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 14053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 14063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int slot = 0; slot < slots; ++slot) { 14073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch WriteVariableAbbreviation(w, current_abbreviation++, false, false); 14083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 14093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 14103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int internal_slot = 0; 14113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch internal_slot < internal_slots; 14123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++internal_slot) { 14133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch WriteVariableAbbreviation(w, current_abbreviation++, false, false); 14143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 14153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 14163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int context_slot = 0; 14173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch context_slot < context_slots; 14183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++context_slot) { 14193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch WriteVariableAbbreviation(w, current_abbreviation++, false, false); 14203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 14213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 14223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int local = 0; local < locals; ++local) { 14233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch WriteVariableAbbreviation(w, current_abbreviation++, true, false); 14243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 14253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 14263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // The function. 14273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch WriteVariableAbbreviation(w, current_abbreviation++, true, false); 14283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 14293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // The context. 14303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch WriteVariableAbbreviation(w, current_abbreviation++, true, false); 14313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch w->WriteULEB128(0); // Terminate the sibling list. 14333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 14343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 14353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch w->WriteULEB128(0); // Terminate the table. 1436b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return true; 1437b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 14383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 14393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private: 14403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CodeDescription* desc_; 1441b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}; 1442b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1443b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 14443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass DebugLineSection : public DebugSection { 1445b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch public: 1446b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch explicit DebugLineSection(CodeDescription* desc) 14473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef __ELF 1448b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch : ELFSection(".debug_line", TYPE_PROGBITS, 1), 14493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else 14503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : MachOSection("__debug_line", 14513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch "__DWARF", 14523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1, 14533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG), 14543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 1455b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch desc_(desc) { } 1456b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1457b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // DWARF2 standard, figure 34. 1458b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch enum DWARF2Opcodes { 1459b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch DW_LNS_COPY = 1, 1460b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch DW_LNS_ADVANCE_PC = 2, 1461b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch DW_LNS_ADVANCE_LINE = 3, 1462b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch DW_LNS_SET_FILE = 4, 1463b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch DW_LNS_SET_COLUMN = 5, 1464b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch DW_LNS_NEGATE_STMT = 6 1465b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch }; 1466b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1467b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // DWARF2 standard, figure 35. 1468b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch enum DWARF2ExtendedOpcode { 1469b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch DW_LNE_END_SEQUENCE = 1, 1470b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch DW_LNE_SET_ADDRESS = 2, 1471b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch DW_LNE_DEFINE_FILE = 3 1472b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch }; 1473b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool WriteBodyInternal(Writer* w) { 1475b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Write prologue. 1476b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Writer::Slot<uint32_t> total_length = w->CreateSlotHere<uint32_t>(); 1477b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t start = w->position(); 1478b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1479e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Used for special opcodes 1480e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const int8_t line_base = 1; 1481e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const uint8_t line_range = 7; 1482e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const int8_t max_line_incr = (line_base + line_range - 1); 1483e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch const uint8_t opcode_base = DW_LNS_NEGATE_STMT + 1; 1484e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1485b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->Write<uint16_t>(2); // Field version. 1486b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Writer::Slot<uint32_t> prologue_length = w->CreateSlotHere<uint32_t>(); 1487b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t prologue_start = w->position(); 1488b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->Write<uint8_t>(1); // Field minimum_instruction_length. 1489b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->Write<uint8_t>(1); // Field default_is_stmt. 1490e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch w->Write<int8_t>(line_base); // Field line_base. 1491e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch w->Write<uint8_t>(line_range); // Field line_range. 1492e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch w->Write<uint8_t>(opcode_base); // Field opcode_base. 1493b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->Write<uint8_t>(0); // DW_LNS_COPY operands count. 1494b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->Write<uint8_t>(1); // DW_LNS_ADVANCE_PC operands count. 1495b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->Write<uint8_t>(1); // DW_LNS_ADVANCE_LINE operands count. 1496b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->Write<uint8_t>(1); // DW_LNS_SET_FILE operands count. 1497b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->Write<uint8_t>(1); // DW_LNS_SET_COLUMN operands count. 1498b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->Write<uint8_t>(0); // DW_LNS_NEGATE_STMT operands count. 1499b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->Write<uint8_t>(0); // Empty include_directories sequence. 1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch w->WriteString(desc_->GetFilename().get()); // File name. 1501b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->WriteULEB128(0); // Current directory. 1502b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->WriteULEB128(0); // Unknown modification time. 1503b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->WriteULEB128(0); // Unknown file size. 1504b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->Write<uint8_t>(0); 1505b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch prologue_length.set(static_cast<uint32_t>(w->position() - prologue_start)); 1506b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1507b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch WriteExtendedOpcode(w, DW_LNE_SET_ADDRESS, sizeof(intptr_t)); 15081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<intptr_t>(desc_->CodeStart()); 1509e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch w->Write<uint8_t>(DW_LNS_COPY); 1510b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1511b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch intptr_t pc = 0; 1512b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch intptr_t line = 1; 1513b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch bool is_statement = true; 1514b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<LineInfo::PCInfo>* pc_info = desc_->lineinfo()->pc_info(); 1516b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch pc_info->Sort(&ComparePCInfo); 1517e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1518e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int pc_info_length = pc_info->length(); 1519e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (int i = 0; i < pc_info_length; i++) { 1520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LineInfo::PCInfo* info = &pc_info->at(i); 1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(info->pc_ >= pc); 1522e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1523e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Reduce bloating in the debug line table by removing duplicate line 1524e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // entries (per DWARF2 standard). 1525e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch intptr_t new_line = desc_->GetScriptLineNumber(info->pos_); 1526e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (new_line == line) { 1527e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch continue; 1528b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 1529e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1530e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Mark statement boundaries. For a better debugging experience, mark 1531e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // the last pc address in the function as a statement (e.g. "}"), so that 1532e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // a user can see the result of the last line executed in the function, 1533e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // should control reach the end. 1534e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if ((i+1) == pc_info_length) { 1535e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!is_statement) { 1536e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch w->Write<uint8_t>(DW_LNS_NEGATE_STMT); 1537e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1538e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else if (is_statement != info->is_statement_) { 1539b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->Write<uint8_t>(DW_LNS_NEGATE_STMT); 1540b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch is_statement = !is_statement; 1541b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 1542e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1543e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Generate special opcodes, if possible. This results in more compact 1544e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // debug line tables. See the DWARF 2.0 standard to learn more about 1545e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // special opcodes. 1546e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch uintptr_t pc_diff = info->pc_ - pc; 1547e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch intptr_t line_diff = new_line - line; 1548e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1549e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Compute special opcode (see DWARF 2.0 standard) 1550e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch intptr_t special_opcode = (line_diff - line_base) + 1551e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (line_range * pc_diff) + opcode_base; 1552e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1553e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // If special_opcode is less than or equal to 255, it can be used as a 1554e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // special opcode. If line_diff is larger than the max line increment 1555e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // allowed for a special opcode, or if line_diff is less than the minimum 1556e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // line that can be added to the line register (i.e. line_base), then 1557e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // special_opcode can't be used. 1558e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if ((special_opcode >= opcode_base) && (special_opcode <= 255) && 1559e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (line_diff <= max_line_incr) && (line_diff >= line_base)) { 1560e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch w->Write<uint8_t>(special_opcode); 1561e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 1562e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch w->Write<uint8_t>(DW_LNS_ADVANCE_PC); 1563e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch w->WriteSLEB128(pc_diff); 1564e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch w->Write<uint8_t>(DW_LNS_ADVANCE_LINE); 1565e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch w->WriteSLEB128(line_diff); 1566b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->Write<uint8_t>(DW_LNS_COPY); 1567b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 1568e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 1569e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Increment the pc and line operands. 1570e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch pc += pc_diff; 1571e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch line += line_diff; 1572b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 1573e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Advance the pc to the end of the routine, since the end sequence opcode 1574e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // requires this. 1575e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch w->Write<uint8_t>(DW_LNS_ADVANCE_PC); 1576e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch w->WriteSLEB128(desc_->CodeSize() - pc); 1577b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch WriteExtendedOpcode(w, DW_LNE_END_SEQUENCE, 0); 1578b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch total_length.set(static_cast<uint32_t>(w->position() - start)); 1579b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return true; 1580b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 1581b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1582b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch private: 1583b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void WriteExtendedOpcode(Writer* w, 1584b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch DWARF2ExtendedOpcode op, 1585b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch size_t operands_size) { 1586b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->Write<uint8_t>(0); 1587b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->WriteULEB128(operands_size + 1); 1588b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch w->Write<uint8_t>(op); 1589b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 1590b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static int ComparePCInfo(const LineInfo::PCInfo* a, 1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const LineInfo::PCInfo* b) { 1593b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (a->pc_ == b->pc_) { 1594b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (a->is_statement_ != b->is_statement_) { 1595b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return b->is_statement_ ? +1 : -1; 1596b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 1597b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return 0; 1598b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } else if (a->pc_ > b->pc_) { 1599b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return +1; 1600b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } else { 1601b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return -1; 1602b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 1603b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 1604b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1605b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch CodeDescription* desc_; 1606b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}; 1607b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1608b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_X64 16101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 16113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass UnwindInfoSection : public DebugSection { 16121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public: 16133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit UnwindInfoSection(CodeDescription* desc); 1614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual bool WriteBodyInternal(Writer* w); 16151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 16163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int WriteCIE(Writer* w); 16173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void WriteFDE(Writer* w, int); 16181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 16193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void WriteFDEStateOnEntry(Writer* w); 16203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void WriteFDEStateAfterRBPPush(Writer* w); 16213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void WriteFDEStateAfterRBPSet(Writer* w); 16223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void WriteFDEStateAfterRBPPop(Writer* w); 16231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 16243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void WriteLength(Writer* w, 16251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Writer::Slot<uint32_t>* length_slot, 16261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int initial_position); 16271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 16281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block private: 16293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CodeDescription* desc_; 16301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 16311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // DWARF3 Specification, Table 7.23 16321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block enum CFIInstructions { 16331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_ADVANCE_LOC = 0x40, 16341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_OFFSET = 0x80, 16351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_RESTORE = 0xC0, 16361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_NOP = 0x00, 16371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_SET_LOC = 0x01, 16381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_ADVANCE_LOC1 = 0x02, 16391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_ADVANCE_LOC2 = 0x03, 16401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_ADVANCE_LOC4 = 0x04, 16411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_OFFSET_EXTENDED = 0x05, 16421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_RESTORE_EXTENDED = 0x06, 16431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_UNDEFINED = 0x07, 16441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_SAME_VALUE = 0x08, 16451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_REGISTER = 0x09, 16461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_REMEMBER_STATE = 0x0A, 16471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_RESTORE_STATE = 0x0B, 16481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_DEF_CFA = 0x0C, 16491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_DEF_CFA_REGISTER = 0x0D, 16501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_DEF_CFA_OFFSET = 0x0E, 16511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 16521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_DEF_CFA_EXPRESSION = 0x0F, 16531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_EXPRESSION = 0x10, 16541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_OFFSET_EXTENDED_SF = 0x11, 16551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_DEF_CFA_SF = 0x12, 16561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_DEF_CFA_OFFSET_SF = 0x13, 16571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_VAL_OFFSET = 0x14, 16581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_VAL_OFFSET_SF = 0x15, 16591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DW_CFA_VAL_EXPRESSION = 0x16 16601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block }; 16611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 16621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // System V ABI, AMD64 Supplement, Version 0.99.5, Figure 3.36 16631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block enum RegisterMapping { 16641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Only the relevant ones have been added to reduce clutter. 16651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block AMD64_RBP = 6, 16661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block AMD64_RSP = 7, 16671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block AMD64_RA = 16 16681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block }; 16691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 16701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block enum CFIConstants { 16711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block CIE_ID = 0, 16721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block CIE_VERSION = 1, 16731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block CODE_ALIGN_FACTOR = 1, 16741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block DATA_ALIGN_FACTOR = 1, 16751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block RETURN_ADDRESS_REGISTER = AMD64_RA 16761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block }; 16771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}; 16781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 16791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 16803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid UnwindInfoSection::WriteLength(Writer* w, 16811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Writer::Slot<uint32_t>* length_slot, 16821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int initial_position) { 16831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block uint32_t align = (w->position() - initial_position) % kPointerSize; 16841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 16851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (align != 0) { 16861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block for (uint32_t i = 0; i < (kPointerSize - align); i++) { 16871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint8_t>(DW_CFA_NOP); 16881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 16891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 16901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((w->position() - initial_position) % kPointerSize == 0); 1692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch length_slot->set(static_cast<uint32_t>(w->position() - initial_position)); 16931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 16941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 16951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 16963ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochUnwindInfoSection::UnwindInfoSection(CodeDescription* desc) 16973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef __ELF 16983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : ELFSection(".eh_frame", TYPE_X86_64_UNWIND, 1), 16993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else 17003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch : MachOSection("__eh_frame", "__TEXT", sizeof(uintptr_t), 17013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch MachOSection::S_REGULAR), 17023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 17033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch desc_(desc) { } 17041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint UnwindInfoSection::WriteCIE(Writer* w) { 17061e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Writer::Slot<uint32_t> cie_length_slot = w->CreateSlotHere<uint32_t>(); 1707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t cie_position = static_cast<uint32_t>(w->position()); 17081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Write out the CIE header. Currently no 'common instructions' are 17101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // emitted onto the CIE; every FDE has its own set of instructions. 17111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint32_t>(CIE_ID); 17131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint8_t>(CIE_VERSION); 17141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint8_t>(0); // Null augmentation string. 17151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->WriteSLEB128(CODE_ALIGN_FACTOR); 17161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->WriteSLEB128(DATA_ALIGN_FACTOR); 17171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint8_t>(RETURN_ADDRESS_REGISTER); 17181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block WriteLength(w, &cie_length_slot, cie_position); 17201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return cie_position; 17221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 17231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid UnwindInfoSection::WriteFDE(Writer* w, int cie_position) { 17261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // The only FDE for this function. The CFA is the current RBP. 17271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Writer::Slot<uint32_t> fde_length_slot = w->CreateSlotHere<uint32_t>(); 1728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int fde_position = static_cast<uint32_t>(w->position()); 17291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<int32_t>(fde_position - cie_position + 4); 17301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uintptr_t>(desc_->CodeStart()); 17321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uintptr_t>(desc_->CodeSize()); 17331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block WriteFDEStateOnEntry(w); 17351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block WriteFDEStateAfterRBPPush(w); 17361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block WriteFDEStateAfterRBPSet(w); 17371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block WriteFDEStateAfterRBPPop(w); 17381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block WriteLength(w, &fde_length_slot, fde_position); 17401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 17411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid UnwindInfoSection::WriteFDEStateOnEntry(Writer* w) { 17441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // The first state, just after the control has been transferred to the the 17451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // function. 17461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // RBP for this function will be the value of RSP after pushing the RBP 17481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // for the previous function. The previous RBP has not been pushed yet. 17491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint8_t>(DW_CFA_DEF_CFA_SF); 17501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->WriteULEB128(AMD64_RSP); 17511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->WriteSLEB128(-kPointerSize); 17521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // The RA is stored at location CFA + kCallerPCOffset. This is an invariant, 17541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // and hence omitted from the next states. 17551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); 17561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->WriteULEB128(AMD64_RA); 17571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->WriteSLEB128(StandardFrameConstants::kCallerPCOffset); 17581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // The RBP of the previous function is still in RBP. 17601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint8_t>(DW_CFA_SAME_VALUE); 17611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->WriteULEB128(AMD64_RBP); 17621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Last location described by this entry. 17641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint8_t>(DW_CFA_SET_LOC); 17651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint64_t>( 17661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_PUSH)); 17671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 17681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid UnwindInfoSection::WriteFDEStateAfterRBPPush(Writer* w) { 17711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // The second state, just after RBP has been pushed. 17721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // RBP / CFA for this function is now the current RSP, so just set the 17741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // offset from the previous rule (from -8) to 0. 17751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint8_t>(DW_CFA_DEF_CFA_OFFSET); 17761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->WriteULEB128(0); 17771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // The previous RBP is stored at CFA + kCallerFPOffset. This is an invariant 17791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // in this and the next state, and hence omitted in the next state. 17801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); 17811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->WriteULEB128(AMD64_RBP); 17821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset); 17831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Last location described by this entry. 17851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint8_t>(DW_CFA_SET_LOC); 17861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint64_t>( 17871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_SET)); 17881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 17891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid UnwindInfoSection::WriteFDEStateAfterRBPSet(Writer* w) { 17921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // The third state, after the RBP has been set. 17931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // The CFA can now directly be set to RBP. 17951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint8_t>(DW_CFA_DEF_CFA); 17961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->WriteULEB128(AMD64_RBP); 17971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->WriteULEB128(0); 17981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 17991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Last location described by this entry. 18001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint8_t>(DW_CFA_SET_LOC); 18011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint64_t>( 18021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_POP)); 18031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 18041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 18051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 18063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid UnwindInfoSection::WriteFDEStateAfterRBPPop(Writer* w) { 18071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // The fourth (final) state. The RBP has been popped (just before issuing a 18081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // return). 18091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 18101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // The CFA can is now calculated in the same way as in the first state. 18111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint8_t>(DW_CFA_DEF_CFA_SF); 18121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->WriteULEB128(AMD64_RSP); 18131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->WriteSLEB128(-kPointerSize); 18141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 18151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // The RBP 18161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); 18171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->WriteULEB128(AMD64_RBP); 18181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset); 18191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 18201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Last location described by this entry. 18211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint8_t>(DW_CFA_SET_LOC); 18221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block w->Write<uint64_t>(desc_->CodeEnd()); 18231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 18241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 18251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool UnwindInfoSection::WriteBodyInternal(Writer* w) { 18271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block uint32_t cie_position = WriteCIE(w); 18281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block WriteFDE(w, cie_position); 18291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return true; 18301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 18311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 18321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 18331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#endif // V8_TARGET_ARCH_X64 18341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void CreateDWARFSections(CodeDescription* desc, 1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone, 1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DebugObject* obj) { 18381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (desc->IsLineInfoAvailable()) { 1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj->AddSection(new(zone) DebugInfoSection(desc)); 1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj->AddSection(new(zone) DebugAbbrevSection(desc)); 1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj->AddSection(new(zone) DebugLineSection(desc)); 1842b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_X64 1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch obj->AddSection(new(zone) UnwindInfoSection(desc)); 18451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#endif 1846b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch} 1847b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1848b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1849b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch// ------------------------------------------------------------------- 1850b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch// Binary GDB JIT Interface as described in 1851b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch// http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html 1852b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochextern "C" { 1853b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch typedef enum { 1854b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch JIT_NOACTION = 0, 1855b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch JIT_REGISTER_FN, 1856b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch JIT_UNREGISTER_FN 1857b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } JITAction; 1858b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1859b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch struct JITCodeEntry { 1860b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch JITCodeEntry* next_; 1861b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch JITCodeEntry* prev_; 1862b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Address symfile_addr_; 1863b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint64_t symfile_size_; 1864b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch }; 1865b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1866b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch struct JITDescriptor { 1867b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint32_t version_; 1868b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uint32_t action_flag_; 18693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JITCodeEntry* relevant_entry_; 18703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JITCodeEntry* first_entry_; 1871b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch }; 1872b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1873b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // GDB will place breakpoint into this function. 1874b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // To prevent GCC from inlining or removing it we place noinline attribute 1875b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // and inline assembler statement inside. 1876b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch void __attribute__((noinline)) __jit_debug_register_code() { 1877b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch __asm__(""); 1878b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 1879b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1880b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // GDB will inspect contents of this descriptor. 1881b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // Static initialization is necessary to prevent GDB from seeing 1882b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch // uninitialized descriptor. 1883b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch JITDescriptor __jit_debug_descriptor = { 1, 0, 0, 0 }; 18843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 18853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef OBJECT_PRINT 1886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void __gdb_print_v8_object(Object* object) { 1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OFStream os(stdout); 1888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object->Print(os); 1889958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier os << std::flush; 18903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 18913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 1892b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch} 1893b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1894b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1895b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochstatic JITCodeEntry* CreateCodeEntry(Address symfile_addr, 1896b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch uintptr_t symfile_size) { 1897b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch JITCodeEntry* entry = static_cast<JITCodeEntry*>( 1898b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch malloc(sizeof(JITCodeEntry) + symfile_size)); 1899b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1900b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch entry->symfile_addr_ = reinterpret_cast<Address>(entry + 1); 1901b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch entry->symfile_size_ = symfile_size; 1902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemCopy(entry->symfile_addr_, symfile_addr, symfile_size); 1903b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1904b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch entry->prev_ = entry->next_ = NULL; 1905b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1906b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return entry; 1907b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch} 1908b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1909b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1910b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochstatic void DestroyCodeEntry(JITCodeEntry* entry) { 1911b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch free(entry); 1912b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch} 1913b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1914b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic void RegisterCodeEntry(JITCodeEntry* entry) { 1916b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch entry->next_ = __jit_debug_descriptor.first_entry_; 1917b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (entry->next_ != NULL) entry->next_->prev_ = entry; 1918b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch __jit_debug_descriptor.first_entry_ = 1919b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch __jit_debug_descriptor.relevant_entry_ = entry; 1920b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1921b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch __jit_debug_descriptor.action_flag_ = JIT_REGISTER_FN; 1922b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch __jit_debug_register_code(); 1923b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch} 1924b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1925b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1926b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochstatic void UnregisterCodeEntry(JITCodeEntry* entry) { 1927b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (entry->prev_ != NULL) { 1928b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch entry->prev_->next_ = entry->next_; 1929b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } else { 1930b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch __jit_debug_descriptor.first_entry_ = entry->next_; 1931b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 1932b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1933b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (entry->next_ != NULL) { 1934b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch entry->next_->prev_ = entry->prev_; 1935b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 1936b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1937b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch __jit_debug_descriptor.relevant_entry_ = entry; 1938b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch __jit_debug_descriptor.action_flag_ = JIT_UNREGISTER_FN; 1939b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch __jit_debug_register_code(); 1940b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch} 1941b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1942b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic JITCodeEntry* CreateELFObject(CodeDescription* desc, Isolate* isolate) { 19443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef __MACH_O 1945c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Zone zone(isolate->allocator(), ZONE_NAME); 1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MachO mach_o(&zone); 19473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Writer w(&mach_o); 19483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mach_o.AddSection(new(&zone) MachOTextSection(kCodeAlignment, 1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc->CodeStart(), 1951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc->CodeSize())); 19523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CreateDWARFSections(desc, &zone, &mach_o); 1954b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 19553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch mach_o.Write(&w, desc->CodeStart(), desc->CodeSize()); 19563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#else 1957c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Zone zone(isolate->allocator(), ZONE_NAME); 1958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ELF elf(&zone); 1959b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Writer w(&elf); 1960b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1961b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch int text_section_index = elf.AddSection( 1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new(&zone) FullHeaderELFSection( 1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ".text", 1964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ELFSection::TYPE_NOBITS, 1965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kCodeAlignment, 1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc->CodeStart(), 1967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 0, 1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch desc->CodeSize(), 1969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ELFSection::FLAG_ALLOC | ELFSection::FLAG_EXEC)); 1970b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CreateSymbolsTable(desc, &zone, &elf, text_section_index); 1972b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CreateDWARFSections(desc, &zone, &elf); 1974b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1975b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch elf.Write(&w); 19763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 1977b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1978b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return CreateCodeEntry(w.buffer(), w.position()); 1979b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch} 1980b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1981b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstruct AddressRange { 1983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address start; 1984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address end; 1985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 1986b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstruct SplayTreeConfig { 1988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch typedef AddressRange Key; 1989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch typedef JITCodeEntry* Value; 1990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const AddressRange kNoKey; 1991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Value NoValue() { return NULL; } 1992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int Compare(const AddressRange& a, const AddressRange& b) { 1993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // ptrdiff_t probably doesn't fit in an int. 1994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (a.start < b.start) return -1; 1995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (a.start == b.start) return 0; 1996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 1; 1997e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 1998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 1999b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst AddressRange SplayTreeConfig::kNoKey = {0, 0}; 2001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef SplayTree<SplayTreeConfig> CodeMap; 2002b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic CodeMap* GetCodeMap() { 2004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static CodeMap* code_map = NULL; 2005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (code_map == NULL) code_map = new CodeMap(); 2006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return code_map; 2007b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch} 2008b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2009b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic uint32_t HashCodeAddress(Address addr) { 2011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const uintptr_t kGoldenRatio = 2654435761u; 2012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uintptr_t offset = OffsetFrom(addr); 2013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return static_cast<uint32_t>((offset >> kCodeAlignmentBits) * kGoldenRatio); 2014b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch} 2015b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 201613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochstatic base::HashMap* GetLineMap() { 201713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static base::HashMap* line_map = NULL; 201813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (line_map == NULL) { 2019f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch line_map = new base::HashMap(); 202013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 2021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return line_map; 2022b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch} 2023b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2024b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic void PutLineInfo(Address addr, LineInfo* info) { 202613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch base::HashMap* line_map = GetLineMap(); 202713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch base::HashMap::Entry* e = 202813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch line_map->LookupOrInsert(addr, HashCodeAddress(addr)); 2029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (e->value != NULL) delete static_cast<LineInfo*>(e->value); 2030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch e->value = info; 2031b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch} 2032b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2033b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic LineInfo* GetLineInfo(Address addr) { 2035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void* value = GetLineMap()->Remove(addr, HashCodeAddress(addr)); 2036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return static_cast<LineInfo*>(value); 20371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 20381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 20403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void AddUnwindInfo(CodeDescription* desc) { 2041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_X64 2042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (desc->is_function()) { 20431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // To avoid propagating unwinding information through 2044e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // compilation pipeline we use an approximation. 2045e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // For most use cases this should not affect usability. 20461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const int kFramePointerPushOffset = 1; 20471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const int kFramePointerSetOffset = 4; 20481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static const int kFramePointerPopOffset = -3; 20491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 20501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block uintptr_t frame_pointer_push_address = 20511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block desc->CodeStart() + kFramePointerPushOffset; 20521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 20531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block uintptr_t frame_pointer_set_address = 20541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block desc->CodeStart() + kFramePointerSetOffset; 20551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 20561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block uintptr_t frame_pointer_pop_address = 20571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block desc->CodeEnd() + kFramePointerPopOffset; 20581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 20591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block desc->SetStackStateStartAddress(CodeDescription::POST_RBP_PUSH, 20601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block frame_pointer_push_address); 20611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block desc->SetStackStateStartAddress(CodeDescription::POST_RBP_SET, 20621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block frame_pointer_set_address); 20631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block desc->SetStackStateStartAddress(CodeDescription::POST_RBP_POP, 20641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block frame_pointer_pop_address); 2065b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } else { 20661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block desc->SetStackStateStartAddress(CodeDescription::POST_RBP_PUSH, 20671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block desc->CodeStart()); 20681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block desc->SetStackStateStartAddress(CodeDescription::POST_RBP_SET, 20691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block desc->CodeStart()); 20701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block desc->SetStackStateStartAddress(CodeDescription::POST_RBP_POP, 20711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block desc->CodeEnd()); 2072b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 20731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#endif // V8_TARGET_ARCH_X64 2074b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch} 2075b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2076b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic base::LazyMutex mutex = LAZY_MUTEX_INITIALIZER; 20788b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 20798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 2080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Remove entries from the splay tree that intersect the given address range, 2081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// and deregister them from GDB. 2082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic void RemoveJITCodeEntries(CodeMap* map, const AddressRange& range) { 2083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(range.start < range.end); 2084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodeMap::Locator cur; 2085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (map->FindGreatestLessThan(range, &cur) || map->FindLeast(&cur)) { 2086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Skip entries that are entirely less than the range of interest. 2087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (cur.key().end <= range.start) { 2088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // CodeMap::FindLeastGreaterThan succeeds for entries whose key is greater 2089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // than _or equal to_ the given key, so we have to advance our key to get 2090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the next one. 2091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddressRange new_key; 2092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch new_key.start = cur.key().end; 2093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch new_key.end = 0; 2094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!map->FindLeastGreaterThan(new_key, &cur)) return; 2095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Evict intersecting ranges. 2097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (cur.key().start < range.end) { 2098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddressRange old_range = cur.key(); 2099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JITCodeEntry* old_entry = cur.value(); 2100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UnregisterCodeEntry(old_entry); 2102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DestroyCodeEntry(old_entry); 2103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(map->Remove(old_range)); 2105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!map->FindLeastGreaterThan(old_range, &cur)) return; 2106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Insert the entry into the splay tree and register it with GDB. 2112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic void AddJITCodeEntry(CodeMap* map, const AddressRange& range, 2113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JITCodeEntry* entry, bool dump_if_enabled, 2114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const char* name_hint) { 2115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if defined(DEBUG) && !V8_OS_WIN 2116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int file_num = 0; 2117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_gdbjit_dump && dump_if_enabled) { 2118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kMaxFileNameSize = 64; 2119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch char file_name[64]; 2120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SNPrintF(Vector<char>(file_name, kMaxFileNameSize), "/tmp/elfdump%s%d.o", 2122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (name_hint != NULL) ? name_hint : "", file_num++); 2123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch WriteBytes(file_name, entry->symfile_addr_, 2124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<int>(entry->symfile_size_)); 2125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 2127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodeMap::Locator cur; 2129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(map->Insert(range, &cur)); 2130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cur.set_value(entry); 2131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterCodeEntry(entry); 2133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic void AddCode(const char* name, Code* code, SharedFunctionInfo* shared, 2137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LineInfo* lineinfo) { 2138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_gc; 2139b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodeMap* code_map = GetCodeMap(); 2141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddressRange range; 2142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch range.start = code->address(); 2143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch range.end = code->address() + code->CodeSize(); 2144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RemoveJITCodeEntries(code_map, range); 2145b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodeDescription code_desc(name, code, shared, lineinfo); 2147b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 21481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (!FLAG_gdbjit_full && !code_desc.IsLineInfoAvailable()) { 2149b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch delete lineinfo; 2150b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return; 2151b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 2152b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 21531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block AddUnwindInfo(&code_desc); 2154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = code->GetIsolate(); 2155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JITCodeEntry* entry = CreateELFObject(&code_desc, isolate); 2156b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2157b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch delete lineinfo; 2158b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 21593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const char* name_hint = NULL; 21603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool should_dump = false; 21613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (FLAG_gdbjit_dump) { 21623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (strlen(FLAG_gdbjit_dump_filter) == 0) { 21633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch name_hint = name; 21643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch should_dump = true; 21653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (name != NULL) { 21663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch name_hint = strstr(name, FLAG_gdbjit_dump_filter); 21673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch should_dump = (name_hint != NULL); 21683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 21693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 2170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddJITCodeEntry(code_map, range, entry, should_dump, name_hint); 2171b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch} 2172b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2173b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid EventHandler(const v8::JitCodeEvent* event) { 2175b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (!FLAG_gdbjit) return; 2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::LockGuard<base::Mutex> lock_guard(mutex.Pointer()); 2177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (event->type) { 2178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case v8::JitCodeEvent::CODE_ADDED: { 2179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address addr = reinterpret_cast<Address>(event->code_start); 2180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Code* code = Code::GetCodeFromTargetAddress(addr); 2181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LineInfo* lineinfo = GetLineInfo(addr); 2182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EmbeddedVector<char, 256> buffer; 2183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StringBuilder builder(buffer.start(), buffer.length()); 2184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch builder.AddSubstring(event->name.str, static_cast<int>(event->name.len)); 2185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // It's called UnboundScript in the API but it's a SharedFunctionInfo. 2186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SharedFunctionInfo* shared = 2187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch event->script.IsEmpty() ? NULL : *Utils::OpenHandle(*event->script); 2188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddCode(builder.Finalize(), code, shared, lineinfo); 2189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case v8::JitCodeEvent::CODE_MOVED: 2192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Enabling the GDB JIT interface should disable code compaction. 2193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 2194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case v8::JitCodeEvent::CODE_REMOVED: 2196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Do nothing. Instead, adding code causes eviction of any entry whose 2197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // address range intersects the address range of the added code. 2198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case v8::JitCodeEvent::CODE_ADD_LINE_POS_INFO: { 2200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LineInfo* line_info = reinterpret_cast<LineInfo*>(event->user_data); 2201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch line_info->SetPosition(static_cast<intptr_t>(event->line_info.offset), 2202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<int>(event->line_info.pos), 2203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch event->line_info.position_type == 2204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::JitCodeEvent::STATEMENT_POSITION); 2205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case v8::JitCodeEvent::CODE_START_LINE_INFO_RECORDING: { 2208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::JitCodeEvent* mutable_event = const_cast<v8::JitCodeEvent*>(event); 2209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mutable_event->user_data = new LineInfo(); 2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case v8::JitCodeEvent::CODE_END_LINE_INFO_RECORDING: { 2213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LineInfo* line_info = reinterpret_cast<LineInfo*>(event->user_data); 2214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PutLineInfo(reinterpret_cast<Address>(event->code_start), line_info); 2215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2219b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#endif 2220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace GDBJITInterface 2221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 2222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 2223