no more common syscall emulation, now common for everyone
authorAli Saidi <saidi@eecs.umich.edu>
Thu, 9 Mar 2006 20:42:09 +0000 (15:42 -0500)
committerAli Saidi <saidi@eecs.umich.edu>
Thu, 9 Mar 2006 20:42:09 +0000 (15:42 -0500)
check abi-tag note section of elf binary for OS
add pseudo functions (moved from alpha and made to be generic)
move setsyscallreturn into isa traits

arch/alpha/SConscript:
    no more common syscall emulation, now common for everyone
arch/alpha/isa_traits.hh:
    move setsyscallreturn into isa description
arch/alpha/linux/process.cc:
arch/alpha/tru64/process.cc:
    use generic functions rather than alpha specific ones
arch/sparc/isa_traits.hh:
    have consts for generic pseudo syscalls
arch/sparc/linux/process.cc:
    use generic functions
base/loader/elf_object.cc:
    check abi-tag note section of elf binary for OS
cpu/exec_context.hh:
    move syssyscallreturn into isa traits
sim/process.cc:
    find call num with a more generic
sim/syscall_emul.cc:
sim/syscall_emul.hh:
    add pseudo functions (moved from alpha and made to be generic)

--HG--
extra : convert_revision : 5a31024ecde7e39b830365ddd84593ea501a34d2

arch/alpha/SConscript
arch/alpha/isa_traits.hh
arch/alpha/linux/process.cc
arch/alpha/tru64/process.cc
arch/sparc/isa_traits.hh
arch/sparc/linux/process.cc
base/loader/elf_object.cc
cpu/exec_context.hh
sim/process.cc
sim/syscall_emul.cc
sim/syscall_emul.hh

index 6dec2d0705170bcfc8413d2f7916189ca8c275b0..ed7fd34044f33972997c53372bab26dd0844446d 100644 (file)
@@ -65,7 +65,6 @@ full_system_sources = Split('''
 
 # Syscall emulation (non-full-system) sources
 syscall_emulation_sources = Split('''
-       common_syscall_emul.cc
        linux/process.cc
        tru64/process.cc
        process.cc
index a551db485e6a04f07226610806f4f6c8f007db04..1984739184297287dd0d8ef1ceb2801edec9e1e2 100644 (file)
@@ -53,6 +53,44 @@ int DTB_ASN_ASN(uint64_t reg);
 int ITB_ASN_ASN(uint64_t reg);
 }
 
+#if !FULL_SYSTEM
+class SyscallReturn {
+        public:
+           template <class T>
+           SyscallReturn(T v, bool s)
+           {
+               retval = (uint64_t)v;
+               success = s;
+           }
+
+           template <class T>
+           SyscallReturn(T v)
+           {
+               success = (v >= 0);
+               retval = (uint64_t)v;
+           }
+
+           ~SyscallReturn() {}
+
+           SyscallReturn& operator=(const SyscallReturn& s) {
+               retval = s.retval;
+               success = s.success;
+               return *this;
+           }
+
+           bool successful() { return success; }
+           uint64_t value() { return retval; }
+
+
+       private:
+           uint64_t retval;
+           bool success;
+};
+
+#endif
+
+
+
 namespace AlphaISA
 {
 
@@ -82,6 +120,7 @@ namespace AlphaISA
         ProcedureValueReg = 27,
         ReturnAddressReg = 26,
         ReturnValueReg = 0,
+        SyscallNumReg = 0,
         FramePointerReg = 15,
         ArgumentReg0 = 16,
         ArgumentReg1 = 17,
@@ -89,6 +128,10 @@ namespace AlphaISA
         ArgumentReg3 = 19,
         ArgumentReg4 = 20,
         ArgumentReg5 = 21,
+        SyscallSuccessReg = 19,
+        // Some OS use a second register (o1) to return a second value
+        // for some syscalls
+        SyscallPseudoReturnReg = ArgumentReg4,
 
         LogVMPageSize = 13,    // 8K bytes
         VMPageSize = (1 << LogVMPageSize),
@@ -303,6 +346,21 @@ extern const int reg_redir[NumIntRegs];
     template <class XC>
     void zeroRegisters(XC *xc);
 
+    static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs)
+    {
+        // check for error condition.  Alpha syscall convention is to
+        // indicate success/failure in reg a3 (r19) and put the
+        // return value itself in the standard return value reg (v0).
+        if (return_value.successful()) {
+            // no error
+            regs->intRegFile[SyscallSuccessReg] = 0;
+            regs->intRegFile[ReturnValueReg] = return_value.value();
+        } else {
+            // got an error, return details
+            regs->intRegFile[SyscallSuccessReg] = (IntReg) -1;
+            regs->intRegFile[ReturnValueReg] = -return_value.value();
+        }
+    }
 
 //typedef AlphaISA TheISA;
 
