Automated merge with ssh://m5sim.org//repo/m5
This commit is contained in:
@@ -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");
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -57,6 +60,119 @@ AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams *params,
|
||||
// Set pointer for next thread stack. Reserve 8M for main stack.
|
||||
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
@@ -65,6 +181,8 @@ AlphaLiveProcess::startup()
|
||||
if (checkpointRestored)
|
||||
return;
|
||||
|
||||
Process::startup();
|
||||
|
||||
argsInit(MachineBytes, VMPageSize);
|
||||
|
||||
ThreadContext *tc = system->getThreadContext(contextIds[0]);
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user