summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLisa Hsu <hsul@eecs.umich.edu>2008-12-05 12:11:46 -0500
committerLisa Hsu <hsul@eecs.umich.edu>2008-12-05 12:11:46 -0500
commit854aa60fdcec2a95d2c08844d62681b498281ca3 (patch)
tree773ef7b3acb7d6b1da8628217a0441fab9c45af2 /src
parentd6b229ea0f46de3a622ebb1ef86cb526625ebc2e (diff)
parentf1430941cf17fc15a8b86eba41f9c856ad9347d8 (diff)
downloadgem5-854aa60fdcec2a95d2c08844d62681b498281ca3.tar.xz
Automated merge with ssh://m5sim.org//repo/m5
Diffstat (limited to 'src')
-rw-r--r--src/arch/alpha/linux/process.cc2
-rw-r--r--src/arch/alpha/process.cc118
-rw-r--r--src/arch/alpha/process.hh5
-rw-r--r--src/arch/sparc/process.hh20
-rw-r--r--src/arch/x86/process.cc9
-rw-r--r--src/arch/x86/process.hh16
-rw-r--r--src/base/loader/elf_object.cc2
-rw-r--r--src/sim/process.cc15
-rw-r--r--src/sim/process.hh16
9 files changed, 152 insertions, 51 deletions
diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc
index efcd6623e..6684051af 100644
--- a/src/arch/alpha/linux/process.cc
+++ b/src/arch/alpha/linux/process.cc
@@ -52,7 +52,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process,
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
- strcpy(name->release, "2.4.20");
+ strcpy(name->release, "2.6.26");
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "alpha");
diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc
index 28e8df308..3e5851e74 100644
--- a/src/arch/alpha/process.cc
+++ b/src/arch/alpha/process.cc
@@ -32,8 +32,11 @@
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/process.hh"
#include "base/loader/object_file.hh"
+#include "base/loader/elf_object.hh"
#include "base/misc.hh"
#include "cpu/thread_context.hh"
+#include "mem/page_table.hh"
+#include "sim/process_impl.hh"
#include "sim/system.hh"
using namespace AlphaISA;
@@ -60,11 +63,126 @@ AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams *params,
}
void
+AlphaLiveProcess::argsInit(int intSize, int pageSize)
+{
+ objFile->loadSections(initVirtMem);
+
+ typedef M5_auxv_t<uint64_t> auxv_t;
+ std::vector<auxv_t> auxv;
+
+ ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
+ if(elfObject)
+ {
+ // modern glibc uses a bunch of auxiliary vectors to set up
+ // TLS as well as do a bunch of other stuff
+ // these vectors go on the bottom of the stack, below argc/argv/envp
+ // pointers but above actual arg strings
+ // I don't have all the ones glibc looks at here, but so far it doesn't
+ // seem to be a problem.
+ // check out _dl_aux_init() in glibc/elf/dl-support.c for details
+ // --Lisa
+ auxv.push_back(auxv_t(M5_AT_PAGESZ, AlphaISA::VMPageSize));
+ auxv.push_back(auxv_t(M5_AT_CLKTCK, 100));
+ auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable()));
+ DPRINTF(Loader, "auxv at PHDR %08p\n", elfObject->programHeaderTable());
+ auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount()));
+ auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint()));
+ 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()));
+
+ }
+
+ // Calculate how much space we need for arg & env & auxv arrays.
+ int argv_array_size = intSize * (argv.size() + 1);
+ int envp_array_size = intSize * (envp.size() + 1);
+ int auxv_array_size = intSize * 2 * (auxv.size() + 1);
+
+ int arg_data_size = 0;
+ for (int i = 0; i < argv.size(); ++i) {
+ arg_data_size += argv[i].size() + 1;
+ }
+ int env_data_size = 0;
+ for (int i = 0; i < envp.size(); ++i) {
+ env_data_size += envp[i].size() + 1;
+ }
+
+ int space_needed =
+ argv_array_size +
+ envp_array_size +
+ auxv_array_size +
+ arg_data_size +
+ env_data_size;
+
+ if (space_needed < 32*1024)
+ space_needed = 32*1024;
+
+ // set bottom of stack
+ stack_min = stack_base - space_needed;
+ // align it
+ stack_min = roundDown(stack_min, pageSize);
+ stack_size = stack_base - stack_min;
+ // map memory
+ pTable->allocate(stack_min, roundUp(stack_size, pageSize));
+
+ // map out initial stack contents
+ Addr argv_array_base = stack_min + intSize; // room for argc
+ Addr envp_array_base = argv_array_base + argv_array_size;
+ Addr auxv_array_base = envp_array_base + envp_array_size;
+ Addr arg_data_base = auxv_array_base + auxv_array_size;
+ Addr env_data_base = arg_data_base + arg_data_size;
+
+ // write contents to stack
+ uint64_t argc = argv.size();
+ if (intSize == 8)
+ argc = htog((uint64_t)argc);
+ else if (intSize == 4)
+ argc = htog((uint32_t)argc);
+ else
+ panic("Unknown int size");
+
+ initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize);
+
+ copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
+ copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
+
+ //Copy the aux stuff
+ for(int x = 0; x < auxv.size(); x++)
+ {
+ initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize,
+ (uint8_t*)&(auxv[x].a_type), intSize);
+ initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize,
+ (uint8_t*)&(auxv[x].a_val), intSize);
+ }
+
+ assert(NumArgumentRegs >= 2);
+
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
+
+ tc->setIntReg(ArgumentReg[0], argc);
+ tc->setIntReg(ArgumentReg[1], argv_array_base);
+ tc->setIntReg(StackPointerReg, stack_min);
+
+ Addr prog_entry = objFile->entryPoint();
+ tc->setPC(prog_entry);
+ tc->setNextPC(prog_entry + sizeof(MachInst));
+
+#if THE_ISA != ALPHA_ISA //e.g. MIPS or Sparc
+ tc->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
+#endif
+
+
+}
+
+void
AlphaLiveProcess::startup()
{
if (checkpointRestored)
return;
+ Process::startup();
+
argsInit(MachineBytes, VMPageSize);
ThreadContext *tc = system->getThreadContext(contextIds[0]);
diff --git a/src/arch/alpha/process.hh b/src/arch/alpha/process.hh
index 0aeeb25db..65c4624ae 100644
--- a/src/arch/alpha/process.hh
+++ b/src/arch/alpha/process.hh
@@ -34,15 +34,14 @@
#include "sim/process.hh"
-class ObjectFile;
-class System;
-
class AlphaLiveProcess : public LiveProcess
{
protected:
AlphaLiveProcess(LiveProcessParams *params, ObjectFile *objFile);
void startup();
+
+ void argsInit(int intSize, int pageSize);
};
#endif // __ARCH_ALPHA_PROCESS_HH__
diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh
index a37760139..95abb93d3 100644
--- a/src/arch/sparc/process.hh
+++ b/src/arch/sparc/process.hh
@@ -71,26 +71,6 @@ class SparcLiveProcess : public LiveProcess
virtual void flushWindows(ThreadContext *tc) = 0;
};
-template<class IntType>
-struct M5_auxv_t
-{
- IntType a_type;
- union {
- IntType a_val;
- IntType a_ptr;
- IntType a_fcn;
- };
-
- M5_auxv_t()
- {}
-
- M5_auxv_t(IntType type, IntType val)
- {
- a_type = SparcISA::htog(type);
- a_val = SparcISA::htog(val);
- }
-};
-
class Sparc32LiveProcess : public SparcLiveProcess
{
protected:
diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc
index 52933b7f4..8d0cd5038 100644
--- a/src/arch/x86/process.cc
+++ b/src/arch/x86/process.cc
@@ -103,11 +103,6 @@
using namespace std;
using namespace X86ISA;
-M5_64_auxv_t::M5_64_auxv_t(int64_t type, int64_t val)
-{
- a_type = X86ISA::htog(type);
- a_val = X86ISA::htog(val);
-}
X86LiveProcess::X86LiveProcess(LiveProcessParams * params,
ObjectFile *objFile)
@@ -205,7 +200,9 @@ X86LiveProcess::startup()
void
X86LiveProcess::argsInit(int intSize, int pageSize)
{
- typedef M5_64_auxv_t auxv_t;
+ typedef M5_auxv_t<uint64_t> auxv_t;
+ std::vector<auxv_t> auxv;
+
Process::startup();
string filename;
diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh
index 5def9e13d..d034d990e 100644
--- a/src/arch/x86/process.hh
+++ b/src/arch/x86/process.hh
@@ -64,26 +64,10 @@
namespace X86ISA
{
- struct M5_64_auxv_t
- {
- int64_t a_type;
- union {
- int64_t a_val;
- int64_t a_ptr;
- int64_t a_fcn;
- };
-
- M5_64_auxv_t()
- {}
-
- M5_64_auxv_t(int64_t type, int64_t val);
- };
class X86LiveProcess : public LiveProcess
{
protected:
- std::vector<M5_64_auxv_t> auxv;
-
X86LiveProcess(LiveProcessParams * params, ObjectFile *objFile);
void startup();
diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc
index f71c4456b..edaf323c7 100644
--- a/src/base/loader/elf_object.cc
+++ b/src/base/loader/elf_object.cc
@@ -291,6 +291,8 @@ ElfObject::ElfObject(const string &_filename, int _fd,
data.size = phdr.p_filesz;
data.fileImage = fileData + phdr.p_offset;
} else {
+ // If it's none of the above but is loadable,
+ // load the filesize worth of data
Segment extra;
extra.baseAddr = phdr.p_paddr;
extra.size = phdr.p_filesz;
diff --git a/src/sim/process.cc b/src/sim/process.cc
index dab374d84..244fb9297 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -86,6 +86,16 @@ using namespace TheISA;
// current number of allocated processes
int num_processes = 0;
+template<class IntType>
+M5_auxv_t<IntType>::M5_auxv_t(IntType type, IntType val)
+{
+ a_type = TheISA::htog(type);
+ a_val = TheISA::htog(val);
+}
+
+template class M5_auxv_t<uint32_t>;
+template class M5_auxv_t<uint64_t>;
+
Process::Process(ProcessParams * params)
: SimObject(params), system(params->system), checkpointRestored(false),
max_stack_size(params->max_stack_size)
@@ -658,11 +668,6 @@ LiveProcess::create(LiveProcessParams * params)
if (objFile->getArch() != ObjectFile::Alpha)
fatal("Object file architecture does not match compiled ISA (Alpha).");
- if (objFile->hasTLS())
- fatal("Object file has a TLS section and single threaded TLS is not\n"
- " currently supported for Alpha! Please recompile your "
- "executable with \n a non-TLS toolchain.\n");
-
switch (objFile->getOpSys()) {
case ObjectFile::Tru64:
process = new AlphaTru64Process(params, objFile);
diff --git a/src/sim/process.hh b/src/sim/process.hh
index d6ed59ced..996663847 100644
--- a/src/sim/process.hh
+++ b/src/sim/process.hh
@@ -61,6 +61,22 @@ namespace TheISA
class RemoteGDB;
}
+template<class IntType>
+struct M5_auxv_t
+{
+ IntType a_type;
+ union {
+ IntType a_val;
+ IntType a_ptr;
+ IntType a_fcn;
+ };
+
+ M5_auxv_t()
+ {}
+
+ M5_auxv_t(IntType type, IntType val);
+};
+
class Process : public SimObject
{
public: