クラス Onikiri::EmulatorUtility::Linux64Loader

#include <Linux64Loader.h>

Onikiri::EmulatorUtility::Linux64Loaderに対する継承グラフ

Inheritance graph
[凡例]
Onikiri::EmulatorUtility::Linux64Loaderのコラボレーション図

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

Public メソッド

virtual std::pair< u64, size_t > GetCodeRange () const
virtual u64 GetEntryPoint () const
virtual u64 GetImageBase () const
virtual u64 GetInitialRegValue (int index) const =0
virtual void InitArgs (EmulatorUtility::MemorySystem *memory, u64 stackHead, u64 stackSize, const String &command, const String &commandArgs)
 Linux64Loader (u16 machine)
virtual void LoadBinary (EmulatorUtility::MemorySystem *memory, const String &command)
virtual ~Linux64Loader ()

Protected メソッド

virtual u64 CalculateEntryPoint (EmulatorUtility::MemorySystem *memory, const EmulatorUtility::ElfReader &elfReader)
virtual void CalculateOthers (EmulatorUtility::MemorySystem *memory, const EmulatorUtility::ElfReader &elfReader)
u64 GetInitialSp () const
bool IsBigEndian () const

説明

Linux64Loader.h45 行で定義されています。


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

Linux64Loader::Linux64Loader ( u16  machine  ) 

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

00048     : m_imageBase(0), m_entryPoint(0), m_initialSp(0), m_machine(machine)
00049 {
00050 
00051 }

Linux64Loader::~Linux64Loader (  )  [virtual]

Linux64Loader.cpp53 行で定義されています。

00054 {
00055 }


関数

u64 Linux64Loader::CalculateEntryPoint ( EmulatorUtility::MemorySystem memory,
const EmulatorUtility::ElfReader elfReader 
) [protected, virtual]

Onikiri::PPC64Linux::PPC64LinuxLoaderで再定義されています。

Linux64Loader.cpp259 行で定義されています。

参照先 Onikiri::EmulatorUtility::ElfReader::GetEntryPoint().

参照元 LoadBinary().

00260 {
00261     return elfReader.GetEntryPoint();
00262 }

関数の呼び出しグラフ:

Here is the caller graph for this function:

void Linux64Loader::CalculateOthers ( EmulatorUtility::MemorySystem memory,
const EmulatorUtility::ElfReader elfReader 
) [protected, virtual]

Onikiri::PPC64Linux::PPC64LinuxLoaderで再定義されています。

Linux64Loader.cpp265 行で定義されています。

参照元 LoadBinary().

00266 {
00267     // ftHg
00268 }

Here is the caller graph for this function:

std::pair< u64, size_t > Linux64Loader::GetCodeRange (  )  const [virtual]

Onikiri::EmulatorUtility::LoaderIFを実装しています。

Linux64Loader.cpp244 行で定義されています。

00245 {
00246     return m_codeRange;
00247 }

u64 Linux64Loader::GetEntryPoint (  )  const [virtual]

Onikiri::EmulatorUtility::LoaderIFを実装しています。

Linux64Loader.cpp239 行で定義されています。

00240 {
00241     return m_entryPoint;
00242 }

u64 Linux64Loader::GetImageBase (  )  const [virtual]

Onikiri::EmulatorUtility::LoaderIFを実装しています。

Linux64Loader.cpp234 行で定義されています。

00235 {
00236     return m_imageBase;
00237 }

virtual u64 Onikiri::EmulatorUtility::Linux64Loader::GetInitialRegValue ( int  index  )  const [pure virtual]

Onikiri::EmulatorUtility::LoaderIFを実装しています。

Onikiri::AlphaLinux::AlphaLinuxLoaderOnikiri::PPC64Linux::PPC64LinuxLoaderで実装されています。

u64 Linux64Loader::GetInitialSp (  )  const [protected]

Linux64Loader.cpp249 行で定義されています。

参照元 Onikiri::PPC64Linux::PPC64LinuxLoader::GetInitialRegValue()Onikiri::AlphaLinux::AlphaLinuxLoader::GetInitialRegValue().

