diff options
Diffstat (limited to 'sim')
-rw-r--r-- | sim/prog.cc | 85 | ||||
-rw-r--r-- | sim/prog.hh | 1 | ||||
-rw-r--r-- | sim/system.cc | 36 |
3 files changed, 110 insertions, 12 deletions
diff --git a/sim/prog.cc b/sim/prog.cc index 8615cab68..355e8d0a1 100644 --- a/sim/prog.cc +++ b/sim/prog.cc @@ -38,7 +38,7 @@ #include "eio.hh" #include "thread.hh" #include "fake_syscall.hh" -#include "loader.hh" +#include "object_file.hh" #include "exec_context.hh" #include "smt.hh" @@ -219,12 +219,93 @@ DEFINE_SIM_OBJECT_CLASS_NAME("Process object", Process) // //////////////////////////////////////////////////////////////////////// + +static void +copyStringArray(vector<string> &strings, Addr array_ptr, Addr data_ptr, + FunctionalMemory *memory) +{ + for (int i = 0; i < strings.size(); ++i) { + memory->access(Write, array_ptr, &data_ptr, sizeof(Addr)); + memory->writeString(data_ptr, strings[i].c_str()); + array_ptr += sizeof(Addr); + data_ptr += strings[i].size() + 1; + } + // add NULL terminator + data_ptr = 0; + memory->access(Write, array_ptr, &data_ptr, sizeof(Addr)); +} + LiveProcess::LiveProcess(const string &name, int stdin_fd, int stdout_fd, int stderr_fd, vector<string> &argv, vector<string> &envp) : Process(name, stdin_fd, stdout_fd, stderr_fd) { - smt_load_prog(argv, envp, init_regs, this); + prog_fname = argv[0]; + ObjectFile *objFile = createObjectFile(prog_fname); + if (objFile == NULL) { + fatal("Can't load object file %s", prog_fname); + } + + prog_entry = objFile->entryPoint(); + text_base = objFile->textBase(); + text_size = objFile->textSize(); + data_base = objFile->dataBase(); + data_size = objFile->dataSize() + objFile->bssSize(); + brk_point = ROUND_UP(data_base + data_size, VMPageSize); + + // load object file into target memory + objFile->loadSections(memory); + + // Set up stack. On Alpha, stack goes below text section. This + // code should get moved to some architecture-specific spot. + stack_base = text_base - (409600+4096); + + // Set pointer for next thread stack. Reserve 8M for main stack. + next_thread_stack_base = stack_base - (8 * 1024 * 1024); + + // Calculate how much space we need for arg & env arrays. + int argv_array_size = sizeof(Addr) * (argv.size() + 1); + int envp_array_size = sizeof(Addr) * (envp.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 + arg_data_size + env_data_size; + // for SimpleScalar compatibility + if (space_needed < 16384) + space_needed = 16384; + + // set bottom of stack + stack_min = stack_base - space_needed; + // align it + stack_min &= ~7; + stack_size = stack_base - stack_min; + + // map out initial stack contents + Addr argv_array_base = stack_min + sizeof(uint64_t); // room for argc + Addr envp_array_base = argv_array_base + argv_array_size; + Addr arg_data_base = envp_array_base + envp_array_size; + Addr env_data_base = arg_data_base + arg_data_size; + + // write contents to stack + uint64_t argc = argv.size(); + memory->access(Write, stack_min, &argc, sizeof(uint64_t)); + + copyStringArray(argv, argv_array_base, arg_data_base, memory); + copyStringArray(envp, envp_array_base, env_data_base, memory); + + init_regs->intRegFile[ArgumentReg0] = argc; + init_regs->intRegFile[ArgumentReg1] = argv_array_base; + init_regs->intRegFile[StackPointerReg] = stack_min; + init_regs->intRegFile[GlobalPointerReg] = objFile->globalPointer(); + init_regs->pc = prog_entry; + init_regs->npc = prog_entry + sizeof(MachInst); } diff --git a/sim/prog.hh b/sim/prog.hh index a38afee14..e04390244 100644 --- a/sim/prog.hh +++ b/sim/prog.hh @@ -86,7 +86,6 @@ class Process : public SimObject Addr brk_point; // top of the data segment - Addr environ_base; // environment base address Addr stack_base; // stack segment base (highest address) unsigned stack_size; // initial stack size Addr stack_min; // lowest address accessed on the stack diff --git a/sim/system.cc b/sim/system.cc index 04db8b134..0f6dce10c 100644 --- a/sim/system.cc +++ b/sim/system.cc @@ -26,7 +26,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "kernel_loader.hh" #include "exec_context.hh" #include "object_file.hh" #include "memory_control.hh" @@ -68,28 +67,47 @@ System::System(const std::string _name, kernelSymtab = new SymbolTable; consoleSymtab = new SymbolTable; - EcoffObject kernel(kernel_path); - EcoffObject console(console_path); + ObjectFile *kernel = createObjectFile(kernel_path); + if (kernel == NULL) + fatal("Could not load kernel file %s", kernel_path); - if (!kernel.loadGlobals(kernelSymtab)) + ObjectFile *console = createObjectFile(console_path); + if (console == NULL) + fatal("Could not load console file %s", console_path); + + if (!kernel->loadGlobalSymbols(kernelSymtab)) panic("could not load kernel symbols\n"); - if (!console.loadGlobals(consoleSymtab)) + if (!console->loadGlobalSymbols(consoleSymtab)) panic("could not load console symbols\n"); // Load pal file - loadPal(palcode, physmem, PAL_BASE); + ObjectFile *pal = createObjectFile(palcode); + if (pal == NULL) + fatal("Could not load PALcode file %s", palcode); + pal->loadSections(physmem, true); // copy of initial reg file contents initRegs = new RegFile; memset(initRegs, 0, sizeof(RegFile)); // Load console file - loadKernel(console_path, physmem); + console->loadSections(physmem, true); // Load kernel file - loadKernel(kernel_path, physmem, initRegs, - &kernelStart, &kernelEnd, &kernelEntry); + kernel->loadSections(physmem, true); + kernelStart = kernel->textBase(); + kernelEnd = kernel->bssBase() + kernel->bssSize(); + kernelEntry = kernel->entryPoint(); + + DPRINTF(Loader, "Kernel start = %#x\n" + "Kernel end = %#x\n" + "Kernel entry = %#x\n", + kernelStart, kernelEnd, kernelEntry); + + // Setup kernel boot parameters + initRegs->pc = 0x4001; + initRegs->npc = initRegs->pc + sizeof(MachInst); DPRINTF(Loader, "Kernel loaded...\n"); |