10511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// Copyright 2010 the V8 project authors. All rights reserved. 20511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// Redistribution and use in source and binary forms, with or without 30511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// modification, are permitted provided that the following conditions are 40511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// met: 50511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// 60511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// * Redistributions of source code must retain the above copyright 70511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// notice, this list of conditions and the following disclaimer. 80511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// * Redistributions in binary form must reproduce the above 90511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// copyright notice, this list of conditions and the following 100511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// disclaimer in the documentation and/or other materials provided 110511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// with the distribution. 120511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// * Neither the name of Google Inc. nor the names of its 130511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// contributors may be used to endorse or promote products derived 140511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// from this software without specific prior written permission. 150511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// 160511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 170511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 180511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 190511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 200511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 230511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 260511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 270511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 280511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#ifdef ENABLE_GDB_JIT_INTERFACE 29ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#include "v8.h" 300511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#include "gdb-jit.h" 310511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#include "bootstrapper.h" 330511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#include "compiler.h" 3433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org#include "frames.h" 3533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org#include "frames-inl.h" 360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#include "global-handles.h" 370511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#include "messages.h" 380511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#include "natives.h" 3933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org#include "platform.h" 4033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org#include "scopes.h" 410511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 420511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comnamespace v8 { 430511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comnamespace internal { 440511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 454f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#ifdef __APPLE__ 464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#define __MACH_O 474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgclass MachO; 484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgclass MachOSection; 494f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgtypedef MachO DebugObject; 504f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgtypedef MachOSection DebugSection; 514f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#else 524f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#define __ELF 530511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comclass ELF; 544f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgclass ELFSection; 554f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgtypedef ELF DebugObject; 564f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgtypedef ELFSection DebugSection; 574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif 580511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 590511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comclass Writer BASE_EMBEDDED { 600511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com public: 614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org explicit Writer(DebugObject* debug_object) 624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org : debug_object_(debug_object), 630511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com position_(0), 640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com capacity_(1024), 650511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com buffer_(reinterpret_cast<byte*>(malloc(capacity_))) { 660511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 670511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 680511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ~Writer() { 690511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com free(buffer_); 700511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 710511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 720511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t position() const { 730511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return position_; 740511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 750511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 760511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com template<typename T> 770511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com class Slot { 780511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com public: 790511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Slot(Writer* w, uintptr_t offset) : w_(w), offset_(offset) { } 800511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 810511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com T* operator-> () { 820511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return w_->RawSlotAt<T>(offset_); 830511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 840511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 850511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com void set(const T& value) { 860511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com *w_->RawSlotAt<T>(offset_) = value; 870511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 880511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 890511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Slot<T> at(int i) { 900511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return Slot<T>(w_, offset_ + sizeof(T) * i); 910511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 920511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 930511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com private: 940511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Writer* w_; 950511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t offset_; 960511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com }; 970511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 980511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com template<typename T> 990511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com void Write(const T& val) { 1000511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Ensure(position_ + sizeof(T)); 1010511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com *RawSlotAt<T>(position_) = val; 1020511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com position_ += sizeof(T); 1030511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 1040511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 1050511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com template<typename T> 1060511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Slot<T> SlotAt(uintptr_t offset) { 1070511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Ensure(offset + sizeof(T)); 1080511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return Slot<T>(this, offset); 1090511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 1100511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 1110511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com template<typename T> 1120511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Slot<T> CreateSlotHere() { 1130511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return CreateSlotsHere<T>(1); 1140511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 1150511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 1160511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com template<typename T> 1170511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Slot<T> CreateSlotsHere(uint32_t count) { 1180511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t slot_position = position_; 1190511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com position_ += sizeof(T) * count; 1200511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Ensure(position_); 1210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return SlotAt<T>(slot_position); 1220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 1230511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 1240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com void Ensure(uintptr_t pos) { 1250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (capacity_ < pos) { 1260511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com while (capacity_ < pos) capacity_ *= 2; 1270511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com buffer_ = reinterpret_cast<byte*>(realloc(buffer_, capacity_)); 1280511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 1290511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 1300511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 1314f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DebugObject* debug_object() { return debug_object_; } 1320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 1330511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com byte* buffer() { return buffer_; } 1340511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 1350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com void Align(uintptr_t align) { 1360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t delta = position_ % align; 1370511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (delta == 0) return; 1380511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t padding = align - delta; 1390511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Ensure(position_ += padding); 1400511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ASSERT((position_ % align) == 0); 1410511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 1420511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 1430511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com void WriteULEB128(uintptr_t value) { 1440511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com do { 1450511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint8_t byte = value & 0x7F; 1460511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com value >>= 7; 1470511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (value != 0) byte |= 0x80; 1480511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Write<uint8_t>(byte); 1490511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } while (value != 0); 1500511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 1510511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 1520511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com void WriteSLEB128(intptr_t value) { 1530511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com bool more = true; 1540511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com while (more) { 1550511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com int8_t byte = value & 0x7F; 1560511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com bool byte_sign = byte & 0x40; 1570511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com value >>= 7; 1580511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 1590511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if ((value == 0 && !byte_sign) || (value == -1 && byte_sign)) { 1600511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com more = false; 1610511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } else { 1620511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com byte |= 0x80; 1630511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 1640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 1650511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Write<int8_t>(byte); 1660511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 1670511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 1680511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 1690511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com void WriteString(const char* str) { 1700511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com do { 1710511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Write<char>(*str); 1720511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } while (*str++); 1730511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 1740511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 1750511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com private: 1760511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com template<typename T> friend class Slot; 1770511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 1780511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com template<typename T> 1790511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com T* RawSlotAt(uintptr_t offset) { 1800511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ASSERT(offset < capacity_ && offset + sizeof(T) <= capacity_); 1810511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return reinterpret_cast<T*>(&buffer_[offset]); 1820511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 1830511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 1844f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DebugObject* debug_object_; 1850511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t position_; 1860511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t capacity_; 1870511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com byte* buffer_; 1880511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com}; 1890511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 1907bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgclass ELFStringTable; 1910511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 1924f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgtemplate<typename THeader> 1934f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgclass DebugSectionBase : public ZoneObject { 1940511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com public: 1954f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org virtual ~DebugSectionBase() { } 1964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 1974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org virtual void WriteBody(Writer::Slot<THeader> header, Writer* writer) { 1984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t start = writer->position(); 19933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org if (WriteBodyInternal(writer)) { 2004f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t end = writer->position(); 2014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->offset = start; 2024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#if defined(__MACH_O) 2034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->addr = 0; 2044f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif 2054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->size = end - start; 2064f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 2074f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 2084f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 20933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org virtual bool WriteBodyInternal(Writer* writer) { 2104f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return false; 2114f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 2124f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 2134f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org typedef THeader Header; 2144f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}; 2154f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 2164f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 2174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgstruct MachOSectionHeader { 2184f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org char sectname[16]; 2194f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org char segname[16]; 22093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 2214f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t addr; 2224f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t size; 2234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#else 2244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint64_t addr; 2254f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint64_t size; 2264f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif 2274f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t offset; 2284f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t align; 2294f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t reloff; 2304f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t nreloc; 2314f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t flags; 2324f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t reserved1; 2334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t reserved2; 2344f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}; 2354f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 2364f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 2374f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgclass MachOSection : public DebugSectionBase<MachOSectionHeader> { 2384f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org public: 2394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org enum Type { 2404f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org S_REGULAR = 0x0u, 2414f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org S_ATTR_COALESCED = 0xbu, 2424f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org S_ATTR_SOME_INSTRUCTIONS = 0x400u, 2434f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org S_ATTR_DEBUG = 0x02000000u, 2444f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org S_ATTR_PURE_INSTRUCTIONS = 0x80000000u 2450511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com }; 2460511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 2474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org MachOSection(const char* name, 2484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org const char* segment, 2494f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t align, 2504f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t flags) 2514f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org : name_(name), 2524f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org segment_(segment), 2534f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org align_(align), 2544f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org flags_(flags) { 2554f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ASSERT(IsPowerOf2(align)); 2564f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (align_ != 0) { 2574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org align_ = WhichPowerOf2(align_); 2584f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 2594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 2604f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 2614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org virtual ~MachOSection() { } 2624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 2634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org virtual void PopulateHeader(Writer::Slot<Header> header) { 2644f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->addr = 0; 2654f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->size = 0; 2664f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->offset = 0; 2674f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->align = align_; 2684f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->reloff = 0; 2694f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->nreloc = 0; 2704f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->flags = flags_; 2714f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->reserved1 = 0; 2724f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->reserved2 = 0; 2734f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org memset(header->sectname, 0, sizeof(header->sectname)); 2744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org memset(header->segname, 0, sizeof(header->segname)); 2754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ASSERT(strlen(name_) < sizeof(header->sectname)); 2764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ASSERT(strlen(segment_) < sizeof(header->segname)); 2774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org strncpy(header->sectname, name_, sizeof(header->sectname)); 2784f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org strncpy(header->segname, segment_, sizeof(header->segname)); 2794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 2804f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 2814f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org private: 2824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org const char* name_; 2834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org const char* segment_; 2844f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t align_; 2854f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t flags_; 2864f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}; 2874f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 2884f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 2894f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgstruct ELFSectionHeader { 2904f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t name; 2914f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t type; 2924f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t flags; 2934f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t address; 2944f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t offset; 2954f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t size; 2964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t link; 2974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t info; 2984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t alignment; 2994f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t entry_size; 3004f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}; 3014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 3024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 3034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#if defined(__ELF) 3044f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgclass ELFSection : public DebugSectionBase<ELFSectionHeader> { 3054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org public: 3060511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com enum Type { 3070511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_NULL = 0, 3080511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_PROGBITS = 1, 3090511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_SYMTAB = 2, 3100511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_STRTAB = 3, 3110511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_RELA = 4, 3120511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_HASH = 5, 3130511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_DYNAMIC = 6, 3140511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_NOTE = 7, 3150511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_NOBITS = 8, 3160511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_REL = 9, 3170511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_SHLIB = 10, 3180511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_DYNSYM = 11, 3190511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_LOPROC = 0x70000000, 32031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org TYPE_X86_64_UNWIND = 0x70000001, 3210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_HIPROC = 0x7fffffff, 3220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_LOUSER = 0x80000000, 3230511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_HIUSER = 0xffffffff 3240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com }; 3250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 3260511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com enum Flags { 3270511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com FLAG_WRITE = 1, 3280511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com FLAG_ALLOC = 2, 3290511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com FLAG_EXEC = 4 3300511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com }; 3310511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 3320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com enum SpecialIndexes { 3330511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com INDEX_ABSOLUTE = 0xfff1 3340511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com }; 3350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 3360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ELFSection(const char* name, Type type, uintptr_t align) 3370511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com : name_(name), type_(type), align_(align) { } 3380511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 3390511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com virtual ~ELFSection() { } 3400511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 3417bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org void PopulateHeader(Writer::Slot<Header> header, ELFStringTable* strtab); 3420511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 3430511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com virtual void WriteBody(Writer::Slot<Header> header, Writer* w) { 3440511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t start = w->position(); 34533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org if (WriteBodyInternal(w)) { 3460511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t end = w->position(); 3470511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->offset = start; 3480511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->size = end - start; 3490511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 3500511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 3510511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 35233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org virtual bool WriteBodyInternal(Writer* w) { 3530511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return false; 3540511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 3550511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 3560511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint16_t index() const { return index_; } 3570511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com void set_index(uint16_t index) { index_ = index; } 3580511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 3590511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com protected: 3600511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com virtual void PopulateHeader(Writer::Slot<Header> header) { 3610511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->flags = 0; 3620511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->address = 0; 3630511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->offset = 0; 3640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->size = 0; 3650511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->link = 0; 3660511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->info = 0; 3670511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->entry_size = 0; 3680511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 3690511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 3700511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com private: 3710511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com const char* name_; 3720511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Type type_; 3730511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t align_; 3740511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint16_t index_; 3750511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com}; 3764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif // defined(__ELF) 3774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 3784f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 3794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#if defined(__MACH_O) 3804f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgclass MachOTextSection : public MachOSection { 3814f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org public: 3824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org MachOTextSection(uintptr_t align, 3834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t addr, 3844f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t size) 3854f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org : MachOSection("__text", 3864f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org "__TEXT", 3874f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org align, 3884f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org MachOSection::S_REGULAR | 3894f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org MachOSection::S_ATTR_SOME_INSTRUCTIONS | 3904f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org MachOSection::S_ATTR_PURE_INSTRUCTIONS), 3914f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org addr_(addr), 3924f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org size_(size) { } 3930511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 3944f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org protected: 3954f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org virtual void PopulateHeader(Writer::Slot<Header> header) { 3964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org MachOSection::PopulateHeader(header); 3974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->addr = addr_; 3984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->size = size_; 3994f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 4000511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 4014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org private: 4024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t addr_; 4034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t size_; 4044f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}; 4054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif // defined(__MACH_O) 4064f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 4074f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 4084f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#if defined(__ELF) 4090511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comclass FullHeaderELFSection : public ELFSection { 4100511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com public: 4110511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com FullHeaderELFSection(const char* name, 4120511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Type type, 4130511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t align, 4140511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t addr, 4150511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t offset, 4160511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t size, 4170511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t flags) 4180511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com : ELFSection(name, type, align), 4190511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com addr_(addr), 4200511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com offset_(offset), 4210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com size_(size), 4220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com flags_(flags) { } 4230511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 4240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com protected: 4250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com virtual void PopulateHeader(Writer::Slot<Header> header) { 4260511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ELFSection::PopulateHeader(header); 4270511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->address = addr_; 4280511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->offset = offset_; 4290511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->size = size_; 4300511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->flags = flags_; 4310511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 4320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 4330511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com private: 4340511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t addr_; 4350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t offset_; 4360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t size_; 4370511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t flags_; 4380511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com}; 4390511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 4400511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 4417bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgclass ELFStringTable : public ELFSection { 4420511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com public: 4437bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org explicit ELFStringTable(const char* name) 4440511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com : ELFSection(name, TYPE_STRTAB, 1), writer_(NULL), offset_(0), size_(0) { 4450511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 4460511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 4470511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t Add(const char* str) { 4480511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (*str == '\0') return 0; 4490511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 4500511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t offset = size_; 4510511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com WriteString(str); 4520511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return offset; 4530511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 4540511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 4550511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com void AttachWriter(Writer* w) { 4560511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com writer_ = w; 4570511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com offset_ = writer_->position(); 4580511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 4590511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // First entry in the string table should be an empty string. 4600511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com WriteString(""); 4610511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 4620511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 4630511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com void DetachWriter() { 4640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com writer_ = NULL; 4650511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 4660511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 4670511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com virtual void WriteBody(Writer::Slot<Header> header, Writer* w) { 4680511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ASSERT(writer_ == NULL); 4690511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->offset = offset_; 4700511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->size = size_; 4710511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 4720511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 4730511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com private: 4740511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com void WriteString(const char* str) { 4750511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t written = 0; 4760511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com do { 4770511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com writer_->Write(*str); 4780511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com written++; 4790511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } while (*str++); 4800511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com size_ += written; 4810511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 4820511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 4830511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Writer* writer_; 4840511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 4850511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t offset_; 4860511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t size_; 4870511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com}; 4880511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 4890511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 4900511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comvoid ELFSection::PopulateHeader(Writer::Slot<ELFSection::Header> header, 4917bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org ELFStringTable* strtab) { 4920511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->name = strtab->Add(name_); 4930511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->type = type_; 4940511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->alignment = align_; 4950511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com PopulateHeader(header); 4960511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 4974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif // defined(__ELF) 4984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 4994f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 5004f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#if defined(__MACH_O) 5014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgclass MachO BASE_EMBEDDED { 5024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org public: 503c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org explicit MachO(Zone* zone) : zone_(zone), sections_(6, zone) { } 5044f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 5054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t AddSection(MachOSection* section) { 506c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org sections_.Add(section, zone_); 5074f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return sections_.length() - 1; 5084f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 5094f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 5104f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org void Write(Writer* w, uintptr_t code_start, uintptr_t code_size) { 5114f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Writer::Slot<MachOHeader> header = WriteHeader(w); 5124f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t load_command_start = w->position(); 5134f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Writer::Slot<MachOSegmentCommand> cmd = WriteSegmentCommand(w, 5144f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org code_start, 5154f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org code_size); 5164f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org WriteSections(w, cmd, header, load_command_start); 5174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 5184f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 5194f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org private: 5204f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org struct MachOHeader { 5214f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t magic; 5224f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t cputype; 5234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t cpusubtype; 5244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t filetype; 5254f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t ncmds; 5264f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t sizeofcmds; 5274f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t flags; 52893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_X64 5294f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t reserved; 5304f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif 5314f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org }; 5324f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 5334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org struct MachOSegmentCommand { 5344f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t cmd; 5354f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t cmdsize; 5364f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org char segname[16]; 53793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 5384f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t vmaddr; 5394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t vmsize; 5404f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t fileoff; 5414f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t filesize; 5424f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#else 5434f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint64_t vmaddr; 5444f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint64_t vmsize; 5454f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint64_t fileoff; 5464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint64_t filesize; 5474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif 5484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t maxprot; 5494f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t initprot; 5504f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t nsects; 5514f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t flags; 5524f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org }; 5534f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 5544f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org enum MachOLoadCommandCmd { 5554f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org LC_SEGMENT_32 = 0x00000001u, 5564f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org LC_SEGMENT_64 = 0x00000019u 5574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org }; 5584f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 5594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 5604f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Writer::Slot<MachOHeader> WriteHeader(Writer* w) { 5614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ASSERT(w->position() == 0); 5624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Writer::Slot<MachOHeader> header = w->CreateSlotHere<MachOHeader>(); 56393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 5644f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->magic = 0xFEEDFACEu; 5654f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->cputype = 7; // i386 5664f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->cpusubtype = 3; // CPU_SUBTYPE_I386_ALL 56793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#elif V8_TARGET_ARCH_X64 5684f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->magic = 0xFEEDFACFu; 5694f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->cputype = 7 | 0x01000000; // i386 | 64-bit ABI 5704f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->cpusubtype = 3; // CPU_SUBTYPE_I386_ALL 5714f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->reserved = 0; 5724f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#else 5734f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#error Unsupported target architecture. 5744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif 5754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->filetype = 0x1; // MH_OBJECT 5764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->ncmds = 1; 5774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->sizeofcmds = 0; 5784f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->flags = 0; 5794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return header; 5804f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 5814f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 5824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 5834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Writer::Slot<MachOSegmentCommand> WriteSegmentCommand(Writer* w, 5844f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t code_start, 5854f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t code_size) { 5864f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Writer::Slot<MachOSegmentCommand> cmd = 5874f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->CreateSlotHere<MachOSegmentCommand>(); 58893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 5894f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org cmd->cmd = LC_SEGMENT_32; 5904f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#else 5914f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org cmd->cmd = LC_SEGMENT_64; 5924f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif 5934f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org cmd->vmaddr = code_start; 5944f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org cmd->vmsize = code_size; 5954f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org cmd->fileoff = 0; 5964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org cmd->filesize = 0; 5974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org cmd->maxprot = 7; 5984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org cmd->initprot = 7; 5994f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org cmd->flags = 0; 6004f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org cmd->nsects = sections_.length(); 6014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org memset(cmd->segname, 0, 16); 6024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org cmd->cmdsize = sizeof(MachOSegmentCommand) + sizeof(MachOSection::Header) * 6034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org cmd->nsects; 6044f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return cmd; 6054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 6064f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 6074f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 6084f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org void WriteSections(Writer* w, 6094f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Writer::Slot<MachOSegmentCommand> cmd, 6104f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Writer::Slot<MachOHeader> header, 6114f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t load_command_start) { 6124f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Writer::Slot<MachOSection::Header> headers = 6134f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->CreateSlotsHere<MachOSection::Header>(sections_.length()); 6144f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org cmd->fileoff = w->position(); 6154f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org header->sizeofcmds = w->position() - load_command_start; 6164f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org for (int section = 0; section < sections_.length(); ++section) { 6174f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org sections_[section]->PopulateHeader(headers.at(section)); 6184f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org sections_[section]->WriteBody(headers.at(section), w); 6194f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 6204f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org cmd->filesize = w->position() - (uintptr_t)cmd->fileoff; 6214f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 6224f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 623c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org Zone* zone_; 6244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ZoneList<MachOSection*> sections_; 6254f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org}; 6264f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif // defined(__MACH_O) 6270511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 6280511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 6294f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#if defined(__ELF) 6300511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comclass ELF BASE_EMBEDDED { 6310511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com public: 632c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org explicit ELF(Zone* zone) : zone_(zone), sections_(6, zone) { 63333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org sections_.Add(new(zone) ELFSection("", ELFSection::TYPE_NULL, 0), zone); 6347bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org sections_.Add(new(zone) ELFStringTable(".shstrtab"), zone); 6350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 6360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 6370511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com void Write(Writer* w) { 6380511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com WriteHeader(w); 6390511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com WriteSectionTable(w); 6400511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com WriteSections(w); 6410511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 6420511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 6430511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ELFSection* SectionAt(uint32_t index) { 6440511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return sections_[index]; 6450511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 6460511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 647c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org uint32_t AddSection(ELFSection* section) { 648c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org sections_.Add(section, zone_); 6490511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com section->set_index(sections_.length() - 1); 6500511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return sections_.length() - 1; 6510511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 6520511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 6530511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com private: 6540511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com struct ELFHeader { 6550511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint8_t ident[16]; 6560511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint16_t type; 6570511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint16_t machine; 6580511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint32_t version; 6590511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t entry; 6600511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t pht_offset; 6610511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t sht_offset; 6620511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint32_t flags; 6630511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint16_t header_size; 6640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint16_t pht_entry_size; 6650511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint16_t pht_entry_num; 6660511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint16_t sht_entry_size; 6670511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint16_t sht_entry_num; 6680511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint16_t sht_strtab_index; 6690511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com }; 6700511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 6710511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 6720511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com void WriteHeader(Writer* w) { 6730511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ASSERT(w->position() == 0); 6740511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Writer::Slot<ELFHeader> header = w->CreateSlotHere<ELFHeader>(); 67593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM 6760511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com const uint8_t ident[16] = 6770511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com { 0x7f, 'E', 'L', 'F', 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 67893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#elif V8_TARGET_ARCH_X64 6790511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com const uint8_t ident[16] = 68033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org { 0x7f, 'E', 'L', 'F', 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 6810511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#else 6820511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#error Unsupported target architecture. 6830511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#endif 684e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OS::MemCopy(header->ident, ident, 16); 6850511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->type = 1; 68693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 6870511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->machine = 3; 68893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#elif V8_TARGET_ARCH_X64 6890511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Processor identification value for x64 is 62 as defined in 6900511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // System V ABI, AMD64 Supplement 6910511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // http://www.x86-64.org/documentation/abi.pdf 6920511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->machine = 62; 69393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#elif V8_TARGET_ARCH_ARM 69449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Set to EM_ARM, defined as 40, in "ARM ELF File Format" at 69549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // infocenter.arm.com/help/topic/com.arm.doc.dui0101a/DUI0101A_Elf.pdf 69649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org header->machine = 40; 6970511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#else 6980511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#error Unsupported target architecture. 6990511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#endif 7000511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->version = 1; 7010511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->entry = 0; 7020511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->pht_offset = 0; 7030511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->sht_offset = sizeof(ELFHeader); // Section table follows header. 7040511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->flags = 0; 7050511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->header_size = sizeof(ELFHeader); 7060511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->pht_entry_size = 0; 7070511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->pht_entry_num = 0; 7080511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->sht_entry_size = sizeof(ELFSection::Header); 7090511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->sht_entry_num = sections_.length(); 7100511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->sht_strtab_index = 1; 7110511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 7120511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 7130511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com void WriteSectionTable(Writer* w) { 7140511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Section headers table immediately follows file header. 7150511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ASSERT(w->position() == sizeof(ELFHeader)); 7160511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 7170511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Writer::Slot<ELFSection::Header> headers = 7180511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->CreateSlotsHere<ELFSection::Header>(sections_.length()); 7190511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 7200511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // String table for section table is the first section. 7217bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org ELFStringTable* strtab = static_cast<ELFStringTable*>(SectionAt(1)); 7220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com strtab->AttachWriter(w); 7230511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com for (int i = 0, length = sections_.length(); 7240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com i < length; 7250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com i++) { 7260511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com sections_[i]->PopulateHeader(headers.at(i), strtab); 7270511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 7280511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com strtab->DetachWriter(); 7290511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 7300511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 7310511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com int SectionHeaderPosition(uint32_t section_index) { 7320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return sizeof(ELFHeader) + sizeof(ELFSection::Header) * section_index; 7330511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 7340511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 7350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com void WriteSections(Writer* w) { 7360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Writer::Slot<ELFSection::Header> headers = 7370511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->SlotAt<ELFSection::Header>(sizeof(ELFHeader)); 7380511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 7390511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com for (int i = 0, length = sections_.length(); 7400511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com i < length; 7410511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com i++) { 7420511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com sections_[i]->WriteBody(headers.at(i), w); 7430511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 7440511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 7450511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 746c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org Zone* zone_; 7470511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ZoneList<ELFSection*> sections_; 7480511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com}; 7490511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 7500511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 7510511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comclass ELFSymbol BASE_EMBEDDED { 7520511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com public: 7530511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com enum Type { 7540511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_NOTYPE = 0, 7550511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_OBJECT = 1, 7560511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_FUNC = 2, 7570511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_SECTION = 3, 7580511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_FILE = 4, 7590511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_LOPROC = 13, 7600511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com TYPE_HIPROC = 15 7610511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com }; 7620511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 7630511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com enum Binding { 7640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com BIND_LOCAL = 0, 7650511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com BIND_GLOBAL = 1, 7660511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com BIND_WEAK = 2, 7670511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com BIND_LOPROC = 13, 7680511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com BIND_HIPROC = 15 7690511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com }; 7700511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 7710511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ELFSymbol(const char* name, 7720511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t value, 7730511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t size, 7740511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Binding binding, 7750511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Type type, 7760511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint16_t section) 7770511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com : name(name), 7780511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com value(value), 7790511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com size(size), 7800511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com info((binding << 4) | type), 7810511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com other(0), 7820511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com section(section) { 7830511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 7840511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 7850511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Binding binding() const { 7860511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return static_cast<Binding>(info >> 4); 7870511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 78893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM 7890511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com struct SerializedLayout { 7900511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com SerializedLayout(uint32_t name, 7910511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t value, 7920511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t size, 7930511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Binding binding, 7940511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Type type, 7950511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint16_t section) 7960511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com : name(name), 7970511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com value(value), 7980511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com size(size), 7990511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com info((binding << 4) | type), 8000511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com other(0), 8010511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com section(section) { 8020511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 8030511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 8040511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint32_t name; 8050511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t value; 8060511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t size; 8070511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint8_t info; 8080511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint8_t other; 8090511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint16_t section; 8100511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com }; 81193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#elif V8_TARGET_ARCH_X64 8120511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com struct SerializedLayout { 8130511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com SerializedLayout(uint32_t name, 8140511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t value, 8150511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t size, 8160511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Binding binding, 8170511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Type type, 8180511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint16_t section) 8190511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com : name(name), 8200511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com info((binding << 4) | type), 8210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com other(0), 8220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com section(section), 8230511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com value(value), 8240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com size(size) { 8250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 8260511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 8270511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint32_t name; 8280511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint8_t info; 8290511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint8_t other; 8300511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint16_t section; 8310511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t value; 8320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t size; 8330511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com }; 8340511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#endif 8350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 8367bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org void Write(Writer::Slot<SerializedLayout> s, ELFStringTable* t) { 8370511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Convert symbol names from strings to indexes in the string table. 8380511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com s->name = t->Add(name); 8390511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com s->value = value; 8400511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com s->size = size; 8410511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com s->info = info; 8420511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com s->other = other; 8430511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com s->section = section; 8440511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 8450511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 8460511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com private: 8470511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com const char* name; 8480511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t value; 8490511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t size; 8500511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint8_t info; 8510511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint8_t other; 8520511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint16_t section; 8530511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com}; 8540511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 8550511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 8560511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comclass ELFSymbolTable : public ELFSection { 8570511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com public: 85833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org ELFSymbolTable(const char* name, Zone* zone) 8590511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com : ELFSection(name, TYPE_SYMTAB, sizeof(uintptr_t)), 86033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org locals_(1, zone), 86133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org globals_(1, zone) { 8620511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 8630511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 8640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com virtual void WriteBody(Writer::Slot<Header> header, Writer* w) { 8650511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->Align(header->alignment); 8660511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com int total_symbols = locals_.length() + globals_.length() + 1; 8670511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->offset = w->position(); 8680511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 8690511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Writer::Slot<ELFSymbol::SerializedLayout> symbols = 8700511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->CreateSlotsHere<ELFSymbol::SerializedLayout>(total_symbols); 8710511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 8720511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->size = w->position() - header->offset; 8730511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 8740511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // String table for this symbol table should follow it in the section table. 8757bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org ELFStringTable* strtab = 8767bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org static_cast<ELFStringTable*>(w->debug_object()->SectionAt(index() + 1)); 8770511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com strtab->AttachWriter(w); 8780511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com symbols.at(0).set(ELFSymbol::SerializedLayout(0, 8790511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 0, 8800511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 0, 8810511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ELFSymbol::BIND_LOCAL, 8820511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ELFSymbol::TYPE_NOTYPE, 8830511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 0)); 8840511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com WriteSymbolsList(&locals_, symbols.at(1), strtab); 8850511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com WriteSymbolsList(&globals_, symbols.at(locals_.length() + 1), strtab); 8860511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com strtab->DetachWriter(); 8870511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 8880511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 88933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org void Add(const ELFSymbol& symbol, Zone* zone) { 8900511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (symbol.binding() == ELFSymbol::BIND_LOCAL) { 89133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org locals_.Add(symbol, zone); 8920511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } else { 89333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org globals_.Add(symbol, zone); 8940511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 8950511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 8960511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 8970511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com protected: 8980511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com virtual void PopulateHeader(Writer::Slot<Header> header) { 8990511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ELFSection::PopulateHeader(header); 9000511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // We are assuming that string table will follow symbol table. 9010511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->link = index() + 1; 9020511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->info = locals_.length() + 1; 9030511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com header->entry_size = sizeof(ELFSymbol::SerializedLayout); 9040511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 9050511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 9060511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com private: 9070511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com void WriteSymbolsList(const ZoneList<ELFSymbol>* src, 9080511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Writer::Slot<ELFSymbol::SerializedLayout> dst, 9097bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org ELFStringTable* strtab) { 9100511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com for (int i = 0, len = src->length(); 9110511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com i < len; 9120511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com i++) { 9130511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com src->at(i).Write(dst.at(i), strtab); 9140511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 9150511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 9160511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 9170511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ZoneList<ELFSymbol> locals_; 9180511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ZoneList<ELFSymbol> globals_; 9190511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com}; 9204f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif // defined(__ELF) 9210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 9220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 9230511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comclass CodeDescription BASE_EMBEDDED { 9240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com public: 92593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_X64 92631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org enum StackState { 92731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org POST_RBP_PUSH, 92831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org POST_RBP_SET, 92931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org POST_RBP_POP, 93031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org STACK_STATE_MAX 93131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org }; 93231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org#endif 93331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 9340511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com CodeDescription(const char* name, 9350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Code* code, 9360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Handle<Script> script, 93731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org GDBJITLineInfo* lineinfo, 9384f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org GDBJITInterface::CodeTag tag, 9394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org CompilationInfo* info) 94031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org : name_(name), 94131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org code_(code), 94231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org script_(script), 94331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org lineinfo_(lineinfo), 9444f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org tag_(tag), 9454f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org info_(info) { 94631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org } 9470511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 94831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org const char* name() const { 9490511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return name_; 9500511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 9510511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 95231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org GDBJITLineInfo* lineinfo() const { 95331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org return lineinfo_; 95431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org } 95531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 95631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org GDBJITInterface::CodeTag tag() const { 95731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org return tag_; 95831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org } 95931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 9604f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org CompilationInfo* info() const { 9614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return info_; 9624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 9634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 9644f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool IsInfoAvailable() const { 9654f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org return info_ != NULL; 9664f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 9674f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 96831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org uintptr_t CodeStart() const { 96931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org return reinterpret_cast<uintptr_t>(code_->instruction_start()); 9700511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 9710511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 97231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org uintptr_t CodeEnd() const { 97331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org return reinterpret_cast<uintptr_t>(code_->instruction_end()); 9740511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 9750511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 97631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org uintptr_t CodeSize() const { 97731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org return CodeEnd() - CodeStart(); 97831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org } 97931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 98031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org bool IsLineInfoAvailable() { 9810511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return !script_.is_null() && 9820511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com script_->source()->IsString() && 9830511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com script_->HasValidSource() && 9840511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com script_->name()->IsString() && 9850511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com lineinfo_ != NULL; 9860511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 9870511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 98893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_X64 98931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org uintptr_t GetStackStateStartAddress(StackState state) const { 99031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org ASSERT(state < STACK_STATE_MAX); 99131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org return stack_state_start_addresses_[state]; 99231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org } 9930511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 99431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org void SetStackStateStartAddress(StackState state, uintptr_t addr) { 99531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org ASSERT(state < STACK_STATE_MAX); 99631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org stack_state_start_addresses_[state] = addr; 99731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org } 99831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org#endif 99931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 100083e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org SmartArrayPointer<char> GetFilename() { 10010511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return String::cast(script_->name())->ToCString(); 10020511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 10030511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 10040511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com int GetScriptLineNumber(int pos) { 10050511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return GetScriptLineNumberSafe(script_, pos) + 1; 10060511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 10070511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 100831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 10090511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com private: 10100511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com const char* name_; 10110511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Code* code_; 10120511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Handle<Script> script_; 10130511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com GDBJITLineInfo* lineinfo_; 101431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org GDBJITInterface::CodeTag tag_; 10154f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org CompilationInfo* info_; 101693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_X64 101731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org uintptr_t stack_state_start_addresses_[STACK_STATE_MAX]; 101831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org#endif 10190511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com}; 10200511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 10214f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#if defined(__ELF) 10220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comstatic void CreateSymbolsTable(CodeDescription* desc, 1023e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Zone* zone, 10240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ELF* elf, 10250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com int text_section_index) { 102633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org ELFSymbolTable* symtab = new(zone) ELFSymbolTable(".symtab", zone); 10277bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org ELFStringTable* strtab = new(zone) ELFStringTable(".strtab"); 10280511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 10290511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Symbol table should be followed by the linked string table. 1030c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org elf->AddSection(symtab); 1031c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org elf->AddSection(strtab); 10320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 10330511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com symtab->Add(ELFSymbol("V8 Code", 10340511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 0, 10350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 0, 10360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ELFSymbol::BIND_LOCAL, 10370511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ELFSymbol::TYPE_FILE, 103833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org ELFSection::INDEX_ABSOLUTE), 103933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org zone); 10400511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 104131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org symtab->Add(ELFSymbol(desc->name(), 10420511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 0, 104331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org desc->CodeSize(), 10440511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ELFSymbol::BIND_GLOBAL, 10450511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ELFSymbol::TYPE_FUNC, 104633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org text_section_index), 104733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org zone); 10480511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 10494f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif // defined(__ELF) 10500511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 10510511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 10524f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgclass DebugInfoSection : public DebugSection { 10530511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com public: 10540511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com explicit DebugInfoSection(CodeDescription* desc) 10554f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#if defined(__ELF) 10564f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org : ELFSection(".debug_info", TYPE_PROGBITS, 1), 10574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#else 10584f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org : MachOSection("__debug_info", 10594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org "__DWARF", 10604f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 1, 10614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG), 10624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif 10634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org desc_(desc) { } 10644f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 10654f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // DWARF2 standard 10664f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org enum DWARF2LocationOp { 10674f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_OP_reg0 = 0x50, 10684f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_OP_reg1 = 0x51, 10694f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_OP_reg2 = 0x52, 10704f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_OP_reg3 = 0x53, 10714f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_OP_reg4 = 0x54, 10724f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_OP_reg5 = 0x55, 10734f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_OP_reg6 = 0x56, 10744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_OP_reg7 = 0x57, 10754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_OP_fbreg = 0x91 // 1 param: SLEB128 offset 10764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org }; 10774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 10784f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org enum DWARF2Encoding { 10794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_ATE_ADDRESS = 0x1, 10804f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_ATE_SIGNED = 0x5 10814f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org }; 10820511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 108333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org bool WriteBodyInternal(Writer* w) { 10844f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t cu_start = w->position(); 10850511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Writer::Slot<uint32_t> size = w->CreateSlotHere<uint32_t>(); 10860511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t start = w->position(); 10870511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->Write<uint16_t>(2); // DWARF version. 10880511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->Write<uint32_t>(0); // Abbreviation table offset. 10890511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->Write<uint8_t>(sizeof(intptr_t)); 10900511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 10910511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->WriteULEB128(1); // Abbreviation code. 109231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->WriteString(*desc_->GetFilename()); 109331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<intptr_t>(desc_->CodeStart()); 109431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize()); 10950511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->Write<uint32_t>(0); 10964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 10974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uint32_t ty_offset = static_cast<uint32_t>(w->position() - cu_start); 10984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(3); 10994f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->Write<uint8_t>(kPointerSize); 11004f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteString("v8value"); 11014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 11024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (desc_->IsInfoAvailable()) { 110333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org Scope* scope = desc_->info()->scope(); 11044f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(2); 11054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteString(desc_->name()); 11064f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->Write<intptr_t>(desc_->CodeStart()); 11074f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize()); 11084f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Writer::Slot<uint32_t> fb_block_size = w->CreateSlotHere<uint32_t>(); 11094f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t fb_block_start = w->position(); 111093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 11114f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->Write<uint8_t>(DW_OP_reg5); // The frame pointer's here on ia32 111293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#elif V8_TARGET_ARCH_X64 11134f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->Write<uint8_t>(DW_OP_reg6); // and here on x64. 111493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#elif V8_TARGET_ARCH_ARM 111533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org UNIMPLEMENTED(); 111693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#elif V8_TARGET_ARCH_MIPS 111789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org UNIMPLEMENTED(); 11184f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#else 11194f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#error Unsupported target architecture. 11204f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif 11214f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org fb_block_size.set(static_cast<uint32_t>(w->position() - fb_block_start)); 11224f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 112333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org int params = scope->num_parameters(); 112433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org int slots = scope->num_stack_slots(); 112533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org int context_slots = scope->ContextLocalCount(); 11264f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // The real slot ID is internal_slots + context_slot_id. 11274f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int internal_slots = Context::MIN_CONTEXT_SLOTS; 112833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org int locals = scope->StackLocalCount(); 11294f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int current_abbreviation = 4; 11304f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 11314f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org for (int param = 0; param < params; ++param) { 11324f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(current_abbreviation++); 11334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteString( 113433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org *scope->parameter(param)->name()->ToCString(DISALLOW_NULLS)); 11354f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->Write<uint32_t>(ty_offset); 11364f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>(); 11374f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t block_start = w->position(); 11384f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->Write<uint8_t>(DW_OP_fbreg); 11394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteSLEB128( 11404f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org JavaScriptFrameConstants::kLastParameterOffset + 11414f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org kPointerSize * (params - param - 1)); 11424f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org block_size.set(static_cast<uint32_t>(w->position() - block_start)); 11434f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 11444f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 11454f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org EmbeddedVector<char, 256> buffer; 11464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org StringBuilder builder(buffer.start(), buffer.length()); 11474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 11484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org for (int slot = 0; slot < slots; ++slot) { 11494f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(current_abbreviation++); 11504f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org builder.Reset(); 11514f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org builder.AddFormatted("slot%d", slot); 11524f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteString(builder.Finalize()); 11534f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 11544f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 11554f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // See contexts.h for more information. 11564f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ASSERT(Context::MIN_CONTEXT_SLOTS == 4); 11574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ASSERT(Context::CLOSURE_INDEX == 0); 11584f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ASSERT(Context::PREVIOUS_INDEX == 1); 11594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ASSERT(Context::EXTENSION_INDEX == 2); 116033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org ASSERT(Context::GLOBAL_OBJECT_INDEX == 3); 11614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(current_abbreviation++); 11624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteString(".closure"); 11634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(current_abbreviation++); 11644f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteString(".previous"); 11654f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(current_abbreviation++); 11664f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteString(".extension"); 11674f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(current_abbreviation++); 11684f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteString(".global"); 11694f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 11704f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org for (int context_slot = 0; 11714f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org context_slot < context_slots; 11724f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ++context_slot) { 11734f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(current_abbreviation++); 11744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org builder.Reset(); 11754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org builder.AddFormatted("context_slot%d", context_slot + internal_slots); 11764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteString(builder.Finalize()); 11774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 11784f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 117933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org ZoneList<Variable*> stack_locals(locals, scope->zone()); 118033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org ZoneList<Variable*> context_locals(context_slots, scope->zone()); 118133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org scope->CollectStackAndContextLocals(&stack_locals, &context_locals); 11824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org for (int local = 0; local < locals; ++local) { 11834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(current_abbreviation++); 11844f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteString( 118533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org *stack_locals[local]->name()->ToCString(DISALLOW_NULLS)); 11864f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->Write<uint32_t>(ty_offset); 11874f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>(); 11884f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t block_start = w->position(); 11894f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->Write<uint8_t>(DW_OP_fbreg); 11904f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteSLEB128( 11914f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org JavaScriptFrameConstants::kLocal0Offset - 11924f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org kPointerSize * local); 11934f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org block_size.set(static_cast<uint32_t>(w->position() - block_start)); 11944f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 11954f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 11964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org { 11974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(current_abbreviation++); 11984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteString("__function"); 11994f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->Write<uint32_t>(ty_offset); 12004f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>(); 12014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t block_start = w->position(); 12024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->Write<uint8_t>(DW_OP_fbreg); 12034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteSLEB128(JavaScriptFrameConstants::kFunctionOffset); 12044f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org block_size.set(static_cast<uint32_t>(w->position() - block_start)); 12054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 12064f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 12074f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org { 12084f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(current_abbreviation++); 12094f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteString("__context"); 12104f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->Write<uint32_t>(ty_offset); 12114f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>(); 12124f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org uintptr_t block_start = w->position(); 12134f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->Write<uint8_t>(DW_OP_fbreg); 12144f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteSLEB128(StandardFrameConstants::kContextOffset); 12154f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org block_size.set(static_cast<uint32_t>(w->position() - block_start)); 12164f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 1217e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 1218e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org w->WriteULEB128(0); // Terminate the sub program. 12194f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 12204f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 1221e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org w->WriteULEB128(0); // Terminate the compile unit. 12220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com size.set(static_cast<uint32_t>(w->position() - start)); 12230511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return true; 12240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 12250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 12260511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com private: 12270511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com CodeDescription* desc_; 12280511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com}; 12290511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 12300511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 12314f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgclass DebugAbbrevSection : public DebugSection { 12320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com public: 12334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org explicit DebugAbbrevSection(CodeDescription* desc) 12344f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#ifdef __ELF 12354f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org : ELFSection(".debug_abbrev", TYPE_PROGBITS, 1), 12364f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#else 12374f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org : MachOSection("__debug_abbrev", 12384f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org "__DWARF", 12394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 1, 12404f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG), 12414f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif 12424f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org desc_(desc) { } 12430511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 12440511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // DWARF2 standard, figure 14. 12450511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com enum DWARF2Tags { 12464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_TAG_FORMAL_PARAMETER = 0x05, 12474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_TAG_POINTER_TYPE = 0xf, 12484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_TAG_COMPILE_UNIT = 0x11, 12494f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_TAG_STRUCTURE_TYPE = 0x13, 12504f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_TAG_BASE_TYPE = 0x24, 12514f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_TAG_SUBPROGRAM = 0x2e, 12524f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_TAG_VARIABLE = 0x34 12530511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com }; 12540511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 12550511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // DWARF2 standard, figure 16. 12560511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com enum DWARF2ChildrenDetermination { 12570511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com DW_CHILDREN_NO = 0, 12580511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com DW_CHILDREN_YES = 1 12590511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com }; 12600511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 12610511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // DWARF standard, figure 17. 12620511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com enum DWARF2Attribute { 12634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_AT_LOCATION = 0x2, 12640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com DW_AT_NAME = 0x3, 12654f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_AT_BYTE_SIZE = 0xb, 12660511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com DW_AT_STMT_LIST = 0x10, 12670511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com DW_AT_LOW_PC = 0x11, 12684f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_AT_HIGH_PC = 0x12, 12694f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_AT_ENCODING = 0x3e, 12704f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_AT_FRAME_BASE = 0x40, 12714f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_AT_TYPE = 0x49 12720511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com }; 12730511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 12740511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // DWARF2 standard, figure 19. 12750511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com enum DWARF2AttributeForm { 12760511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com DW_FORM_ADDR = 0x1, 12774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_FORM_BLOCK4 = 0x4, 12780511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com DW_FORM_STRING = 0x8, 12794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_FORM_DATA4 = 0x6, 12804f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_FORM_BLOCK = 0x9, 12814f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_FORM_DATA1 = 0xb, 12824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_FORM_FLAG = 0xc, 12834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org DW_FORM_REF4 = 0x13 12840511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com }; 12850511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 12864f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org void WriteVariableAbbreviation(Writer* w, 12874f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int abbreviation_code, 12884f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool has_value, 12894f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool is_parameter) { 12904f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(abbreviation_code); 12914f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(is_parameter ? DW_TAG_FORMAL_PARAMETER : DW_TAG_VARIABLE); 12924f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->Write<uint8_t>(DW_CHILDREN_NO); 12934f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(DW_AT_NAME); 12944f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(DW_FORM_STRING); 12954f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (has_value) { 12964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(DW_AT_TYPE); 12974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(DW_FORM_REF4); 12984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(DW_AT_LOCATION); 12994f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(DW_FORM_BLOCK4); 13004f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 13014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(0); 13024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(0); 13034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 13044f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 130533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org bool WriteBodyInternal(Writer* w) { 13064f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int current_abbreviation = 1; 13074f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool extra_info = desc_->IsInfoAvailable(); 13084f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ASSERT(desc_->IsLineInfoAvailable()); 13094f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(current_abbreviation++); 13100511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->WriteULEB128(DW_TAG_COMPILE_UNIT); 13114f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->Write<uint8_t>(extra_info ? DW_CHILDREN_YES : DW_CHILDREN_NO); 13120511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->WriteULEB128(DW_AT_NAME); 13130511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->WriteULEB128(DW_FORM_STRING); 13140511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->WriteULEB128(DW_AT_LOW_PC); 13150511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->WriteULEB128(DW_FORM_ADDR); 13160511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->WriteULEB128(DW_AT_HIGH_PC); 13170511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->WriteULEB128(DW_FORM_ADDR); 13180511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->WriteULEB128(DW_AT_STMT_LIST); 13190511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->WriteULEB128(DW_FORM_DATA4); 13200511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->WriteULEB128(0); 13210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->WriteULEB128(0); 13224f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 13234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (extra_info) { 132433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org Scope* scope = desc_->info()->scope(); 132533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org int params = scope->num_parameters(); 132633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org int slots = scope->num_stack_slots(); 132733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org int context_slots = scope->ContextLocalCount(); 13284f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // The real slot ID is internal_slots + context_slot_id. 13294f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org int internal_slots = Context::MIN_CONTEXT_SLOTS; 133033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org int locals = scope->StackLocalCount(); 1331e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Total children is params + slots + context_slots + internal_slots + 1332e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // locals + 2 (__function and __context). 13334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 13344f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // The extra duplication below seems to be necessary to keep 13354f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // gdb from getting upset on OSX. 13364f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(current_abbreviation++); // Abbreviation code. 13374f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(DW_TAG_SUBPROGRAM); 1338e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org w->Write<uint8_t>(DW_CHILDREN_YES); 13394f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(DW_AT_NAME); 13404f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(DW_FORM_STRING); 13414f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(DW_AT_LOW_PC); 13424f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(DW_FORM_ADDR); 13434f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(DW_AT_HIGH_PC); 13444f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(DW_FORM_ADDR); 13454f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(DW_AT_FRAME_BASE); 13464f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(DW_FORM_BLOCK4); 13474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(0); 13484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(0); 13494f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 13504f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(current_abbreviation++); 13514f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(DW_TAG_STRUCTURE_TYPE); 13524f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->Write<uint8_t>(DW_CHILDREN_NO); 13534f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(DW_AT_BYTE_SIZE); 13544f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(DW_FORM_DATA1); 13554f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(DW_AT_NAME); 13564f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(DW_FORM_STRING); 13574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(0); 13584f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(0); 13594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 13604f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org for (int param = 0; param < params; ++param) { 13614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org WriteVariableAbbreviation(w, current_abbreviation++, true, true); 13624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 13634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 13644f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org for (int slot = 0; slot < slots; ++slot) { 13654f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org WriteVariableAbbreviation(w, current_abbreviation++, false, false); 13664f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 13674f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 13684f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org for (int internal_slot = 0; 13694f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org internal_slot < internal_slots; 13704f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ++internal_slot) { 13714f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org WriteVariableAbbreviation(w, current_abbreviation++, false, false); 13724f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 13734f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 13744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org for (int context_slot = 0; 13754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org context_slot < context_slots; 13764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org ++context_slot) { 13774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org WriteVariableAbbreviation(w, current_abbreviation++, false, false); 13784f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 13794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 13804f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org for (int local = 0; local < locals; ++local) { 13814f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org WriteVariableAbbreviation(w, current_abbreviation++, true, false); 13824f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 13834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 13844f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // The function. 13854f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org WriteVariableAbbreviation(w, current_abbreviation++, true, false); 13864f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 13874f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // The context. 13884f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org WriteVariableAbbreviation(w, current_abbreviation++, true, false); 13894f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 1390e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org w->WriteULEB128(0); // Terminate the sibling list. 13914f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 13924f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 13934f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org w->WriteULEB128(0); // Terminate the table. 13940511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return true; 13950511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 13964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 13974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org private: 13984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org CodeDescription* desc_; 13990511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com}; 14000511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 14010511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 14024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgclass DebugLineSection : public DebugSection { 14030511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com public: 14040511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com explicit DebugLineSection(CodeDescription* desc) 14054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#ifdef __ELF 14060511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com : ELFSection(".debug_line", TYPE_PROGBITS, 1), 14074f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#else 14084f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org : MachOSection("__debug_line", 14094f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org "__DWARF", 14104f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 1, 14114f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG), 14124f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif 14130511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com desc_(desc) { } 14140511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 14150511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // DWARF2 standard, figure 34. 14160511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com enum DWARF2Opcodes { 14170511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com DW_LNS_COPY = 1, 14180511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com DW_LNS_ADVANCE_PC = 2, 14190511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com DW_LNS_ADVANCE_LINE = 3, 14200511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com DW_LNS_SET_FILE = 4, 14210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com DW_LNS_SET_COLUMN = 5, 14220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com DW_LNS_NEGATE_STMT = 6 14230511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com }; 14240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 14250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // DWARF2 standard, figure 35. 14260511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com enum DWARF2ExtendedOpcode { 14270511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com DW_LNE_END_SEQUENCE = 1, 14280511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com DW_LNE_SET_ADDRESS = 2, 14290511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com DW_LNE_DEFINE_FILE = 3 14300511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com }; 14310511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 143233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org bool WriteBodyInternal(Writer* w) { 14330511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Write prologue. 14340511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Writer::Slot<uint32_t> total_length = w->CreateSlotHere<uint32_t>(); 14350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t start = w->position(); 14360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 143749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Used for special opcodes 143849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org const int8_t line_base = 1; 143949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org const uint8_t line_range = 7; 144049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org const int8_t max_line_incr = (line_base + line_range - 1); 144149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org const uint8_t opcode_base = DW_LNS_NEGATE_STMT + 1; 144249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 14430511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->Write<uint16_t>(2); // Field version. 14440511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Writer::Slot<uint32_t> prologue_length = w->CreateSlotHere<uint32_t>(); 14450511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t prologue_start = w->position(); 14460511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->Write<uint8_t>(1); // Field minimum_instruction_length. 14470511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->Write<uint8_t>(1); // Field default_is_stmt. 144849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org w->Write<int8_t>(line_base); // Field line_base. 144949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org w->Write<uint8_t>(line_range); // Field line_range. 145049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org w->Write<uint8_t>(opcode_base); // Field opcode_base. 14510511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->Write<uint8_t>(0); // DW_LNS_COPY operands count. 14520511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->Write<uint8_t>(1); // DW_LNS_ADVANCE_PC operands count. 14530511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->Write<uint8_t>(1); // DW_LNS_ADVANCE_LINE operands count. 14540511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->Write<uint8_t>(1); // DW_LNS_SET_FILE operands count. 14550511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->Write<uint8_t>(1); // DW_LNS_SET_COLUMN operands count. 14560511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->Write<uint8_t>(0); // DW_LNS_NEGATE_STMT operands count. 14570511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->Write<uint8_t>(0); // Empty include_directories sequence. 145831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->WriteString(*desc_->GetFilename()); // File name. 14590511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->WriteULEB128(0); // Current directory. 14600511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->WriteULEB128(0); // Unknown modification time. 14610511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->WriteULEB128(0); // Unknown file size. 14620511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->Write<uint8_t>(0); 14630511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com prologue_length.set(static_cast<uint32_t>(w->position() - prologue_start)); 14640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 14650511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com WriteExtendedOpcode(w, DW_LNE_SET_ADDRESS, sizeof(intptr_t)); 146631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<intptr_t>(desc_->CodeStart()); 146749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org w->Write<uint8_t>(DW_LNS_COPY); 14680511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 14690511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com intptr_t pc = 0; 14700511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com intptr_t line = 1; 14710511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com bool is_statement = true; 14720511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 14730511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com List<GDBJITLineInfo::PCInfo>* pc_info = desc_->lineinfo()->pc_info(); 14740511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com pc_info->Sort(&ComparePCInfo); 147549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 147649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org int pc_info_length = pc_info->length(); 147749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org for (int i = 0; i < pc_info_length; i++) { 14780511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com GDBJITLineInfo::PCInfo* info = &pc_info->at(i); 14790511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ASSERT(info->pc_ >= pc); 148049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 148149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Reduce bloating in the debug line table by removing duplicate line 148249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // entries (per DWARF2 standard). 148349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org intptr_t new_line = desc_->GetScriptLineNumber(info->pos_); 148449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org if (new_line == line) { 148549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org continue; 14860511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 148749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 148849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Mark statement boundaries. For a better debugging experience, mark 148949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // the last pc address in the function as a statement (e.g. "}"), so that 149049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // a user can see the result of the last line executed in the function, 149149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // should control reach the end. 149249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org if ((i+1) == pc_info_length) { 149349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org if (!is_statement) { 149449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org w->Write<uint8_t>(DW_LNS_NEGATE_STMT); 149549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 149649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } else if (is_statement != info->is_statement_) { 14970511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->Write<uint8_t>(DW_LNS_NEGATE_STMT); 14980511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com is_statement = !is_statement; 14990511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 150049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 150149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Generate special opcodes, if possible. This results in more compact 150249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // debug line tables. See the DWARF 2.0 standard to learn more about 150349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // special opcodes. 150449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org uintptr_t pc_diff = info->pc_ - pc; 150549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org intptr_t line_diff = new_line - line; 150649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 150749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Compute special opcode (see DWARF 2.0 standard) 150849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org intptr_t special_opcode = (line_diff - line_base) + 150949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org (line_range * pc_diff) + opcode_base; 151049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 151149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // If special_opcode is less than or equal to 255, it can be used as a 151249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // special opcode. If line_diff is larger than the max line increment 151349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // allowed for a special opcode, or if line_diff is less than the minimum 151449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // line that can be added to the line register (i.e. line_base), then 151549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // special_opcode can't be used. 151649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org if ((special_opcode >= opcode_base) && (special_opcode <= 255) && 151749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org (line_diff <= max_line_incr) && (line_diff >= line_base)) { 151849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org w->Write<uint8_t>(special_opcode); 151949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } else { 152049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org w->Write<uint8_t>(DW_LNS_ADVANCE_PC); 152149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org w->WriteSLEB128(pc_diff); 152249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org w->Write<uint8_t>(DW_LNS_ADVANCE_LINE); 152349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org w->WriteSLEB128(line_diff); 15240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->Write<uint8_t>(DW_LNS_COPY); 15250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 152649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 152749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Increment the pc and line operands. 152849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org pc += pc_diff; 152949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org line += line_diff; 15300511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 153149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Advance the pc to the end of the routine, since the end sequence opcode 153249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // requires this. 153349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org w->Write<uint8_t>(DW_LNS_ADVANCE_PC); 153449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org w->WriteSLEB128(desc_->CodeSize() - pc); 15350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com WriteExtendedOpcode(w, DW_LNE_END_SEQUENCE, 0); 15360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com total_length.set(static_cast<uint32_t>(w->position() - start)); 15370511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return true; 15380511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 15390511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 15400511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com private: 15410511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com void WriteExtendedOpcode(Writer* w, 15420511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com DWARF2ExtendedOpcode op, 15430511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com size_t operands_size) { 15440511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->Write<uint8_t>(0); 15450511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->WriteULEB128(operands_size + 1); 15460511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com w->Write<uint8_t>(op); 15470511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 15480511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 15490511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com static int ComparePCInfo(const GDBJITLineInfo::PCInfo* a, 15500511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com const GDBJITLineInfo::PCInfo* b) { 15510511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (a->pc_ == b->pc_) { 15520511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (a->is_statement_ != b->is_statement_) { 15530511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return b->is_statement_ ? +1 : -1; 15540511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 15550511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return 0; 15560511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } else if (a->pc_ > b->pc_) { 15570511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return +1; 15580511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } else { 15590511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return -1; 15600511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 15610511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 15620511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 15630511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com CodeDescription* desc_; 15640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com}; 15650511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 15660511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 156793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_X64 156831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 15694f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgclass UnwindInfoSection : public DebugSection { 157031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org public: 1571f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com explicit UnwindInfoSection(CodeDescription* desc); 157233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org virtual bool WriteBodyInternal(Writer* w); 157331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 1574f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com int WriteCIE(Writer* w); 1575f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com void WriteFDE(Writer* w, int); 157631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 1577f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com void WriteFDEStateOnEntry(Writer* w); 1578f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com void WriteFDEStateAfterRBPPush(Writer* w); 1579f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com void WriteFDEStateAfterRBPSet(Writer* w); 1580f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com void WriteFDEStateAfterRBPPop(Writer* w); 158131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 1582f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com void WriteLength(Writer* w, 158331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org Writer::Slot<uint32_t>* length_slot, 158431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org int initial_position); 158531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 158631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org private: 1587f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com CodeDescription* desc_; 158831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 158931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // DWARF3 Specification, Table 7.23 159031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org enum CFIInstructions { 159131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_ADVANCE_LOC = 0x40, 159231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_OFFSET = 0x80, 159331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_RESTORE = 0xC0, 159431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_NOP = 0x00, 159531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_SET_LOC = 0x01, 159631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_ADVANCE_LOC1 = 0x02, 159731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_ADVANCE_LOC2 = 0x03, 159831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_ADVANCE_LOC4 = 0x04, 159931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_OFFSET_EXTENDED = 0x05, 160031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_RESTORE_EXTENDED = 0x06, 160131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_UNDEFINED = 0x07, 160231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_SAME_VALUE = 0x08, 160331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_REGISTER = 0x09, 160431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_REMEMBER_STATE = 0x0A, 160531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_RESTORE_STATE = 0x0B, 160631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_DEF_CFA = 0x0C, 160731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_DEF_CFA_REGISTER = 0x0D, 160831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_DEF_CFA_OFFSET = 0x0E, 160931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 161031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_DEF_CFA_EXPRESSION = 0x0F, 161131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_EXPRESSION = 0x10, 161231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_OFFSET_EXTENDED_SF = 0x11, 161331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_DEF_CFA_SF = 0x12, 161431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_DEF_CFA_OFFSET_SF = 0x13, 161531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_VAL_OFFSET = 0x14, 161631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_VAL_OFFSET_SF = 0x15, 161731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DW_CFA_VAL_EXPRESSION = 0x16 161831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org }; 161931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 162031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // System V ABI, AMD64 Supplement, Version 0.99.5, Figure 3.36 162131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org enum RegisterMapping { 162231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // Only the relevant ones have been added to reduce clutter. 162331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org AMD64_RBP = 6, 162431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org AMD64_RSP = 7, 162531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org AMD64_RA = 16 162631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org }; 162731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 162831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org enum CFIConstants { 162931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org CIE_ID = 0, 163031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org CIE_VERSION = 1, 163131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org CODE_ALIGN_FACTOR = 1, 163231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org DATA_ALIGN_FACTOR = 1, 163331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org RETURN_ADDRESS_REGISTER = AMD64_RA 163431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org }; 163531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org}; 163631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 163731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 1638f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid UnwindInfoSection::WriteLength(Writer* w, 163931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org Writer::Slot<uint32_t>* length_slot, 164031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org int initial_position) { 164131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org uint32_t align = (w->position() - initial_position) % kPointerSize; 164231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 164331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org if (align != 0) { 164431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org for (uint32_t i = 0; i < (kPointerSize - align); i++) { 164531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint8_t>(DW_CFA_NOP); 164631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org } 164731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org } 164831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 164931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org ASSERT((w->position() - initial_position) % kPointerSize == 0); 165031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org length_slot->set(w->position() - initial_position); 165131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org} 165231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 165331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 1654f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comUnwindInfoSection::UnwindInfoSection(CodeDescription* desc) 16554f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#ifdef __ELF 16564f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org : ELFSection(".eh_frame", TYPE_X86_64_UNWIND, 1), 16574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#else 16584f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org : MachOSection("__eh_frame", "__TEXT", sizeof(uintptr_t), 16594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org MachOSection::S_REGULAR), 16604f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif 16614f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org desc_(desc) { } 166231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 1663f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comint UnwindInfoSection::WriteCIE(Writer* w) { 166431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org Writer::Slot<uint32_t> cie_length_slot = w->CreateSlotHere<uint32_t>(); 166531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org uint32_t cie_position = w->position(); 166631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 166731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // Write out the CIE header. Currently no 'common instructions' are 166831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // emitted onto the CIE; every FDE has its own set of instructions. 166931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 167031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint32_t>(CIE_ID); 167131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint8_t>(CIE_VERSION); 167231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint8_t>(0); // Null augmentation string. 167331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->WriteSLEB128(CODE_ALIGN_FACTOR); 167431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->WriteSLEB128(DATA_ALIGN_FACTOR); 167531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint8_t>(RETURN_ADDRESS_REGISTER); 167631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 167731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org WriteLength(w, &cie_length_slot, cie_position); 167831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 167931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org return cie_position; 168031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org} 168131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 168231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 1683f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid UnwindInfoSection::WriteFDE(Writer* w, int cie_position) { 168431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // The only FDE for this function. The CFA is the current RBP. 168531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org Writer::Slot<uint32_t> fde_length_slot = w->CreateSlotHere<uint32_t>(); 168631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org int fde_position = w->position(); 168731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<int32_t>(fde_position - cie_position + 4); 168831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 168931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uintptr_t>(desc_->CodeStart()); 169031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uintptr_t>(desc_->CodeSize()); 169131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 169231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org WriteFDEStateOnEntry(w); 169331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org WriteFDEStateAfterRBPPush(w); 169431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org WriteFDEStateAfterRBPSet(w); 169531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org WriteFDEStateAfterRBPPop(w); 169631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 169731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org WriteLength(w, &fde_length_slot, fde_position); 169831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org} 169931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 170031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 1701f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid UnwindInfoSection::WriteFDEStateOnEntry(Writer* w) { 170231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // The first state, just after the control has been transferred to the the 170331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // function. 170431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 170531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // RBP for this function will be the value of RSP after pushing the RBP 170631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // for the previous function. The previous RBP has not been pushed yet. 170731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint8_t>(DW_CFA_DEF_CFA_SF); 170831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->WriteULEB128(AMD64_RSP); 170931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->WriteSLEB128(-kPointerSize); 171031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 171131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // The RA is stored at location CFA + kCallerPCOffset. This is an invariant, 171231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // and hence omitted from the next states. 171331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); 171431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->WriteULEB128(AMD64_RA); 171531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->WriteSLEB128(StandardFrameConstants::kCallerPCOffset); 171631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 171731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // The RBP of the previous function is still in RBP. 171831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint8_t>(DW_CFA_SAME_VALUE); 171931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->WriteULEB128(AMD64_RBP); 172031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 172131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // Last location described by this entry. 172231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint8_t>(DW_CFA_SET_LOC); 172331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint64_t>( 172431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_PUSH)); 172531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org} 172631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 172731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 1728f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid UnwindInfoSection::WriteFDEStateAfterRBPPush(Writer* w) { 172931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // The second state, just after RBP has been pushed. 173031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 173131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // RBP / CFA for this function is now the current RSP, so just set the 173231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // offset from the previous rule (from -8) to 0. 173331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint8_t>(DW_CFA_DEF_CFA_OFFSET); 173431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->WriteULEB128(0); 173531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 173631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // The previous RBP is stored at CFA + kCallerFPOffset. This is an invariant 173731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // in this and the next state, and hence omitted in the next state. 173831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); 173931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->WriteULEB128(AMD64_RBP); 174031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset); 174131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 174231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // Last location described by this entry. 174331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint8_t>(DW_CFA_SET_LOC); 174431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint64_t>( 174531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_SET)); 174631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org} 174731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 174831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 1749f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid UnwindInfoSection::WriteFDEStateAfterRBPSet(Writer* w) { 175031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // The third state, after the RBP has been set. 175131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 175231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // The CFA can now directly be set to RBP. 175331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint8_t>(DW_CFA_DEF_CFA); 175431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->WriteULEB128(AMD64_RBP); 175531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->WriteULEB128(0); 175631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 175731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // Last location described by this entry. 175831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint8_t>(DW_CFA_SET_LOC); 175931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint64_t>( 176031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_POP)); 176131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org} 176231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 176331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 1764f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid UnwindInfoSection::WriteFDEStateAfterRBPPop(Writer* w) { 176531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // The fourth (final) state. The RBP has been popped (just before issuing a 176631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // return). 176731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 176831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // The CFA can is now calculated in the same way as in the first state. 176931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint8_t>(DW_CFA_DEF_CFA_SF); 177031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->WriteULEB128(AMD64_RSP); 177131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->WriteSLEB128(-kPointerSize); 177231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 177331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // The RBP 177431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); 177531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->WriteULEB128(AMD64_RBP); 177631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset); 177731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 177831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // Last location described by this entry. 177931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint8_t>(DW_CFA_SET_LOC); 178031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org w->Write<uint64_t>(desc_->CodeEnd()); 178131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org} 178231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 178331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 178433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.orgbool UnwindInfoSection::WriteBodyInternal(Writer* w) { 178531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org uint32_t cie_position = WriteCIE(w); 178631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org WriteFDE(w, cie_position); 178731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org return true; 178831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org} 178931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 179031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 179131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org#endif // V8_TARGET_ARCH_X64 179231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 1793e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgstatic void CreateDWARFSections(CodeDescription* desc, 1794e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Zone* zone, 1795e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org DebugObject* obj) { 179631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org if (desc->IsLineInfoAvailable()) { 1797c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org obj->AddSection(new(zone) DebugInfoSection(desc)); 1798c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org obj->AddSection(new(zone) DebugAbbrevSection(desc)); 1799c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org obj->AddSection(new(zone) DebugLineSection(desc)); 18000511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 180193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_X64 1802c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org obj->AddSection(new(zone) UnwindInfoSection(desc)); 180331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org#endif 18040511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 18050511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 18060511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 18070511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// ------------------------------------------------------------------- 18080511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// Binary GDB JIT Interface as described in 18090511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com// http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html 18100511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comextern "C" { 18110511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com typedef enum { 18120511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com JIT_NOACTION = 0, 18130511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com JIT_REGISTER_FN, 18140511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com JIT_UNREGISTER_FN 18150511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } JITAction; 18160511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 18170511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com struct JITCodeEntry { 18180511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com JITCodeEntry* next_; 18190511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com JITCodeEntry* prev_; 18200511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Address symfile_addr_; 18210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint64_t symfile_size_; 18220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com }; 18230511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 18240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com struct JITDescriptor { 18250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint32_t version_; 18260511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uint32_t action_flag_; 1827f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com JITCodeEntry* relevant_entry_; 1828f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com JITCodeEntry* first_entry_; 18290511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com }; 18300511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 18310511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // GDB will place breakpoint into this function. 18320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // To prevent GCC from inlining or removing it we place noinline attribute 18330511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // and inline assembler statement inside. 18340511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com void __attribute__((noinline)) __jit_debug_register_code() { 18350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com __asm__(""); 18360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 18370511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 18380511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // GDB will inspect contents of this descriptor. 18390511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Static initialization is necessary to prevent GDB from seeing 18400511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // uninitialized descriptor. 18410511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com JITDescriptor __jit_debug_descriptor = { 1, 0, 0, 0 }; 18424f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 18434f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#ifdef OBJECT_PRINT 18444f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org void __gdb_print_v8_object(MaybeObject* object) { 18454f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org object->Print(); 1846e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org PrintF(stdout, "\n"); 18474f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 18484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif 18490511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 18500511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 18510511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 18520511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comstatic JITCodeEntry* CreateCodeEntry(Address symfile_addr, 18530511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t symfile_size) { 18540511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com JITCodeEntry* entry = static_cast<JITCodeEntry*>( 18550511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com malloc(sizeof(JITCodeEntry) + symfile_size)); 18560511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 18570511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com entry->symfile_addr_ = reinterpret_cast<Address>(entry + 1); 18580511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com entry->symfile_size_ = symfile_size; 1859e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OS::MemCopy(entry->symfile_addr_, symfile_addr, symfile_size); 18600511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 18610511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com entry->prev_ = entry->next_ = NULL; 18620511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 18630511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return entry; 18640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 18650511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 18660511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 18670511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comstatic void DestroyCodeEntry(JITCodeEntry* entry) { 18680511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com free(entry); 18690511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 18700511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 18710511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 18724f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.orgstatic void RegisterCodeEntry(JITCodeEntry* entry, 18734f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool dump_if_enabled, 18744f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org const char* name_hint) { 1875662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org#if defined(DEBUG) && !V8_OS_WIN 187649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org static int file_num = 0; 18774f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (FLAG_gdbjit_dump && dump_if_enabled) { 187849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org static const int kMaxFileNameSize = 64; 187949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org static const char* kElfFilePrefix = "/tmp/elfdump"; 188049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org static const char* kObjFileExt = ".o"; 188149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org char file_name[64]; 188249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 18834f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org OS::SNPrintF(Vector<char>(file_name, kMaxFileNameSize), 18844f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org "%s%s%d%s", 18854f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org kElfFilePrefix, 18864f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org (name_hint != NULL) ? name_hint : "", 18874f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org file_num++, 18884f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org kObjFileExt); 188949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org WriteBytes(file_name, entry->symfile_addr_, entry->symfile_size_); 189049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 189149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org#endif 189249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 18930511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com entry->next_ = __jit_debug_descriptor.first_entry_; 18940511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (entry->next_ != NULL) entry->next_->prev_ = entry; 18950511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com __jit_debug_descriptor.first_entry_ = 18960511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com __jit_debug_descriptor.relevant_entry_ = entry; 18970511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 18980511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com __jit_debug_descriptor.action_flag_ = JIT_REGISTER_FN; 18990511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com __jit_debug_register_code(); 19000511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 19010511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19020511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19030511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comstatic void UnregisterCodeEntry(JITCodeEntry* entry) { 19040511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (entry->prev_ != NULL) { 19050511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com entry->prev_->next_ = entry->next_; 19060511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } else { 19070511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com __jit_debug_descriptor.first_entry_ = entry->next_; 19080511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 19090511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19100511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (entry->next_ != NULL) { 19110511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com entry->next_->prev_ = entry->prev_; 19120511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 19130511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19140511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com __jit_debug_descriptor.relevant_entry_ = entry; 19150511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com __jit_debug_descriptor.action_flag_ = JIT_UNREGISTER_FN; 19160511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com __jit_debug_register_code(); 19170511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 19180511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19190511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgstatic JITCodeEntry* CreateELFObject(CodeDescription* desc, Isolate* isolate) { 19214f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#ifdef __MACH_O 1922c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org Zone zone(isolate); 1923c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org MachO mach_o(&zone); 19244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Writer w(&mach_o); 19254f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 1926c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org mach_o.AddSection(new(&zone) MachOTextSection(kCodeAlignment, 1927c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org desc->CodeStart(), 1928c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org desc->CodeSize())); 19294f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org 1930c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org CreateDWARFSections(desc, &zone, &mach_o); 19310511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19324f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org mach_o.Write(&w, desc->CodeStart(), desc->CodeSize()); 19334f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#else 19341510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Zone zone(isolate); 19351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ELF elf(&zone); 19360511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Writer w(&elf); 19370511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19380511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com int text_section_index = elf.AddSection( 19391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org new(&zone) FullHeaderELFSection( 194033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org ".text", 194133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org ELFSection::TYPE_NOBITS, 194233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org kCodeAlignment, 194333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org desc->CodeStart(), 194433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org 0, 194533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org desc->CodeSize(), 1946c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org ELFSection::FLAG_ALLOC | ELFSection::FLAG_EXEC)); 19470511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19481510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org CreateSymbolsTable(desc, &zone, &elf, text_section_index); 19490511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org CreateDWARFSections(desc, &zone, &elf); 19510511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19520511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com elf.Write(&w); 19534f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org#endif 19540511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19550511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return CreateCodeEntry(w.buffer(), w.position()); 19560511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 19570511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19580511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19590511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comstatic bool SameCodeObjects(void* key1, void* key2) { 19600511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return key1 == key2; 19610511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 19620511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19630511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 196449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.orgstatic HashMap* GetEntries() { 196549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org static HashMap* entries = NULL; 196649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org if (entries == NULL) { 196749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org entries = new HashMap(&SameCodeObjects); 196849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 196949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org return entries; 197049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org} 19710511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19720511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19730511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comstatic uint32_t HashForCodeObject(Code* code) { 19740511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com static const uintptr_t kGoldenRatio = 2654435761u; 19750511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com uintptr_t hash = reinterpret_cast<uintptr_t>(code->address()); 19760511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return static_cast<uint32_t>((hash >> kCodeAlignmentBits) * kGoldenRatio); 19770511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 19780511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19790511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19800511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comstatic const intptr_t kLineInfoTag = 0x1; 19810511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19820511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19830511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comstatic bool IsLineInfoTagged(void* ptr) { 19840511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return 0 != (reinterpret_cast<intptr_t>(ptr) & kLineInfoTag); 19850511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 19860511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19870511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19880511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comstatic void* TagLineInfo(GDBJITLineInfo* ptr) { 19890511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return reinterpret_cast<void*>( 19900511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com reinterpret_cast<intptr_t>(ptr) | kLineInfoTag); 19910511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 19920511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19930511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19940511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comstatic GDBJITLineInfo* UntagLineInfo(void* ptr) { 19950511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return reinterpret_cast<GDBJITLineInfo*>( 19960511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com reinterpret_cast<intptr_t>(ptr) & ~kLineInfoTag); 19970511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 19980511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 19990511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 20007bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgvoid GDBJITInterface::AddCode(Handle<Name> name, 20010511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Handle<Script> script, 20024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Handle<Code> code, 20034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org CompilationInfo* info) { 20040511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (!FLAG_gdbjit) return; 20050511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 20060511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Force initialization of line_ends array. 20070511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com GetScriptLineNumber(script, 0); 20080511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 20097bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org if (!name.is_null() && name->IsString()) { 20107bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org SmartArrayPointer<char> name_cstring = 20117bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org Handle<String>::cast(name)->ToCString(DISALLOW_NULLS); 20124f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script, info); 201331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org } else { 20144f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org AddCode("", *code, GDBJITInterface::FUNCTION, *script, info); 201531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org } 201631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org} 201731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 2018e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 2019f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comstatic void AddUnwindInfo(CodeDescription* desc) { 202093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_X64 202131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org if (desc->tag() == GDBJITInterface::FUNCTION) { 202231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // To avoid propagating unwinding information through 20233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // compilation pipeline we use an approximation. 20243a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // For most use cases this should not affect usability. 202531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org static const int kFramePointerPushOffset = 1; 202631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org static const int kFramePointerSetOffset = 4; 202731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org static const int kFramePointerPopOffset = -3; 202831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 202931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org uintptr_t frame_pointer_push_address = 203031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org desc->CodeStart() + kFramePointerPushOffset; 203131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 203231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org uintptr_t frame_pointer_set_address = 203331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org desc->CodeStart() + kFramePointerSetOffset; 203431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 203531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org uintptr_t frame_pointer_pop_address = 203631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org desc->CodeEnd() + kFramePointerPopOffset; 203731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org 203831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org desc->SetStackStateStartAddress(CodeDescription::POST_RBP_PUSH, 203931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org frame_pointer_push_address); 204031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org desc->SetStackStateStartAddress(CodeDescription::POST_RBP_SET, 204131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org frame_pointer_set_address); 204231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org desc->SetStackStateStartAddress(CodeDescription::POST_RBP_POP, 204331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org frame_pointer_pop_address); 20440511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } else { 204531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org desc->SetStackStateStartAddress(CodeDescription::POST_RBP_PUSH, 204631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org desc->CodeStart()); 204731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org desc->SetStackStateStartAddress(CodeDescription::POST_RBP_SET, 204831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org desc->CodeStart()); 204931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org desc->SetStackStateStartAddress(CodeDescription::POST_RBP_POP, 205031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org desc->CodeEnd()); 20510511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 205231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org#endif // V8_TARGET_ARCH_X64 20530511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 20540511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 20550511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 20561456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgstatic LazyMutex mutex = LAZY_MUTEX_INITIALIZER; 205744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 205844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 20590511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comvoid GDBJITInterface::AddCode(const char* name, 20600511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Code* code, 206131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org GDBJITInterface::CodeTag tag, 20624f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org Script* script, 20634f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org CompilationInfo* info) { 20640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (!FLAG_gdbjit) return; 206544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 2066dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org LockGuard<Mutex> lock_guard(mutex.Pointer()); 2067837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org DisallowHeapAllocation no_gc; 20680511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 206949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true); 20700511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (e->value != NULL && !IsLineInfoTagged(e->value)) return; 20710511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 20720511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com GDBJITLineInfo* lineinfo = UntagLineInfo(e->value); 20730511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com CodeDescription code_desc(name, 20740511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com code, 20750511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com script != NULL ? Handle<Script>(script) 20760511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com : Handle<Script>(), 207731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org lineinfo, 20784f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org tag, 20794f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org info); 20800511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 208131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org if (!FLAG_gdbjit_full && !code_desc.IsLineInfoAvailable()) { 20820511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com delete lineinfo; 208349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org GetEntries()->Remove(code, HashForCodeObject(code)); 20840511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return; 20850511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 20860511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 208731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org AddUnwindInfo(&code_desc); 20881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Isolate* isolate = code->GetIsolate(); 20891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org JITCodeEntry* entry = CreateELFObject(&code_desc, isolate); 20900511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ASSERT(!IsLineInfoTagged(entry)); 20910511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 20920511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com delete lineinfo; 20930511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com e->value = entry; 20940511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 20954f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org const char* name_hint = NULL; 20964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org bool should_dump = false; 20974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (FLAG_gdbjit_dump) { 20984f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org if (strlen(FLAG_gdbjit_dump_filter) == 0) { 20994f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org name_hint = name; 21004f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org should_dump = true; 21014f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } else if (name != NULL) { 21024f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org name_hint = strstr(name, FLAG_gdbjit_dump_filter); 21034f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org should_dump = (name_hint != NULL); 21044f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 21054f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org } 21064f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org RegisterCodeEntry(entry, should_dump, name_hint); 21070511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 21080511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 21090511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 21100511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comvoid GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag, 21110511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com const char* name, 21120511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Code* code) { 21130511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (!FLAG_gdbjit) return; 21140511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 21150511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com EmbeddedVector<char, 256> buffer; 21160511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com StringBuilder builder(buffer.start(), buffer.length()); 21170511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 21180511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com builder.AddString(Tag2String(tag)); 21190511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if ((name != NULL) && (*name != '\0')) { 21200511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com builder.AddString(": "); 21210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com builder.AddString(name); 21220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } else { 21230511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com builder.AddFormatted(": code object %p", static_cast<void*>(code)); 21240511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 21250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 21264f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org AddCode(builder.Finalize(), code, tag, NULL, NULL); 21270511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 21280511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 21290511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 21300511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comvoid GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag, 21317bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org Name* name, 21320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Code* code) { 21330511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (!FLAG_gdbjit) return; 21347bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org if (name != NULL && name->IsString()) { 21357bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org AddCode(tag, *String::cast(name)->ToCString(DISALLOW_NULLS), code); 21367bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org } else { 21377bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org AddCode(tag, "", code); 21387bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org } 21390511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 21400511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 21410511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 21420511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comvoid GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag, Code* code) { 21430511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (!FLAG_gdbjit) return; 21440511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 21450511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com AddCode(tag, "", code); 21460511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 21470511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 21480511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 21490511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comvoid GDBJITInterface::RemoveCode(Code* code) { 21500511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (!FLAG_gdbjit) return; 21510511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 2152dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org LockGuard<Mutex> lock_guard(mutex.Pointer()); 215349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org HashMap::Entry* e = GetEntries()->Lookup(code, 215449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org HashForCodeObject(code), 215549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org false); 21560511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (e == NULL) return; 21570511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 21580511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (IsLineInfoTagged(e->value)) { 21590511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com delete UntagLineInfo(e->value); 21600511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } else { 21610511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com JITCodeEntry* entry = static_cast<JITCodeEntry*>(e->value); 21620511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com UnregisterCodeEntry(entry); 21630511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com DestroyCodeEntry(entry); 21640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 21650511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com e->value = NULL; 216649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org GetEntries()->Remove(code, HashForCodeObject(code)); 21670511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 21680511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 21690511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 2170c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.orgvoid GDBJITInterface::RemoveCodeRange(Address start, Address end) { 2171c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org HashMap* entries = GetEntries(); 2172c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org Zone zone(Isolate::Current()); 2173c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org ZoneList<Code*> dead_codes(1, &zone); 2174c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 2175c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org for (HashMap::Entry* e = entries->Start(); e != NULL; e = entries->Next(e)) { 2176c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org Code* code = reinterpret_cast<Code*>(e->key); 2177c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org if (code->address() >= start && code->address() < end) { 2178c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org dead_codes.Add(code, &zone); 2179c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 2180c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 2181c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 2182c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org for (int i = 0; i < dead_codes.length(); i++) { 2183c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org RemoveCode(dead_codes.at(i)); 2184c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org } 2185c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org} 2186c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 2187c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org 21880511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.comvoid GDBJITInterface::RegisterDetailedLineInfo(Code* code, 21890511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com GDBJITLineInfo* line_info) { 2190dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org LockGuard<Mutex> lock_guard(mutex.Pointer()); 21910511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ASSERT(!IsLineInfoTagged(line_info)); 219249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true); 21930511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com ASSERT(e->value == NULL); 21940511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com e->value = TagLineInfo(line_info); 21950511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 21960511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 21970511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 21980511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} } // namespace v8::internal 21990511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com#endif 2200