summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configs/common/cpu2000.py6
-rw-r--r--src/arch/sparc/linux/process.cc2
-rw-r--r--src/arch/sparc/process.cc48
-rw-r--r--src/sim/process.cc18
-rw-r--r--src/sim/process.hh24
-rw-r--r--src/sim/syscall_emul.cc33
-rw-r--r--src/sim/syscall_emul.hh4
7 files changed, 84 insertions, 51 deletions
diff --git a/configs/common/cpu2000.py b/configs/common/cpu2000.py
index 7dc7a7afe..59799eb49 100644
--- a/configs/common/cpu2000.py
+++ b/configs/common/cpu2000.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2006 The Regents of The University of Michigan
+# Copyright (c) 2006-2007 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -104,6 +104,8 @@ class Benchmark(object):
# dirs for input & output files for this input set
inputs_dir = joinpath(data_dir, input_set, 'input')
outputs_dir = joinpath(data_dir, input_set, 'output')
+ # keep around which input set was specified
+ self.input_set = input_set
if not isdir(inputs_dir):
raise AttributeError, '%s not found' % inputs_dir
@@ -619,6 +621,8 @@ class vortex(Benchmark):
def __init__(self, isa, os, input_set):
if isa == 'alpha':
self.endian = 'lendian'
+ elif (isa == 'sparc' or isa == 'sparc32'):
+ self.endian = 'bendian'
else:
raise AttributeError, "unknown ISA %s" % isa
diff --git a/src/arch/sparc/linux/process.cc b/src/arch/sparc/linux/process.cc
index 9c7c0e643..10cde3af8 100644
--- a/src/arch/sparc/linux/process.cc
+++ b/src/arch/sparc/linux/process.cc
@@ -333,7 +333,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 233 */ SyscallDesc("stime", unimplementedFunc),
/* 234 */ SyscallDesc("statfs64", unimplementedFunc),
/* 235 */ SyscallDesc("fstatfs64", unimplementedFunc),
- /* 236 */ SyscallDesc("_llseek", unimplementedFunc),
+ /* 236 */ SyscallDesc("_llseek", _llseekFunc),
/* 237 */ SyscallDesc("mlock", unimplementedFunc),
/* 238 */ SyscallDesc("munlock", unimplementedFunc),
/* 239 */ SyscallDesc("mlockall", unimplementedFunc),
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc
index d5a95e0c0..c3b833562 100644
--- a/src/arch/sparc/process.cc
+++ b/src/arch/sparc/process.cc
@@ -425,7 +425,9 @@ Sparc32LiveProcess::argsInit(int intSize, int pageSize)
else
filename = argv[0];
- Addr alignmentMask = ~(intSize - 1);
+ //Even though this is a 32 bit process, the ABI says we still need to
+ //maintain double word alignment of the stack pointer.
+ Addr alignmentMask = ~(8 - 1);
// load object file into target memory
objFile->loadSections(initVirtMem);
@@ -525,21 +527,11 @@ Sparc32LiveProcess::argsInit(int intSize, int pageSize)
arg_data_size += argv[i].size() + 1;
}
- //The info_block needs to be padded so it's size is a multiple of the
- //alignment mask. Also, it appears that there needs to be at least some
- //padding, so if the size is already a multiple, we need to increase it
- //anyway.
+ //The info_block
int info_block_size =
(file_name_size +
env_data_size +
- arg_data_size +
- intSize) & alignmentMask;
-
- int info_block_padding =
- info_block_size -
- file_name_size -
- env_data_size -
- arg_data_size;
+ arg_data_size);
//Each auxilliary vector is two 8 byte words
int aux_array_size = intSize * 2 * (auxv.size() + 1);
@@ -552,7 +544,6 @@ Sparc32LiveProcess::argsInit(int intSize, int pageSize)
int space_needed =
mysterious_size +
- info_block_size +
aux_array_size +
envp_array_size +
argv_array_size +
@@ -568,18 +559,17 @@ Sparc32LiveProcess::argsInit(int intSize, int pageSize)
roundUp(stack_size, pageSize));
// map out initial stack contents
- Addr mysterious_base = stack_base - mysterious_size;
- Addr file_name_base = mysterious_base - file_name_size;
- Addr env_data_base = file_name_base - env_data_size;
- Addr arg_data_base = env_data_base - arg_data_size;
- Addr auxv_array_base = arg_data_base - aux_array_size - info_block_padding;
- Addr envp_array_base = auxv_array_base - envp_array_size;
- Addr argv_array_base = envp_array_base - argv_array_size;
- Addr argc_base = argv_array_base - argc_size;
-#ifndef NDEBUG
- // only used in DPRINTF
- Addr window_save_base = argc_base - window_save_size;
-#endif
+ uint32_t window_save_base = stack_min;
+ uint32_t argc_base = window_save_base + window_save_size;
+ uint32_t argv_array_base = argc_base + argc_size;
+ uint32_t envp_array_base = argv_array_base + argv_array_size;
+ uint32_t auxv_array_base = envp_array_base + envp_array_size;
+ //The info block is pushed up against the top of the stack, while
+ //the rest of the initial stack frame is aligned to an 8 byte boudary.
+ uint32_t arg_data_base = stack_base - info_block_size;
+ uint32_t env_data_base = arg_data_base + arg_data_size;
+ uint32_t file_name_base = env_data_base + env_data_size;
+ uint32_t mysterious_base = file_name_base + file_name_size;
DPRINTF(Sparc, "The addresses of items on the initial stack:\n");
DPRINTF(Sparc, "0x%x - file name\n", file_name_base);
@@ -619,8 +609,8 @@ Sparc32LiveProcess::argsInit(int intSize, int pageSize)
initVirtMem->writeBlob(auxv_array_base + 2 * intSize * auxv.size(),
(uint8_t*)&zero, 2 * intSize);
- copyStringArray(envp, envp_array_base, env_data_base, initVirtMem, intSize);
- copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem, intSize);
+ copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
+ copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
@@ -639,7 +629,7 @@ Sparc32LiveProcess::argsInit(int intSize, int pageSize)
threadContexts[0]->setIntReg(ArgumentReg1, argv_array_base);
threadContexts[0]->setIntReg(StackPointerReg, stack_min);
- Addr prog_entry = objFile->entryPoint();
+ uint32_t prog_entry = objFile->entryPoint();
threadContexts[0]->setPC(prog_entry);
threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst));
threadContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
diff --git a/src/sim/process.cc b/src/sim/process.cc
index acc509a6f..b3ce182e5 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -300,24 +300,6 @@ DEFINE_SIM_OBJECT_CLASS_NAME("Process", Process)
////////////////////////////////////////////////////////////////////////
-void
-copyStringArray(vector<string> &strings, Addr array_ptr, Addr data_ptr,
- TranslatingPort* memPort, int ptr_size)
-{
- Addr data_ptr_swap;
- for (int i = 0; i < strings.size(); ++i) {
- data_ptr_swap = htog(data_ptr);
- memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr_swap, ptr_size);
- memPort->writeString(data_ptr, strings[i].c_str());
- array_ptr += ptr_size;
- data_ptr += strings[i].size() + 1;
- }
- // add NULL terminator
- data_ptr = 0;
-
- memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr, ptr_size);
-}
-
LiveProcess::LiveProcess(const string &nm, ObjectFile *_objFile,
System *_system,
int stdin_fd, int stdout_fd, int stderr_fd,
diff --git a/src/sim/process.hh b/src/sim/process.hh
index 1226db81b..dd64fa607 100644
--- a/src/sim/process.hh
+++ b/src/sim/process.hh
@@ -41,9 +41,11 @@
#if !FULL_SYSTEM
+#include <string>
#include <vector>
#include "base/statistics.hh"
+#include "mem/translating_port.hh"
#include "sim/host.hh"
#include "sim/sim_object.hh"
@@ -58,9 +60,27 @@ namespace TheISA
class RemoteGDB;
}
+//This needs to be templated for cases where 32 bit pointers are needed.
+template<class AddrType>
void
-copyStringArray(std::vector<std::string> &strings, Addr array_ptr,
- Addr data_ptr, TranslatingPort* memPort, int ptr_size = sizeof(Addr));
+copyStringArray(std::vector<std::string> &strings,
+ AddrType array_ptr, AddrType data_ptr,
+ TranslatingPort* memPort)
+{
+ AddrType data_ptr_swap;
+ for (int i = 0; i < strings.size(); ++i) {
+ data_ptr_swap = htog(data_ptr);
+ memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr_swap,
+ sizeof(AddrType));
+ memPort->writeString(data_ptr, strings[i].c_str());
+ array_ptr += sizeof(AddrType);
+ data_ptr += strings[i].size() + 1;
+ }
+ // add NULL terminator
+ data_ptr = 0;
+
+ memPort->writeBlob(array_ptr, (uint8_t*)&data_ptr, sizeof(AddrType));
+}
class Process : public SimObject
{
diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc
index ab44c0a35..876f39e99 100644
--- a/src/sim/syscall_emul.cc
+++ b/src/sim/syscall_emul.cc
@@ -184,6 +184,39 @@ lseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
SyscallReturn
+_llseekFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
+{
+ int fd = p->sim_fd(tc->getSyscallArg(0));
+ uint64_t offset_high = tc->getSyscallArg(1);
+ uint32_t offset_low = tc->getSyscallArg(2);
+ Addr result_ptr = tc->getSyscallArg(3);
+ int whence = tc->getSyscallArg(4);
+
+ uint64_t offset = (offset_high << 32) | offset_low;
+
+ uint64_t result = lseek(fd, offset, whence);
+ result = TheISA::htog(result);
+
+ if (result == (off_t)-1) {
+ //The seek failed.
+ return -errno;
+ } else {
+ //The seek succeeded.
+ //Copy "result" to "result_ptr"
+ //XXX We'll assume that the size of loff_t is 64 bits on the
+ //target platform
+ BufferArg result_buf(result_ptr, sizeof(result));
+ memcpy(result_buf.bufferPtr(), &result, sizeof(result));
+ result_buf.copyOut(tc->getMemPort());
+ return 0;
+ }
+
+
+ return (result == (off_t)-1) ? -errno : result;
+}
+
+
+SyscallReturn
munmapFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc)
{
// given that we don't really implement mmap, munmap is really easy
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index f57bd5272..5ca2f6be5 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -211,6 +211,10 @@ SyscallReturn writeFunc(SyscallDesc *desc, int num,
SyscallReturn lseekFunc(SyscallDesc *desc, int num,
LiveProcess *p, ThreadContext *tc);
+/// Target _llseek() handler.
+SyscallReturn _llseekFunc(SyscallDesc *desc, int num,
+ LiveProcess *p, ThreadContext *tc);
+
/// Target munmap() handler.
SyscallReturn munmapFunc(SyscallDesc *desc, int num,
LiveProcess *p, ThreadContext *tc);