From: Sandipan Das Date: Thu, 7 Jun 2018 14:37:02 +0000 (+0530) Subject: arch-power: Fix stack layout for 64-bit execution X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1a67a905db5b51ca9112da8ffa259e3b5e5daad2;p=gem5.git arch-power: Fix stack layout for 64-bit execution This fixes the call stack layout by changing the size of the auxiliary vector entries, each of which contain two 64-bit values. Also, all base addresses for stack contents are now considered to be 64 bits in order to prevent underflows during program execution. Users can now run statically-linked 64-bit ELF ABI v2 compliant PowerPC LSB ELF executables in syscall emulation mode. Change-Id: I256399d9344b1b101385e32ad8978325aec9844e Signed-off-by: Sandipan Das --- diff --git a/src/arch/power/isa_traits.hh b/src/arch/power/isa_traits.hh index 2d90895c7..08801f99a 100644 --- a/src/arch/power/isa_traits.hh +++ b/src/arch/power/isa_traits.hh @@ -46,6 +46,21 @@ StaticInstPtr decodeInst(ExtMachInst); const Addr PageShift = 12; const Addr PageBytes = ULL(1) << PageShift; +const Addr Page_Mask = ~(PageBytes - 1); +const Addr PageOffset = PageBytes - 1; + +const Addr PteShift = 3; +const Addr NPtePageShift = PageShift - PteShift; +const Addr NPtePage = ULL(1) << NPtePageShift; +const Addr PteMask = NPtePage - 1; + +const int MachineBytes = 8; + +// Memory accesses can be unaligned +const bool HasUnalignedMemAcc = true; + +const bool CurThreadInfoImplemented = false; +const int CurThreadInfoReg = -1; } // namespace PowerISA diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc index 19834e999..eb505b062 100644 --- a/src/arch/power/process.cc +++ b/src/arch/power/process.cc @@ -83,7 +83,8 @@ PowerProcess::initState() void PowerProcess::argsInit(int intSize, int pageSize) { - std::vector> auxv; + typedef AuxVector auxv_t; + std::vector auxv; string filename; if (argv.size() < 1) @@ -98,11 +99,37 @@ PowerProcess::argsInit(int intSize, int pageSize) image.write(*initVirtMem); interpImage.write(*initVirtMem); + enum PowerCpuFeature { + Power_32 = ULL(1) << 31, // Always set for powerpc64 + Power_64 = ULL(1) << 30, // Always set for powerpc64 + Power_HAS_ALTIVEC = ULL(1) << 28, + Power_HAS_FPU = ULL(1) << 27, + Power_HAS_MMU = ULL(1) << 26, + Power_UNIFIED_CACHE = ULL(1) << 24, + Power_NO_TB = ULL(1) << 20, // 601/403gx have no timebase + Power_POWER4 = ULL(1) << 19, // POWER4 ISA 2.00 + Power_POWER5 = ULL(1) << 18, // POWER5 ISA 2.02 + Power_POWER5_PLUS = ULL(1) << 17, // POWER5+ ISA 2.03 + Power_CELL_BE = ULL(1) << 16, // CELL Broadband Engine + Power_BOOKE = ULL(1) << 15, // ISA Category Embedded + Power_SMT = ULL(1) << 14, // Simultaneous Multi-Threading + Power_ICACHE_SNOOP = ULL(1) << 13, + Power_ARCH_2_05 = ULL(1) << 12, // ISA 2.05 + Power_PA6T = ULL(1) << 11, // PA Semi 6T Core + Power_HAS_DFP = ULL(1) << 10, // Decimal FP Unit + Power_POWER6_EXT = ULL(1) << 9, // P6 + mffgpr/mftgpr + Power_ARCH_2_06 = ULL(1) << 8, // ISA 2.06 + Power_HAS_VSX = ULL(1) << 7, // P7 Vector Extension + Power_PSERIES_PERFMON_COMPAT = ULL(1) << 6, + Power_TRUE_LE = ULL(1) << 1, + Power_PPC_LE = ULL(1) << 0 + }; + //Setup the auxilliary vectors. These will already have endian conversion. //Auxilliary vectors are loaded only for elf formatted executables. auto *elfObject = dynamic_cast<::Loader::ElfObject *>(objFile); if (elfObject) { - uint32_t features = 0; + uint64_t features = Power_32 | Power_64 | Power_PPC_LE; //Bits which describe the system hardware capabilities //XXX Figure out what these should be @@ -138,7 +165,10 @@ PowerProcess::argsInit(int intSize, int pageSize) //The filename of the program auxv.emplace_back(M5_AT_EXECFN, 0); //The string "v51" with unknown meaning - auxv.emplace_back(M5_AT_PLATFORM, 0); + auxv.push_back(auxv_t(M5_AT_PLATFORM, 0)); + //The address of 16 bytes in the data section containing a random + //value; it is required for stack protection using a canary value. + auxv.push_back(auxv_t(M5_AT_RANDOM, objFile->dataBase())); } //Figure out how big the initial stack nedes to be @@ -205,15 +235,15 @@ PowerProcess::argsInit(int intSize, int pageSize) roundUp(memState->getStackSize(), pageSize), "stack"); // map out initial stack contents - uint32_t sentry_base = memState->getStackBase() - sentry_size; - uint32_t aux_data_base = sentry_base - aux_data_size; - uint32_t env_data_base = aux_data_base - env_data_size; - uint32_t arg_data_base = env_data_base - arg_data_size; - uint32_t platform_base = arg_data_base - platform_size; - uint32_t auxv_array_base = platform_base - aux_array_size - aux_padding; - uint32_t envp_array_base = auxv_array_base - envp_array_size; - uint32_t argv_array_base = envp_array_base - argv_array_size; - uint32_t argc_base = argv_array_base - argc_size; + uint64_t sentry_base = memState->getStackBase() - sentry_size; + uint64_t aux_data_base = sentry_base - aux_data_size; + uint64_t env_data_base = aux_data_base - env_data_size; + uint64_t arg_data_base = env_data_base - arg_data_size; + uint64_t platform_base = arg_data_base - platform_size; + uint64_t auxv_array_base = platform_base - aux_array_size - aux_padding; + uint64_t envp_array_base = auxv_array_base - envp_array_size; + uint64_t argv_array_base = envp_array_base - argv_array_size; + uint64_t argc_base = argv_array_base - argc_size; DPRINTF(Stack, "The addresses of items on the initial stack:\n"); DPRINTF(Stack, "0x%x - aux data\n", aux_data_base); @@ -229,12 +259,13 @@ PowerProcess::argsInit(int intSize, int pageSize) // write contents to stack // figure out argc - uint32_t argc = argv.size(); - uint32_t guestArgc = htobe(argc); + uint64_t argc = argv.size(); + uint64_t guestArgc = PowerISA::htog(argc); //Write out the sentry void * - uint32_t sentry_NULL = 0; - initVirtMem->writeBlob(sentry_base, &sentry_NULL, sentry_size); + uint64_t sentry_NULL = 0; + initVirtMem.writeBlob(sentry_base, + (uint8_t*)&sentry_NULL, sentry_size); //Fix up the aux vectors which point to other data for (int i = auxv.size() - 1; i >= 0; i--) {