blob: 8ebc08e11584554e3ec3cfced96ab39a66011481 [file] [log] [blame]
//===-- RecordingMemoryManager.h --------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef lldb_RecordingMemoryManager_h_
#define lldb_RecordingMemoryManager_h_
// C Includes
// C++ Includes
#include <string>
#include <vector>
#include <map>
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"
#include "lldb/Core/ClangForward.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
#include "lldb/Expression/ClangExpression.h"
namespace lldb_private {
class RecordingMemoryManager : public llvm::JITMemoryManager
{
// I can't write the JIT code in this class because this class has to be
// built without RTTI, which means I can't include Process.h. But I don't
// want to write iterators or "do_over_regions" functions right now, so I'm
// just going to let the ClangExpression handle it using our data members directly.
friend bool ClangExpression::WriteJITCode (const ExecutionContext &exc_context);
public:
RecordingMemoryManager ();
virtual ~RecordingMemoryManager();
virtual void setMemoryWritable ();
virtual void setMemoryExecutable ();
virtual void setPoisonMemory (bool poison)
{
m_default_mm_ap->setPoisonMemory (poison);
}
virtual void AllocateGOT()
{
m_default_mm_ap->AllocateGOT();
}
virtual uint8_t *getGOTBase() const
{
return m_default_mm_ap->getGOTBase();
}
virtual uint8_t *startFunctionBody(const llvm::Function *F,
uintptr_t &ActualSize);
virtual uint8_t *allocateStub(const llvm::GlobalValue* F, unsigned StubSize,
unsigned Alignment);
virtual void endFunctionBody(const llvm::Function *F, uint8_t *FunctionStart,
uint8_t *FunctionEnd);
virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment);
virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment);
virtual void deallocateFunctionBody(void *Body);
virtual uint8_t* startExceptionTable(const llvm::Function* F,
uintptr_t &ActualSize);
virtual void endExceptionTable(const llvm::Function *F, uint8_t *TableStart,
uint8_t *TableEnd, uint8_t* FrameRegister);
virtual void deallocateExceptionTable(void *ET);
virtual size_t GetDefaultCodeSlabSize() {
return m_default_mm_ap->GetDefaultCodeSlabSize();
}
virtual size_t GetDefaultDataSlabSize() {
return m_default_mm_ap->GetDefaultDataSlabSize();
}
virtual size_t GetDefaultStubSlabSize() {
return m_default_mm_ap->GetDefaultStubSlabSize();
}
virtual unsigned GetNumCodeSlabs() {
return m_default_mm_ap->GetNumCodeSlabs();
}
virtual unsigned GetNumDataSlabs() {
return m_default_mm_ap->GetNumDataSlabs();
}
virtual unsigned GetNumStubSlabs() {
return m_default_mm_ap->GetNumStubSlabs();
}
// These are methods I've added so we can transfer the memory we've remembered down
// to the target program. For now I'm assuming all this code is PIC without fixups,
// so I'll just copy it blind, but if we need to we can do fixups later.
lldb::addr_t
GetRemoteAddressForLocal (lldb::addr_t local_address);
bool
WriteJITRegions (const ExecutionContext &exc_context);
private:
std::auto_ptr<JITMemoryManager> m_default_mm_ap;
std::map<uint8_t *, uint8_t *> m_functions;
std::map<uint8_t *, intptr_t> m_spaceBlocks;
std::map<uint8_t *, unsigned> m_stubs;
std::map<uint8_t *, uintptr_t> m_globals;
std::map<uint8_t *, uint8_t *> m_exception_tables;
struct LocalToRemoteAddressRange
{
lldb::addr_t m_local_start;
size_t m_size;
lldb::addr_t m_remote_start;
LocalToRemoteAddressRange (lldb::addr_t lstart, size_t size, lldb::addr_t rstart) :
m_local_start (lstart),
m_size (size),
m_remote_start (rstart)
{}
};
void
AddToLocalToRemoteMap (lldb::addr_t lstart, size_t size, lldb::addr_t rstart);
// We should probably store this by address so we can efficiently
// search it but there really won't be many elements in this array
// at present. So we can put that off for now.
std::vector<LocalToRemoteAddressRange> m_address_map;
};
}; // namespace lldb_private
#endif // lldb_RecordingMemoryManager_h_