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 <fcntl.h> 34#include <unistd.h> 35 36#include <cstdio> 37#include <string> 38 39#include "base/loader/object_file.hh" 40#include "base/loader/symtab.hh" 41#include "base/intmath.hh" 42#include "base/statistics.hh" 43#include "config/the_isa.hh" 44#include "cpu/thread_context.hh" 45#include "mem/page_table.hh" 46#include "mem/physical.hh" 47#include "mem/translating_port.hh" 48#include "params/LiveProcess.hh" 49#include "params/Process.hh" 50#include "sim/debug.hh" 51#include "sim/process.hh" 52#include "sim/process_impl.hh" 53#include "sim/stats.hh" 54#include "sim/syscall_emul.hh" 55#include "sim/system.hh" 56 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#elif THE_ISA == POWER_ISA 70#include "arch/power/linux/process.hh" 71#else 72#error "THE_ISA not set" 73#endif 74 75 76using namespace std; 77using namespace TheISA; 78 79// current number of allocated processes 80int num_processes = 0; 81 82template<class IntType> 83AuxVector<IntType>::AuxVector(IntType type, IntType val) 84{ 85 a_type = TheISA::htog(type); 86 a_val = TheISA::htog(val); 87} 88 89template class AuxVector<uint32_t>; 90template class AuxVector<uint64_t>; 91 92Process::Process(ProcessParams * params) 93 : SimObject(params), system(params->system), 94 max_stack_size(params->max_stack_size) 95{ 96 string in = params->input; 97 string out = params->output; 98 string err = params->errout; 99 100 // initialize file descriptors to default: same as simulator 101 int stdin_fd, stdout_fd, stderr_fd; 102 103 if (in == "stdin" || in == "cin") 104 stdin_fd = STDIN_FILENO; 105 else if (in == "None") 106 stdin_fd = -1; 107 else 108 stdin_fd = Process::openInputFile(in); 109 110 if (out == "stdout" || out == "cout") 111 stdout_fd = STDOUT_FILENO; 112 else if (out == "stderr" || out == "cerr") 113 stdout_fd = STDERR_FILENO; 114 else if (out == "None") 115 stdout_fd = -1; 116 else 117 stdout_fd = Process::openOutputFile(out); 118 119 if (err == "stdout" || err == "cout") 120 stderr_fd = STDOUT_FILENO; 121 else if (err == "stderr" || err == "cerr") 122 stderr_fd = STDERR_FILENO; 123 else if (err == "None") 124 stderr_fd = -1; 125 else if (err == out) 126 stderr_fd = stdout_fd; 127 else 128 stderr_fd = Process::openOutputFile(err); 129 130 M5_pid = system->allocatePID(); 131 // initialize first 3 fds (stdin, stdout, stderr) 132 Process::FdMap *fdo = &fd_map[STDIN_FILENO]; 133 fdo->fd = stdin_fd; 134 fdo->filename = in; 135 fdo->flags = O_RDONLY; 136 fdo->mode = -1; 137 fdo->fileOffset = 0; 138 139 fdo = &fd_map[STDOUT_FILENO]; 140 fdo->fd = stdout_fd; 141 fdo->filename = out; 142 fdo->flags = O_WRONLY | O_CREAT | O_TRUNC; 143 fdo->mode = 0774; 144 fdo->fileOffset = 0; 145 146 fdo = &fd_map[STDERR_FILENO]; 147 fdo->fd = stderr_fd; 148 fdo->filename = err; 149 fdo->flags = O_WRONLY; 150 fdo->mode = -1; 151 fdo->fileOffset = 0; 152 153 154 // mark remaining fds as free 155 for (int i = 3; i <= MAX_FD; ++i) { 156 Process::FdMap *fdo = &fd_map[i]; 157 fdo->fd = -1; 158 } 159 160 mmap_start = mmap_end = 0; 161 nxm_start = nxm_end = 0;
|
162 pTable = new PageTable(this);
|
162 pTable = new PageTable(name(), M5_pid); |
163 // other parameters will be initialized when the program is loaded 164} 165 166 167void 168Process::regStats() 169{ 170 using namespace Stats; 171 172 num_syscalls 173 .name(name() + ".num_syscalls") 174 .desc("Number of system calls") 175 ; 176} 177 178// 179// static helper functions 180// 181int 182Process::openInputFile(const string &filename) 183{ 184 int fd = open(filename.c_str(), O_RDONLY); 185 186 if (fd == -1) { 187 perror(NULL); 188 cerr << "unable to open \"" << filename << "\" for reading\n"; 189 fatal("can't open input file"); 190 } 191 192 return fd; 193} 194 195 196int 197Process::openOutputFile(const string &filename) 198{ 199 int fd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0664); 200 201 if (fd == -1) { 202 perror(NULL); 203 cerr << "unable to open \"" << filename << "\" for writing\n"; 204 fatal("can't open output file"); 205 } 206 207 return fd; 208} 209 210ThreadContext * 211Process::findFreeContext() 212{ 213 int size = contextIds.size(); 214 ThreadContext *tc; 215 for (int i = 0; i < size; ++i) { 216 tc = system->getThreadContext(contextIds[i]); 217 if (tc->status() == ThreadContext::Halted) { 218 // inactive context, free to use 219 return tc; 220 } 221 } 222 return NULL; 223} 224 225void 226Process::initState() 227{ 228 if (contextIds.empty()) 229 fatal("Process %s is not associated with any HW contexts!\n", name()); 230 231 // first thread context for this process... initialize & enable 232 ThreadContext *tc = system->getThreadContext(contextIds[0]); 233 234 // mark this context as active so it will start ticking. 235 tc->activate(0); 236 237 Port *mem_port; 238 mem_port = system->physmem->getPort("functional"); 239 initVirtMem = new TranslatingPort("process init port", this, 240 TranslatingPort::Always); 241 mem_port->setPeer(initVirtMem); 242 initVirtMem->setPeer(mem_port); 243} 244 245// map simulator fd sim_fd to target fd tgt_fd 246void 247Process::dup_fd(int sim_fd, int tgt_fd) 248{ 249 if (tgt_fd < 0 || tgt_fd > MAX_FD) 250 panic("Process::dup_fd tried to dup past MAX_FD (%d)", tgt_fd); 251 252 Process::FdMap *fdo = &fd_map[tgt_fd]; 253 fdo->fd = sim_fd; 254} 255 256 257// generate new target fd for sim_fd 258int 259Process::alloc_fd(int sim_fd, string filename, int flags, int mode, bool pipe) 260{ 261 // in case open() returns an error, don't allocate a new fd 262 if (sim_fd == -1) 263 return -1; 264 265 // find first free target fd 266 for (int free_fd = 0; free_fd <= MAX_FD; ++free_fd) { 267 Process::FdMap *fdo = &fd_map[free_fd]; 268 if (fdo->fd == -1) { 269 fdo->fd = sim_fd; 270 fdo->filename = filename; 271 fdo->mode = mode; 272 fdo->fileOffset = 0; 273 fdo->flags = flags; 274 fdo->isPipe = pipe; 275 fdo->readPipeSource = 0; 276 return free_fd; 277 } 278 } 279 280 panic("Process::alloc_fd: out of file descriptors!"); 281} 282 283 284// free target fd (e.g., after close) 285void 286Process::free_fd(int tgt_fd) 287{ 288 Process::FdMap *fdo = &fd_map[tgt_fd]; 289 if (fdo->fd == -1) 290 warn("Process::free_fd: request to free unused fd %d", tgt_fd); 291 292 fdo->fd = -1; 293 fdo->filename = "NULL"; 294 fdo->mode = 0; 295 fdo->fileOffset = 0; 296 fdo->flags = 0; 297 fdo->isPipe = false; 298 fdo->readPipeSource = 0; 299} 300 301 302// look up simulator fd for given target fd 303int 304Process::sim_fd(int tgt_fd) 305{ 306 if (tgt_fd < 0 || tgt_fd > MAX_FD) 307 return -1; 308 309 return fd_map[tgt_fd].fd; 310} 311 312Process::FdMap * 313Process::sim_fd_obj(int tgt_fd) 314{ 315 if (tgt_fd < 0 || tgt_fd > MAX_FD) 316 return NULL; 317 318 return &fd_map[tgt_fd]; 319} 320
|
321void 322Process::allocateMem(Addr vaddr, int64_t size, bool clobber) 323{ 324 int npages = divCeil(size, (int64_t)VMPageSize); 325 Addr paddr = system->allocPhysPages(npages); 326 pTable->map(vaddr, paddr, size, clobber); 327} 328 |
329bool 330Process::fixupStackFault(Addr vaddr) 331{ 332 // Check if this is already on the stack and there's just no page there 333 // yet. 334 if (vaddr >= stack_min && vaddr < stack_base) {
|
327 pTable->allocate(roundDown(vaddr, VMPageSize), VMPageSize);
|
335 allocateMem(roundDown(vaddr, VMPageSize), VMPageSize); |
336 return true; 337 } 338 339 // We've accessed the next page of the stack, so extend it to include 340 // this address. 341 if (vaddr < stack_min && vaddr >= stack_base - max_stack_size) { 342 while (vaddr < stack_min) { 343 stack_min -= TheISA::PageBytes; 344 if (stack_base - stack_min > max_stack_size) 345 fatal("Maximum stack size exceeded\n"); 346 if (stack_base - stack_min > 8 * 1024 * 1024) 347 fatal("Over max stack size for one thread\n");
|
340 pTable->allocate(stack_min, TheISA::PageBytes);
|
348 allocateMem(stack_min, TheISA::PageBytes); |
349 inform("Increasing stack size by one page."); 350 }; 351 return true; 352 } 353 warn("Not extending stack: address %#x isn't at the end of the stack.", 354 vaddr); 355 return false; 356} 357 358// find all offsets for currently open files and save them 359void 360Process::fix_file_offsets() 361{ 362 Process::FdMap *fdo_stdin = &fd_map[STDIN_FILENO]; 363 Process::FdMap *fdo_stdout = &fd_map[STDOUT_FILENO]; 364 Process::FdMap *fdo_stderr = &fd_map[STDERR_FILENO]; 365 string in = fdo_stdin->filename; 366 string out = fdo_stdout->filename; 367 string err = fdo_stderr->filename; 368 369 // initialize file descriptors to default: same as simulator 370 int stdin_fd, stdout_fd, stderr_fd; 371 372 if (in == "stdin" || in == "cin") 373 stdin_fd = STDIN_FILENO; 374 else if (in == "None") 375 stdin_fd = -1; 376 else { 377 // open standard in and seek to the right location 378 stdin_fd = Process::openInputFile(in); 379 if (lseek(stdin_fd, fdo_stdin->fileOffset, SEEK_SET) < 0) 380 panic("Unable to seek to correct location in file: %s", in); 381 } 382 383 if (out == "stdout" || out == "cout") 384 stdout_fd = STDOUT_FILENO; 385 else if (out == "stderr" || out == "cerr") 386 stdout_fd = STDERR_FILENO; 387 else if (out == "None") 388 stdout_fd = -1; 389 else { 390 stdout_fd = Process::openOutputFile(out); 391 if (lseek(stdout_fd, fdo_stdout->fileOffset, SEEK_SET) < 0) 392 panic("Unable to seek to correct location in file: %s", out); 393 } 394 395 if (err == "stdout" || err == "cout") 396 stderr_fd = STDOUT_FILENO; 397 else if (err == "stderr" || err == "cerr") 398 stderr_fd = STDERR_FILENO; 399 else if (err == "None") 400 stderr_fd = -1; 401 else if (err == out) 402 stderr_fd = stdout_fd; 403 else { 404 stderr_fd = Process::openOutputFile(err); 405 if (lseek(stderr_fd, fdo_stderr->fileOffset, SEEK_SET) < 0) 406 panic("Unable to seek to correct location in file: %s", err); 407 } 408 409 fdo_stdin->fd = stdin_fd; 410 fdo_stdout->fd = stdout_fd; 411 fdo_stderr->fd = stderr_fd; 412 413 414 for (int free_fd = 3; free_fd <= MAX_FD; ++free_fd) { 415 Process::FdMap *fdo = &fd_map[free_fd]; 416 if (fdo->fd != -1) { 417 if (fdo->isPipe){ 418 if (fdo->filename == "PIPE-WRITE") 419 continue; 420 else { 421 assert (fdo->filename == "PIPE-READ"); 422 //create a new pipe 423 int fds[2]; 424 int pipe_retval = pipe(fds); 425 426 if (pipe_retval < 0) { 427 // error 428 panic("Unable to create new pipe."); 429 } 430 fdo->fd = fds[0]; //set read pipe 431 Process::FdMap *fdo_write = &fd_map[fdo->readPipeSource]; 432 if (fdo_write->filename != "PIPE-WRITE") 433 panic ("Couldn't find write end of the pipe"); 434 435 fdo_write->fd = fds[1];//set write pipe 436 } 437 } else { 438 //Open file 439 int fd = open(fdo->filename.c_str(), fdo->flags, fdo->mode); 440 441 if (fd == -1) 442 panic("Unable to open file: %s", fdo->filename); 443 fdo->fd = fd; 444 445 //Seek to correct location before checkpoint 446 if (lseek(fd,fdo->fileOffset, SEEK_SET) < 0) 447 panic("Unable to seek to correct location in file: %s", 448 fdo->filename); 449 } 450 } 451 } 452} 453 454void 455Process::find_file_offsets() 456{ 457 for (int free_fd = 0; free_fd <= MAX_FD; ++free_fd) { 458 Process::FdMap *fdo = &fd_map[free_fd]; 459 if (fdo->fd != -1) { 460 fdo->fileOffset = lseek(fdo->fd, 0, SEEK_CUR); 461 } else { 462 fdo->filename = "NULL"; 463 fdo->fileOffset = 0; 464 } 465 } 466} 467 468void 469Process::setReadPipeSource(int read_pipe_fd, int source_fd) 470{ 471 Process::FdMap *fdo = &fd_map[read_pipe_fd]; 472 fdo->readPipeSource = source_fd; 473} 474 475void 476Process::FdMap::serialize(std::ostream &os) 477{ 478 SERIALIZE_SCALAR(fd); 479 SERIALIZE_SCALAR(isPipe); 480 SERIALIZE_SCALAR(filename); 481 SERIALIZE_SCALAR(flags); 482 SERIALIZE_SCALAR(readPipeSource); 483 SERIALIZE_SCALAR(fileOffset); 484} 485 486void 487Process::FdMap::unserialize(Checkpoint *cp, const std::string §ion) 488{ 489 UNSERIALIZE_SCALAR(fd); 490 UNSERIALIZE_SCALAR(isPipe); 491 UNSERIALIZE_SCALAR(filename); 492 UNSERIALIZE_SCALAR(flags); 493 UNSERIALIZE_SCALAR(readPipeSource); 494 UNSERIALIZE_SCALAR(fileOffset); 495} 496 497void 498Process::serialize(std::ostream &os) 499{ 500 SERIALIZE_SCALAR(brk_point); 501 SERIALIZE_SCALAR(stack_base); 502 SERIALIZE_SCALAR(stack_size); 503 SERIALIZE_SCALAR(stack_min); 504 SERIALIZE_SCALAR(next_thread_stack_base); 505 SERIALIZE_SCALAR(mmap_start); 506 SERIALIZE_SCALAR(mmap_end); 507 SERIALIZE_SCALAR(nxm_start); 508 SERIALIZE_SCALAR(nxm_end); 509 find_file_offsets(); 510 pTable->serialize(os); 511 for (int x = 0; x <= MAX_FD; x++) { 512 nameOut(os, csprintf("%s.FdMap%d", name(), x)); 513 fd_map[x].serialize(os); 514 } 515 SERIALIZE_SCALAR(M5_pid); 516 517} 518 519void 520Process::unserialize(Checkpoint *cp, const std::string §ion) 521{ 522 UNSERIALIZE_SCALAR(brk_point); 523 UNSERIALIZE_SCALAR(stack_base); 524 UNSERIALIZE_SCALAR(stack_size); 525 UNSERIALIZE_SCALAR(stack_min); 526 UNSERIALIZE_SCALAR(next_thread_stack_base); 527 UNSERIALIZE_SCALAR(mmap_start); 528 UNSERIALIZE_SCALAR(mmap_end); 529 UNSERIALIZE_SCALAR(nxm_start); 530 UNSERIALIZE_SCALAR(nxm_end); 531 pTable->unserialize(cp, section); 532 for (int x = 0; x <= MAX_FD; x++) { 533 fd_map[x].unserialize(cp, csprintf("%s.FdMap%d", section, x)); 534 } 535 fix_file_offsets(); 536 UNSERIALIZE_OPT_SCALAR(M5_pid); 537 // The above returns a bool so that you could do something if you don't 538 // find the param in the checkpoint if you wanted to, like set a default 539 // but in this case we'll just stick with the instantianted value if not 540 // found. 541} 542 543 544//////////////////////////////////////////////////////////////////////// 545// 546// LiveProcess member definitions 547// 548//////////////////////////////////////////////////////////////////////// 549 550 551LiveProcess::LiveProcess(LiveProcessParams * params, ObjectFile *_objFile) 552 : Process(params), objFile(_objFile), 553 argv(params->cmd), envp(params->env), cwd(params->cwd) 554{ 555 __uid = params->uid; 556 __euid = params->euid; 557 __gid = params->gid; 558 __egid = params->egid; 559 __pid = params->pid; 560 __ppid = params->ppid; 561 562 prog_fname = params->cmd[0]; 563 564 // load up symbols, if any... these may be used for debugging or 565 // profiling. 566 if (!debugSymbolTable) { 567 debugSymbolTable = new SymbolTable(); 568 if (!objFile->loadGlobalSymbols(debugSymbolTable) || 569 !objFile->loadLocalSymbols(debugSymbolTable)) { 570 // didn't load any symbols 571 delete debugSymbolTable; 572 debugSymbolTable = NULL; 573 } 574 } 575} 576 577void 578LiveProcess::syscall(int64_t callnum, ThreadContext *tc) 579{ 580 num_syscalls++; 581 582 SyscallDesc *desc = getDesc(callnum); 583 if (desc == NULL) 584 fatal("Syscall %d out of range", callnum); 585 586 desc->doSyscall(callnum, this, tc); 587} 588 589IntReg 590LiveProcess::getSyscallArg(ThreadContext *tc, int &i, int width) 591{ 592 return getSyscallArg(tc, i); 593} 594 595LiveProcess * 596LiveProcess::create(LiveProcessParams * params) 597{ 598 LiveProcess *process = NULL; 599 600 string executable = 601 params->executable == "" ? params->cmd[0] : params->executable; 602 ObjectFile *objFile = createObjectFile(executable); 603 if (objFile == NULL) { 604 fatal("Can't load object file %s", executable); 605 } 606 607 if (objFile->isDynamic()) 608 fatal("Object file is a dynamic executable however only static " 609 "executables are supported!\n Please recompile your " 610 "executable as a static binary and try again.\n"); 611 612#if THE_ISA == ALPHA_ISA 613 if (objFile->getArch() != ObjectFile::Alpha) 614 fatal("Object file architecture does not match compiled ISA (Alpha)."); 615 616 switch (objFile->getOpSys()) { 617 case ObjectFile::Tru64: 618 process = new AlphaTru64Process(params, objFile); 619 break; 620 621 case ObjectFile::UnknownOpSys: 622 warn("Unknown operating system; assuming Linux."); 623 // fall through 624 case ObjectFile::Linux: 625 process = new AlphaLinuxProcess(params, objFile); 626 break; 627 628 default: 629 fatal("Unknown/unsupported operating system."); 630 } 631#elif THE_ISA == SPARC_ISA 632 if (objFile->getArch() != ObjectFile::SPARC64 && 633 objFile->getArch() != ObjectFile::SPARC32) 634 fatal("Object file architecture does not match compiled ISA (SPARC)."); 635 switch (objFile->getOpSys()) { 636 case ObjectFile::UnknownOpSys: 637 warn("Unknown operating system; assuming Linux."); 638 // fall through 639 case ObjectFile::Linux: 640 if (objFile->getArch() == ObjectFile::SPARC64) { 641 process = new Sparc64LinuxProcess(params, objFile); 642 } else { 643 process = new Sparc32LinuxProcess(params, objFile); 644 } 645 break; 646 647 648 case ObjectFile::Solaris: 649 process = new SparcSolarisProcess(params, objFile); 650 break; 651 652 default: 653 fatal("Unknown/unsupported operating system."); 654 } 655#elif THE_ISA == X86_ISA 656 if (objFile->getArch() != ObjectFile::X86_64 && 657 objFile->getArch() != ObjectFile::I386) 658 fatal("Object file architecture does not match compiled ISA (x86)."); 659 switch (objFile->getOpSys()) { 660 case ObjectFile::UnknownOpSys: 661 warn("Unknown operating system; assuming Linux."); 662 // fall through 663 case ObjectFile::Linux: 664 if (objFile->getArch() == ObjectFile::X86_64) { 665 process = new X86_64LinuxProcess(params, objFile); 666 } else { 667 process = new I386LinuxProcess(params, objFile); 668 } 669 break; 670 671 default: 672 fatal("Unknown/unsupported operating system."); 673 } 674#elif THE_ISA == MIPS_ISA 675 if (objFile->getArch() != ObjectFile::Mips) 676 fatal("Object file architecture does not match compiled ISA (MIPS)."); 677 switch (objFile->getOpSys()) { 678 case ObjectFile::UnknownOpSys: 679 warn("Unknown operating system; assuming Linux."); 680 // fall through 681 case ObjectFile::Linux: 682 process = new MipsLinuxProcess(params, objFile); 683 break; 684 685 default: 686 fatal("Unknown/unsupported operating system."); 687 } 688#elif THE_ISA == ARM_ISA 689 if (objFile->getArch() != ObjectFile::Arm && 690 objFile->getArch() != ObjectFile::Thumb) 691 fatal("Object file architecture does not match compiled ISA (ARM)."); 692 switch (objFile->getOpSys()) { 693 case ObjectFile::UnknownOpSys: 694 warn("Unknown operating system; assuming Linux."); 695 // fall through 696 case ObjectFile::Linux: 697 process = new ArmLinuxProcess(params, objFile, objFile->getArch()); 698 break; 699 case ObjectFile::LinuxArmOABI: 700 fatal("M5 does not support ARM OABI binaries. Please recompile with an" 701 " EABI compiler."); 702 default: 703 fatal("Unknown/unsupported operating system."); 704 } 705#elif THE_ISA == POWER_ISA 706 if (objFile->getArch() != ObjectFile::Power) 707 fatal("Object file architecture does not match compiled ISA (Power)."); 708 switch (objFile->getOpSys()) { 709 case ObjectFile::UnknownOpSys: 710 warn("Unknown operating system; assuming Linux."); 711 // fall through 712 case ObjectFile::Linux: 713 process = new PowerLinuxProcess(params, objFile); 714 break; 715 716 default: 717 fatal("Unknown/unsupported operating system."); 718 } 719#else 720#error "THE_ISA not set" 721#endif 722 723 if (process == NULL) 724 fatal("Unknown error creating process object."); 725 return process; 726} 727 728LiveProcess * 729LiveProcessParams::create() 730{ 731 return LiveProcess::create(this); 732}
|