00250 {
00251     return m_initialSp;
00252 }

Here is the caller graph for this function:

void Linux64Loader::InitArgs ( EmulatorUtility::MemorySystem memory,
u64  stackHead,
u64  stackSize,
const String command,
const String commandArgs 
) [virtual]

Onikiri::EmulatorUtility::LoaderIFを実装しています。

Linux64Loader.cpp120 行で定義されています。

参照先 Onikiri::EmulatorUtility::ELF64::ELF64_AUXV::a_typeOnikiri::EmulatorUtility::ELF64::ELF64_AUXV::a_unOnikiri::EmulatorUtility::ELF64::ELF64_AUXV::a_valOnikiri::EmulatorUtility::ELF::AT_BASEOnikiri::EmulatorUtility::ELF::AT_EGIDOnikiri::EmulatorUtility::ELF::AT_EUIDOnikiri::EmulatorUtility::ELF::AT_GIDOnikiri::EmulatorUtility::ELF::AT_NULLOnikiri::EmulatorUtility::ELF::AT_PAGESZOnikiri::EmulatorUtility::ELF::AT_PHDROnikiri::EmulatorUtility::ELF::AT_PHENTOnikiri::EmulatorUtility::ELF::AT_PHNUMOnikiri::EmulatorUtility::ELF::AT_UIDOnikiri::EndianHostToSpecified()Onikiri::EmulatorUtility::MemorySystem::GetPageSize()Onikiri::EmulatorUtility::MemorySystem::MemCopyToTarget()Onikiri::String::split().

