process.cc revision 5759
111320Ssteve.reinhardt@amd.com/* 210328Smitch.hayenga@arm.com * Copyright (c) 2003-2004 The Regents of The University of Michigan 39444SAndreas.Sandberg@ARM.com * All rights reserved. 49444SAndreas.Sandberg@ARM.com * 59444SAndreas.Sandberg@ARM.com * Redistribution and use in source and binary forms, with or without 69444SAndreas.Sandberg@ARM.com * modification, are permitted provided that the following conditions are 79444SAndreas.Sandberg@ARM.com * met: redistributions of source code must retain the above copyright 89444SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer; 99444SAndreas.Sandberg@ARM.com * redistributions in binary form must reproduce the above copyright 109444SAndreas.Sandberg@ARM.com * notice, this list of conditions and the following disclaimer in the 119444SAndreas.Sandberg@ARM.com * documentation and/or other materials provided with the distribution; 129444SAndreas.Sandberg@ARM.com * neither the name of the copyright holders nor the names of its 139444SAndreas.Sandberg@ARM.com * contributors may be used to endorse or promote products derived from 142329SN/A * this software without specific prior written permission. 151689SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271689SN/A * 281689SN/A * Authors: Gabe Black 291689SN/A * Ali Saidi 301689SN/A */ 311689SN/A 321689SN/A#include "arch/alpha/isa_traits.hh" 331689SN/A#include "arch/alpha/process.hh" 341689SN/A#include "base/loader/object_file.hh" 351689SN/A#include "base/loader/elf_object.hh" 361689SN/A#include "base/misc.hh" 371689SN/A#include "cpu/thread_context.hh" 381689SN/A#include "mem/page_table.hh" 392665Ssaidi@eecs.umich.edu#include "sim/process_impl.hh" 402665Ssaidi@eecs.umich.edu#include "sim/system.hh" 411689SN/A 421689SN/Ausing namespace AlphaISA; 439944Smatt.horsnell@ARM.comusing namespace std; 449944Smatt.horsnell@ARM.com 459944Smatt.horsnell@ARM.comAlphaLiveProcess::AlphaLiveProcess(LiveProcessParams *params, 468230Snate@binkert.org ObjectFile *objFile) 478230Snate@binkert.org : LiveProcess(params, objFile) 486658Snate@binkert.org{ 491717SN/A brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize(); 508230Snate@binkert.org brk_point = roundUp(brk_point, VMPageSize); 518232Snate@binkert.org 528232Snate@binkert.org // Set up stack. On Alpha, stack goes below text section. This 539527SMatt.Horsnell@arm.com // code should get moved to some architecture-specific spot. 546221Snate@binkert.org stack_base = objFile->textBase() - (409600+4096); 558793Sgblack@eecs.umich.edu 561060SN/A // Set up region for mmaps. Tru64 seems to start just above 0 and 578737Skoansin.tan@gmail.com // grow up from there. 588737Skoansin.tan@gmail.com mmap_start = mmap_end = 0x10000; 598737Skoansin.tan@gmail.com 605529Snate@binkert.org // Set pointer for next thread stack. Reserve 8M for main stack. 611060SN/A next_thread_stack_base = stack_base - (8 * 1024 * 1024); 625529Snate@binkert.org 634329Sktlim@umich.edu} 644329Sktlim@umich.edu 652292SN/Avoid 662292SN/AAlphaLiveProcess::argsInit(int intSize, int pageSize) 672292SN/A{ 682292SN/A objFile->loadSections(initVirtMem); 695529Snate@binkert.org 701060SN/A typedef M5_auxv_t<uint64_t> auxv_t; 7110172Sdam.sunwoo@arm.com std::vector<auxv_t> auxv; 7210172Sdam.sunwoo@arm.com 7310172Sdam.sunwoo@arm.com ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile); 7410172Sdam.sunwoo@arm.com if(elfObject) 7510172Sdam.sunwoo@arm.com { 769444SAndreas.Sandberg@ARM.com // modern glibc uses a bunch of auxiliary vectors to set up 779444SAndreas.Sandberg@ARM.com // TLS as well as do a bunch of other stuff 789444SAndreas.Sandberg@ARM.com // these vectors go on the bottom of the stack, below argc/argv/envp 799444SAndreas.Sandberg@ARM.com // pointers but above actual arg strings 809444SAndreas.Sandberg@ARM.com // I don't have all the ones glibc looks at here, but so far it doesn't 819444SAndreas.Sandberg@ARM.com // seem to be a problem. 829444SAndreas.Sandberg@ARM.com // check out _dl_aux_init() in glibc/elf/dl-support.c for details 839444SAndreas.Sandberg@ARM.com // --Lisa 849444SAndreas.Sandberg@ARM.com auxv.push_back(auxv_t(M5_AT_PAGESZ, AlphaISA::VMPageSize)); 859444SAndreas.Sandberg@ARM.com auxv.push_back(auxv_t(M5_AT_CLKTCK, 100)); 869444SAndreas.Sandberg@ARM.com auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable())); 879444SAndreas.Sandberg@ARM.com DPRINTF(Loader, "auxv at PHDR %08p\n", elfObject->programHeaderTable()); 889444SAndreas.Sandberg@ARM.com auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount())); 899444SAndreas.Sandberg@ARM.com auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint())); 909444SAndreas.Sandberg@ARM.com auxv.push_back(auxv_t(M5_AT_UID, uid())); 912292SN/A auxv.push_back(auxv_t(M5_AT_EUID, euid())); 922292SN/A auxv.push_back(auxv_t(M5_AT_GID, gid())); 932348SN/A auxv.push_back(auxv_t(M5_AT_EGID, egid())); 946221Snate@binkert.org 956221Snate@binkert.org } 962292SN/A 976221Snate@binkert.org // Calculate how much space we need for arg & env & auxv arrays. 982292SN/A int argv_array_size = intSize * (argv.size() + 1); 992292SN/A int envp_array_size = intSize * (envp.size() + 1); 1002292SN/A int auxv_array_size = intSize * 2 * (auxv.size() + 1); 1012292SN/A 1022292SN/A int arg_data_size = 0; 1032292SN/A for (int i = 0; i < argv.size(); ++i) { 1042292SN/A arg_data_size += argv[i].size() + 1; 1052292SN/A } 1061060SN/A int env_data_size = 0; 1071060SN/A for (int i = 0; i < envp.size(); ++i) { 1081062SN/A env_data_size += envp[i].size() + 1; 1091062SN/A } 1102292SN/A 1111062SN/A int space_needed = 1121062SN/A argv_array_size + 1138240Snate@binkert.org envp_array_size + 1141062SN/A auxv_array_size + 1151062SN/A arg_data_size + 1161062SN/A env_data_size; 1178240Snate@binkert.org 1181062SN/A if (space_needed < 32*1024) 1191062SN/A space_needed = 32*1024; 1202292SN/A 1218240Snate@binkert.org // set bottom of stack 1222292SN/A stack_min = stack_base - space_needed; 1232292SN/A // align it 1241062SN/A stack_min = roundDown(stack_min, pageSize); 1258240Snate@binkert.org stack_size = stack_base - stack_min; 1261062SN/A // map memory 1271062SN/A pTable->allocate(stack_min, roundUp(stack_size, pageSize)); 1281062SN/A 1298240Snate@binkert.org // map out initial stack contents 1301062SN/A Addr argv_array_base = stack_min + intSize; // room for argc 1311062SN/A Addr envp_array_base = argv_array_base + argv_array_size; 1322307SN/A Addr auxv_array_base = envp_array_base + envp_array_size; 1338240Snate@binkert.org Addr arg_data_base = auxv_array_base + auxv_array_size; 1342307SN/A Addr env_data_base = arg_data_base + arg_data_size; 1352307SN/A 1361062SN/A // write contents to stack 1378240Snate@binkert.org uint64_t argc = argv.size(); 1381062SN/A if (intSize == 8) 1391062SN/A argc = htog((uint64_t)argc); 1401062SN/A else if (intSize == 4) 1418240Snate@binkert.org argc = htog((uint32_t)argc); 1421062SN/A else 1431062SN/A panic("Unknown int size"); 1441062SN/A 1451062SN/A initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize); 1468240Snate@binkert.org 1471062SN/A copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem); 1481062SN/A copyStringArray(envp, envp_array_base, env_data_base, initVirtMem); 1491062SN/A 1508240Snate@binkert.org //Copy the aux stuff 1511062SN/A for(int x = 0; x < auxv.size(); x++) 1521062SN/A { 1531062SN/A initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize, 1541062SN/A (uint8_t*)&(auxv[x].a_type), intSize); 1551060SN/A initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize, 1561060SN/A (uint8_t*)&(auxv[x].a_val), intSize); 1572292SN/A } 1581060SN/A 1591060SN/A assert(NumArgumentRegs >= 2); 1601060SN/A 1611060SN/A ThreadContext *tc = system->getThreadContext(contextIds[0]); 1621060SN/A 1631060SN/A tc->setIntReg(ArgumentReg[0], argc); 1641060SN/A tc->setIntReg(ArgumentReg[1], argv_array_base); 1651060SN/A tc->setIntReg(StackPointerReg, stack_min); 1661060SN/A 1671060SN/A Addr prog_entry = objFile->entryPoint(); 1681060SN/A tc->setPC(prog_entry); 1691060SN/A tc->setNextPC(prog_entry + sizeof(MachInst)); 1701060SN/A 1711060SN/A#if THE_ISA != ALPHA_ISA //e.g. MIPS or Sparc 1722292SN/A tc->setNextNPC(prog_entry + (2 * sizeof(MachInst))); 1731060SN/A#endif 1741060SN/A 1751060SN/A 1761060SN/A} 1771060SN/A 1781060SN/Avoid 1791060SN/AAlphaLiveProcess::startup() 1801060SN/A{ 1811060SN/A if (checkpointRestored) 1822292SN/A return; 1831060SN/A 1841060SN/A Process::startup(); 1851060SN/A 1861060SN/A argsInit(MachineBytes, VMPageSize); 1871060SN/A 1881060SN/A ThreadContext *tc = system->getThreadContext(contextIds[0]); 1891060SN/A tc->setIntReg(GlobalPointerReg, objFile->globalPointer()); 1901060SN/A //Operate in user mode 1912292SN/A tc->setMiscRegNoEffect(IPR_ICM, 0x18); 1926221Snate@binkert.org //No super page mapping 1932292SN/A tc->setMiscRegNoEffect(IPR_MCSR, 0); 1942292SN/A //Set this to 0 for now, but it should be unique for each process 1952292SN/A tc->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57); 1962292SN/A} 1972307SN/A 1989444SAndreas.Sandberg@ARM.com