process.cc revision 11392:5967db4cff04
11689SN/A/* 29783Sandreas.hansson@arm.com * Copyright (c) 2014 Advanced Micro Devices, Inc. 37598Sminkyu.jeong@arm.com * Copyright (c) 2012 ARM Limited 47598Sminkyu.jeong@arm.com * All rights reserved 57598Sminkyu.jeong@arm.com * 67598Sminkyu.jeong@arm.com * The license below extends only to copyright in the software and shall 77598Sminkyu.jeong@arm.com * not be construed as granting a license to any other intellectual 87598Sminkyu.jeong@arm.com * property including but not limited to intellectual property relating 97598Sminkyu.jeong@arm.com * to a hardware implementation of the functionality of the software 107598Sminkyu.jeong@arm.com * licensed hereunder. You may use the software subject to the license 117598Sminkyu.jeong@arm.com * terms below provided that you ensure that this notice is replicated 127598Sminkyu.jeong@arm.com * unmodified and in its entirety in all distributions of the software, 137598Sminkyu.jeong@arm.com * modified or unmodified, in source code or in binary form. 142326SN/A * 151689SN/A * Copyright (c) 2001-2005 The Regents of The University of Michigan 161689SN/A * All rights reserved. 171689SN/A * 181689SN/A * Redistribution and use in source and binary forms, with or without 191689SN/A * modification, are permitted provided that the following conditions are 201689SN/A * met: redistributions of source code must retain the above copyright 211689SN/A * notice, this list of conditions and the following disclaimer; 221689SN/A * redistributions in binary form must reproduce the above copyright 231689SN/A * notice, this list of conditions and the following disclaimer in the 241689SN/A * documentation and/or other materials provided with the distribution; 251689SN/A * neither the name of the copyright holders nor the names of its 261689SN/A * contributors may be used to endorse or promote products derived from 271689SN/A * this software without specific prior written permission. 281689SN/A * 291689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 301689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 311689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 321689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 331689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 341689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 351689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 361689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 371689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 381689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 392665Ssaidi@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402665Ssaidi@eecs.umich.edu * 411689SN/A * Authors: Nathan Binkert 421689SN/A * Steve Reinhardt 439944Smatt.horsnell@ARM.com * Ali Saidi 449944Smatt.horsnell@ARM.com */ 459944Smatt.horsnell@ARM.com 461060SN/A#include <fcntl.h> 471060SN/A#include <unistd.h> 481689SN/A 491060SN/A#include <cstdio> 501060SN/A#include <map> 511060SN/A#include <string> 528230Snate@binkert.org 536658Snate@binkert.org#include "base/loader/object_file.hh" 548887Sgeoffrey.blake@arm.com#include "base/loader/symtab.hh" 552292SN/A#include "base/intmath.hh" 561717SN/A#include "base/statistics.hh" 578229Snate@binkert.org#include "config/the_isa.hh" 588232Snate@binkert.org#include "cpu/thread_context.hh" 599444SAndreas.Sandberg@ARM.com#include "mem/page_table.hh" 608232Snate@binkert.org#include "mem/multi_level_page_table.hh" 619527SMatt.Horsnell@arm.com#include "mem/se_translating_port_proxy.hh" 625529Snate@binkert.org#include "params/LiveProcess.hh" 631060SN/A#include "params/Process.hh" 646221Snate@binkert.org#include "sim/debug.hh" 656221Snate@binkert.org#include "sim/process.hh" 661681SN/A#include "sim/process_impl.hh" 675529Snate@binkert.org#include "sim/stats.hh" 682873Sktlim@umich.edu#include "sim/syscall_emul.hh" 694329Sktlim@umich.edu#include "sim/system.hh" 704329Sktlim@umich.edu 714329Sktlim@umich.edu#if THE_ISA == ALPHA_ISA 722292SN/A#include "arch/alpha/linux/process.hh" 732292SN/A#include "arch/alpha/tru64/process.hh" 742292SN/A#elif THE_ISA == SPARC_ISA 752292SN/A#include "arch/sparc/linux/process.hh" 762820Sktlim@umich.edu#include "arch/sparc/solaris/process.hh" 772292SN/A#elif THE_ISA == MIPS_ISA 782820Sktlim@umich.edu#include "arch/mips/linux/process.hh" 792820Sktlim@umich.edu#elif THE_ISA == ARM_ISA 809444SAndreas.Sandberg@ARM.com#include "arch/arm/linux/process.hh" 811060SN/A#include "arch/arm/freebsd/process.hh" 8210172Sdam.sunwoo@arm.com#elif THE_ISA == X86_ISA 8310172Sdam.sunwoo@arm.com#include "arch/x86/linux/process.hh" 8410172Sdam.sunwoo@arm.com#elif THE_ISA == POWER_ISA 8510172Sdam.sunwoo@arm.com#include "arch/power/linux/process.hh" 8610172Sdam.sunwoo@arm.com#else 8710172Sdam.sunwoo@arm.com#error "THE_ISA not set" 8810172Sdam.sunwoo@arm.com#endif 8910172Sdam.sunwoo@arm.com 9010172Sdam.sunwoo@arm.com 9110172Sdam.sunwoo@arm.comusing namespace std; 9210172Sdam.sunwoo@arm.comusing namespace TheISA; 9310172Sdam.sunwoo@arm.com 9410172Sdam.sunwoo@arm.com// current number of allocated processes 952292SN/Aint num_processes = 0; 962292SN/A 972292SN/Atemplate<class IntType> 981060SN/A 991060SN/AAuxVector<IntType>::AuxVector(IntType type, IntType val) 1001060SN/A{ 1011060SN/A a_type = TheISA::htog(type); 1021060SN/A a_val = TheISA::htog(val); 1031060SN/A} 1041681SN/A 1056221Snate@binkert.orgtemplate struct AuxVector<uint32_t>; 1066221Snate@binkert.orgtemplate struct AuxVector<uint64_t>; 1076221Snate@binkert.org 1086221Snate@binkert.orgstatic int 1092292SN/AopenFile(const string& filename, int flags, mode_t mode) 1102292SN/A{ 1112820Sktlim@umich.edu int sim_fd = open(filename.c_str(), flags, mode); 1122820Sktlim@umich.edu if (sim_fd != -1) 1132292SN/A return sim_fd; 1142292SN/A fatal("Unable to open %s with mode %O", filename, mode); 1152820Sktlim@umich.edu} 1162820Sktlim@umich.edu 1172292SN/Astatic int 1182292SN/AopenInputFile(const string &filename) 1192292SN/A{ 1202292SN/A return openFile(filename, O_RDONLY, 0); 1212292SN/A} 1222292SN/A 1232292SN/Astatic int 1242292SN/AopenOutputFile(const string &filename) 1251060SN/A{ 1261060SN/A return openFile(filename, O_WRONLY | O_CREAT | O_TRUNC, 0664); 1271681SN/A} 1281062SN/A 12910023Smatt.horsnell@ARM.comProcess::Process(ProcessParams * params) 13010023Smatt.horsnell@ARM.com : SimObject(params), system(params->system), 13110023Smatt.horsnell@ARM.com brk_point(0), stack_base(0), stack_size(0), stack_min(0), 13210023Smatt.horsnell@ARM.com max_stack_size(params->max_stack_size), 13310023Smatt.horsnell@ARM.com next_thread_stack_base(0), 13410023Smatt.horsnell@ARM.com M5_pid(system->allocatePID()), 13510023Smatt.horsnell@ARM.com useArchPT(params->useArchPT), 13610023Smatt.horsnell@ARM.com kvmInSE(params->kvmInSE), 1372292SN/A pTable(useArchPT ? 1381062SN/A static_cast<PageTableBase *>(new ArchPageTable(name(), M5_pid, system)) : 1392301SN/A static_cast<PageTableBase *>(new FuncPageTable(name(), M5_pid)) ), 1402301SN/A initVirtMem(system->getSystemPort(), this, 1411062SN/A SETranslatingPortProxy::Always), 1422727Sktlim@umich.edu fd_array(make_shared<array<FDEntry, NUM_FDS>>()), 1431062SN/A imap {{"", -1}, 1441062SN/A {"cin", STDIN_FILENO}, 1451062SN/A {"stdin", STDIN_FILENO}}, 1461062SN/A oemap{{"", -1}, 1471062SN/A {"cout", STDOUT_FILENO}, 1481062SN/A {"stdout", STDOUT_FILENO}, 1491062SN/A {"cerr", STDERR_FILENO}, 1501062SN/A {"stderr", STDERR_FILENO}} 1511062SN/A{ 1521062SN/A int sim_fd; 1531062SN/A std::map<string,int>::iterator it; 1541062SN/A 1551062SN/A // Search through the input options and set fd if match is found; 1561062SN/A // otherwise, open an input file and seek to location. 1571062SN/A FDEntry *fde_stdin = getFDEntry(STDIN_FILENO); 1581062SN/A if ((it = imap.find(params->input)) != imap.end()) 1591062SN/A sim_fd = it->second; 1601062SN/A else 1611062SN/A sim_fd = openInputFile(params->input); 1621062SN/A fde_stdin->set(sim_fd, params->input, O_RDONLY, -1, false); 1631062SN/A 1641062SN/A // Search through the output/error options and set fd if match is found; 1651062SN/A // otherwise, open an output file and seek to location. 1661062SN/A FDEntry *fde_stdout = getFDEntry(STDOUT_FILENO); 1671062SN/A if ((it = oemap.find(params->output)) != oemap.end()) 1681062SN/A sim_fd = it->second; 1691062SN/A else 1701062SN/A sim_fd = openOutputFile(params->output); 1711062SN/A fde_stdout->set(sim_fd, params->output, O_WRONLY | O_CREAT | O_TRUNC, 1721062SN/A 0664, false); 1731062SN/A 1741062SN/A FDEntry *fde_stderr = getFDEntry(STDERR_FILENO); 1751062SN/A if (params->output == params->errout) 1761062SN/A // Reuse the same file descriptor if these match. 1771062SN/A sim_fd = fde_stdout->fd; 1781062SN/A else if ((it = oemap.find(params->errout)) != oemap.end()) 1791062SN/A sim_fd = it->second; 1801062SN/A else 1811062SN/A sim_fd = openOutputFile(params->errout); 1821062SN/A fde_stderr->set(sim_fd, params->errout, O_WRONLY | O_CREAT | O_TRUNC, 1831062SN/A 0664, false); 1842292SN/A 1852292SN/A mmap_end = 0; 1862292SN/A nxm_start = nxm_end = 0; 1872292SN/A // other parameters will be initialized when the program is loaded 1881062SN/A} 1891062SN/A 1901062SN/A 1911062SN/Avoid 1921062SN/AProcess::regStats() 1931062SN/A{ 1941062SN/A using namespace Stats; 1952292SN/A 1962292SN/A num_syscalls 1972292SN/A .name(name() + ".num_syscalls") 1982292SN/A .desc("Number of system calls") 1992292SN/A ; 2002292SN/A} 2012292SN/A 2022292SN/Avoid 2032292SN/AProcess::inheritFDArray(Process *p) 2042292SN/A{ 2052301SN/A fd_array = p->fd_array; 2062727Sktlim@umich.edu} 2072353SN/A 2082727Sktlim@umich.eduThreadContext * 2092727Sktlim@umich.eduProcess::findFreeContext() 2102727Sktlim@umich.edu{ 2116221Snate@binkert.org for (int id : contextIds) { 2122353SN/A ThreadContext *tc = system->getThreadContext(id); 2132727Sktlim@umich.edu if (tc->status() == ThreadContext::Halted) 2142727Sktlim@umich.edu return tc; 2152727Sktlim@umich.edu } 2162727Sktlim@umich.edu return NULL; 2172353SN/A} 2182727Sktlim@umich.edu 2192727Sktlim@umich.eduvoid 2202727Sktlim@umich.eduProcess::initState() 2216221Snate@binkert.org{ 2228240Snate@binkert.org if (contextIds.empty()) 2232301SN/A fatal("Process %s is not associated with any HW contexts!\n", name()); 2242727Sktlim@umich.edu 2252301SN/A // first thread context for this process... initialize & enable 2262727Sktlim@umich.edu ThreadContext *tc = system->getThreadContext(contextIds[0]); 2276221Snate@binkert.org 2288240Snate@binkert.org // mark this context as active so it will start ticking. 2292301SN/A tc->activate(); 2302727Sktlim@umich.edu 2312301SN/A pTable->initState(tc); 2322727Sktlim@umich.edu} 2336221Snate@binkert.org 2348240Snate@binkert.orgDrainState 2352301SN/AProcess::drain() 2362727Sktlim@umich.edu{ 2372301SN/A findFileOffsets(); 2382727Sktlim@umich.edu return DrainState::Drained; 2396221Snate@binkert.org} 2408240Snate@binkert.org 2412301SN/Aint 2422727Sktlim@umich.eduProcess::allocFD(int sim_fd, const string& filename, int flags, int mode, 2432301SN/A bool pipe) 2442301SN/A{ 2458240Snate@binkert.org for (int free_fd = 0; free_fd < fd_array->size(); free_fd++) { 2462301SN/A FDEntry *fde = getFDEntry(free_fd); 2472727Sktlim@umich.edu if (fde->isFree()) { 2482727Sktlim@umich.edu fde->set(sim_fd, filename, flags, mode, pipe); 2492727Sktlim@umich.edu return free_fd; 2502727Sktlim@umich.edu } 2518240Snate@binkert.org } 2522727Sktlim@umich.edu 2532727Sktlim@umich.edu fatal("Out of target file descriptors"); 2542727Sktlim@umich.edu} 2552727Sktlim@umich.edu 2562301SN/Avoid 2572301SN/AProcess::resetFDEntry(int tgt_fd) 2586221Snate@binkert.org{ 2598240Snate@binkert.org FDEntry *fde = getFDEntry(tgt_fd); 2602301SN/A assert(fde->fd > -1); 2612727Sktlim@umich.edu 2622301SN/A fde->reset(); 2632326SN/A} 2646221Snate@binkert.org 2658240Snate@binkert.orgint 2662301SN/AProcess::getSimFD(int tgt_fd) 2672727Sktlim@umich.edu{ 2682301SN/A FDEntry *entry = getFDEntry(tgt_fd); 2692326SN/A return entry ? entry->fd : -1; 2706221Snate@binkert.org} 2718240Snate@binkert.org 2722301SN/AFDEntry * 2732727Sktlim@umich.eduProcess::getFDEntry(int tgt_fd) 2742301SN/A{ 2752326SN/A assert(0 <= tgt_fd && tgt_fd < fd_array->size()); 2766221Snate@binkert.org return &(*fd_array)[tgt_fd]; 2778240Snate@binkert.org} 2782301SN/A 2792727Sktlim@umich.eduint 2802301SN/AProcess::getTgtFD(int sim_fd) 2812326SN/A{ 2826221Snate@binkert.org for (int index = 0; index < fd_array->size(); index++) 2838240Snate@binkert.org if ((*fd_array)[index].fd == sim_fd) 2842301SN/A return index; 2852727Sktlim@umich.edu return -1; 2862301SN/A} 2872326SN/A 2888240Snate@binkert.orgvoid 2892301SN/AProcess::allocateMem(Addr vaddr, int64_t size, bool clobber) 2902727Sktlim@umich.edu{ 2912301SN/A int npages = divCeil(size, (int64_t)PageBytes); 2922326SN/A Addr paddr = system->allocPhysPages(npages); 2932301SN/A pTable->map(vaddr, paddr, size, 2942326SN/A clobber ? PageTableBase::Clobber : PageTableBase::Zero); 2958240Snate@binkert.org} 2962301SN/A 2972727Sktlim@umich.edubool 2982301SN/AProcess::fixupStackFault(Addr vaddr) 2992326SN/A{ 3002301SN/A // Check if this is already on the stack and there's just no page there 3012326SN/A // yet. 3028240Snate@binkert.org if (vaddr >= stack_min && vaddr < stack_base) { 3032301SN/A allocateMem(roundDown(vaddr, PageBytes), PageBytes); 3042727Sktlim@umich.edu return true; 3052326SN/A } 3061062SN/A 3071062SN/A // We've accessed the next page of the stack, so extend it to include 3081681SN/A // this address. 3091060SN/A if (vaddr < stack_min && vaddr >= stack_base - max_stack_size) { 3109427SAndreas.Sandberg@ARM.com while (vaddr < stack_min) { 3111060SN/A stack_min -= TheISA::PageBytes; 3126221Snate@binkert.org if (stack_base - stack_min > max_stack_size) 3132292SN/A fatal("Maximum stack size exceeded\n"); 3142292SN/A allocateMem(stack_min, TheISA::PageBytes); 3152292SN/A inform("Increasing stack size by one page."); 3162292SN/A }; 3172292SN/A return true; 3182292SN/A } 3192292SN/A return false; 3202292SN/A} 3212292SN/A 3228887Sgeoffrey.blake@arm.comvoid 3238733Sgeoffrey.blake@arm.comProcess::fixFileOffsets() 3248850Sandreas.hansson@arm.com{ 3258887Sgeoffrey.blake@arm.com auto seek = [] (FDEntry *fde) 3268733Sgeoffrey.blake@arm.com { 3272733Sktlim@umich.edu if (lseek(fde->fd, fde->fileOffset, SEEK_SET) < 0) 3281060SN/A fatal("Unable to see to location in %s", fde->filename); 3291060SN/A }; 3301681SN/A 3311060SN/A std::map<string,int>::iterator it; 3322292SN/A 3331060SN/A // Search through the input options and set fd if match is found; 3341060SN/A // otherwise, open an input file and seek to location. 3351060SN/A FDEntry *fde_stdin = getFDEntry(STDIN_FILENO); 3361060SN/A if ((it = imap.find(fde_stdin->filename)) != imap.end()) { 3371060SN/A fde_stdin->fd = it->second; 3381060SN/A } else { 3391060SN/A fde_stdin->fd = openInputFile(fde_stdin->filename); 3401060SN/A seek(fde_stdin); 3411060SN/A } 3422292SN/A 3432292SN/A // Search through the output/error options and set fd if match is found; 3441060SN/A // otherwise, open an output file and seek to location. 3451060SN/A FDEntry *fde_stdout = getFDEntry(STDOUT_FILENO); 3461060SN/A if ((it = oemap.find(fde_stdout->filename)) != oemap.end()) { 3471060SN/A fde_stdout->fd = it->second; 3481681SN/A } else { 3491060SN/A fde_stdout->fd = openOutputFile(fde_stdout->filename); 3502292SN/A seek(fde_stdout); 3511060SN/A } 3521060SN/A 3531060SN/A FDEntry *fde_stderr = getFDEntry(STDERR_FILENO); 3541060SN/A if (fde_stdout->filename == fde_stderr->filename) { 3551060SN/A // Reuse the same file descriptor if these match. 3561060SN/A fde_stderr->fd = fde_stdout->fd; 3571060SN/A } else if ((it = oemap.find(fde_stderr->filename)) != oemap.end()) { 3581681SN/A fde_stderr->fd = it->second; 3591060SN/A } else { 3602292SN/A fde_stderr->fd = openOutputFile(fde_stderr->filename); 3611060SN/A seek(fde_stderr); 3621060SN/A } 3631060SN/A 3641060SN/A for (int tgt_fd = 3; tgt_fd < fd_array->size(); tgt_fd++) { 3651060SN/A FDEntry *fde = getFDEntry(tgt_fd); 3661060SN/A if (fde->fd == -1) 3671060SN/A continue; 3681681SN/A 3691060SN/A if (fde->isPipe) { 3706221Snate@binkert.org if (fde->filename == "PIPE-WRITE") 3711060SN/A continue; 3722292SN/A assert(fde->filename == "PIPE-READ"); 3732292SN/A 3742292SN/A int fds[2]; 3752292SN/A if (pipe(fds) < 0) 3761060SN/A fatal("Unable to create new pipe"); 3771060SN/A 3781681SN/A fde->fd = fds[0]; 3791060SN/A 3802292SN/A FDEntry *fde_write = getFDEntry(fde->readPipeSource); 3811060SN/A assert(fde_write->filename == "PIPE-WRITE"); 3822292SN/A fde_write->fd = fds[1]; 3831060SN/A } else { 3841060SN/A fde->fd = openFile(fde->filename.c_str(), fde->flags, fde->mode); 3852307SN/A seek(fde); 3862863Sktlim@umich.edu } 3879444SAndreas.Sandberg@ARM.com } 3882307SN/A} 3899444SAndreas.Sandberg@ARM.com 3909444SAndreas.Sandberg@ARM.comvoid 3919444SAndreas.Sandberg@ARM.comProcess::findFileOffsets() 3929444SAndreas.Sandberg@ARM.com{ 3939444SAndreas.Sandberg@ARM.com for (auto& fde : *fd_array) { 3949444SAndreas.Sandberg@ARM.com if (fde.fd != -1) 3959444SAndreas.Sandberg@ARM.com fde.fileOffset = lseek(fde.fd, 0, SEEK_CUR); 3969444SAndreas.Sandberg@ARM.com } 3979444SAndreas.Sandberg@ARM.com} 3989444SAndreas.Sandberg@ARM.com 3999444SAndreas.Sandberg@ARM.comvoid 4009444SAndreas.Sandberg@ARM.comProcess::setReadPipeSource(int read_pipe_fd, int source_fd) 4019444SAndreas.Sandberg@ARM.com{ 4029783Sandreas.hansson@arm.com FDEntry *fde = getFDEntry(read_pipe_fd); 4039783Sandreas.hansson@arm.com assert(source_fd >= -1); 4049783Sandreas.hansson@arm.com fde->readPipeSource = source_fd; 4059783Sandreas.hansson@arm.com} 4069783Sandreas.hansson@arm.com 4079783Sandreas.hansson@arm.comvoid 4089783Sandreas.hansson@arm.comProcess::serialize(CheckpointOut &cp) const 4099783Sandreas.hansson@arm.com{ 4109444SAndreas.Sandberg@ARM.com SERIALIZE_SCALAR(brk_point); 4111681SN/A SERIALIZE_SCALAR(stack_base); 4121681SN/A SERIALIZE_SCALAR(stack_size); 4132316SN/A SERIALIZE_SCALAR(stack_min); 4141681SN/A SERIALIZE_SCALAR(next_thread_stack_base); 4159444SAndreas.Sandberg@ARM.com SERIALIZE_SCALAR(mmap_end); 4162843Sktlim@umich.edu SERIALIZE_SCALAR(nxm_start); 4179444SAndreas.Sandberg@ARM.com SERIALIZE_SCALAR(nxm_end); 4182843Sktlim@umich.edu pTable->serialize(cp); 4199444SAndreas.Sandberg@ARM.com for (int x = 0; x < fd_array->size(); x++) { 4209444SAndreas.Sandberg@ARM.com (*fd_array)[x].serializeSection(cp, csprintf("FDEntry%d", x)); 4211681SN/A } 4221681SN/A SERIALIZE_SCALAR(M5_pid); 4232307SN/A 4241681SN/A} 4252307SN/A 4261060SN/Avoid 4272348SN/AProcess::unserialize(CheckpointIn &cp) 4282307SN/A{ 4292307SN/A UNSERIALIZE_SCALAR(brk_point); 4302307SN/A UNSERIALIZE_SCALAR(stack_base); 4311060SN/A UNSERIALIZE_SCALAR(stack_size); 4322307SN/A UNSERIALIZE_SCALAR(stack_min); 4332307SN/A UNSERIALIZE_SCALAR(next_thread_stack_base); 4349444SAndreas.Sandberg@ARM.com UNSERIALIZE_SCALAR(mmap_end); 4351060SN/A UNSERIALIZE_SCALAR(nxm_start); 4369427SAndreas.Sandberg@ARM.com UNSERIALIZE_SCALAR(nxm_end); 4372307SN/A pTable->unserialize(cp); 4381060SN/A for (int x = 0; x < fd_array->size(); x++) { 4396221Snate@binkert.org FDEntry *fde = getFDEntry(x); 4406221Snate@binkert.org fde->unserializeSection(cp, csprintf("FDEntry%d", x)); 4416221Snate@binkert.org } 4426221Snate@binkert.org fixFileOffsets(); 4432307SN/A UNSERIALIZE_OPT_SCALAR(M5_pid); 4441060SN/A // The above returns a bool so that you could do something if you don't 4452307SN/A // find the param in the checkpoint if you wanted to, like set a default 4462307SN/A // but in this case we'll just stick with the instantiated value if not 4472873Sktlim@umich.edu // found. 4482307SN/A} 4491060SN/A 4501060SN/A 4511060SN/Abool 4521681SN/AProcess::map(Addr vaddr, Addr paddr, int size, bool cacheable) 4531060SN/A{ 4546221Snate@binkert.org pTable->map(vaddr, paddr, size, 4552107SN/A cacheable ? PageTableBase::Zero : PageTableBase::Uncacheable); 4566221Snate@binkert.org return true; 4572107SN/A} 4582292SN/A 4592292SN/A 4602107SN/A//////////////////////////////////////////////////////////////////////// 4612292SN/A// 4622326SN/A// LiveProcess member definitions 4632292SN/A// 4642107SN/A//////////////////////////////////////////////////////////////////////// 4652292SN/A 4662935Sksewell@umich.edu 4674632Sgblack@eecs.umich.eduLiveProcess::LiveProcess(LiveProcessParams *params, ObjectFile *_objFile) 4682935Sksewell@umich.edu : Process(params), objFile(_objFile), 4692292SN/A argv(params->cmd), envp(params->env), cwd(params->cwd), 4702292SN/A executable(params->executable), 4712292SN/A __uid(params->uid), __euid(params->euid), 4722292SN/A __gid(params->gid), __egid(params->egid), 4732292SN/A __pid(params->pid), __ppid(params->ppid), 4742107SN/A drivers(params->drivers) 4752292SN/A{ 4762107SN/A 4772292SN/A // load up symbols, if any... these may be used for debugging or 4782292SN/A // profiling. 4792107SN/A if (!debugSymbolTable) { 4802702Sktlim@umich.edu debugSymbolTable = new SymbolTable(); 4812107SN/A if (!objFile->loadGlobalSymbols(debugSymbolTable) || 4822107SN/A !objFile->loadLocalSymbols(debugSymbolTable) || 4832107SN/A !objFile->loadWeakSymbols(debugSymbolTable)) { 4842107SN/A // didn't load any symbols 4856221Snate@binkert.org delete debugSymbolTable; 4862292SN/A debugSymbolTable = NULL; 4877720Sgblack@eecs.umich.edu } 4887720Sgblack@eecs.umich.edu } 4892292SN/A} 49010231Ssteve.reinhardt@amd.com 4917852SMatt.Horsnell@arm.comvoid 4927852SMatt.Horsnell@arm.comLiveProcess::syscall(int64_t callnum, ThreadContext *tc) 4937852SMatt.Horsnell@arm.com{ 4947852SMatt.Horsnell@arm.com num_syscalls++; 4952935Sksewell@umich.edu 4967852SMatt.Horsnell@arm.com SyscallDesc *desc = getDesc(callnum); 4977852SMatt.Horsnell@arm.com if (desc == NULL) 4982292SN/A fatal("Syscall %d out of range", callnum); 4997852SMatt.Horsnell@arm.com 5007852SMatt.Horsnell@arm.com desc->doSyscall(callnum, this, tc); 5017852SMatt.Horsnell@arm.com} 5022292SN/A 5037852SMatt.Horsnell@arm.comIntReg 5047852SMatt.Horsnell@arm.comLiveProcess::getSyscallArg(ThreadContext *tc, int &i, int width) 5057852SMatt.Horsnell@arm.com{ 5062292SN/A return getSyscallArg(tc, i); 5072292SN/A} 5082292SN/A 5092292SN/A 5106221Snate@binkert.orgEmulatedDriver * 5112292SN/ALiveProcess::findDriver(std::string filename) 5128513SGiacomo.Gabrielli@arm.com{ 5138513SGiacomo.Gabrielli@arm.com for (EmulatedDriver *d : drivers) { 5148513SGiacomo.Gabrielli@arm.com if (d->match(filename)) 5158513SGiacomo.Gabrielli@arm.com return d; 5168513SGiacomo.Gabrielli@arm.com } 5178513SGiacomo.Gabrielli@arm.com 5188513SGiacomo.Gabrielli@arm.com return NULL; 5198513SGiacomo.Gabrielli@arm.com} 52010231Ssteve.reinhardt@amd.com 5218513SGiacomo.Gabrielli@arm.comvoid 5228513SGiacomo.Gabrielli@arm.comLiveProcess::updateBias() 5232292SN/A{ 5247852SMatt.Horsnell@arm.com ObjectFile *interp = objFile->getInterpreter(); 5258513SGiacomo.Gabrielli@arm.com 5268137SAli.Saidi@ARM.com if (!interp || !interp->relocatable()) 5272292SN/A return; 5288513SGiacomo.Gabrielli@arm.com 5298513SGiacomo.Gabrielli@arm.com // Determine how large the interpreters footprint will be in the process 5302292SN/A // address space. 5317852SMatt.Horsnell@arm.com Addr interp_mapsize = roundUp(interp->mapSize(), TheISA::PageBytes); 5327852SMatt.Horsnell@arm.com 5332292SN/A // We are allocating the memory area; set the bias to the lowest address 5342292SN/A // in the allocated memory region. 5352292SN/A Addr ld_bias = mmapGrowsDown() ? mmap_end - interp_mapsize : mmap_end; 5362292SN/A 5376221Snate@binkert.org // Adjust the process mmap area to give the interpreter room; the real 5382292SN/A // execve system call would just invoke the kernel's internal mmap 5392292SN/A // functions to make these adjustments. 5407720Sgblack@eecs.umich.edu mmap_end = mmapGrowsDown() ? ld_bias : mmap_end + interp_mapsize; 54110231Ssteve.reinhardt@amd.com 5427852SMatt.Horsnell@arm.com interp->updateBias(ld_bias); 5437852SMatt.Horsnell@arm.com} 5442292SN/A 5457852SMatt.Horsnell@arm.com 5467852SMatt.Horsnell@arm.comObjectFile * 5478137SAli.Saidi@ARM.comLiveProcess::getInterpreter() 5482292SN/A{ 5497852SMatt.Horsnell@arm.com return objFile->getInterpreter(); 5507852SMatt.Horsnell@arm.com} 5512292SN/A 5527852SMatt.Horsnell@arm.com 5532292SN/AAddr 5547852SMatt.Horsnell@arm.comLiveProcess::getBias() 5557852SMatt.Horsnell@arm.com{ 5562292SN/A ObjectFile *interp = getInterpreter(); 5572292SN/A 5582292SN/A return interp ? interp->bias() : objFile->bias(); 5592292SN/A} 5606221Snate@binkert.org 5612292SN/A 5622292SN/AAddr 5632292SN/ALiveProcess::getStartPC() 5642292SN/A{ 5652292SN/A ObjectFile *interp = getInterpreter(); 5662292SN/A 5672292SN/A return interp ? interp->entryPoint() : objFile->entryPoint(); 5682292SN/A} 5692292SN/A 5702292SN/A 5712292SN/ALiveProcess * 5722292SN/ALiveProcess::create(LiveProcessParams * params) 5732292SN/A{ 5742292SN/A LiveProcess *process = NULL; 5752292SN/A 5762292SN/A // If not specified, set the executable parameter equal to the 5772292SN/A // simulated system's zeroth command line parameter 5782292SN/A if (params->executable == "") { 5796221Snate@binkert.org params->executable = params->cmd[0]; 5802292SN/A } 5812292SN/A 5822292SN/A ObjectFile *objFile = createObjectFile(params->executable); 5832292SN/A if (objFile == NULL) { 5842292SN/A fatal("Can't load object file %s", params->executable); 5852292SN/A } 5862292SN/A 5872292SN/A#if THE_ISA == ALPHA_ISA 5882292SN/A if (objFile->getArch() != ObjectFile::Alpha) 5892292SN/A fatal("Object file architecture does not match compiled ISA (Alpha)."); 5902292SN/A 5912292SN/A switch (objFile->getOpSys()) { 5922292SN/A case ObjectFile::Tru64: 5932292SN/A process = new AlphaTru64Process(params, objFile); 5942292SN/A break; 5952292SN/A 5962292SN/A case ObjectFile::UnknownOpSys: 5971060SN/A warn("Unknown operating system; assuming Linux."); 5981681SN/A // fall through 5991060SN/A case ObjectFile::Linux: 6001060SN/A process = new AlphaLinuxProcess(params, objFile); 6012292SN/A break; 6022292SN/A 6032292SN/A default: 6042292SN/A fatal("Unknown/unsupported operating system."); 6052292SN/A } 6062292SN/A#elif THE_ISA == SPARC_ISA 6071681SN/A if (objFile->getArch() != ObjectFile::SPARC64 && 6081681SN/A objFile->getArch() != ObjectFile::SPARC32) 6091060SN/A fatal("Object file architecture does not match compiled ISA (SPARC)."); 6102292SN/A switch (objFile->getOpSys()) { 6111060SN/A case ObjectFile::UnknownOpSys: 6122292SN/A warn("Unknown operating system; assuming Linux."); 6132292SN/A // fall through 6141060SN/A case ObjectFile::Linux: 6152292SN/A if (objFile->getArch() == ObjectFile::SPARC64) { 6162292SN/A process = new Sparc64LinuxProcess(params, objFile); 6172292SN/A } else { 6182292SN/A process = new Sparc32LinuxProcess(params, objFile); 6193221Sktlim@umich.edu } 6203221Sktlim@umich.edu break; 6213221Sktlim@umich.edu 6223221Sktlim@umich.edu 6233221Sktlim@umich.edu case ObjectFile::Solaris: 6242292SN/A process = new SparcSolarisProcess(params, objFile); 6252292SN/A break; 6262292SN/A 6272292SN/A default: 6282326SN/A fatal("Unknown/unsupported operating system."); 6292292SN/A } 6302292SN/A#elif THE_ISA == X86_ISA 6312820Sktlim@umich.edu if (objFile->getArch() != ObjectFile::X86_64 && 6322292SN/A objFile->getArch() != ObjectFile::I386) 6332292SN/A fatal("Object file architecture does not match compiled ISA (x86)."); 6342292SN/A switch (objFile->getOpSys()) { 6352292SN/A case ObjectFile::UnknownOpSys: 6362353SN/A warn("Unknown operating system; assuming Linux."); 6372292SN/A // fall through 6382292SN/A case ObjectFile::Linux: 6392353SN/A if (objFile->getArch() == ObjectFile::X86_64) { 6402353SN/A process = new X86_64LinuxProcess(params, objFile); 6412292SN/A } else { 6422292SN/A process = new I386LinuxProcess(params, objFile); 6432292SN/A } 6442292SN/A break; 6452292SN/A 6462292SN/A default: 6472292SN/A fatal("Unknown/unsupported operating system."); 6482292SN/A } 6492292SN/A#elif THE_ISA == MIPS_ISA 6502292SN/A if (objFile->getArch() != ObjectFile::Mips) 6512292SN/A fatal("Object file architecture does not match compiled ISA (MIPS)."); 6522292SN/A switch (objFile->getOpSys()) { 6532731Sktlim@umich.edu case ObjectFile::UnknownOpSys: 6542292SN/A warn("Unknown operating system; assuming Linux."); 6552292SN/A // fall through 6562292SN/A case ObjectFile::Linux: 6572292SN/A process = new MipsLinuxProcess(params, objFile); 6582292SN/A break; 6592292SN/A 6602292SN/A default: 6612292SN/A fatal("Unknown/unsupported operating system."); 6626221Snate@binkert.org } 6632292SN/A#elif THE_ISA == ARM_ISA 6642292SN/A ObjectFile::Arch arch = objFile->getArch(); 6652292SN/A if (arch != ObjectFile::Arm && arch != ObjectFile::Thumb && 6662292SN/A arch != ObjectFile::Arm64) 6672292SN/A fatal("Object file architecture does not match compiled ISA (ARM)."); 6682292SN/A switch (objFile->getOpSys()) { 6692292SN/A case ObjectFile::UnknownOpSys: 6702292SN/A warn("Unknown operating system; assuming Linux."); 6719937SFaissal.Sleiman@arm.com // fall through 6722292SN/A case ObjectFile::Linux: 6737720Sgblack@eecs.umich.edu if (arch == ObjectFile::Arm64) { 6742292SN/A process = new ArmLinuxProcess64(params, objFile, 6752292SN/A objFile->getArch()); 6762292SN/A } else { 6772292SN/A process = new ArmLinuxProcess32(params, objFile, 6782292SN/A objFile->getArch()); 6792292SN/A } 6802292SN/A break; 6812292SN/A case ObjectFile::FreeBSD: 6822292SN/A if (arch == ObjectFile::Arm64) { 6832292SN/A process = new ArmFreebsdProcess64(params, objFile, 6842292SN/A objFile->getArch()); 6852292SN/A } else { 6862292SN/A process = new ArmFreebsdProcess32(params, objFile, 6872292SN/A objFile->getArch()); 6886221Snate@binkert.org } 6896221Snate@binkert.org break; 6902292SN/A case ObjectFile::LinuxArmOABI: 6913867Sbinkertn@umich.edu fatal("M5 does not support ARM OABI binaries. Please recompile with an" 6926221Snate@binkert.org " EABI compiler."); 6933867Sbinkertn@umich.edu default: 6942292SN/A fatal("Unknown/unsupported operating system."); 6952292SN/A } 6962292SN/A#elif THE_ISA == POWER_ISA 6972292SN/A if (objFile->getArch() != ObjectFile::Power) 6982292SN/A fatal("Object file architecture does not match compiled ISA (Power)."); 6992292SN/A switch (objFile->getOpSys()) { 7002292SN/A case ObjectFile::UnknownOpSys: 7012292SN/A warn("Unknown operating system; assuming Linux."); 7022292SN/A // fall through 7032292SN/A case ObjectFile::Linux: 7042292SN/A process = new PowerLinuxProcess(params, objFile); 7056221Snate@binkert.org break; 7066221Snate@binkert.org 7072292SN/A default: 7083867Sbinkertn@umich.edu fatal("Unknown/unsupported operating system."); 7096221Snate@binkert.org } 7103867Sbinkertn@umich.edu#else 7113867Sbinkertn@umich.edu#error "THE_ISA not set" 7122292SN/A#endif 7132292SN/A 7142292SN/A if (process == NULL) 7152292SN/A fatal("Unknown error creating process object."); 7161062SN/A return process; 7171062SN/A} 7181681SN/A 7191062SN/ALiveProcess * 7202292SN/ALiveProcessParams::create() 7211062SN/A{ 7222292SN/A return LiveProcess::create(this); 7231062SN/A} 7246221Snate@binkert.org