00121 {
00122     u64 sp = stackHead+stackSize;
00123 
00124     // 
00125     std::vector<String> stringArgs = commandArgs.split(" ");
00126     int argc = (int)stringArgs.size()+1;
00127     scoped_array<const char *> argv(new const char*[argc+1]);
00128 
00129     argv[0] = command.c_str();
00130     for (int i = 1; i < argc; i ++) {
00131         argv[i] = stringArgs[i-1].c_str();
00132     }
00133     argv[argc] = NULL;
00134 
00135     // X^bNRs[
00136     scoped_array<u64> target_argv ( new u64 [argc+1] );
00137     for (int i = 0; i <= argc; i ++) {
00138         if (argv[i]) {
00139             size_t len = strlen(argv[i]);
00140             sp -= len+1;
00141             memory->MemCopyToTarget(sp, argv[i], len+1);
00142             target_argv[i] = sp;
00143         }
00144         else {
00145             target_argv[i] = 0;
00146         }
00147     }
00148     sp -= sp % sizeof(u64);
00149 
00150     // <Linux>
00151     // stack : argc, argv[argc-1], NULL, environ[], NULL, auxv[], NULL
00152 
00153     // Auxiliary Vector 
00154     ELF64_AUXV auxv;
00155 
00156     const int uid = posix_getuid(), gid = posix_getgid(), euid = posix_geteuid(), egid = posix_getegid();
00157 
00158     sp -= sizeof(ELF64_AUXV);
00159     auxv.a_type = EndianHostToSpecified((u64)AT_NULL, m_bigEndian);
00160     auxv.a_un.a_val = 0;
00161     memory->MemCopyToTarget(sp, &auxv, sizeof(ELF64_AUXV));
00162 
00163     sp -= sizeof(ELF64_AUXV);
00164     auxv.a_type = EndianHostToSpecified((u64)AT_PHDR, m_bigEndian);
00165     auxv.a_un.a_val = EndianHostToSpecified((u64)(m_imageBase + m_elfProgramHeaderOffset), m_bigEndian);
00166     memory->MemCopyToTarget(sp, &auxv, sizeof(ELF64_AUXV));
00167 
00168     sp -= sizeof(ELF64_AUXV);
00169     auxv.a_type = EndianHostToSpecified((u64)AT_PHNUM, m_bigEndian);
00170     auxv.a_un.a_val = EndianHostToSpecified((u64)m_elfProgramHeaderCount, m_bigEndian);
00171     memory->MemCopyToTarget(sp, &auxv, sizeof(ELF64_AUXV));
00172 
00173     sp -= sizeof(ELF64_AUXV);
00174     auxv.a_type = EndianHostToSpecified((u64)AT_PHENT, m_bigEndian);
00175     auxv.a_un.a_val = EndianHostToSpecified((u64)sizeof(ElfReader::Elf_Phdr), m_bigEndian);
00176     memory->MemCopyToTarget(sp, &auxv, sizeof(ELF64_AUXV));
00177 
00178     sp -= sizeof(ELF64_AUXV);
00179     auxv.a_type = EndianHostToSpecified((u64)AT_PAGESZ, m_bigEndian);
00180     auxv.a_un.a_val = EndianHostToSpecified((u64)memory->GetPageSize(), m_bigEndian);
00181     memory->MemCopyToTarget(sp, &auxv, sizeof(ELF64_AUXV));
00182 
00183     sp -= sizeof(ELF64_AUXV);
00184     auxv.a_type = EndianHostToSpecified((u64)AT_BASE, m_bigEndian);
00185     auxv.a_un.a_val = 0;
00186     memory->MemCopyToTarget(sp, &auxv, sizeof(ELF64_AUXV));
00187 
00188     sp -= sizeof(ELF64_AUXV);
00189     auxv.a_type = EndianHostToSpecified((u64)AT_UID, m_bigEndian);
00190     auxv.a_un.a_val = EndianHostToSpecified((u64)uid, m_bigEndian);
00191     memory->MemCopyToTarget(sp, &auxv, sizeof(ELF64_AUXV));
00192 
00193     sp -= sizeof(ELF64_AUXV);
00194     auxv.a_type = EndianHostToSpecified((u64)AT_EUID, m_bigEndian);
00195     auxv.a_un.a_val = EndianHostToSpecified((u64)euid, m_bigEndian);
00196     memory->MemCopyToTarget(sp, &auxv, sizeof(ELF64_AUXV));
00197 
00198     sp -= sizeof(ELF64_AUXV);
00199     auxv.a_type = EndianHostToSpecified((u64)AT_GID, m_bigEndian);
00200     auxv.a_un.a_val = EndianHostToSpecified((u64)gid, m_bigEndian);
00201     memory->MemCopyToTarget(sp, &auxv, sizeof(ELF64_AUXV));
00202 
00203     sp -= sizeof(ELF64_AUXV);
00204     auxv.a_type = EndianHostToSpecified((u64)AT_EGID, m_bigEndian);
00205     auxv.a_un.a_val = EndianHostToSpecified((u64)egid, m_bigEndian);
00206     memory->MemCopyToTarget(sp, &auxv, sizeof(ELF64_AUXV));
00207 
00208     sp -= sizeof(u64); // NULL
00209     // environ
00210     sp -= sizeof(u64);
00211     WriteMemory( memory, sp, sizeof(u64), sp-8);    // argv[argc] (== NULL) w
00212 
00213     sp -= sizeof(u64); // NULL
00214     // argv
00215     for (int i = 0; i <= argc; i ++) {
00216         sp -= sizeof(u64);
00217         WriteMemory( memory, sp, sizeof(u64), target_argv[argc-i]);
00218     }
00219 
00220     // argc
00221     sp -= sizeof(u64);
00222     WriteMemory( memory, sp, sizeof(u64), argc);
00223 
00224     m_initialSp = sp;
00225 }

関数の呼び出しグラフ:

bool Linux64Loader::IsBigEndian (  )  const [protected]

Linux64Loader.cpp254 行で定義されています。

00255 {
00256     return m_bigEndian;
00257 }

void Linux64Loader::LoadBinary ( EmulatorUtility::MemorySystem memory,
const String command 
) [virtual]

Onikiri::EmulatorUtility::LoaderIFを実装しています。

Linux64Loader.cpp57 行で定義されています。