@@ -336,42 +394,6 @@ extern const int reg_redir[NumIntRegs];
 const Addr MaxAddr = (Addr)-1;
 };
 
-#if !FULL_SYSTEM
-class SyscallReturn {
-        public:
-           template <class T>
-           SyscallReturn(T v, bool s)
-           {
-               retval = (uint64_t)v;
-               success = s;
-           }
-
-           template <class T>
-           SyscallReturn(T v)
-           {
-               success = (v >= 0);
-               retval = (uint64_t)v;
-           }
-
-           ~SyscallReturn() {}
-
-           SyscallReturn& operator=(const SyscallReturn& s) {
-               retval = s.retval;
-               success = s.success;
-               return *this;
-           }
-
-           bool successful() { return success; }
-           uint64_t value() { return retval; }
-
-
-       private:
-           uint64_t retval;
-           bool success;
-};
-
-#endif
-
 static inline AlphaISA::ExtMachInst
 AlphaISA::makeExtMI(AlphaISA::MachInst inst, const uint64_t &pc) {
 #if FULL_SYSTEM
index d78e6a4ee72d3c09c154eafd638fe527863122c1..2ebdbfc0f09bb596512ed9c4673eca8ff1fc2968 100644 (file)
@@ -26,7 +26,6 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "arch/alpha/common_syscall_emul.hh"
 #include "arch/alpha/linux/process.hh"
 #include "arch/alpha/isa_traits.hh"
 
 using namespace std;
 using namespace AlphaISA;
 
-/// Target pipe() handler.  Even though this is a generic Posix call,
-/// the Alpha return convention is funky, so that makes it
-/// Alpha-specific.
-SyscallReturn
-pipeFunc(SyscallDesc *desc, int callnum, Process *process,
-         ExecContext *xc)
-{
-    int fds[2], sim_fds[2];
-    int pipe_retval = pipe(fds);
-
-    if (pipe_retval < 0) {
-        // error
-        return pipe_retval;
-    }
 
-    sim_fds[0] = process->alloc_fd(fds[0]);
-    sim_fds[1] = process->alloc_fd(fds[1]);
-
-    // Alpha Linux convention for pipe() is that fd[0] is returned as
-    // the return value of the function, and fd[1] is returned in r20.
-    xc->regs.intRegFile[20] = sim_fds[1];
-    return sim_fds[0];
-}
 
 
 /// Target uname() handler.
@@ -162,11 +139,11 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = {
     /* 17 */ SyscallDesc("brk", obreakFunc),
     /* 18 */ SyscallDesc("osf_getfsstat", unimplementedFunc),
     /* 19 */ SyscallDesc("lseek", lseekFunc),
-    /* 20 */ SyscallDesc("getxpid", getpidFunc),
+    /* 20 */ SyscallDesc("getxpid", getpidPseudoFunc),
     /* 21 */ SyscallDesc("osf_mount", unimplementedFunc),
     /* 22 */ SyscallDesc("umount", unimplementedFunc),
     /* 23 */ SyscallDesc("setuid", setuidFunc),
-    /* 24 */ SyscallDesc("getxuid", getuidFunc),
+    /* 24 */ SyscallDesc("getxuid", getuidPseudoFunc),
     /* 25 */ SyscallDesc("exec_with_loader", unimplementedFunc),
     /* 26 */ SyscallDesc("osf_ptrace", unimplementedFunc),
     /* 27 */ SyscallDesc("osf_nrecvmsg", unimplementedFunc),
@@ -184,12 +161,12 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = {
     /* 39 */ SyscallDesc("setpgid", unimplementedFunc),
     /* 40 */ SyscallDesc("osf_old_lstat", unimplementedFunc),
     /* 41 */ SyscallDesc("dup", unimplementedFunc),
-    /* 42 */ SyscallDesc("pipe", pipeFunc),
+    /* 42 */ SyscallDesc("pipe", pipePseudoFunc),
     /* 43 */ SyscallDesc("osf_set_program_attributes", unimplementedFunc),
     /* 44 */ SyscallDesc("osf_profil", unimplementedFunc),
     /* 45 */ SyscallDesc("open", openFunc<Linux>),
     /* 46 */ SyscallDesc("osf_old_sigaction", unimplementedFunc),
-    /* 47 */ SyscallDesc("getxgid", getgidFunc),
+    /* 47 */ SyscallDesc("getxgid", getgidPseudoFunc),
     /* 48 */ SyscallDesc("osf_sigprocmask", ignoreFunc),
     /* 49 */ SyscallDesc("osf_getlogin", unimplementedFunc),
     /* 50 */ SyscallDesc("osf_setlogin", unimplementedFunc),
index 58d41e3ef72a1c9c7c32db0a3c4e3eb9ca752634..16621a8e2a0cd48b3ab21bd823d423515addbe6c 100644 (file)
@@ -27,7 +27,6 @@
  */
 
 #include "arch/alpha/isa_traits.hh"
-#include "arch/alpha/common_syscall_emul.hh"
 #include "arch/alpha/tru64/process.hh"
 #include "cpu/exec_context.hh"
 #include "kern/tru64/tru64.hh"
@@ -179,11 +178,11 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = {
     /* 17 */ SyscallDesc("obreak", obreakFunc),
     /* 18 */ SyscallDesc("pre_F64_getfsstat", unimplementedFunc),
     /* 19 */ SyscallDesc("lseek", lseekFunc),
-    /* 20 */ SyscallDesc("getpid", getpidFunc),
+    /* 20 */ SyscallDesc("getpid", getpidPseudoFunc),
     /* 21 */ SyscallDesc("mount", unimplementedFunc),
     /* 22 */ SyscallDesc("unmount", unimplementedFunc),
     /* 23 */ SyscallDesc("setuid", setuidFunc),
-    /* 24 */ SyscallDesc("getuid", getuidFunc),
+    /* 24 */ SyscallDesc("getuid", getuidPseudoFunc),
     /* 25 */ SyscallDesc("exec_with_loader", unimplementedFunc),
     /* 26 */ SyscallDesc("ptrace", unimplementedFunc),
     /* 27 */ SyscallDesc("recvmsg", unimplementedFunc),
@@ -206,7 +205,7 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = {
     /* 44 */ SyscallDesc("profil", unimplementedFunc),
     /* 45 */ SyscallDesc("open", openFunc<Tru64>),
     /* 46 */ SyscallDesc("obsolete osigaction", unimplementedFunc),
-    /* 47 */ SyscallDesc("getgid", getgidFunc),
+    /* 47 */ SyscallDesc("getgid", getgidPseudoFunc),
     /* 48 */ SyscallDesc("sigprocmask", ignoreFunc),
     /* 49 */ SyscallDesc("getlogin", unimplementedFunc),
     /* 50 */ SyscallDesc("setlogin", unimplementedFunc),
index 5a58bbaef4569245c826a55cd4dc516d353d61da..7f654e33b85e7eb8eff09207f5d896e9bb79d054 100644 (file)
@@ -78,7 +78,21 @@ namespace SparcISA
         // semantically meaningful register indices
         ZeroReg = 0    // architecturally meaningful
         // the rest of these depend on the ABI
-    };
+        SyscallNumReg = 1,
+        ArgumentReg0 = 8,
+        ArgumentReg1 = 9,
+        ArgumentReg2 = 10,
+        ArgumentReg3 = 11,
+        ArgumentReg4 = 12,
+        ArgumentReg5 = 13,
+        StackPoniterReg = 14,
+        ReturnAddressReg = 31, // Post Call, precall, 15
+        ReturnValueReg = 8, // Post return, 24 is pre-return.
+        // Some OS use a second register (o1) to return a second value
+        // for some syscalls
+        SyscallPseudoReturnReg = 9,
+        FramePointerReg = 30
+};
     typedef uint64_t IntReg;
 
     class IntRegFile
@@ -455,6 +469,22 @@ namespace SparcISA
      */
     template <class XC>
     static void zeroRegisters(XC *xc);
+
+    static inline setSyscallReturn(SyscallReturn return_value, RegFile *regs)
+    {
+        // check for error condition.  SPARC syscall convention is to
+        // indicate success/failure in reg the carry bit of the ccr
+        // and put the return value itself in the standard return value reg ().
+        if (return_value.successful()) {
+            // no error
+            regs->miscRegFile.ccrFields.iccFields.c = 0;
+            regs->intRegFile[ReturnValueReg] = return_value.value();
+        } else {
+            // got an error, return details
+            regs->miscRegFile.ccrFields.iccFields.c = 1;
+            regs->intRegFile[ReturnValueReg] = -return_value.value();
+        }
+    }
 };
 
 const int VMPageSize   = TheISA::VMPageSize;
index ebfbb2f6476854a3397773db98e1cfd769d27778..456f99b32404356167d9fc916bbc7d42ac24793d 100644 (file)
 using namespace std;
 using namespace SparcISA;
 
-/// Target pipe() handler.  Even though this is a generic Posix call,
-/// the Alpha return convention is funky, so that makes it
-/// Alpha-specific.
-SyscallReturn
-pipeFunc(SyscallDesc *desc, int callnum, Process *process,
-         ExecContext *xc)
-{
-    int fds[2], sim_fds[2];
-    int pipe_retval = pipe(fds);
-
-    if (pipe_retval < 0) {
-        // error
-        return pipe_retval;
-    }
-
-    sim_fds[0] = process->alloc_fd(fds[0]);
-    sim_fds[1] = process->alloc_fd(fds[1]);
-
-    // Alpha Linux convention for pipe() is that fd[0] is returned as
-    // the return value of the function, and fd[1] is returned in r20.
-    xc->regs.intRegFile[20] = sim_fds[1];
-    return sim_fds[0];
-}
-
 
 /// Target uname() handler.
 static SyscallReturn
@@ -77,95 +53,38 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process,
     strcpy(name->nodename, "m5.eecs.umich.edu");
     strcpy(name->release, "2.4.20");
     strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
-    strcpy(name->machine, "alpha");
+    strcpy(name->machine, "sparc");
 
     name.copyOut(xc->mem);
     return 0;
 }
 
-/// Target osf_getsysyinfo() handler.  Even though this call is
-/// borrowed from Tru64, the subcases that get used appear to be
-/// different in practice from those used by Tru64 processes.
-static SyscallReturn
-osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
-                   ExecContext *xc)
-{
-    unsigned op = xc->getSyscallArg(0);
-    // unsigned nbytes = xc->getSyscallArg(2);
-
-    switch (op) {
-
-      case 45: { // GSI_IEEE_FP_CONTROL
-          TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
-          // I don't think this exactly matches the HW FPCR
-          *fpcr = 0;
-          fpcr.copyOut(xc->mem);
-          return 0;
-      }
-
-      default:
-        cerr << "osf_getsysinfo: unknown op " << op << endl;
-        abort();
-        break;
-    }
-
-    return 1;
-}
-
-/// Target osf_setsysinfo() handler.
-static SyscallReturn
-osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
-                   ExecContext *xc)
-{
-    unsigned op = xc->getSyscallArg(0);
-    // unsigned nbytes = xc->getSyscallArg(2);
-
-    switch (op) {
-
-      case 14: { // SSI_IEEE_FP_CONTROL
-          TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
-          // I don't think this exactly matches the HW FPCR
-          fpcr.copyIn(xc->mem);
-          DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
-                   " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
-          return 0;
-      }
-
-      default:
-        cerr << "osf_setsysinfo: unknown op " << op << endl;
-        abort();
-        break;
-    }
-
-    return 1;
-}
-
 SyscallDesc SparcLinuxProcess::syscallDescs[] = {
     /*  0 */ SyscallDesc("restart_syscall", unimplimentedFunc);
-    /*  1 */ SyscallDesc("exit", unimplimentedFunc);
+    /*  1 */ SyscallDesc("exit", exitFunc);
     /*  2 */ SyscallDesc("fork", unimplimentedFunc);
-    /*  3 */ SyscallDesc("read", unimplimentedFunc);
-    /*  4 */ SyscallDesc("write", unimplimentedFunc);
-    /*  5 */ SyscallDesc("open", unimplimentedFunc);
-    /*  6 */ SyscallDesc("close", unimplimentedFunc);
+    /*  3 */ SyscallDesc("read", readFunc);
+    /*  4 */ SyscallDesc("write", writeFunc);
+    /*  5 */ SyscallDesc("open", openFunc<Linux>);
+    /*  6 */ SyscallDesc("close", closeFinc);
     /*  7 */ SyscallDesc("wait4", unimplimentedFunc);
     /*  8 */ SyscallDesc("creat", unimplimentedFunc);
     /*  9 */ SyscallDesc("link", unimplimentedFunc);
-    /* 10 */ SyscallDesc("unlink", unimplimentedFunc);
+    /* 10 */ SyscallDesc("unlink", unlinkFunc);
     /* 11 */ SyscallDesc("execv", unimplimentedFunc);
     /* 12 */ SyscallDesc("chdir", unimplimentedFunc);
-    /* 13 */ SyscallDesc("chown", unimplimentedFunc);
+    /* 13 */ SyscallDesc("chown", chownFunc);
     /* 14 */ SyscallDesc("mknod", unimplimentedFunc);
-    /* 15 */ SyscallDesc("chmod", unimplimentedFunc);
+    /* 15 */ SyscallDesc("chmod", chmodFunc<Linux>);
     /* 16 */ SyscallDesc("lchown", unimplimentedFunc);
-    /* 17 */ SyscallDesc("brk", unimplimentedFunc);
+    /* 17 */ SyscallDesc("brk", obreakFunc);
     /* 18 */ SyscallDesc("perfctr", unimplimentedFunc);
-    /* 19 */ SyscallDesc("lseek", unimplimentedFunc);
-    /* 20 */ SyscallDesc("getpid", unimplimentedFunc);
+    /* 19 */ SyscallDesc("lseek", lseekFunc);
+    /* 20 */ SyscallDesc("getpid", getpidFunc);
     /* 21 */ SyscallDesc("capget", unimplimentedFunc);
     /* 22 */ SyscallDesc("capset", unimplimentedFunc);
-    /* 23 */ SyscallDesc("setuid", unimplimentedFunc);
-    /* 24 */ SyscallDesc("getuid", unimplimentedFunc);
+    /* 23 */ SyscallDesc("setuid", setuidFunc);
+    /* 24 */ SyscallDesc("getuid", getuidFunc);
     /* 25 */ SyscallDesc("time", unimplimentedFunc);
     /* 26 */ SyscallDesc("ptrace", unimplimentedFunc);
     /* 27 */ SyscallDesc("alarm", unimplimentedFunc);
@@ -183,15 +102,15 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
     /* 39 */ SyscallDesc("sendfile", unimplimentedFunc);
     /* 40 */ SyscallDesc("lstat", unimplimentedFunc);
     /* 41 */ SyscallDesc("dup", unimplimentedFunc);
-    /* 42 */ SyscallDesc("pipe", unimplimentedFunc);
+    /* 42 */ SyscallDesc("pipe", pipePseudoFunc);
     /* 43 */ SyscallDesc("times", unimplimentedFunc);
     /* 44 */ SyscallDesc("getuid32", unimplimentedFunc);
     /* 45 */ SyscallDesc("umount2", unimplimentedFunc);
     /* 46 */ SyscallDesc("setgid", unimplimentedFunc);
-    /* 47 */ SyscallDesc("getgid", unimplimentedFunc);
+    /* 47 */ SyscallDesc("getgid", getgidFunc);
     /* 48 */ SyscallDesc("signal", unimplimentedFunc);
-    /* 49 */ SyscallDesc("geteuid", unimplimentedFunc);
-    /* 50 */ SyscallDesc("getegid", unimplimentedFunc);
+    /* 49 */ SyscallDesc("geteuid", geteuidFunc);
+    /* 50 */ SyscallDesc("getegid", getegidFunc);
     /* 51 */ SyscallDesc("acct", unimplimentedFunc);
     /* 52 */ SyscallDesc("memory_ordering", unimplimentedFunc);
     /* 53 */ SyscallDesc("getgid32", unimplimentedFunc);
@@ -330,7 +249,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
     /* 186 */ SyscallDesc("fremovexattr", unimplimentedFunc);
     /* 187 */ SyscallDesc("tkill", unimplimentedFunc);
     /* 188 */ SyscallDesc("exit_group", unimplimentedFunc);
-    /* 189 */ SyscallDesc("uname", unimplimentedFunc);
+    /* 189 */ SyscallDesc("uname", unameFunc);
     /* 190 */ SyscallDesc("init_module", unimplimentedFunc);
     /* 191 */ SyscallDesc("personality", unimplimentedFunc);
     /* 192 */ SyscallDesc("remap_file_pages", unimplimentedFunc);
@@ -338,7 +257,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
     /* 194 */ SyscallDesc("epoll_ctl", unimplimentedFunc);
     /* 195 */ SyscallDesc("epoll_wait", unimplimentedFunc);
     /* 196 */ SyscallDesc("ioprio_set", unimplimentedFunc);
-    /* 197 */ SyscallDesc("getppid", unimplimentedFunc);
+    /* 197 */ SyscallDesc("getppid", getppidFunc);
     /* 198 */ SyscallDesc("sigaction", unimplimentedFunc);
     /* 199 */ SyscallDesc("sgetmask", unimplimentedFunc);
     /* 200 */ SyscallDesc("ssetmask", unimplimentedFunc);
@@ -437,6 +356,10 @@ SparcLinuxProcess::SparcLinuxProcess(const std::string &name,
     : LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp),
      Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
 {
+    // The sparc syscall table must be <= 283 entries because that is all there
+    // is space for.
+    assert(Num_Syscall_Descs <= 283);
+
     init_regs->intRegFile[0] = 0;
 }
 
index fd69c9e5611589aea99ae014991e0637f492e00d..791c6f6ded1ef5c28617202b0f70e6bf70945fa3 100644 (file)
@@ -75,15 +75,6 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
         return NULL;
     }
     else {
-//        if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
-//            panic("32 bit ELF Binary, Not Supported");
-        /* @todo this emachine value isn't offical yet.
-         *       so we probably shouldn't check it. */
-//        if (ehdr.e_machine != EM_ALPHA)
-//            panic("Non Alpha Binary, Not Supported");
-
-        elf_end(elf);
-
         //Detect the architecture
         //Versioning issues in libelf need to be resolved to get the correct
         //SPARC constants.
@@ -109,17 +100,61 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data)
         //Detect the operating system
         switch (ehdr.e_ident[EI_OSABI])
         {
+
           case ELFOSABI_LINUX:
             opSys = ObjectFile::Linux;
             break;
           case ELFOSABI_SOLARIS:
             opSys = ObjectFile::Solaris;
+            break;
           case ELFOSABI_TRU64:
             opSys = ObjectFile::Tru64;
+            break;
           default:
             opSys = ObjectFile::UnknownOpSys;
         }
 
