Files
clang-p2996/lldb/source/Expression/RecordingMemoryManager.cpp
Sean Callanan d5f33a86f0 Updated LLVM to take a new MC JIT that supports
allocations by section.  We install these sections
in the target process and inform the JIT of their
new locations.

Also removed some unused variable warnings.

llvm-svn: 151789
2012-03-01 02:03:47 +00:00

336 lines
9.2 KiB
C++

//===-- RecordingMemoryManager.cpp ------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// C Includes
// C++ Includes
// Other libraries and framework includes
#include "llvm/ExecutionEngine/ExecutionEngine.h"
// Project includes
#include "lldb/Expression/RecordingMemoryManager.h"
using namespace lldb_private;
RecordingMemoryManager::RecordingMemoryManager () :
llvm::JITMemoryManager(),
m_default_mm_ap (llvm::JITMemoryManager::CreateDefaultMemManager()),
m_log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
{
}
RecordingMemoryManager::~RecordingMemoryManager ()
{
}
void
RecordingMemoryManager::setMemoryWritable ()
{
m_default_mm_ap->setMemoryWritable();
}
void
RecordingMemoryManager::setMemoryExecutable ()
{
m_default_mm_ap->setMemoryExecutable();
}
uint8_t *
RecordingMemoryManager::startFunctionBody(const llvm::Function *F,
uintptr_t &ActualSize)
{
return m_default_mm_ap->startFunctionBody(F, ActualSize);
}
uint8_t *
RecordingMemoryManager::allocateStub(const llvm::GlobalValue* F, unsigned StubSize,
unsigned Alignment)
{
uint8_t *return_value = m_default_mm_ap->allocateStub(F, StubSize, Alignment);
Allocation allocation;
allocation.m_size = StubSize;
allocation.m_alignment = Alignment;
allocation.m_local_start = (uintptr_t)return_value;
if (m_log)
{
m_log->Printf("RecordingMemoryManager::allocateStub (F=%p, StubSize=%u, Alignment=%u) = %p",
F, StubSize, Alignment, return_value);
allocation.dump(m_log);
}
m_allocations.push_back(allocation);
return return_value;
}
void
RecordingMemoryManager::endFunctionBody(const llvm::Function *F, uint8_t *FunctionStart,
uint8_t *FunctionEnd)
{
m_default_mm_ap->endFunctionBody(F, FunctionStart, FunctionEnd);
}
uint8_t *
RecordingMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment)
{
uint8_t *return_value = m_default_mm_ap->allocateSpace(Size, Alignment);
Allocation allocation;
allocation.m_size = Size;
allocation.m_alignment = Alignment;
allocation.m_local_start = (uintptr_t)return_value;
if (m_log)
{
m_log->Printf("RecordingMemoryManager::allocateSpace(Size=%llu, Alignment=%u) = %p",
(uint64_t)Size, Alignment, return_value);
allocation.dump(m_log);
}
m_allocations.push_back(allocation);
return return_value;
}
uint8_t *
RecordingMemoryManager::allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID)
{
uint8_t *return_value = m_default_mm_ap->allocateCodeSection(Size, Alignment, SectionID);
Allocation allocation;
allocation.m_size = Size;
allocation.m_alignment = Alignment;
allocation.m_local_start = (uintptr_t)return_value;
allocation.m_section_id = SectionID;
allocation.m_executable = true;
if (m_log)
{
m_log->Printf("RecordingMemoryManager::allocateCodeSection(Size=0x%llx, Alignment=%u, SectionID=%u) = %p",
(uint64_t)Size, Alignment, SectionID, return_value);
allocation.dump(m_log);
}
m_allocations.push_back(allocation);
return return_value;
}
uint8_t *
RecordingMemoryManager::allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID)
{
uint8_t *return_value = m_default_mm_ap->allocateDataSection(Size, Alignment, SectionID);
Allocation allocation;
allocation.m_size = Size;
allocation.m_alignment = Alignment;
allocation.m_local_start = (uintptr_t)return_value;
allocation.m_section_id = SectionID;
if (m_log)
{
m_log->Printf("RecordingMemoryManager::allocateDataSection(Size=0x%llx, Alignment=%u, SectionID=%u) = %p",
(uint64_t)Size, Alignment, SectionID, return_value);
allocation.dump(m_log);
}
m_allocations.push_back(allocation);
return return_value;
}
uint8_t *
RecordingMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment)
{
uint8_t *return_value = m_default_mm_ap->allocateGlobal(Size, Alignment);
Allocation allocation;
allocation.m_size = Size;
allocation.m_alignment = Alignment;
allocation.m_local_start = (uintptr_t)return_value;
if (m_log)
{
m_log->Printf("RecordingMemoryManager::allocateGlobal(Size=0x%llx, Alignment=%u) = %p",
(uint64_t)Size, Alignment, return_value);
allocation.dump(m_log);
}
m_allocations.push_back(allocation);
return return_value;
}
void
RecordingMemoryManager::deallocateFunctionBody(void *Body)
{
m_default_mm_ap->deallocateFunctionBody(Body);
}
uint8_t*
RecordingMemoryManager::startExceptionTable(const llvm::Function* F,
uintptr_t &ActualSize)
{
return m_default_mm_ap->startExceptionTable(F, ActualSize);
}
void
RecordingMemoryManager::endExceptionTable(const llvm::Function *F, uint8_t *TableStart,
uint8_t *TableEnd, uint8_t* FrameRegister)
{
m_default_mm_ap->endExceptionTable(F, TableStart, TableEnd, FrameRegister);
}
void
RecordingMemoryManager::deallocateExceptionTable(void *ET)
{
m_default_mm_ap->deallocateExceptionTable (ET);
}
lldb::addr_t
RecordingMemoryManager::GetRemoteAddressForLocal (lldb::addr_t local_address)
{
for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
ai != ae;
++ai)
{
if (local_address >= ai->m_local_start &&
local_address < ai->m_local_start + ai->m_size)
return ai->m_remote_start + (local_address - ai->m_local_start);
}
return LLDB_INVALID_ADDRESS;
}
RecordingMemoryManager::AddrRange
RecordingMemoryManager::GetRemoteRangeForLocal (lldb::addr_t local_address)
{
for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
ai != ae;
++ai)
{
if (local_address >= ai->m_local_start &&
local_address < ai->m_local_start + ai->m_size)
return AddrRange(ai->m_remote_start, ai->m_size);
}
return AddrRange (0, 0);
}
bool
RecordingMemoryManager::CommitAllocations (Process &process)
{
bool ret = true;
for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
ai != ae;
++ai)
{
if (ai->m_allocated)
continue;
lldb_private::Error err;
ai->m_remote_allocation = process.AllocateMemory(
ai->m_size + ai->m_alignment - 1,
ai->m_executable ? (lldb::ePermissionsReadable | lldb::ePermissionsExecutable)
: (lldb::ePermissionsReadable | lldb::ePermissionsWritable),
err);
uint64_t mask = ai->m_alignment - 1;
ai->m_remote_start = (ai->m_remote_allocation + mask) & (~mask);
if (!err.Success())
{
ret = false;
break;
}
ai->m_allocated = true;
if (m_log)
{
m_log->Printf("RecordingMemoryManager::CommitAllocations() committed an allocation");
ai->dump(m_log);
}
}
if (!ret)
{
for (AllocationList::iterator ai = m_allocations.end(), ae = m_allocations.end();
ai != ae;
++ai)
{
if (ai->m_allocated)
process.DeallocateMemory(ai->m_remote_start);
}
}
return ret;
}
void
RecordingMemoryManager::ReportAllocations (llvm::ExecutionEngine &engine)
{
for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
ai != ae;
++ai)
{
if (!ai->m_allocated)
continue;
engine.mapSectionAddress((void*)ai->m_local_start, ai->m_remote_start);
}
}
bool
RecordingMemoryManager::WriteData (Process &process)
{
for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
ai != ae;
++ai)
{
if (!ai->m_allocated)
return false;
lldb_private::Error err;
if (process.WriteMemory(ai->m_remote_start,
(void*)ai->m_local_start,
ai->m_size,
err) != ai->m_size ||
!err.Success())
return false;
if (m_log)
{
m_log->Printf("RecordingMemoryManager::CommitAllocations() wrote an allocation");
ai->dump(m_log);
}
}
return true;
}
void
RecordingMemoryManager::Allocation::dump (lldb::LogSP log)
{
if (!log)
return;
log->Printf("[0x%llx+0x%llx]->0x%llx (alignment %d, section ID %d)",
(unsigned long long)m_local_start,
(unsigned long long)m_size,
(unsigned long long)m_remote_start,
(unsigned)m_alignment,
(unsigned)m_section_id);
}