[gem5-dev] Change in gem5/gem5[develop]: arch-power: Add multi-mode support
Boris Shingarov has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/40944 ) Change subject: arch-power: Add multi-mode support .. arch-power: Add multi-mode support This adds multi-mode support and allows the simulator to read, interpret and execute 32bit and 64-bit, big and little endian binaries in syscall emulation mode. During process initialization, a minimal set of hardware capabilities are also advertised by the simulator to show support for 64-bit mode and little endian byte order. This also adds some fixups specific to 64-bit ELF ABI v1 that readjust the entry point and symbol table due to the use of function descriptors. Change-Id: I124339eff7b70dbd14e50ff970340c88c13bd0ad Signed-off-by: Sandipan Das Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40944 Reviewed-by: Boris Shingarov Maintainer: Boris Shingarov Tested-by: kokoro --- M src/arch/power/PowerSeWorkload.py M src/arch/power/linux/se_workload.cc M src/arch/power/process.cc M src/arch/power/regs/int.hh M src/base/loader/elf_object.cc M src/base/loader/object_file.cc M src/base/loader/object_file.hh 7 files changed, 100 insertions(+), 18 deletions(-) Approvals: Boris Shingarov: Looks good to me, approved; Looks good to me, approved kokoro: Regressions pass diff --git a/src/arch/power/PowerSeWorkload.py b/src/arch/power/PowerSeWorkload.py index ef7bbb5..2b081f2 100644 --- a/src/arch/power/PowerSeWorkload.py +++ b/src/arch/power/PowerSeWorkload.py @@ -40,5 +40,5 @@ @classmethod def _is_compatible_with(cls, obj): -return obj.get_arch() == 'power' and \ +return obj.get_arch() in ('power', 'power64') and \ obj.get_op_sys() in ('linux', 'unknown') diff --git a/src/arch/power/linux/se_workload.cc b/src/arch/power/linux/se_workload.cc index 75eb210..815a145 100644 --- a/src/arch/power/linux/se_workload.cc +++ b/src/arch/power/linux/se_workload.cc @@ -50,7 +50,9 @@ Process * load(const ProcessParams , loader::ObjectFile *obj) override { -if (obj->getArch() != loader::Power) +auto arch = obj->getArch(); + +if (arch != loader::Power && arch != loader::Power64) return nullptr; auto opsys = obj->getOpSys(); @@ -60,7 +62,10 @@ opsys = loader::Linux; } -if (opsys != loader::Linux) +if ((arch == loader::Power && opsys != loader::Linux) || +(arch == loader::Power64 && + opsys != loader::LinuxPower64ABIv1 && + opsys != loader::LinuxPower64ABIv2)) return nullptr; return new PowerProcess(params, obj); diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc index 688cc1e..8ac5946 100644 --- a/src/arch/power/process.cc +++ b/src/arch/power/process.cc @@ -82,7 +82,55 @@ { Process::initState(); -argsInit(PageBytes); +if (objFile->getArch() == loader::Power) +argsInit(PageBytes); +else +argsInit(PageBytes); + +// Fix up entry point and symbol table for 64-bit ELF ABI v1 +if (objFile->getOpSys() != loader::LinuxPower64ABIv1) +return; + +// Fix entry point address and the base TOC pointer by looking the +// the function descriptor in the .opd section +Addr entryPoint, tocBase; +ByteOrder byteOrder = objFile->getByteOrder(); +ThreadContext *tc = system->threads[contextIds[0]]; + +// The first doubleword of the descriptor contains the address of the +// entry point of the function +initVirtMem->readBlob(getStartPC(), , sizeof(Addr)); + +// Update the PC state +auto pc = tc->pcState(); +pc.byteOrder(byteOrder); +pc.set(gtoh(entryPoint, byteOrder)); +tc->pcState(pc); + +// The second doubleword of the descriptor contains the TOC base +// address for the function +initVirtMem->readBlob(getStartPC() + 8, , sizeof(Addr)); +tc->setIntReg(TOCPointerReg, gtoh(tocBase, byteOrder)); + +// Fix symbol table entries as they would otherwise point to the +// function descriptor rather than the actual entry point address +auto *symbolTable = new loader::SymbolTable; + +for (auto sym : loader::debugSymbolTable) { +Addr entry; +loader::Symbol symbol = sym; + +// Try to read entry point from function descriptor +if (initVirtMem->tryReadBlob(sym.address, , sizeof(Addr))) +symbol.address = gtoh(entry, byteOrder); + +symbolTable->insert(symbol); +} + +// Replace the current debug symbol table +loader::debugSymbolTable.clear(); +loader::debugSymbolTable.insert(*symbolTable); +delete symbolTable; } template @@ -91,6 +139,8 @@ { int intSize = sizeof(IntType); ByteOrder byteOrder = objFile->getByteOrder(); +bool is64bit = (objFile->getArch() == loader::Power64); +bool isLittleEndian = (byteOrder ==
[gem5-dev] Change in gem5/gem5[develop]: arch-power: Add multi-mode support
Sandipan Das has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/40944 ) Change subject: arch-power: Add multi-mode support .. arch-power: Add multi-mode support This adds multi-mode support and allows the simulator to read, interpret and execute 32bit and 64-bit, big and little endian binaries in syscall emulation mode. During process initialization, a minimal set of hardware capabilities are also advertised by the simulator to show support for 64-bit mode and little endian byte order. This also adds some fixups specific to 64-bit ELF ABI v1 that readjust the entry point and symbol table due to the use of function descriptors. Change-Id: I124339eff7b70dbd14e50ff970340c88c13bd0ad Signed-off-by: Sandipan Das --- M src/arch/power/PowerSeWorkload.py M src/arch/power/linux/se_workload.cc M src/arch/power/process.cc M src/arch/power/registers.hh M src/base/loader/elf_object.cc M src/base/loader/object_file.cc M src/base/loader/object_file.hh 7 files changed, 100 insertions(+), 18 deletions(-) diff --git a/src/arch/power/PowerSeWorkload.py b/src/arch/power/PowerSeWorkload.py index 2d3d3cb..40e989c 100644 --- a/src/arch/power/PowerSeWorkload.py +++ b/src/arch/power/PowerSeWorkload.py @@ -40,5 +40,5 @@ @classmethod def _is_compatible_with(cls, obj): -return obj.get_arch() == 'power' and \ +return obj.get_arch() in ('power', 'power64') and \ obj.get_op_sys() in ('linux', 'unknown') diff --git a/src/arch/power/linux/se_workload.cc b/src/arch/power/linux/se_workload.cc index 864468f..091fd35 100644 --- a/src/arch/power/linux/se_workload.cc +++ b/src/arch/power/linux/se_workload.cc @@ -47,7 +47,9 @@ Process * load(const ProcessParams , ::Loader::ObjectFile *obj) override { -if (obj->getArch() != ::Loader::Power) +auto arch = obj->getArch(); + +if (arch != ::Loader::Power && arch != ::Loader::Power64) return nullptr; auto opsys = obj->getOpSys(); @@ -57,7 +59,10 @@ opsys = ::Loader::Linux; } -if (opsys != ::Loader::Linux) +if ((arch == ::Loader::Power && opsys != ::Loader::Linux) || +(arch == ::Loader::Power64 && + opsys != ::Loader::LinuxPower64ABIv1 && + opsys != ::Loader::LinuxPower64ABIv2)) return nullptr; return new PowerProcess(params, obj); diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc index 409f980..735b3d9 100644 --- a/src/arch/power/process.cc +++ b/src/arch/power/process.cc @@ -76,7 +76,55 @@ { Process::initState(); -argsInit(PageBytes); +if (objFile->getArch() == ::Loader::Power) +argsInit(PageBytes); +else +argsInit(PageBytes); + +// Fix up entry point and symbol table for 64-bit ELF ABI v1 +if (objFile->getOpSys() != ::Loader::LinuxPower64ABIv1) +return; + +// Fix entry point address and the base TOC pointer by looking the +// the function descriptor in the .opd section +Addr entryPoint, tocBase; +ByteOrder byteOrder = objFile->getByteOrder(); +ThreadContext *tc = system->threads[contextIds[0]]; + +// The first doubleword of the descriptor contains the address of the +// entry point of the function +initVirtMem->readBlob(getStartPC(), , sizeof(Addr)); + +// Update the PC state +auto pc = tc->pcState(); +pc.byteOrder(byteOrder); +pc.set(gtoh(entryPoint, byteOrder)); +tc->pcState(pc); + +// The second doubleword of the descriptor contains the TOC base +// address for the function +initVirtMem->readBlob(getStartPC() + 8, , sizeof(Addr)); +tc->setIntReg(TOCPointerReg, gtoh(tocBase, byteOrder)); + +// Fix symbol table entries as they would otherwise point to the +// function descriptor rather than the actual entry point address +auto *symbolTable = new ::Loader::SymbolTable; + +for (auto sym : ::Loader::debugSymbolTable) { +Addr entry; +::Loader::Symbol symbol = sym; + +// Try to read entry point from function descriptor +if (initVirtMem->tryReadBlob(sym.address, , sizeof(Addr))) +symbol.address = gtoh(entry, byteOrder); + +symbolTable->insert(symbol); +} + +// Replace the current debug symbol table +::Loader::debugSymbolTable.clear(); +::Loader::debugSymbolTable.insert(*symbolTable); +delete symbolTable; } template @@ -85,6 +133,8 @@ { int intSize = sizeof(IntType); ByteOrder byteOrder = objFile->getByteOrder(); +bool is64bit = (objFile->getArch() == ::Loader::Power64); +bool isLittleEndian = (byteOrder == ByteOrder::little); std::vector> auxv; std::string filename; @@ -104,13 +154,21 @@ //Auxilliary vectors are loaded only for elf formatted executables. auto *elfObject = dynamic_cast<::Loader::ElfObject