クラス Onikiri::EmulatorUtility::MemorySystem

#include <MemorySystem.h>

Onikiri::EmulatorUtility::MemorySystemのコラボレーション図

Collaboration graph
[凡例]
すべてのメンバ一覧

Public メソッド

void AddHeapBlock (u64 addr, u64 size)
void AssignPhysicalMemory (u64 addr, u64 size, VIRTUAL_MEMORY_ATTR_TYPE attr)
u64 Brk (u64 addr)
u64 GetPageSize () const
u64 GetPageSize ()
u64 GetReservedAddressRange ()
bool IsBigEndian () const
void MemCopyToHost (void *dst, u64 src, u64 size)
void MemCopyToTarget (u64 dst, const void *src, u64 size)
 MemorySystem (int pid, bool bigEndian, SystemIF *simSystem)
u64 MMap (u64 addr, u64 length)
u64 MRemap (u64 old_addr, u64 old_size, u64 new_size, bool mayMove=false)
int MUnmap (u64 addr, u64 length)
void ReadMemory (MemAccess *access)
void SetInitialBrk (u64 initialBrk)
void TargetMemset (u64 targetAddr, int value, u64 size)
void WriteMemory (MemAccess *access)
 ~MemorySystem ()

説明

MemorySystem.h43 行で定義されています。


コンストラクタとデストラクタ

MemorySystem::MemorySystem ( int  pid,
bool  bigEndian,
SystemIF simSystem 
)

MemorySystem.cpp47 行で定義されています。

参照先 Onikiri::EmulatorUtility::VirtualMemory::AssignPhysicalMemory()GetPageSize()Onikiri::EmulatorUtility::VirtualMemory::TargetMemset()THROW_RUNTIME_ERROR.

00047                                                                          : 
00048     m_virtualMemory( pid, bigEndian, simSystem ), 
00049     m_heapAlloc( m_virtualMemory.GetPageSize() ), 
00050     m_currentBrk(0), 
00051     m_simSystem(simSystem),
00052     m_pid(pid),
00053     m_bigEndian(bigEndian)
00054 {
00055     u64 pageSize = GetPageSize();
00056 
00057     // m0y[W
00058     u64 zeroPageAddr = RESERVED_PAGE_ZERO_FILLED * pageSize;
00059     m_virtualMemory.AssignPhysicalMemory( zeroPageAddr, VIRTUAL_MEMORY_ATTR_READ ); // Read only    
00060     m_virtualMemory.TargetMemset( zeroPageAddr, 0, pageSize );  // TargetMemset ignores page attribute.
00061 
00062     if( ( pageSize & (pageSize - 1) ) != 0 ){
00063         THROW_RUNTIME_ERROR( "The page size is not power-of-two." );
00064     }
00065 }

関数の呼び出しグラフ:

MemorySystem::~MemorySystem (  ) 

MemorySystem.cpp67 行で定義されています。

参照先 Onikiri::EmulatorUtility::VirtualMemory::FreePhysicalMemory()GetPageSize().

00068 {
00069     // m0y[W
00070     u64 zeroPageAddr = RESERVED_PAGE_ZERO_FILLED * GetPageSize();
00071     m_virtualMemory.FreePhysicalMemory( zeroPageAddr );
00072 }

関数の呼び出しグラフ:


関数

void MemorySystem::AddHeapBlock ( u64  addr,
u64  size 
)

MemorySystem.cpp83 行で定義されています。

参照先 Onikiri::EmulatorUtility::HeapAllocator::AddMemoryBlock().

00084 {
00085     m_heapAlloc.AddMemoryBlock(addr, size);
00086 }

関数の呼び出しグラフ:

void Onikiri::EmulatorUtility::MemorySystem::AssignPhysicalMemory ( u64  addr,
u64  size,
VIRTUAL_MEMORY_ATTR_TYPE  attr 
) [inline]

MemorySystem.h81 行で定義されています。

参照先 Onikiri::EmulatorUtility::VirtualMemory::AssignPhysicalMemory().

参照元 Onikiri::EmulatorUtility::Linux64Loader::LoadBinary().

00082             {
00083                 m_virtualMemory.AssignPhysicalMemory( addr, size, attr );
00084             }

関数の呼び出しグラフ:

Here is the caller graph for this function:

u64 MemorySystem::Brk ( u64  addr  ) 

MemorySystem.cpp98 行で定義されています。

参照先 Onikiri::EmulatorUtility::VirtualMemory::AssignPhysicalMemory()Onikiri::EmulatorUtility::VirtualMemory::FreePhysicalMemory()GetPageSize()TargetMemset().

00099 {
00100 
00101     if (addr == 0)
00102         return m_currentBrk;
00103 
00104     u64 pageSize = GetPageSize();
00105 
00106     
00107     if( addr < m_currentBrk ){
00108         // Shrink program break and free unused memory.
00109         u64 endPageAddr = MaskPageOffset( addr, pageSize );
00110         u64 pageAddr    = MaskPageOffset( m_currentBrk, pageSize );
00111         while( pageAddr != endPageAddr ){
00112             m_virtualMemory.FreePhysicalMemory( pageAddr, pageSize );
00113             pageAddr -= pageSize;
00114         }
00115         m_currentBrk = addr;
00116         return 0;
00117     }
00118     else{
00119         // Expand program break and allocate memory.
00120         u64 endPageAddr  = MaskPageOffset( addr, pageSize );
00121         u64 pageAddr     = MaskPageOffset( m_currentBrk, pageSize ) + pageSize;
00122         //u64 zeroPageAddr = RESERVED_PAGE_ZERO_FILLED * GetPageSize();
00123 
00124         while( pageAddr <= endPageAddr ){
00125             //m_virtualMemory.SetPhysicalMemoryMapping( pageAddr, zeroPageAddr );
00126             m_virtualMemory.AssignPhysicalMemory( pageAddr, VIRTUAL_MEMORY_ATTR_READ|VIRTUAL_MEMORY_ATTR_WRITE );
00127             pageAddr += pageSize;
00128         }
00129         TargetMemset(m_currentBrk, 0, addr-m_currentBrk);
00130         m_currentBrk = addr;
00131     }
00132 
00133 
00134     return 0;
00135 }

関数の呼び出しグラフ:

u64 Onikiri::EmulatorUtility::MemorySystem::GetPageSize (  )  const [inline]

MemorySystem.h75 行で定義されています。

参照先 Onikiri::EmulatorUtility::VirtualMemory::GetPageSize().

00076             {
00077                 return m_virtualMemory.GetPageSize();
00078             }

関数の呼び出しグラフ:

u64 MemorySystem::GetPageSize (  ) 

MemorySystem.cpp78 行で定義されています。

参照先 Onikiri::EmulatorUtility::HeapAllocator::GetPageSize().

参照元 Brk()GetReservedAddressRange()Onikiri::EmulatorUtility::Linux64Loader::InitArgs()MemorySystem()MMap()MRemap()MUnmap()~MemorySystem().

00079 {
00080     return m_heapAlloc.GetPageSize();
00081 }

関数の呼び出しグラフ:

Here is the caller graph for this function:

u64 Onikiri::EmulatorUtility::MemorySystem::GetReservedAddressRange (  )  [inline]

MemorySystem.h57 行で定義されています。

参照先 GetPageSize().

参照元 Onikiri::EmulatorUtility::Linux64Loader::LoadBinary().

00057 { return GetPageSize() * RESERVED_PAGES - 1; };

関数の呼び出しグラフ:

Here is the caller graph for this function:

bool Onikiri::EmulatorUtility::MemorySystem::IsBigEndian (  )  const [inline]

MemorySystem.h70 行で定義されています。

参照元 Onikiri::EmulatorUtility::Linux64SyscallConv::write_stat64().

00071             {
00072                 return m_bigEndian;
00073             }

Here is the caller graph for this function:

void Onikiri::EmulatorUtility::MemorySystem::MemCopyToHost ( void *  dst,
u64  src,
u64  size 
) [inline]

MemorySystem.h105 行で定義されています。

参照先 Onikiri::EmulatorUtility::VirtualMemory::MemCopyToHost().

参照元 Onikiri::EmulatorUtility::TargetBuffer::TargetBuffer().

00106             {
00107                 m_virtualMemory.MemCopyToHost( dst, src, size );
00108             }

関数の呼び出しグラフ:

Here is the caller graph for this function:

void Onikiri::EmulatorUtility::MemorySystem::MemCopyToTarget ( u64  dst,
const void *  src,
u64  size 
) [inline]

MemorySystem.h110 行で定義されています。

参照先 Onikiri::EmulatorUtility::VirtualMemory::MemCopyToTarget().

参照元 Onikiri::EmulatorUtility::Linux64Loader::InitArgs()MRemap()Onikiri::EmulatorUtility::Linux64SyscallConv::syscall_uname()Onikiri::EmulatorUtility::TargetBuffer::~TargetBuffer().

00111             {
00112                 m_virtualMemory.MemCopyToTarget( dst, src, size );
00113             }

関数の呼び出しグラフ:

Here is the caller graph for this function:

u64 MemorySystem::MMap ( u64  addr,
u64  length 
)

MemorySystem.cpp138 行で定義されています。

