# - Local objects (use the kernel includes)\r
OBJ := helpers.o threads.o threads_glue.o server.o syscalls.o time.o\r
OBJ += video.o keyboard.o mouse.o nativefs.o vfs_handle.o ui_sdl.o\r
-OBJ += net.o\r
+OBJ += net.o syscall_getpath.o\r
\r
BUILDINFO_OBJ := obj-$(PLATFORM)/buildinfo.o\r
BUILDINFO_SRC := $(BUILDINFO_OBJ:%.o=%.c)\r
extern int giBuildNumber;
// === GLOBALS ===
-const char *gsAcessDir = "../Usermode/Output/x86_64";
+const char *gsAcessDir = "../Usermode/Output/native";
// === CODE ===
#ifndef __WIN32__
--- /dev/null
+/*
+ * AcessNative Kernel
+ *
+ * syscall_getpath.c
+ * - Implementation of the SYS_AN_GETPATH system call
+ */
+
+#include <acess.h>
+#include <vfs_int.h>
+
+extern char *getcwd(char *buf, size_t size);
+
+extern tVFS_NodeType gNativeFS_FileNodeType;
+extern tVFS_NodeType gNativeFS_DirNodeType;
+
+int Syscall_AN_GetPath_Real(char *Dst, size_t DstLen, const char *Path)
+{
+ tVFS_Node *node = VFS_ParsePath(Path, NULL, NULL);
+ if(!node) return -1;
+
+ const char *relpath = NULL;
+
+ if( node->Type == &gNativeFS_FileNodeType || node->Type == &gNativeFS_DirNodeType )
+ {
+ relpath = node->Data;
+ }
+ else
+ {
+ relpath = NULL;
+ }
+
+ size_t ret;
+ if( relpath )
+ {
+ if( relpath[0] == '/' ) {
+ ret = snprintf(Dst, DstLen, "%s", relpath);
+ }
+ else {
+ getcwd(Dst, DstLen);
+ ret = strlen(Dst);
+ ret += snprintf(Dst+ret, DstLen-ret, "/%s", relpath);
+ }
+ }
+ else
+ {
+ ret = 0;
+ }
+
+ _CloseNode(node);
+ return ret;
+}
// === IMPORTS ===
extern int Threads_Fork(void); // AcessNative only function
extern int Threads_Spawn(int nFD, int FDs[], const void *info);
+extern int Syscall_AN_GetPath_Real(char *Dest, size_t DstLen, const char *Path);
// === TYPES ===
typedef int (*tSyscallHandler)(Uint *Errno, const char *Format, void *Args, int *Sizes);
// === MACROS ===
+#define _SYSCALL_CHKFMT(_name,_fmtstr,Fmt) do{ \
+ if(strcmp(Fmt,_fmtstr) != 0) {\
+ *Errno = EINVAL;\
+ Log_Error("Syscalls", "Call %s takes args '%s', given '%s'", #_name, _fmtstr, Fmt);\
+ return -1;\
+ }\
+} while(0)
#define SYSCALL6(_name, _fmtstr, _t0, _t1, _t2, _t3, _t4, _t5, _call) int _name(Uint*Errno,const char*Fmt,void*Args,int*Sizes){\
_t0 a0;_t1 a1;_t2 a2;_t3 a3;_t4 a4;_t5 a5;\
- if(strcmp(Fmt,_fmtstr)!=0)return 0;\
+ _SYSCALL_CHKFMT(_name,_fmtstr,Fmt);\
a0 = *(_t0*)Args;Args+=sizeof(_t0);\
a1 = *(_t1*)Args;Args+=sizeof(_t1);\
a2 = *(_t2*)Args;Args+=sizeof(_t2);\
}
#define SYSCALL5(_name, _fmtstr, _t0, _t1, _t2, _t3, _t4, _call) int _name(Uint*Errno,const char*Fmt,void*Args,int*Sizes){\
_t0 a0;_t1 a1;_t2 a2;_t3 a3;_t4 a4;\
- if(strcmp(Fmt,_fmtstr)!=0)return 0;\
+ _SYSCALL_CHKFMT(_name,_fmtstr,Fmt);\
a0 = *(_t0*)Args;Args+=sizeof(_t0);\
a1 = *(_t1*)Args;Args+=sizeof(_t1);\
a2 = *(_t2*)Args;Args+=sizeof(_t2);\
}
#define SYSCALL4(_name, _fmtstr, _t0, _t1, _t2, _t3, _call) int _name(Uint*Errno,const char*Fmt,void*Args,int*Sizes){\
_t0 a0;_t1 a1;_t2 a2;_t3 a3;\
- if(strcmp(Fmt,_fmtstr)!=0)return 0;\
+ _SYSCALL_CHKFMT(_name,_fmtstr,Fmt);\
a0 = *(_t0*)Args;Args+=sizeof(_t0);\
a1 = *(_t1*)Args;Args+=sizeof(_t1);\
a2 = *(_t2*)Args;Args+=sizeof(_t2);\
#define SYSCALL3(_name, _fmtstr, _t0, _t1, _t2, _call) int _name(Uint*Errno,const char*Fmt,void*Args,int*Sizes){\
_t0 a0;_t1 a1;_t2 a2;\
- if(strcmp(Fmt,_fmtstr)!=0)return 0;\
+ _SYSCALL_CHKFMT(_name,_fmtstr,Fmt);\
a0 = *(_t0*)Args;Args+=sizeof(_t0);\
a1 = *(_t1*)Args;Args+=sizeof(_t1);\
a2 = *(_t2*)Args;Args+=sizeof(_t2);\
#define SYSCALL2(_name, _fmtstr, _t0, _t1, _call) int _name(Uint*Errno,const char*Fmt,void*Args,int*Sizes){\
_t0 a0;_t1 a1;\
- if(strcmp(Fmt,_fmtstr)!=0)return 0;\
+ _SYSCALL_CHKFMT(_name,_fmtstr,Fmt);\
a0 = *(_t0*)Args;Args+=sizeof(_t0);\
a1 = *(_t1*)Args;Args+=sizeof(_t1);\
LOG("SYSCALL2 '%s' %p %p", Fmt, (intptr_t)a0,(intptr_t)a1);\
#define SYSCALL1(_name, _fmtstr, _t0, _call) int _name(Uint*Errno,const char*Fmt, void*Args,int*Sizes){\
_t0 a0;\
- if(strcmp(Fmt,_fmtstr)!=0)return 0;\
+ _SYSCALL_CHKFMT(_name,_fmtstr,Fmt);\
a0 = *(_t0*)Args;Args+=sizeof(_t0);\
LOG("SYSCALL1 '%s' %p", Fmt,(intptr_t)a0);\
_call;\
}
#define SYSCALL0(_name, _call) int _name(Uint*Errno,const char*Fmt, void*Args,int*Sizes){\
- if(strcmp(Fmt,"")!=0)return 0;\
+ _SYSCALL_CHKFMT(_name,"",Fmt);\
LOG("SYSCALL0");\
_call;\
}
SYSCALL1(Syscall_Chdir, "s", const char *,
return VFS_ChDir(a0);
);
+
+SYSCALL2(Syscall_AN_Getpath, "ds", char *, const char *,
+ return Syscall_AN_GetPath_Real(a0, Sizes[0], a1);
+);
+
SYSCALL0(Syscall_Sleep,
Threads_Sleep();
return 0;
[SYS_MOUNT] = Syscall_Mount,
[SYS_REOPEN] = NULL, // SYS_REOPEN
[SYS_CHDIR] = Syscall_Chdir,
+ [SYS_AN_GETPATH] = Syscall_AN_Getpath,
[SYS_WAITTID] = Syscall_WaitTID,
[SYS_SETUID] = Syscall_SetUID,
Syscall_GetGID,
Syscall_Sleep,
- Syscall_AN_Fork,
- Syscall_AN_Spawn,
+ [SYS_AN_FORK] = Syscall_AN_Fork,
+ [SYS_AN_SPAWN] = Syscall_AN_Spawn,
Syscall_SendMessage,
Syscall_GetMessage,
CFLAGS += -Wall
CFLAGS += -Werror
-CFLAGS += -g
+CFLAGS += -g -std=c99
CPPFLAGS += -DARCHDIR_is_x86_64=1
LDFLAGS += -g -Wl,-T,obj-$(PLATFORM)/link.ld
return _Syscall(SYS_CHDIR, ">s", Path);
}
-int acess__SysOpen(const char *Path, int Flags)
+int acess__SysOpen(const char *Path, unsigned int Flags)
{
if( strncmp(Path, "$$$$", 4) == 0 )
{
int kernel_tid;
int newID;
- newID = _Syscall(SYS_AN_SPAWN, "<d >d >d", sizeof(int), &kernel_tid,
+ newID = _Syscall(SYS_AN_SPAWN, "<d >d >d",
+ sizeof(int), &kernel_tid,
nfd*sizeof(int), fds,
info ? sizeof(*info) : 0, info);
#define _EXPORTS_H_
#include <stddef.h>
+#include <stdint.h>
// Syscall request (used by acess_*)
extern uint64_t _Syscall(int SyscallID, const char *ArgTypes, ...);
extern int native_spawn(const char *filename, const char *const argv[], const char *const envp[]);
// Syscalls used by the linker
-extern int acess__SysOpen(const char *Path, int Flags);
+extern int acess__SysOpen(const char *Path, unsigned int Flags);
extern void acess__SysClose(int FD);
extern size_t acess__SysRead(int FD, void *Dest, size_t Bytes);
extern int acess__SysSeek(int FD, int64_t Offset, int Dir);
int native_spawn(const char *filename, const char *const argv[], const char *const envp[])
{
int rv;
-
+
+ fprintf(stderr, "native_spawn('%s')\n", filename);
+
#if __WIN32__
rv = _spawnve(_P_NOWAIT, filename, argv, envp);
#else
rv = posix_spawn(NULL, filename, NULL, NULL, (void*)argv, (void*)envp);
#endif
+ if( rv == 0 ) {
+ perror("native_spawn");
+ }
+
return rv;
}
ifeq ($(PLATFORM),lin)
BIN := ../libacess-native.so
endif
+BINLINK := ../../Usermode/Output/native/Libs/$(notdir $(BIN))
+$(warning $(BINLINK))
CFLAGS += -Wall
CFLAGS += -Werror
.PHONY: all clean
-all: $(BIN)
+all: $(BIN) $(BINLINK)
clean:
$(RM) $(BIN) $(OBJ) $(DEPFILES)
$(CC) -o $@ $(OBJ) $(LDFLAGS)
+$(BINLINK): $(BIN)
+ @mkdir -p $(dir $@)
+ @cd $(dir $@) && ln -sf ../../../../AcessNative/$(notdir $@)
+
obj-$(PLATFORM)/%.o: %.c
@mkdir -p $(dir $@)
@echo [CC] -o $@
--- /dev/null
+
+#ifndef _LIBACESSNATIVE_COMMON_H_
+#define _LIBACESSNATIVE_COMMON_H_
+
+extern int giSyscall_ClientID;
+extern void Request_Preinit(void);
+extern int acess__SysOpen(const char *Path, unsigned int flags);
+extern int acessnative_spawn(const char *Binary, int SyscallID, const char * const * argv, const char * const * envp);
+
+#define ENV_VAR_PREOPENS "AN_PREOPEN"
+#define ENV_VAR_KEY "ACESSNATIVE_KEY"
+
+#endif
+
+#include "common.h"
#define acess__SysSpawn _disabled_acess__SysSpawn
#include "../ld-acess_src/exports.c"
int acess__SysSpawn(const char *binary, const char **argv, const char **envp, int nfd, int fds[], struct s_sys_spawninfo *info)
{
int argc = 0;
- while( argv[argc++] );
+ while( argv[argc++] )
+ ;
Debug("_SysSpawn('%s', %p (%i), %p, %i, %p, %p)",
binary, argv, argc, envp, nfd, fds, info);
- int kernel_tid;
- int newID;
- newID = _Syscall(SYS_AN_SPAWN, "<d >d >d", sizeof(int), &kernel_tid,
+ char realpath[256];
+ realpath[255] = 0;
+
+ if( _Syscall(SYS_AN_GETPATH, "<d >s", sizeof(realpath)-1, realpath, binary) <= 0 ) {
+ Warning("No translation for path '%s'", binary);
+ acess__errno = -11;
+ return -1;
+ }
+
+ Warning("TODO: Spawn '%s' = '%s'", binary, realpath);
+
+ int emulated_tid;
+ int newID = _Syscall(SYS_AN_SPAWN, "<d >d >d",
+ sizeof(emulated_tid), &emulated_tid,
nfd*sizeof(int), fds,
- info ? sizeof(*info) : 0, info);
-
+ (info ? sizeof(*info) : 0), info
+ );
- Warning("TODO: Spawn '%s'", binary);
- // TODO: Translate internal path to actual path
+ if( newID <= 0 ) {
+ return -1;
+ }
- // TODO: set environment variables for libacess-native
- // > ACESSNATIVE_KEY=`newID`
- //native_spawn(binary, argv, envp);
+ if( acessnative_spawn(realpath, newID, argv, envp) ) {
+ }
- return 0;
+ return emulated_tid;
}
void ldacess_DumpLoadedLibraries(void)
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-
-extern int giSyscall_ClientID;
-extern void Request_Preinit(void);
-extern int acess__SysOpen(const char *Path, unsigned int flags);
+#include <stdbool.h>
+#include "common.h"
+#include <stdint.h>
+#include "../ld-acess_src/exports.h"
#ifdef __WINDOWS__
int DllMain(void)
{
Request_Preinit();
- const char *preopens = getenv_p(envp, "AN_PREOPEN");
+ const char *preopens = getenv_p(envp, ENV_VAR_PREOPENS);
printf("preopens = %s\n", preopens);
if( preopens )
{
}
}
-// if( !getenv("ACESSNATIVE_ID")
+// if( !getenv(ENV_VAR_KEY)
return 0;
}
#endif
+int acessnative_spawn(const char *Binary, int SyscallID, const char * const * argv, const char * const * envp)
+{
+ int envc = 0;
+ while( envp[envc++] )
+ envc ++;
+
+ // Set environment variables for libacess-native
+ // > ACESSNATIVE_KEY=`newID`
+ size_t keystr_len = snprintf(NULL, 0, "%s=%i", ENV_VAR_KEY, SyscallID);
+ char keystr[keystr_len+1];
+ snprintf(keystr, keystr_len+1, "%s=%i", ENV_VAR_KEY, SyscallID);
+ bool bKeyHit = false;
+
+ const char *newenv[envc+2+1];
+ int i = 0;
+ for( ; envp[i]; i ++ )
+ {
+ const char *ev = envp[i];
+ if( strncmp(ev, ENV_VAR_KEY"=", sizeof(ENV_VAR_KEY"=")) == 0 ) {
+ ev = keystr;
+ bKeyHit = true;
+ }
+ newenv[i] = ev;
+ }
+ if( !bKeyHit )
+ newenv[i++] = keystr;
+ newenv[i++] = "LD_LIBRARY_PATH=Libs/"; // HACK
+ newenv[i] = NULL;
+
+ // TODO: Detect native_spawn failing
+ return native_spawn(Binary, argv, newenv);
+}
void Debug(const char *format, ...)
{
{
}
+void __stack_chk_fail(void)
+{
+ fprintf(stderr, "__stack_chk_fail");
+ exit(1);
+}
+
_(SYS_MOUNT),
_(SYS_CHDIR),
+_(SYS_AN_GETPATH),
+
_(SYS_WAITTID),
_(SYS_SETUID),
_(SYS_SETGID),