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 <sandipan@linux.ibm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40944
Reviewed-by: Boris Shingarov <shingarov@labware.com>
Maintainer: Boris Shingarov <shingarov@labware.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Sandipan Das
2021-02-06 17:39:51 +05:30
committed by Boris Shingarov
parent be3a57e68a
commit 480effb522
7 changed files with 100 additions and 18 deletions

View File

@@ -252,15 +252,8 @@ ElfObject::determineArch()
arch = (eclass == ELFCLASS64) ? Riscv64 : Riscv32;
} else if (emach == EM_PPC && eclass == ELFCLASS32) {
arch = Power;
if (edata != ELFDATA2MSB) {
fatal("The binary you're trying to load is compiled for "
"little endian Power.\ngem5 only supports big "
"endian Power. Please recompile your binary.\n");
}
} else if (emach == EM_PPC64) {
fatal("The binary you're trying to load is compiled for 64-bit "
"Power. M5\n only supports 32-bit Power. Please "
"recompile your binary.\n");
} else if (emach == EM_PPC64 && eclass == ELFCLASS64) {
arch = Power64;
} else {
warn("Unknown architecture: %d\n", emach);
}
@@ -269,6 +262,21 @@ ElfObject::determineArch()
void
ElfObject::determineOpSys()
{
// For 64-bit Power, EI_OSABI and EI_ABIVERSION cannot be used to
// determine the ABI version used by the ELF object
if (ehdr.e_machine == EM_PPC64) {
switch (ehdr.e_flags & 0x3) {
case 0x1: opSys = LinuxPower64ABIv1; return;
case 0x2: opSys = LinuxPower64ABIv2; return;
default:
if (ehdr.e_ident[EI_DATA] == ELFDATA2MSB)
opSys = LinuxPower64ABIv1;
if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
opSys = LinuxPower64ABIv2;
return;
}
}
// Detect the operating system
switch (ehdr.e_ident[EI_OSABI]) {
case ELFOSABI_LINUX:

View File

@@ -66,6 +66,8 @@ archToString(Arch arch)
return "thumb";
case Power:
return "power";
case Power64:
return "power64";
case Riscv64:
return "riscv64";
case Riscv32:
@@ -84,6 +86,8 @@ opSysToString(OpSys op_sys)
case Tru64:
return "tru64";
case Linux:
case LinuxPower64ABIv1:
case LinuxPower64ABIv2:
return "linux";
case Solaris:
return "solaris";

View File

@@ -59,6 +59,7 @@ enum Arch
Arm,
Thumb,
Power,
Power64,
Riscv64,
Riscv32
};
@@ -72,6 +73,8 @@ enum OpSys
Linux,
Solaris,
LinuxArmOABI,
LinuxPower64ABIv1,
LinuxPower64ABIv2,
FreeBSD
};