参照先 Onikiri::EmulatorUtility::HeapAllocator::Alloc()Onikiri::EmulatorUtility::VirtualMemory::AssignPhysicalMemory()GetPageSize()Onikiri::EmulatorUtility::VirtualMemory::SetPhysicalMemoryMapping()TargetMemset().

参照元 Onikiri::EmulatorUtility::Linux64SyscallConv::syscall_mmap().

00139 {
00140     if (addr != 0)
00141         return (u64)-1;
00142     if (length <= 0)
00143         return (u64)-1;
00144 
00145     u64 result = m_heapAlloc.Alloc(addr, length);
00146     CheckValueOnPageBoundary( result, "mmap:address" );
00147 
00148     if (result) {
00149 #ifdef ENABLE_MEMORY_SYSTEM_COPY_ON_WRITE
00150         u64 zeroPageAddr = RESERVED_PAGE_ZERO_FILLED * GetPageSize();
00151         m_virtualMemory.SetPhysicalMemoryMapping( result, zeroPageAddr, length, VIRTUAL_MEMORY_ATTR_READ|VIRTUAL_MEMORY_ATTR_WRITE );
00152 #else
00153         m_virtualMemory.AssignPhysicalMemory(result, length, VIRTUAL_MEMORY_ATTR_READ);
00154         TargetMemset(result, 0, length);
00155 #endif
00156         return result;
00157     }
00158     else{
00159         return (u64)-1;
00160     }
00161 }

関数の呼び出しグラフ:

Here is the caller graph for this function:

u64 MemorySystem::MRemap ( u64  old_addr,
u64  old_size,
u64  new_size,
bool  mayMove = false 
)

MemorySystem.cpp163 行で定義されています。

参照先 Onikiri::EmulatorUtility::HeapAllocator::Alloc()ASSERTOnikiri::EmulatorUtility::VirtualMemory::AssignPhysicalMemory()Onikiri::EmulatorUtility::VirtualMemory::FreePhysicalMemory()Onikiri::EmulatorUtility::TargetBuffer::Get()Onikiri::EmulatorUtility::HeapAllocator::GetBlockSize()GetPageSize()MemCopyToTarget()MUnmap()Onikiri::EmulatorUtility::HeapAllocator::ReAlloc()TargetMemset().

参照元 Onikiri::EmulatorUtility::Linux64SyscallConv::syscall_mremap().

00164 {
00165     // Debug
00166     //g_env.Print( "MemorySystem::MRemap\n" );
00167 
00168     CheckValueOnPageBoundary( old_addr, "mremap:old_addr" );
00169 
00170     if (new_size <= 0)
00171         return (u64)-1;
00172     // 
00173     if (m_heapAlloc.GetBlockSize(old_addr) != old_size)
00174         return (u64)-1;
00175 
00176     u64 result = m_heapAlloc.ReAlloc(old_addr, old_size, new_size);
00177     CheckValueOnPageBoundary( result, "mremap/not move" );
00178 
00179     if (result) {
00180         CheckValueOnPageBoundary( old_size, "mremap:old_size" );
00181         CheckValueOnPageBoundary( new_size, "mremap:new_size" );
00182         if( new_size > old_size ){
00183             
00184             u64 pageMask = GetPageSize() - 1;
00185             if( ( ( result + old_size ) & pageMask) != 0 ){
00186                 // y[WECy[Wm
00187                 s64 length = (s64)new_size - (s64)(( old_size + pageMask ) & ~pageMask);
00188                 u64 addr   = result + new_size - length;
00189                 if( length > 0 ){
00190                     m_virtualMemory.AssignPhysicalMemory( addr, length, VIRTUAL_MEMORY_ATTR_READ|VIRTUAL_MEMORY_ATTR_WRITE );
00191                 }
00192             }
00193             else{
00194                 m_virtualMemory.AssignPhysicalMemory(result+old_size, new_size - old_size, VIRTUAL_MEMORY_ATTR_READ|VIRTUAL_MEMORY_ATTR_WRITE );
00195             }
00196             TargetMemset(result+old_size, 0, new_size-old_size);
00197         }
00198         else if( new_size < old_size ){
00199             u64 pageMask = GetPageSize() - 1;
00200             if( ( ( result + new_size ) & pageMask ) != 0 ){
00201                 // Vy[WECy[W
00202                 // Todo: EH
00203                 s64 length = (s64)old_size - (s64)(( new_size + pageMask ) & ~pageMask);
00204                 u64 addr   = result + old_size - length;
00205                 if( length > 0 ){
00206                     m_virtualMemory.FreePhysicalMemory( addr, length );
00207                 }
00208             }
00209             else{
00210                 m_virtualMemory.FreePhysicalMemory(result+new_size, old_size - new_size);
00211             }
00212         }
00213 
00214         return result;
00215     }
00216     else if (mayMove) {
00217         // um
00218         ASSERT(old_size < new_size, "HeapAlloc::ReAlloc Logic Error");
00219         result = m_heapAlloc.Alloc(0, new_size);
00220         CheckValueOnPageBoundary( result, "mremap/move" );
00221 
00222         if (result) {
00223             m_virtualMemory.AssignPhysicalMemory(result, new_size, VIRTUAL_MEMORY_ATTR_READ|VIRTUAL_MEMORY_ATTR_WRITE );
00224 
00225             // f[^VRs[
00226             // Note: The destructor of TargetBuffer must be called before memory pages are freed.
00227             {
00228                 TargetBuffer buf(this, old_addr, static_cast<size_t>(old_size));
00229                 MemCopyToTarget(result, buf.Get(), old_size);
00230                 TargetMemset(result+old_size, 0, new_size-old_size);
00231             }
00232             
00233             MUnmap(old_addr, old_size);
00234             return result;
00235         }
00236         else {
00237             return (u64)-1;
00238         }
00239     }
00240     else {
00241         return (u64)-1;
00242     }
00243 }

関数の呼び出しグラフ:

Here is the caller graph for this function:

int MemorySystem::MUnmap ( u64  addr,
u64  length 
)

MemorySystem.cpp245 行で定義されています。

参照先 Onikiri::EmulatorUtility::HeapAllocator::Free()Onikiri::EmulatorUtility::VirtualMemory::FreePhysicalMemory()GetPageSize().

参照元 MRemap()Onikiri::EmulatorUtility::Linux64SyscallConv::syscall_munmap().

00246 {
00247     CheckValueOnPageBoundary( addr,   "munmap:address" );
00248     CheckValueOnPageBoundary( length, "munmap:length" );
00249 
00250     if (length <= 0)
00251         return -1;
00252 
00253     if (m_heapAlloc.Free(addr, length)) {
00254         // y[WECy[W
00255         u64 pageMask = GetPageSize() - 1;
00256         if( ( ( addr + length ) & pageMask ) != 0 ){
00257             length = length & ~pageMask;
00258         }
00259         m_virtualMemory.FreePhysicalMemory( addr, length );
00260         return 0;
00261     }
00262     else
00263         return -1;
00264 }

関数の呼び出しグラフ:

Here is the caller graph for this function:

void Onikiri::EmulatorUtility::MemorySystem::ReadMemory ( MemAccess access  )  [inline]

MemorySystem.h87 行で定義されています。

参照先 Onikiri::EmulatorUtility::VirtualMemory::ReadMemory().

参照元 Onikiri::PPC64Linux::PPC64LinuxLoader::CalculateEntryPoint()Onikiri::PPC64Linux::PPC64LinuxLoader::CalculateOthers()Onikiri::EmulatorUtility::CommonEmulator< Traits >::Read()Onikiri::EmulatorUtility::StrCpyToHost()Onikiri::EmulatorUtility::TargetStrlen().

00088             {
00089                 m_virtualMemory.ReadMemory( access );
00090             }

関数の呼び出しグラフ:

Here is the caller graph for this function:

void MemorySystem::SetInitialBrk ( u64  initialBrk  ) 

MemorySystem.cpp88 行で定義されています。

参照元 Onikiri::EmulatorUtility::Linux64Loader::LoadBinary().

00089 {
00090     m_currentBrk = initialBrk;
00091 }

Here is the caller graph for this function:

void Onikiri::EmulatorUtility::MemorySystem::TargetMemset ( u64  targetAddr,
int  value,
u64  size 
) [inline]

MemorySystem.h100 行で定義されています。

参照先 Onikiri::EmulatorUtility::VirtualMemory::TargetMemset().

参照元 Brk()MMap()MRemap().

00101             {
00102                 m_virtualMemory.TargetMemset( targetAddr, value, size );
00103             }

関数の呼び出しグラフ:

Here is the caller graph for this function:

void Onikiri::EmulatorUtility::MemorySystem::WriteMemory ( MemAccess access  )  [inline]

MemorySystem.h92 行で定義されています。

参照先 Onikiri::EmulatorUtility::VirtualMemory::WriteMemory().

参照元 Onikiri::EmulatorUtility::CommonEmulator< Traits >::Write().

00093             {
00094                 m_virtualMemory.WriteMemory( access );
00095             }

関数の呼び出しグラフ:

Here is the caller graph for this function:


このクラスの説明は次のファイルから生成されました:
Onikiri2に対してTue Jun 18 15:28:51 2013に生成されました。  doxygen 1.4.7