+        //take a look at the .note.ABI section
+        //It can let us know what's what.
+        if (opSys == ObjectFile::UnknownOpSys)
+        {
+            Elf_Scn *section;
+            GElf_Shdr shdr;
+            Elf_Data *data;
+            uint32_t osAbi;;
+            int secIdx = 1;
+
+            // Get the first section
+            section = elf_getscn(elf, secIdx);
+
+            // While there are no more sections
+            while (section != NULL) {
+                gelf_getshdr(section, &shdr);
+                if (shdr.sh_type == SHT_NOTE && !strcmp(".note.ABI-tag",
+                            elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name))) {
+                    // we have found a ABI note section
+                    // Check the 5th 32bit word for OS  0 == linux, 1 == hurd,
+                    // 2 == solaris, 3 == freebsd
+                    data = elf_rawdata(section, NULL);
+                    assert(data->d_buf);
+                    if(ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
+                        osAbi = htole(((uint32_t*)data->d_buf)[4]);
+                    else
+                        osAbi = htobe(((uint32_t*)data->d_buf)[4]);
+
+                    switch(osAbi) {
+                      case 0:
+                        opSys = ObjectFile::Linux;
+                        break;
+                      case 2:
+                        opSys = ObjectFile::Solaris;
+                        break;
+                    }
+                } // if section found
+            section = elf_getscn(elf, ++secIdx);
+            } // while sections
+        }
+        elf_end(elf);
         return new ElfObject(fname, fd, len, data, arch, opSys);
     }
 }
