summaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
authorSteve Reinhardt <stever@eecs.umich.edu>2003-10-07 23:13:01 -0700
committerSteve Reinhardt <stever@eecs.umich.edu>2003-10-07 23:13:01 -0700
commite475dba424d70e99646f897fae832f87b1cf15cf (patch)
tree04acc02acfc77419aaf80a26e03b4ccf742838cc /sim
parent998d2914db377d5236d6241e3c839af1728c36e7 (diff)
downloadgem5-e475dba424d70e99646f897fae832f87b1cf15cf.tar.xz
New loader structure. Expand Nate's ObjectFile to automatically detect file formats
and generate an appropriate child object, which knows how to load its text & data into memory (and symbols, for ecoff only at this point). Ecoff format supports Tru64 binaries, kernel, and console. A.out format is used by PAL code. Elf support is there and appears to work for Alpha/Linux binaries, but awaits a Linux syscall emulation layer before further testing. arch/alpha/ecoff_machdep.h: base/coff_sym.h: base/coff_symconst.h: base/exec_ecoff.h: Add Id string & provenance comment, clean up types base/object_file.cc: base/object_file.hh: Add auto format detection and text/data loading. sim/prog.cc: Moved binary loading & stack setup here (was in arch/alpha/loader.cc). Some of this is platform-dependent, but I think most of it is not. We'll factor out the platform-dependent parts when the need arises. sim/prog.hh: Get rid of unused environ_base field. sim/system.cc: Use new ObjectFile loader structure for console, kernel, & palcode. --HG-- extra : convert_revision : 8eae509bf71cf204bc3ec78c68699cfd01baed97
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");