process.cc revision 5514:9a903bf83a33
1/*
2 * Copyright (c) 2001-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Nathan Binkert
29 *          Steve Reinhardt
30 *          Ali Saidi
31 */
32
33#include <unistd.h>
34#include <fcntl.h>
35#include <string>
36
37#include "arch/remote_gdb.hh"
38#include "base/intmath.hh"
39#include "base/loader/object_file.hh"
40#include "base/loader/symtab.hh"
41#include "base/statistics.hh"
42#include "config/full_system.hh"
43#include "cpu/thread_context.hh"
44#include "mem/page_table.hh"
45#include "mem/physical.hh"
46#include "mem/translating_port.hh"
47#include "params/Process.hh"
48#include "params/LiveProcess.hh"
49#include "sim/debug.hh"
50#include "sim/process.hh"
51#include "sim/process_impl.hh"
52#include "sim/stats.hh"
53#include "sim/syscall_emul.hh"
54#include "sim/system.hh"
55
56#include "arch/isa_specific.hh"
57#if THE_ISA == ALPHA_ISA
58#include "arch/alpha/linux/process.hh"
59#include "arch/alpha/tru64/process.hh"
60#elif THE_ISA == SPARC_ISA
61#include "arch/sparc/linux/process.hh"
62#include "arch/sparc/solaris/process.hh"
63#elif THE_ISA == MIPS_ISA
64#include "arch/mips/linux/process.hh"
65#elif THE_ISA == ARM_ISA
66#include "arch/arm/linux/process.hh"
67#elif THE_ISA == X86_ISA
68#include "arch/x86/linux/process.hh"
69#else
70#error "THE_ISA not set"
71#endif
72
73
74using namespace std;
75using namespace TheISA;
76
77//
78// The purpose of this code is to fake the loader & syscall mechanism
79// when there's no OS: thus there's no resone to use it in FULL_SYSTEM
80// mode when we do have an OS
81//
82#if FULL_SYSTEM
83#error "process.cc not compatible with FULL_SYSTEM"
84#endif
85
86// current number of allocated processes
87int num_processes = 0;
88
89Process::Process(ProcessParams * params)
90    : SimObject(params), system(params->system), checkpointRestored(false),
91    max_stack_size(params->max_stack_size)
92{
93    string in = params->input;
94    string out = params->output;
95    string err = params->errout;
96
97    // initialize file descriptors to default: same as simulator
98    int stdin_fd, stdout_fd, stderr_fd;
99
100    if (in == "stdin" || in == "cin")
101        stdin_fd = STDIN_FILENO;
102    else if (in == "None")
103        stdin_fd = -1;
104    else
105        stdin_fd = Process::openInputFile(in);
106
107    if (out == "stdout" || out == "cout")
108        stdout_fd = STDOUT_FILENO;
109    else if (out == "stderr" || out == "cerr")
110        stdout_fd = STDERR_FILENO;
111    else if (out == "None")
112        stdout_fd = -1;
113    else
114        stdout_fd = Process::openOutputFile(out);
115
116    if (err == "stdout" || err == "cout")
117        stderr_fd = STDOUT_FILENO;
118    else if (err == "stderr" || err == "cerr")
119        stderr_fd = STDERR_FILENO;
120    else if (err == "None")
121        stderr_fd = -1;
122    else if (err == out)
123        stderr_fd = stdout_fd;
124    else
125        stderr_fd = Process::openOutputFile(err);
126
127    M5_pid = system->allocatePID();
128    // initialize first 3 fds (stdin, stdout, stderr)
129    Process::FdMap *fdo = &fd_map[STDIN_FILENO];
130    fdo->fd = stdin_fd;
131    fdo->filename = in;
132    fdo->flags = O_RDONLY;
133    fdo->mode = -1;
134    fdo->fileOffset = 0;
135
136    fdo =  &fd_map[STDOUT_FILENO];
137    fdo->fd = stdout_fd;
138    fdo->filename = out;
139    fdo->flags =  O_WRONLY | O_CREAT | O_TRUNC;
140    fdo->mode = 0774;
141    fdo->fileOffset = 0;
142
143    fdo = &fd_map[STDERR_FILENO];
144    fdo->fd = stderr_fd;
145    fdo->filename = err;
146    fdo->flags = O_WRONLY;
147    fdo->mode = -1;
148    fdo->fileOffset = 0;
149
150
151    // mark remaining fds as free
152    for (int i = 3; i <= MAX_FD; ++i) {
153        Process::FdMap *fdo = &fd_map[i];
154        fdo->fd = -1;
155    }
156
157    mmap_start = mmap_end = 0;
158    nxm_start = nxm_end = 0;
159    pTable = new PageTable(this);
160    // other parameters will be initialized when the program is loaded
161}
162
163
164void
165Process::regStats()
166{
167    using namespace Stats;
168
169    num_syscalls
170        .name(name() + ".PROG:num_syscalls")
171        .desc("Number of system calls")
172        ;
173}
174
175//
176// static helper functions
177//
178int
179Process::openInputFile(const string &filename)
180{
181    int fd = open(filename.c_str(), O_RDONLY);
182
183    if (fd == -1) {
184        perror(NULL);
185        cerr << "unable to open \"" << filename << "\" for reading\n";
186        fatal("can't open input file");
187    }
188
189    return fd;
190}
191
192
193int
194Process::openOutputFile(const string &filename)
195{
196    int fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0664);
197
198    if (fd == -1) {
199        perror(NULL);
200        cerr << "unable to open \"" << filename << "\" for writing\n";
201        fatal("can't open output file");
202    }
203
204    return fd;
205}
206
207
208int
209Process::registerThreadContext(ThreadContext *tc)
210{
211    // add to list
212    int myIndex = threadContexts.size();
213    threadContexts.push_back(tc);
214
215    int port = getRemoteGDBPort();
216    if (port) {
217        RemoteGDB *rgdb = new RemoteGDB(system, tc);
218        GDBListener *gdbl = new GDBListener(rgdb, port + myIndex);
219        gdbl->listen();
220
221        remoteGDB.push_back(rgdb);
222    }
223
224    // return CPU number to caller
225    return myIndex;
226}
227
228void
229Process::startup()
230{
231    if (threadContexts.empty())
232        fatal("Process %s is not associated with any CPUs!\n", name());
233
234    // first thread context for this process... initialize & enable
235    ThreadContext *tc = threadContexts[0];
236
237    // mark this context as active so it will start ticking.
238    tc->activate(0);
239
240    Port *mem_port;
241    mem_port = system->physmem->getPort("functional");
242    initVirtMem = new TranslatingPort("process init port", this,
243            TranslatingPort::Always);
244    mem_port->setPeer(initVirtMem);
245    initVirtMem->setPeer(mem_port);
246}
247
248void
249Process::replaceThreadContext(ThreadContext *tc, int tcIndex)
250{
251    if (tcIndex >= threadContexts.size()) {
252        panic("replaceThreadContext: bad tcIndex, %d >= %d\n",
253              tcIndex, threadContexts.size());
254    }
255
256    threadContexts[tcIndex] = tc;
257}
258
259// map simulator fd sim_fd to target fd tgt_fd
260void
261Process::dup_fd(int sim_fd, int tgt_fd)
262{
263    if (tgt_fd < 0 || tgt_fd > MAX_FD)
264        panic("Process::dup_fd tried to dup past MAX_FD (%d)", tgt_fd);
265
266    Process::FdMap *fdo = &fd_map[tgt_fd];
267    fdo->fd = sim_fd;
268}
269
270
271// generate new target fd for sim_fd
272int
273Process::alloc_fd(int sim_fd, string filename, int flags, int mode, bool pipe)
274{
275    // in case open() returns an error, don't allocate a new fd
276    if (sim_fd == -1)
277        return -1;
278
279    // find first free target fd
280    for (int free_fd = 0; free_fd <= MAX_FD; ++free_fd) {
281        Process::FdMap *fdo = &fd_map[free_fd];
282        if (fdo->fd == -1) {
283            fdo->fd = sim_fd;
284            fdo->filename = filename;
285            fdo->mode = mode;
286            fdo->fileOffset = 0;
287            fdo->flags = flags;
288            fdo->isPipe = pipe;
289            fdo->readPipeSource = 0;
290            return free_fd;
291        }
292    }
293
294    panic("Process::alloc_fd: out of file descriptors!");
295}
296
297
298// free target fd (e.g., after close)
299void
300Process::free_fd(int tgt_fd)
301{
302    Process::FdMap *fdo = &fd_map[tgt_fd];
303    if (fdo->fd == -1)
304        warn("Process::free_fd: request to free unused fd %d", tgt_fd);
305
306    fdo->fd = -1;
307    fdo->filename = "NULL";
308    fdo->mode = 0;
309    fdo->fileOffset = 0;
310    fdo->flags = 0;
311    fdo->isPipe = false;
312    fdo->readPipeSource = 0;
313}
314
315
316// look up simulator fd for given target fd
317int
318Process::sim_fd(int tgt_fd)
319{
320    if (tgt_fd > MAX_FD)
321        return -1;
322
323    return fd_map[tgt_fd].fd;
324}
325
326Process::FdMap *
327Process::sim_fd_obj(int tgt_fd)
328{
329    if (tgt_fd > MAX_FD)
330        panic("sim_fd_obj called in fd out of range.");
331
332    return &fd_map[tgt_fd];
333}
334bool
335Process::checkAndAllocNextPage(Addr vaddr)
336{
337    // if this is an initial write we might not have
338    if (vaddr >= stack_min && vaddr < stack_base) {
339        pTable->allocate(roundDown(vaddr, VMPageSize), VMPageSize);
340        return true;
341    }
342
343    // We've accessed the next page of the stack, so extend the stack
344    // to cover it.
345    if (vaddr < stack_min && vaddr >= stack_base - max_stack_size) {
346        while (vaddr < stack_min) {
347            stack_min -= TheISA::PageBytes;
348            if(stack_base - stack_min > max_stack_size)
349                fatal("Maximum stack size exceeded\n");
350            if(stack_base - stack_min > 8*1024*1024)
351                fatal("Over max stack size for one thread\n");
352            pTable->allocate(stack_min, TheISA::PageBytes);
353            warn("Increasing stack size by one page.");
354        };
355        return true;
356    }
357    return false;
358}
359
360 // find all offsets for currently open files and save them
361void
362Process::fix_file_offsets() {
363    Process::FdMap *fdo_stdin = &fd_map[STDIN_FILENO];
364    Process::FdMap *fdo_stdout = &fd_map[STDOUT_FILENO];
365    Process::FdMap *fdo_stderr = &fd_map[STDERR_FILENO];
366    string in = fdo_stdin->filename;
367    string out = fdo_stdout->filename;
368    string err = fdo_stderr->filename;
369
370    // initialize file descriptors to default: same as simulator
371    int stdin_fd, stdout_fd, stderr_fd;
372
373    if (in == "stdin" || in == "cin")
374        stdin_fd = STDIN_FILENO;
375    else if (in == "None")
376        stdin_fd = -1;
377    else{
378        //OPEN standard in and seek to the right location
379        stdin_fd = Process::openInputFile(in);
380        if (lseek(stdin_fd, fdo_stdin->fileOffset, SEEK_SET) < 0)
381            panic("Unable to seek to correct location in file: %s", in);
382    }
383
384    if (out == "stdout" || out == "cout")
385        stdout_fd = STDOUT_FILENO;
386    else if (out == "stderr" || out == "cerr")
387        stdout_fd = STDERR_FILENO;
388    else if (out == "None")
389        stdout_fd = -1;
390    else{
391        stdout_fd = Process::openOutputFile(out);
392        if (lseek(stdout_fd, fdo_stdout->fileOffset, SEEK_SET) < 0)
393            panic("Unable to seek to correct location in file: %s", out);
394    }
395
396    if (err == "stdout" || err == "cout")
397        stderr_fd = STDOUT_FILENO;
398    else if (err == "stderr" || err == "cerr")
399        stderr_fd = STDERR_FILENO;
400    else if (err == "None")
401        stderr_fd = -1;
402    else if (err == out)
403        stderr_fd = stdout_fd;
404    else {
405        stderr_fd = Process::openOutputFile(err);
406        if (lseek(stderr_fd, fdo_stderr->fileOffset, SEEK_SET) < 0)
407            panic("Unable to seek to correct location in file: %s", err);
408    }
409
410    fdo_stdin->fd = stdin_fd;
411    fdo_stdout->fd = stdout_fd;
412    fdo_stderr->fd = stderr_fd;
413
414
415    for (int free_fd = 3; free_fd <= MAX_FD; ++free_fd) {
416        Process::FdMap *fdo = &fd_map[free_fd];
417        if (fdo->fd != -1) {
418            if (fdo->isPipe){
419                if (fdo->filename == "PIPE-WRITE")
420                    continue;
421                else {
422                    assert (fdo->filename == "PIPE-READ");
423                    //create a new pipe
424                    int fds[2];
425                    int pipe_retval = pipe(fds);
426
427                    if (pipe_retval < 0) {
428                        // error
429                        panic("Unable to create new pipe.");
430                    }
431                    fdo->fd = fds[0]; //set read pipe
432                    Process::FdMap *fdo_write = &fd_map[fdo->readPipeSource];
433                    if (fdo_write->filename != "PIPE-WRITE")
434                        panic ("Couldn't find write end of the pipe");
435
436                    fdo_write->fd = fds[1];//set write pipe
437               }
438            } else {
439                //Open file
440                int fd = open(fdo->filename.c_str(), fdo->flags, fdo->mode);
441
442                if (fd == -1)
443                    panic("Unable to open file: %s", fdo->filename);
444                fdo->fd = fd;
445
446                //Seek to correct location before checkpoint
447                if (lseek(fd,fdo->fileOffset, SEEK_SET) < 0)
448                    panic("Unable to seek to correct location in file: %s", fdo->filename);
449            }
450        }
451    }
452}
453void
454Process::find_file_offsets(){
455    for (int free_fd = 0; free_fd <= MAX_FD; ++free_fd) {
456        Process::FdMap *fdo = &fd_map[free_fd];
457        if (fdo->fd != -1) {
458            fdo->fileOffset = lseek(fdo->fd, 0, SEEK_CUR);
459        }  else {
460                fdo->filename = "NULL";
461                fdo->fileOffset = 0;
462        }
463    }
464}
465
466void
467Process::setReadPipeSource(int read_pipe_fd, int source_fd){
468    Process::FdMap *fdo = &fd_map[read_pipe_fd];
469    fdo->readPipeSource = source_fd;
470}
471
472void
473Process::FdMap::serialize(std::ostream &os)
474{
475    SERIALIZE_SCALAR(fd);
476    SERIALIZE_SCALAR(isPipe);
477    SERIALIZE_SCALAR(filename);
478    SERIALIZE_SCALAR(flags);
479    SERIALIZE_SCALAR(readPipeSource);
480    SERIALIZE_SCALAR(fileOffset);
481}
482
483void
484Process::FdMap::unserialize(Checkpoint *cp, const std::string &section)
485{
486    UNSERIALIZE_SCALAR(fd);
487    UNSERIALIZE_SCALAR(isPipe);
488    UNSERIALIZE_SCALAR(filename);
489    UNSERIALIZE_SCALAR(flags);
490    UNSERIALIZE_SCALAR(readPipeSource);
491    UNSERIALIZE_SCALAR(fileOffset);
492}
493
494void
495Process::serialize(std::ostream &os)
496{
497    SERIALIZE_SCALAR(initialContextLoaded);
498    SERIALIZE_SCALAR(brk_point);
499    SERIALIZE_SCALAR(stack_base);
500    SERIALIZE_SCALAR(stack_size);
501    SERIALIZE_SCALAR(stack_min);
502    SERIALIZE_SCALAR(next_thread_stack_base);
503    SERIALIZE_SCALAR(mmap_start);
504    SERIALIZE_SCALAR(mmap_end);
505    SERIALIZE_SCALAR(nxm_start);
506    SERIALIZE_SCALAR(nxm_end);
507    find_file_offsets();
508    pTable->serialize(os);
509    for (int x = 0; x <= MAX_FD; x++) {
510        nameOut(os, csprintf("%s.FdMap%d", name(), x));
511        fd_map[x].serialize(os);
512    }
513
514}
515
516void
517Process::unserialize(Checkpoint *cp, const std::string &section)
518{
519    UNSERIALIZE_SCALAR(initialContextLoaded);
520    UNSERIALIZE_SCALAR(brk_point);
521    UNSERIALIZE_SCALAR(stack_base);
522    UNSERIALIZE_SCALAR(stack_size);
523    UNSERIALIZE_SCALAR(stack_min);
524    UNSERIALIZE_SCALAR(next_thread_stack_base);
525    UNSERIALIZE_SCALAR(mmap_start);
526    UNSERIALIZE_SCALAR(mmap_end);
527    UNSERIALIZE_SCALAR(nxm_start);
528    UNSERIALIZE_SCALAR(nxm_end);
529    pTable->unserialize(cp, section);
530    for (int x = 0; x <= MAX_FD; x++) {
531        fd_map[x].unserialize(cp, csprintf("%s.FdMap%d", section, x));
532     }
533    fix_file_offsets();
534
535    checkpointRestored = true;
536
537}
538
539
540////////////////////////////////////////////////////////////////////////
541//
542// LiveProcess member definitions
543//
544////////////////////////////////////////////////////////////////////////
545
546
547LiveProcess::LiveProcess(LiveProcessParams * params, ObjectFile *_objFile)
548    : Process(params), objFile(_objFile),
549      argv(params->cmd), envp(params->env), cwd(params->cwd)
550{
551    __uid = params->uid;
552    __euid = params->euid;
553    __gid = params->gid;
554    __egid = params->egid;
555    __pid = params->pid;
556    __ppid = params->ppid;
557
558    prog_fname = params->cmd[0];
559
560    // load up symbols, if any... these may be used for debugging or
561    // profiling.
562    if (!debugSymbolTable) {
563        debugSymbolTable = new SymbolTable();
564        if (!objFile->loadGlobalSymbols(debugSymbolTable) ||
565            !objFile->loadLocalSymbols(debugSymbolTable)) {
566            // didn't load any symbols
567            delete debugSymbolTable;
568            debugSymbolTable = NULL;
569        }
570    }
571}
572
573void
574LiveProcess::argsInit(int intSize, int pageSize)
575{
576    Process::startup();
577
578    // load object file into target memory
579    objFile->loadSections(initVirtMem);
580
581    // Calculate how much space we need for arg & env arrays.
582    int argv_array_size = intSize * (argv.size() + 1);
583    int envp_array_size = intSize * (envp.size() + 1);
584    int arg_data_size = 0;
585    for (int i = 0; i < argv.size(); ++i) {
586        arg_data_size += argv[i].size() + 1;
587    }
588    int env_data_size = 0;
589    for (int i = 0; i < envp.size(); ++i) {
590        env_data_size += envp[i].size() + 1;
591    }
592
593    int space_needed =
594        argv_array_size + envp_array_size + arg_data_size + env_data_size;
595    if (space_needed < 32*1024)
596        space_needed = 32*1024;
597
598    // set bottom of stack
599    stack_min = stack_base - space_needed;
600    // align it
601    stack_min = roundDown(stack_min, pageSize);
602    stack_size = stack_base - stack_min;
603    // map memory
604    pTable->allocate(stack_min, roundUp(stack_size, pageSize));
605
606    // map out initial stack contents
607    Addr argv_array_base = stack_min + intSize; // room for argc
608    Addr envp_array_base = argv_array_base + argv_array_size;
609    Addr arg_data_base = envp_array_base + envp_array_size;
610    Addr env_data_base = arg_data_base + arg_data_size;
611
612    // write contents to stack
613    uint64_t argc = argv.size();
614    if (intSize == 8)
615        argc = htog((uint64_t)argc);
616    else if (intSize == 4)
617        argc = htog((uint32_t)argc);
618    else
619        panic("Unknown int size");
620
621    initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize);
622
623    copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
624    copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
625
626    assert(NumArgumentRegs >= 2);
627    threadContexts[0]->setIntReg(ArgumentReg[0], argc);
628    threadContexts[0]->setIntReg(ArgumentReg[1], argv_array_base);
629    threadContexts[0]->setIntReg(StackPointerReg, stack_min);
630
631    Addr prog_entry = objFile->entryPoint();
632    threadContexts[0]->setPC(prog_entry);
633    threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst));
634
635#if THE_ISA != ALPHA_ISA //e.g. MIPS or Sparc
636    threadContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
637#endif
638
639    num_processes++;
640}
641
642void
643LiveProcess::syscall(int64_t callnum, ThreadContext *tc)
644{
645    num_syscalls++;
646
647    SyscallDesc *desc = getDesc(callnum);
648    if (desc == NULL)
649        fatal("Syscall %d out of range", callnum);
650
651    desc->doSyscall(callnum, this, tc);
652}
653
654LiveProcess *
655LiveProcess::create(LiveProcessParams * params)
656{
657    LiveProcess *process = NULL;
658
659    string executable =
660        params->executable == "" ? params->cmd[0] : params->executable;
661    ObjectFile *objFile = createObjectFile(executable);
662    if (objFile == NULL) {
663        fatal("Can't load object file %s", executable);
664    }
665
666    if (objFile->isDynamic())
667       fatal("Object file is a dynamic executable however only static "
668             "executables are supported!\n       Please recompile your "
669             "executable as a static binary and try again.\n");
670
671#if THE_ISA == ALPHA_ISA
672    if (objFile->hasTLS())
673        fatal("Object file has a TLS section and single threaded TLS is not\n"
674              "       currently supported for Alpha! Please recompile your "
675              "executable with \n       a non-TLS toolchain.\n");
676
677    if (objFile->getArch() != ObjectFile::Alpha)
678        fatal("Object file architecture does not match compiled ISA (Alpha).");
679    switch (objFile->getOpSys()) {
680      case ObjectFile::Tru64:
681        process = new AlphaTru64Process(params, objFile);
682        break;
683
684      case ObjectFile::Linux:
685        process = new AlphaLinuxProcess(params, objFile);
686        break;
687
688      default:
689        fatal("Unknown/unsupported operating system.");
690    }
691#elif THE_ISA == SPARC_ISA
692    if (objFile->getArch() != ObjectFile::SPARC64 && objFile->getArch() != ObjectFile::SPARC32)
693        fatal("Object file architecture does not match compiled ISA (SPARC).");
694    switch (objFile->getOpSys()) {
695      case ObjectFile::Linux:
696        if (objFile->getArch() == ObjectFile::SPARC64) {
697            process = new Sparc64LinuxProcess(params, objFile);
698        } else {
699            process = new Sparc32LinuxProcess(params, objFile);
700        }
701        break;
702
703
704      case ObjectFile::Solaris:
705        process = new SparcSolarisProcess(params, objFile);
706        break;
707      default:
708        fatal("Unknown/unsupported operating system.");
709    }
710#elif THE_ISA == X86_ISA
711    if (objFile->getArch() != ObjectFile::X86)
712        fatal("Object file architecture does not match compiled ISA (x86).");
713    switch (objFile->getOpSys()) {
714      case ObjectFile::Linux:
715        process = new X86LinuxProcess(params, objFile);
716        break;
717      default:
718        fatal("Unknown/unsupported operating system.");
719    }
720#elif THE_ISA == MIPS_ISA
721    if (objFile->getArch() != ObjectFile::Mips)
722        fatal("Object file architecture does not match compiled ISA (MIPS).");
723    switch (objFile->getOpSys()) {
724      case ObjectFile::Linux:
725        process = new MipsLinuxProcess(params, objFile);
726        break;
727
728      default:
729        fatal("Unknown/unsupported operating system.");
730    }
731#elif THE_ISA == ARM_ISA
732    if (objFile->getArch() != ObjectFile::Arm)
733        fatal("Object file architecture does not match compiled ISA (ARM).");
734    switch (objFile->getOpSys()) {
735      case ObjectFile::Linux:
736        process = new ArmLinuxProcess(params, objFile);
737        break;
738
739      default:
740        fatal("Unknown/unsupported operating system.");
741    }
742#else
743#error "THE_ISA not set"
744#endif
745
746
747    if (process == NULL)
748        fatal("Unknown error creating process object.");
749    return process;
750}
751
752LiveProcess *
753LiveProcessParams::create()
754{
755    return LiveProcess::create(this);
756}
757