index bc3551b4fa0b0d0e0fd48284ec0a48e38e2d176c..97bfc5f0d22411dfafc7d99e22748a15dda98f11 100644 (file)
@@ -464,19 +464,7 @@ class ExecContext
 
     void setSyscallReturn(SyscallReturn return_value)
     {
-        // check for error condition.  Alpha syscall convention is to
-        // indicate success/failure in reg a3 (r19) and put the
-        // return value itself in the standard return value reg (v0).
-        const int RegA3 = 19;  // only place this is used
-        if (return_value.successful()) {
-            // no error
-            regs.intRegFile[RegA3] = 0;
-            regs.intRegFile[TheISA::ReturnValueReg] = return_value.value();
-        } else {
-            // got an error, return details
-            regs.intRegFile[RegA3] = (TheISA::IntReg) -1;
-            regs.intRegFile[TheISA::ReturnValueReg] = -return_value.value();
-        }
+        TheISA::setSyscallReturn(return_value, &regs);
     }
 
     void syscall()
index fddd9a0b9d9cbd24bad4d23b1907b4b42ae8b041..894beeb05f05bf4b6dbcb9bfbe4f0a219f900a15 100644 (file)
@@ -354,7 +354,7 @@ LiveProcess::syscall(ExecContext *xc)
 {
     num_syscalls++;
 
-    int64_t callnum = xc->regs.intRegFile[ReturnValueReg];
+    int64_t callnum = xc->regs.intRegFile[SyscallNumReg];
 
     SyscallDesc *desc = getDesc(callnum);
     if (desc == NULL)
index d22dde3b8a9e8fc0fb1dfee077bfe756fbbb22d5..682d11267aec20565898325717d5a3b03ac4cb1f 100644 (file)
@@ -324,4 +324,118 @@ fcntlFunc(SyscallDesc *desc, int num, Process *process,
     }
 }
 
