#include <Linux64Loader.h>
Onikiri::EmulatorUtility::Linux64Loaderに対する継承グラフ
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.h の 45 行で定義されています。
Linux64Loader::Linux64Loader | ( | u16 | machine | ) |
Linux64Loader::~Linux64Loader | ( | ) | [virtual] |
u64 Linux64Loader::CalculateEntryPoint | ( | EmulatorUtility::MemorySystem * | memory, | |
const EmulatorUtility::ElfReader & | elfReader | |||
) | [protected, virtual] |
Onikiri::PPC64Linux::PPC64LinuxLoaderで再定義されています。
Linux64Loader.cpp の 259 行で定義されています。
参照先 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.cpp の 265 行で定義されています。
参照元 LoadBinary().
Here is the caller graph for this function:
std::pair< u64, size_t > Linux64Loader::GetCodeRange | ( | ) | const [virtual] |
u64 Linux64Loader::GetEntryPoint | ( | ) | const [virtual] |
u64 Linux64Loader::GetImageBase | ( | ) | const [virtual] |
virtual u64 Onikiri::EmulatorUtility::Linux64Loader::GetInitialRegValue | ( | int | index | ) | const [pure virtual] |
u64 Linux64Loader::GetInitialSp | ( | ) | const [protected] |
Linux64Loader.cpp の 249 行で定義されています。
参照元 Onikiri::PPC64Linux::PPC64LinuxLoader::GetInitialRegValue()・Onikiri::AlphaLinux::AlphaLinuxLoader::GetInitialRegValue().
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.cpp の 120 行で定義されています。
参照先 Onikiri::EmulatorUtility::ELF64::ELF64_AUXV::a_type・Onikiri::EmulatorUtility::ELF64::ELF64_AUXV::a_un・Onikiri::EmulatorUtility::ELF64::ELF64_AUXV::a_val・Onikiri::EmulatorUtility::ELF::AT_BASE・Onikiri::EmulatorUtility::ELF::AT_EGID・Onikiri::EmulatorUtility::ELF::AT_EUID・Onikiri::EmulatorUtility::ELF::AT_GID・Onikiri::EmulatorUtility::ELF::AT_NULL・Onikiri::EmulatorUtility::ELF::AT_PAGESZ・Onikiri::EmulatorUtility::ELF::AT_PHDR・Onikiri::EmulatorUtility::ELF::AT_PHENT・Onikiri::EmulatorUtility::ELF::AT_PHNUM・Onikiri::EmulatorUtility::ELF::AT_UID・Onikiri::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] |
void Linux64Loader::LoadBinary | ( | EmulatorUtility::MemorySystem * | memory, | |
const String & | command | |||
) | [virtual] |
Onikiri::EmulatorUtility::LoaderIFを実装しています。
Linux64Loader.cpp の 57 行で定義されています。
参照先 ASSERT・Onikiri::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_X・Onikiri::EmulatorUtility::ELF::PT_LOAD・Onikiri::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 }
関数の呼び出しグラフ: