From e996ff74978c09eda4903dc491ed5261b5def789 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 28 Jul 2007 20:33:42 -0700 Subject: X86: Fix up auxiliary vectors. The type constants should go into an architecture independent spot since they are universal to all Linux elf binaries. The right value for some of the vectors needs to be determined. Also, x86 does not store argc or argv_array_base in registers like some other architectures. --HG-- extra : convert_revision : 8d3f6a3e028d881d3c41e8ddf4f29d25738b529c --- src/arch/x86/process.cc | 49 ++++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 21 deletions(-) (limited to 'src/arch/x86') diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 09962fdb6..713e5d0a2 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -187,7 +187,14 @@ X86LiveProcess::argsInit(int intSize, int pageSize) X86_AT_UID = 11, X86_AT_EUID = 12, X86_AT_GID = 13, - X86_AT_EGID = 14 + X86_AT_EGID = 14, + X86_AT_PLATFORM = 15, + X86_AT_HWCAP = 16, + X86_AT_CLKTCK = 17, + + X86_AT_SECURE = 13, + + X86_AT_VECTOR_SIZE = 44 }; //Setup the auxilliary vectors. These will already have endian conversion. @@ -195,36 +202,39 @@ X86LiveProcess::argsInit(int intSize, int pageSize) ElfObject * elfObject = dynamic_cast(objFile); if(elfObject) { - /* //Bits which describe the system hardware capabilities - auxv.push_back(auxv_t(SPARC_AT_HWCAP, hwcap)); + //XXX Figure out what these should be + auxv.push_back(auxv_t(X86_AT_HWCAP, 0)); //The system page size - auxv.push_back(auxv_t(SPARC_AT_PAGESZ, SparcISA::VMPageSize)); - //Defined to be 100 in the kernel source. + auxv.push_back(auxv_t(X86_AT_PAGESZ, X86ISA::VMPageSize)); //Frequency at which times() increments - auxv.push_back(auxv_t(SPARC_AT_CLKTCK, 100)); + auxv.push_back(auxv_t(X86_AT_CLKTCK, 100)); // For statically linked executables, this is the virtual address of the // program header tables if they appear in the executable image - auxv.push_back(auxv_t(SPARC_AT_PHDR, elfObject->programHeaderTable())); + auxv.push_back(auxv_t(X86_AT_PHDR, elfObject->programHeaderTable())); // This is the size of a program header entry from the elf file. - auxv.push_back(auxv_t(SPARC_AT_PHENT, elfObject->programHeaderSize())); + auxv.push_back(auxv_t(X86_AT_PHENT, elfObject->programHeaderSize())); // This is the number of program headers from the original elf file. - auxv.push_back(auxv_t(SPARC_AT_PHNUM, elfObject->programHeaderCount())); + auxv.push_back(auxv_t(X86_AT_PHNUM, elfObject->programHeaderCount())); + //Defined to be 100 in the kernel source. //This is the address of the elf "interpreter", It should be set //to 0 for regular executables. It should be something else //(not sure what) for dynamic libraries. - auxv.push_back(auxv_t(SPARC_AT_BASE, 0)); - //This is hardwired to 0 in the elf loading code in the kernel - auxv.push_back(auxv_t(SPARC_AT_FLAGS, 0)); + auxv.push_back(auxv_t(X86_AT_BASE, 0)); + + //XXX Figure out what this should be. + auxv.push_back(auxv_t(X86_AT_FLAGS, 0)); //The entry point to the program - auxv.push_back(auxv_t(SPARC_AT_ENTRY, objFile->entryPoint())); + auxv.push_back(auxv_t(X86_AT_ENTRY, objFile->entryPoint())); //Different user and group IDs - auxv.push_back(auxv_t(SPARC_AT_UID, uid())); - auxv.push_back(auxv_t(SPARC_AT_EUID, euid())); - auxv.push_back(auxv_t(SPARC_AT_GID, gid())); - auxv.push_back(auxv_t(SPARC_AT_EGID, egid())); + auxv.push_back(auxv_t(X86_AT_UID, uid())); + auxv.push_back(auxv_t(X86_AT_EUID, euid())); + auxv.push_back(auxv_t(X86_AT_GID, gid())); + auxv.push_back(auxv_t(X86_AT_EGID, egid())); //Whether to enable "secure mode" in the executable - auxv.push_back(auxv_t(SPARC_AT_SECURE, 0));*/ + auxv.push_back(auxv_t(X86_AT_SECURE, 0)); + //The string "x86_64" with unknown meaning + auxv.push_back(auxv_t(X86_AT_PLATFORM, 0)); } //Figure out how big the initial stack needs to be @@ -338,9 +348,6 @@ X86LiveProcess::argsInit(int intSize, int pageSize) initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize); //Set up the thread context to start running the process - assert(NumArgumentRegs >= 2); - threadContexts[0]->setIntReg(ArgumentReg[0], argc); - threadContexts[0]->setIntReg(ArgumentReg[1], argv_array_base); threadContexts[0]->setIntReg(StackPointerReg, stack_min); Addr prog_entry = objFile->entryPoint(); -- cgit v1.2.3 From dc86f3229c2d3278bf5f32fb9b0b4bf039c0735e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 28 Jul 2007 21:18:53 -0700 Subject: X86: Fix a comment and adjust the stack base address. The stack base on my development machine starts one page below where it needs to. I don't know why it does, but I've duplicated it in m5. --HG-- extra : convert_revision : c4783ba885b90f17e843f61e07af0bc3330a74bc --- src/arch/x86/process.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/arch/x86') diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 713e5d0a2..ff23be339 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -122,9 +122,10 @@ X86LiveProcess::X86LiveProcess(const std::string &nm, ObjectFile *objFile, // Set pointer for next thread stack. Reserve 8M for main stack. next_thread_stack_base = stack_base - (8 * 1024 * 1024); - // Set up stack. On SPARC Linux, stack goes from the top of memory - // downward, less the hole for the kernel address space. - stack_base = (Addr)0x80000000000ULL; + // Set up stack. On X86_64 Linux, stack goes from the top of memory + // downward, less the hole for the kernel address space plus one page + // for undertermined purposes. + stack_base = (Addr)0x7FFFFFFF000ULL; // Set up region for mmaps. Tru64 seems to start just above 0 and // grow up from there. -- cgit v1.2.3 From 3dcd848ec340e96f374ee9859bf4f8906fb577cc Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 29 Jul 2007 01:24:57 -0700 Subject: X86: Fix a bug with merge Merge was returning the value to merge in, not the actual result of the merge. --HG-- extra : convert_revision : 230b4b5064037d099ae7859edabdf5be84603849 --- src/arch/x86/insts/static_inst.hh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/arch/x86') diff --git a/src/arch/x86/insts/static_inst.hh b/src/arch/x86/insts/static_inst.hh index c39c2956e..f42e6693d 100644 --- a/src/arch/x86/insts/static_inst.hh +++ b/src/arch/x86/insts/static_inst.hh @@ -58,6 +58,7 @@ #ifndef __ARCH_X86_INSTS_STATICINST_HH__ #define __ARCH_X86_INSTS_STATICINST_HH__ +#include "base/trace.hh" #include "cpu/static_inst.hh" namespace X86ISA @@ -113,7 +114,7 @@ namespace X86ISA default: panic("Tried to merge with unrecognized size %d.\n", size); } - return val; + return reg; } inline uint64_t pick(uint64_t from, int size) -- cgit v1.2.3 From d99557534217dc59e33ca70591b52d9d9e8322a8 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 29 Jul 2007 01:26:47 -0700 Subject: X86: Fix popa and push with the stack pointer. POPA used st instead of ld, and it didn't skip rsp. push rsp needs to store the -original- value of the stack pointer. --HG-- extra : convert_revision : 376370c99b6ab60fb2bc4cd4f0a6dce71153ad06 --- .../x86/isa/insts/data_transfer/stack_operations.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src/arch/x86') diff --git a/src/arch/x86/isa/insts/data_transfer/stack_operations.py b/src/arch/x86/isa/insts/data_transfer/stack_operations.py index 889e7b88b..1c13b44b4 100644 --- a/src/arch/x86/isa/insts/data_transfer/stack_operations.py +++ b/src/arch/x86/isa/insts/data_transfer/stack_operations.py @@ -85,8 +85,10 @@ def macroop PUSH_R { # Make the default data size of pops 64 bits in 64 bit mode .adjust_env oszIn64Override + # This needs to work slightly differently from the other versions of push + # because the -original- version of the stack pointer is what gets pushed + st reg, ss, [0, t0, rsp], "-env.dataSize" subi rsp, rsp, dsz - st reg, ss, [0, t0, rsp] }; def macroop PUSH_I { @@ -130,14 +132,13 @@ def macroop PUSHA { }; def macroop POPA { - st rdi, ss, [0, t0, rsp], "0 * env.dataSize" - st rsi, ss, [0, t0, rsp], "1 * env.dataSize" - st rbp, ss, [0, t0, rsp], "2 * env.dataSize" - st rsp, ss, [0, t0, rsp], "3 * env.dataSize" - st rbx, ss, [0, t0, rsp], "4 * env.dataSize" - st rdx, ss, [0, t0, rsp], "5 * env.dataSize" - st rcx, ss, [0, t0, rsp], "6 * env.dataSize" - st rax, ss, [0, t0, rsp], "7 * env.dataSize" + ld rdi, ss, [0, t0, rsp], "0 * env.dataSize" + ld rsi, ss, [0, t0, rsp], "1 * env.dataSize" + ld rbp, ss, [0, t0, rsp], "2 * env.dataSize" + ld rbx, ss, [0, t0, rsp], "4 * env.dataSize" + ld rdx, ss, [0, t0, rsp], "5 * env.dataSize" + ld rcx, ss, [0, t0, rsp], "6 * env.dataSize" + ld rax, ss, [0, t0, rsp], "7 * env.dataSize" addi rsp, rsp, "8 * env.dataSize" }; ''' -- cgit v1.2.3 From 33847f8c83f8ac3c85c1388b5b69aacbc5163564 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 29 Jul 2007 01:27:34 -0700 Subject: X86: return -return_value.value() on failure. --HG-- extra : convert_revision : d8e1486ff075b2917be62a0008f83fd6c9e4c09a --- src/arch/x86/syscallreturn.hh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/arch/x86') diff --git a/src/arch/x86/syscallreturn.hh b/src/arch/x86/syscallreturn.hh index 6a7fdba58..be9715d21 100644 --- a/src/arch/x86/syscallreturn.hh +++ b/src/arch/x86/syscallreturn.hh @@ -67,7 +67,11 @@ namespace X86ISA static inline void setSyscallReturn(SyscallReturn return_value, ThreadContext * tc) { - tc->setIntReg(INTREG_RAX, return_value.value()); + if (return_value.successful()) { + tc->setIntReg(INTREG_RAX, return_value.value()); + } else { + tc->setIntReg(INTREG_RAX, -return_value.value()); + } } }; -- cgit v1.2.3 From e5f58903651299d8cbba793423d953e750eb16f4 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 29 Jul 2007 01:30:28 -0700 Subject: X86: Make limm use merge and allow overriding the data size. --HG-- extra : convert_revision : c6057226b8ff8f272612a9d3bf7d1d9ba90c819b --- src/arch/x86/isa/microops/limmop.isa | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/arch/x86') diff --git a/src/arch/x86/isa/microops/limmop.isa b/src/arch/x86/isa/microops/limmop.isa index 37180d7fa..ec68c36dc 100644 --- a/src/arch/x86/isa/microops/limmop.isa +++ b/src/arch/x86/isa/microops/limmop.isa @@ -142,12 +142,12 @@ def template MicroLimmOpConstructor {{ let {{ class LimmOp(X86Microop): - def __init__(self, dest, imm): + def __init__(self, dest, imm, dataSize="env.dataSize"): self.className = "Limm" self.mnemonic = "limm" self.dest = dest self.imm = imm - self.dataSize = "env.dataSize" + self.dataSize = dataSize def getAllocator(self, *microFlags): allocator = '''new %(class_name)s(machInst, mnemonic @@ -165,7 +165,7 @@ let {{ let {{ # Build up the all register version of this micro op iop = InstObjParams("limm", "Limm", 'X86MicroopBase', - {"code" : "DestReg = imm;"}) + {"code" : "DestReg = merge(DestReg, imm, dataSize);"}) header_output += MicroLimmOpDeclare.subst(iop) decoder_output += MicroLimmOpConstructor.subst(iop) decoder_output += MicroLimmOpDisassembly.subst(iop) -- cgit v1.2.3 From 5e34c62b3b3f54c826730841029a875607824c42 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 29 Jul 2007 01:33:06 -0700 Subject: X86: Initial stack frame fixes and constant shuffling. The initial stack frame for x86 is now substantially more correct. The fixes made here can be back ported to SPARC and possible the other ISAs as well. The auxiliary vector types were moved to the LiveProcess base class because they are independent of ISA. Some of the types may only apply to Linux, though, so they may have to be moved. --HG-- extra : convert_revision : 89ace35fcc8eb9586d2fee8eeccbc3686499ef24 --- src/arch/x86/process.cc | 167 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 118 insertions(+), 49 deletions(-) (limited to 'src/arch/x86') diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index ff23be339..6d30e53e3 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -125,7 +125,7 @@ X86LiveProcess::X86LiveProcess(const std::string &nm, ObjectFile *objFile, // Set up stack. On X86_64 Linux, stack goes from the top of memory // downward, less the hole for the kernel address space plus one page // for undertermined purposes. - stack_base = (Addr)0x7FFFFFFF000ULL; + stack_base = (Addr)0x7FFFFFFFF000ULL; // Set up region for mmaps. Tru64 seems to start just above 0 and // grow up from there. @@ -166,36 +166,49 @@ X86LiveProcess::argsInit(int intSize, int pageSize) else filename = argv[0]; - Addr alignmentMask = ~(intSize - 1); + //We want 16 byte alignment + Addr alignmentMask = ~mask(4); // load object file into target memory objFile->loadSections(initVirtMem); - //These are the auxilliary vector types - enum auxTypes - { - X86_AT_NULL = 0, - X86_AT_IGNORE = 1, - X86_AT_EXECFD = 2, - X86_AT_PHDR = 3, - X86_AT_PHENT = 4, - X86_AT_PHNUM = 5, - X86_AT_PAGESZ = 6, - X86_AT_BASE = 7, - X86_AT_FLAGS = 8, - X86_AT_ENTRY = 9, - X86_AT_NOTELF = 10, - X86_AT_UID = 11, - X86_AT_EUID = 12, - X86_AT_GID = 13, - X86_AT_EGID = 14, - X86_AT_PLATFORM = 15, - X86_AT_HWCAP = 16, - X86_AT_CLKTCK = 17, - - X86_AT_SECURE = 13, - - X86_AT_VECTOR_SIZE = 44 + enum X86CpuFeature { + X86_OnboardFPU = 1 << 0, + X86_VirtualModeExtensions = 1 << 1, + X86_DebuggingExtensions = 1 << 2, + X86_PageSizeExtensions = 1 << 3, + + X86_TimeStampCounter = 1 << 4, + X86_ModelSpecificRegisters = 1 << 5, + X86_PhysicalAddressExtensions = 1 << 6, + X86_MachineCheckExtensions = 1 << 7, + + X86_CMPXCHG8Instruction = 1 << 8, + X86_OnboardAPIC = 1 << 9, + X86_SYSENTER_SYSEXIT = 1 << 11, + + X86_MemoryTypeRangeRegisters = 1 << 12, + X86_PageGlobalEnable = 1 << 13, + X86_MachineCheckArchitecture = 1 << 14, + X86_CMOVInstruction = 1 << 15, + + X86_PageAttributeTable = 1 << 16, + X86_36BitPSEs = 1 << 17, + X86_ProcessorSerialNumber = 1 << 18, + X86_CLFLUSHInstruction = 1 << 19, + + X86_DebugTraceStore = 1 << 21, + X86_ACPIViaMSR = 1 << 22, + X86_MultimediaExtensions = 1 << 23, + + X86_FXSAVE_FXRSTOR = 1 << 24, + X86_StreamingSIMDExtensions = 1 << 25, + X86_StreamingSIMDExtensions2 = 1 << 26, + X86_CPUSelfSnoop = 1 << 27, + + X86_HyperThreading = 1 << 28, + X86_AutomaticClockControl = 1 << 29, + X86_IA64Processor = 1 << 30 }; //Setup the auxilliary vectors. These will already have endian conversion. @@ -203,39 +216,71 @@ X86LiveProcess::argsInit(int intSize, int pageSize) ElfObject * elfObject = dynamic_cast(objFile); if(elfObject) { + uint64_t features = + X86_OnboardFPU | + X86_VirtualModeExtensions | + X86_DebuggingExtensions | + X86_PageSizeExtensions | + X86_TimeStampCounter | + X86_ModelSpecificRegisters | + X86_PhysicalAddressExtensions | + X86_MachineCheckExtensions | + X86_CMPXCHG8Instruction | + X86_OnboardAPIC | + X86_SYSENTER_SYSEXIT | + X86_MemoryTypeRangeRegisters | + X86_PageGlobalEnable | + X86_MachineCheckArchitecture | + X86_CMOVInstruction | + X86_PageAttributeTable | + X86_36BitPSEs | +// X86_ProcessorSerialNumber | + X86_CLFLUSHInstruction | +// X86_DebugTraceStore | +// X86_ACPIViaMSR | + X86_MultimediaExtensions | + X86_FXSAVE_FXRSTOR | + X86_StreamingSIMDExtensions | + X86_StreamingSIMDExtensions2 | +// X86_CPUSelfSnoop | +// X86_HyperThreading | +// X86_AutomaticClockControl | +// X86_IA64Processor | + 0; + //Bits which describe the system hardware capabilities //XXX Figure out what these should be - auxv.push_back(auxv_t(X86_AT_HWCAP, 0)); + auxv.push_back(auxv_t(M5_AT_HWCAP, features)); //The system page size - auxv.push_back(auxv_t(X86_AT_PAGESZ, X86ISA::VMPageSize)); + auxv.push_back(auxv_t(M5_AT_PAGESZ, X86ISA::VMPageSize)); //Frequency at which times() increments - auxv.push_back(auxv_t(X86_AT_CLKTCK, 100)); + auxv.push_back(auxv_t(M5_AT_CLKTCK, 100)); // For statically linked executables, this is the virtual address of the // program header tables if they appear in the executable image - auxv.push_back(auxv_t(X86_AT_PHDR, elfObject->programHeaderTable())); + auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable())); // This is the size of a program header entry from the elf file. - auxv.push_back(auxv_t(X86_AT_PHENT, elfObject->programHeaderSize())); + auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize())); // This is the number of program headers from the original elf file. - auxv.push_back(auxv_t(X86_AT_PHNUM, elfObject->programHeaderCount())); + auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount())); //Defined to be 100 in the kernel source. //This is the address of the elf "interpreter", It should be set //to 0 for regular executables. It should be something else //(not sure what) for dynamic libraries. - auxv.push_back(auxv_t(X86_AT_BASE, 0)); + auxv.push_back(auxv_t(M5_AT_BASE, 0)); //XXX Figure out what this should be. - auxv.push_back(auxv_t(X86_AT_FLAGS, 0)); + auxv.push_back(auxv_t(M5_AT_FLAGS, 0)); //The entry point to the program - auxv.push_back(auxv_t(X86_AT_ENTRY, objFile->entryPoint())); + auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint())); //Different user and group IDs - auxv.push_back(auxv_t(X86_AT_UID, uid())); - auxv.push_back(auxv_t(X86_AT_EUID, euid())); - auxv.push_back(auxv_t(X86_AT_GID, gid())); - auxv.push_back(auxv_t(X86_AT_EGID, egid())); + auxv.push_back(auxv_t(M5_AT_UID, uid())); + auxv.push_back(auxv_t(M5_AT_EUID, euid())); + auxv.push_back(auxv_t(M5_AT_GID, gid())); + auxv.push_back(auxv_t(M5_AT_EGID, egid())); //Whether to enable "secure mode" in the executable - auxv.push_back(auxv_t(X86_AT_SECURE, 0)); + auxv.push_back(auxv_t(M5_AT_SECURE, 0)); //The string "x86_64" with unknown meaning - auxv.push_back(auxv_t(X86_AT_PLATFORM, 0)); + auxv.push_back(auxv_t(M5_AT_PLATFORM, 0)); } //Figure out how big the initial stack needs to be @@ -245,29 +290,39 @@ X86LiveProcess::argsInit(int intSize, int pageSize) //This is the name of the file which is present on the initial stack //It's purpose is to let the user space linker examine the original file. - int file_name_size = filename.size() + 1; + int file_name_size = filename.size(); + + string platform = "x86_64"; + int aux_data_size = platform.size() + 1; int env_data_size = 0; for (int i = 0; i < envp.size(); ++i) { - env_data_size += envp[i].size() + 1; + env_data_size += envp[i].size(); } int arg_data_size = 0; for (int i = 0; i < argv.size(); ++i) { - arg_data_size += argv[i].size() + 1; + arg_data_size += argv[i].size(); } + //The auxiliary vector data needs to be padded so it's size is a multiple + //of the alignment mask. + int aux_padding = + ((aux_data_size + ~alignmentMask) & alignmentMask) - aux_data_size; + //The info_block needs to be padded so it's size is a multiple of the //alignment mask. Also, it appears that there needs to be at least some //padding, so if the size is already a multiple, we need to increase it //anyway. int info_block_size = - (file_name_size + + (mysterious_size + + file_name_size + env_data_size + arg_data_size + - intSize) & alignmentMask; + ~alignmentMask) & alignmentMask; int info_block_padding = info_block_size - + mysterious_size - file_name_size - env_data_size - arg_data_size; @@ -281,8 +336,9 @@ X86LiveProcess::argsInit(int intSize, int pageSize) int argc_size = intSize; int space_needed = - mysterious_size + info_block_size + + aux_data_size + + aux_padding + aux_array_size + envp_array_size + argv_array_size + @@ -301,7 +357,8 @@ X86LiveProcess::argsInit(int intSize, int pageSize) Addr file_name_base = mysterious_base - file_name_size; Addr env_data_base = file_name_base - env_data_size; Addr arg_data_base = env_data_base - arg_data_size; - Addr auxv_array_base = arg_data_base - aux_array_size - info_block_padding; + Addr aux_data_base = arg_data_base - aux_data_size - info_block_padding; + Addr auxv_array_base = aux_data_base - aux_array_size - aux_padding; Addr envp_array_base = auxv_array_base - envp_array_size; Addr argv_array_base = envp_array_base - argv_array_size; Addr argc_base = argv_array_base - argc_size; @@ -310,6 +367,7 @@ X86LiveProcess::argsInit(int intSize, int pageSize) DPRINTF(X86, "0x%x - file name\n", file_name_base); DPRINTF(X86, "0x%x - env data\n", env_data_base); DPRINTF(X86, "0x%x - arg data\n", arg_data_base); + DPRINTF(X86, "0x%x - aux data\n", aux_data_base); DPRINTF(X86, "0x%x - auxv array\n", auxv_array_base); DPRINTF(X86, "0x%x - envp array\n", envp_array_base); DPRINTF(X86, "0x%x - argv array\n", argv_array_base); @@ -330,6 +388,10 @@ X86LiveProcess::argsInit(int intSize, int pageSize) //Write the file name initVirtMem->writeString(file_name_base, filename.c_str()); + //Fix up the aux vector which points to the "platform" string + assert(auxv[auxv.size() - 1].a_type = M5_AT_PLATFORM); + auxv[auxv.size() - 1].a_val = aux_data_base; + //Copy the aux stuff for(int x = 0; x < auxv.size(); x++) { @@ -343,12 +405,19 @@ X86LiveProcess::argsInit(int intSize, int pageSize) initVirtMem->writeBlob(auxv_array_base + 2 * intSize * auxv.size(), (uint8_t*)&zero, 2 * intSize); + initVirtMem->writeString(aux_data_base, platform.c_str()); + copyStringArray(envp, envp_array_base, env_data_base, initVirtMem); copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem); initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize); //Set up the thread context to start running the process + //Because of the peculiarities of how syscall works, I believe + //a process starts with r11 containing the value of eflags or maybe r11 + //from before the call to execve. Empirically this value is 0x200. + threadContexts[0]->setIntReg(INTREG_R11, 0x200); + //Set the stack pointer register threadContexts[0]->setIntReg(StackPointerReg, stack_min); Addr prog_entry = objFile->entryPoint(); -- cgit v1.2.3