参照先 ASSERTOnikiri::EmulatorUtility::MemorySystem::AssignPhysicalMemory()CalculateEntryPoint()CalculateOthers()Onikiri::EmulatorUtility::TargetBuffer::Get()Onikiri::EmulatorUtility::ElfReader::GetMachine()Onikiri::EmulatorUtility::ElfReader::GetProgramHeader()Onikiri::EmulatorUtility::ElfReader::GetProgramHeaderCount()Onikiri::EmulatorUtility::ElfReader::GetProgramHeaderOffset()Onikiri::EmulatorUtility::MemorySystem::GetReservedAddressRange()Onikiri::EmulatorUtility::ElfReader::IsBigEndian()Onikiri::EmulatorUtility::ElfReader::Open()Onikiri::EmulatorUtility::ELF::PF_XOnikiri::EmulatorUtility::ELF::PT_LOADOnikiri::EmulatorUtility::ElfReader::ReadRange()Onikiri::EmulatorUtility::MemorySystem::SetInitialBrk()THROW_RUNTIME_ERROR.

00058 {
00059     ElfReader elfReader;
00060 
00061     try {
00062         elfReader.Open(command.c_str());
00063 
00064         if (elfReader.GetMachine() != m_machine)
00065             throw runtime_error((command + " : machine type does not match").c_str());
00066 
00067         m_bigEndian = elfReader.IsBigEndian();
00068 
00069         u64 initialBrk = 0;
00070         for (int i = 0; i < elfReader.GetProgramHeaderCount(); i ++) {
00071             const ElfReader::Elf_Phdr &ph = elfReader.GetProgramHeader(i);
00072 
00073             VIRTUAL_MEMORY_ATTR_TYPE pageAttr =
00074                 VIRTUAL_MEMORY_ATTR_READ | VIRTUAL_MEMORY_ATTR_WRITE;
00075 
00076             // Do not add a writable attribute to a code page.
00077             if(ph.p_flags & PF_X){
00078                 pageAttr = VIRTUAL_MEMORY_ATTR_READ | VIRTUAL_MEMORY_ATTR_EXEC;
00079             }
00080 
00081             // ZOgAhXCZOg
00082             if (ph.p_type == PT_LOAD) {
00083                 if (ph.p_offset == 0)
00084                     m_imageBase = ph.p_vaddr;
00085                 memory->AssignPhysicalMemory(ph.p_vaddr, ph.p_memsz, pageAttr);
00086                 TargetBuffer buf(memory, ph.p_vaddr, static_cast<size_t>(ph.p_filesz));
00087                 elfReader.ReadRange(static_cast<size_t>(ph.p_offset), (char*)buf.Get(), static_cast<size_t>(ph.p_filesz));
00088 
00089                 initialBrk = max(initialBrk, ph.p_vaddr+ph.p_memsz);
00090 
00091                 if( memory->GetReservedAddressRange() >= ph.p_vaddr ){
00092                     THROW_RUNTIME_ERROR( "Reserved address region is too large.");
00093                 }
00094             }
00095             //if (ph.p_flags & PF_W && writable_base == 0) {
00096             //}
00097 
00098             // タsZOg1
00099             if (ph.p_flags & PF_X) {
00100                 m_codeRange.first = ph.p_vaddr;
00101                 m_codeRange.second = static_cast<size_t>(ph.p_memsz);
00102             }
00103         }
00104         ASSERT(m_imageBase != 0);
00105 
00106         memory->SetInitialBrk(initialBrk);
00107 
00108         m_elfProgramHeaderOffset = elfReader.GetProgramHeaderOffset();
00109         m_elfProgramHeaderCount = elfReader.GetProgramHeaderCount();
00110 
00111         // Gg|CgvZ
00112         m_entryPoint = CalculateEntryPoint(memory, elfReader);
00113         CalculateOthers(memory, elfReader);
00114     }
00115     catch (runtime_error& e) {
00116         THROW_RUNTIME_ERROR(e.what());
00117     }
00118 }

関数の呼び出しグラフ:


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