summaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
Diffstat (limited to 'sim')
-rw-r--r--sim/prog.cc85
-rw-r--r--sim/prog.hh1
-rw-r--r--sim/system.cc36
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");