34a35
> #include "base/loader/elf_object.hh"
36a38,39
> #include "mem/page_table.hh"
> #include "sim/process_impl.hh"
62a66,178
> 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
67a184,185
> Process::startup();
>