+SyscallReturn
+pipePseudoFunc(SyscallDesc *desc, int callnum, Process *process,
+         ExecContext *xc)
+{
+    int fds[2], sim_fds[2];
+    int pipe_retval = pipe(fds);
+
+    if (pipe_retval < 0) {
+        // error
+        return pipe_retval;
+    }
+
+    sim_fds[0] = process->alloc_fd(fds[0]);
+    sim_fds[1] = process->alloc_fd(fds[1]);
+
+    // Alpha Linux convention for pipe() is that fd[0] is returned as
+    // the return value of the function, and fd[1] is returned in r20.
+    xc->regs.intRegFile[SyscallPseudoReturnReg] = sim_fds[1];
+    return sim_fds[0];
+}
+
+
+SyscallReturn
+getpidPseudoFunc(SyscallDesc *desc, int callnum, Process *process,
+           ExecContext *xc)
+{
+    // Make up a PID.  There's no interprocess communication in
+    // fake_syscall mode, so there's no way for a process to know it's
+    // not getting a unique value.
+
+    xc->regs.intRegFile[SyscallPseudoReturnReg] = 99;
+    return 100;
+}
+
+
+SyscallReturn
+getuidPseudoFunc(SyscallDesc *desc, int callnum, Process *process,
+           ExecContext *xc)
+{
+    // Make up a UID and EUID... it shouldn't matter, and we want the
+    // simulation to be deterministic.
+
+    // EUID goes in r20.
+    xc->regs.intRegFile[SyscallPseudoReturnReg] = 100; // EUID
+    return 100;                // UID
+}
+
+
+SyscallReturn
+getgidPseudoFunc(SyscallDesc *desc, int callnum, Process *process,
+           ExecContext *xc)
+{
+    // Get current group ID.  EGID goes in r20.
+    xc->regs.intRegFile[SyscallPseudoReturnReg] = 100;
+    return 100;
+}
+
+
+SyscallReturn
+setuidFunc(SyscallDesc *desc, int callnum, Process *process,
+           ExecContext *xc)
+{
+    // can't fathom why a benchmark would call this.
+    warn("Ignoring call to setuid(%d)\n", xc->getSyscallArg(0));
+    return 0;
+}
+
+SyscallReturn
+getpidFunc(SyscallDesc *desc, int callnum, Process *process,
+           ExecContext *xc)
+{
+    // Make up a PID.  There's no interprocess communication in
+    // fake_syscall mode, so there's no way for a process to know it's
+    // not getting a unique value.
+
+    xc->regs.intRegFile[SyscallPseudoReturnReg] = 99;
+    return 100;
+}
+
+SyscallReturn
+getppidFunc(SyscallDesc *desc, int callnum, Process *process,
+           ExecContext *xc)
+{
+    return 99;
+}
+
+SyscallReturn
+getuidFunc(SyscallDesc *desc, int callnum, Process *process,
+           ExecContext *xc)
+{
+    return 100;                // UID
+}
+
+SyscallReturn
+geteuidFunc(SyscallDesc *desc, int callnum, Process *process,
+           ExecContext *xc)
+{
+    return 100;                // UID
+}
+
+SyscallReturn
+getgidFunc(SyscallDesc *desc, int callnum, Process *process,
+           ExecContext *xc)
+{
+    return 100;
+}
+
+SyscallReturn
+getegidFunc(SyscallDesc *desc, int callnum, Process *process,
+           ExecContext *xc)
+{
+    return 100;
+}
+
 
index eca9f79e040b6c48541a4391c1a09c5ba9c4124d..539358b8f2295605cabf5d380f2bfed7f5f567d1 100644 (file)
@@ -243,6 +243,54 @@ SyscallReturn fchownFunc(SyscallDesc *desc, int num,
 SyscallReturn fcntlFunc(SyscallDesc *desc, int num,
                         Process *process, ExecContext *xc);
 
+/// Target setuid() handler.
+SyscallReturn setuidFunc(SyscallDesc *desc, int num,
+                               Process *p, ExecContext *xc);
+
+/// Target getpid() handler.
+SyscallReturn getpidFunc(SyscallDesc *desc, int num,
+                               Process *p, ExecContext *xc);
+
+/// Target getuid() handler.
+SyscallReturn getuidFunc(SyscallDesc *desc, int num,
+                               Process *p, ExecContext *xc);
+
+/// Target getgid() handler.
+SyscallReturn getgidFunc(SyscallDesc *desc, int num,
+                               Process *p, ExecContext *xc);
+
+/// Target getppid() handler.
+SyscallReturn getppidFunc(SyscallDesc *desc, int num,
+                               Process *p, ExecContext *xc);
+
+/// Target geteuid() handler.
+SyscallReturn geteuidFunc(SyscallDesc *desc, int num,
+                               Process *p, ExecContext *xc);
+
+/// Target getegid() handler.
+SyscallReturn getegidFunc(SyscallDesc *desc, int num,
+                               Process *p, ExecContext *xc);
+
+
+
+/// Pseudo Funcs  - These functions use a different return convension,
+/// returning a second value in a register other than the normal return register
+SyscallReturn pipePseudoFunc(SyscallDesc *desc, int num,
+                             Process *process, ExecContext *xc);
+
+/// Target getpidPseudo() handler.
+SyscallReturn getpidPseudoFunc(SyscallDesc *desc, int num,
+                               Process *p, ExecContext *xc);
+
+/// Target getuidPseudo() handler.
+SyscallReturn getuidPseudoFunc(SyscallDesc *desc, int num,
+                               Process *p, ExecContext *xc);
+
+/// Target getgidPseudo() handler.
+SyscallReturn getgidPseudoFunc(SyscallDesc *desc, int num,
+                               Process *p, ExecContext *xc);
+
+
 /// This struct is used to build an target-OS-dependent table that
 /// maps the target's open() flags to the host open() flags.
 struct OpenFlagTransTable {