Tools/NetTest - Add TCP retransmit test
[tpg/acess2.git] / AcessNative / ld-acess_src / exports.c
1 /*
2  * AcessNative
3  *
4  * exports.c
5  * - Exported functions
6  */
7 #define DONT_INCLUDE_SYSCALL_NAMES 1
8 #include "../../Usermode/Libraries/ld-acess.so_src/include_exp/acess/sys.h"
9 #include "../syscalls.h"
10 #include "exports.h"
11 #include <stdarg.h>
12 #include <stddef.h>
13
14 #define DEBUG(v...)     do{if(gbSyscallDebugEnabled)Debug(v);}while(0)
15 #define PAGE_SIZE       4096
16
17 #define TODO()  Warning("TODO: %s", __func__)
18
19 typedef struct sFILE    FILE;
20
21 extern void     exit(int) __attribute__ ((noreturn));
22 extern int      printf(const char *, ...);
23 extern int      fprintf(FILE *,const char *, ...);
24 extern int      sprintf(char *,const char *, ...);
25 extern int      vprintf(const char *, va_list);
26 extern int      strncmp(const char *, const char *, size_t);
27
28 extern int      gSocket;
29 extern int      giSyscall_ClientID;     // Needed for execve
30 extern void     _InitSyscalls(void);
31 extern void     _CloseSyscalls(void);
32
33 extern void     Warning(const char *Format, ...);
34 extern void     Debug(const char *Format, ...);
35 extern int      AllocateMemory(uintptr_t VirtAddr, size_t ByteCount);
36
37 // === CONSTANTS ===
38 #define NATIVE_FILE_MASK        0x40000000
39
40 // === GLOBALS ===
41 int     acess__errno;
42  int    gbSyscallDebugEnabled = 0;
43 char    *gsExecutablePath = "./ld-acess";
44
45 // === CODE ===
46 // --- VFS Calls
47 int acess__SysChdir(const char *Path)
48 {
49         return _Syscall(SYS_CHDIR, ">s", Path);
50 }
51
52 int acess__SysOpen(const char *Path, unsigned int Flags)
53 {
54         if( strncmp(Path, "$$$$", 4) == 0 )
55         {
56                 return native_open(Path+4, Flags) | NATIVE_FILE_MASK;
57         }
58         if( strncmp(Path, "/Devices/shm/", 13) == 0 )
59         {
60                 const char* tag = Path + 13;
61                 Warning("TODO: Handle open SHM \"%s\"", tag);
62                 return native_shm(tag, Flags) | NATIVE_FILE_MASK;
63         }
64         SYSTRACE("open(\"%s\", 0x%x)", Path, Flags);
65         return _Syscall(SYS_OPEN, ">s >i", Path, Flags);
66 }
67
68 void acess__SysClose(int FD)
69 {
70         if(FD & NATIVE_FILE_MASK) {
71                 return native_close(FD & (NATIVE_FILE_MASK-1));
72         }
73         SYSTRACE("close(%i)", FD);
74         _Syscall(SYS_CLOSE, ">i", FD);
75 }
76
77 int acess__SysReopen(int FD, const char *Path, int Flags) {
78         SYSTRACE("reopen(0x%x, \"%s\", 0x%x)", FD, Path, Flags);
79         return _Syscall(SYS_REOPEN, ">i >s >i", FD, Path, Flags);
80 }
81
82 int acess__SysCopyFD(int srcfd, int dstfd) {
83         SYSTRACE("_SysCopyFD(%i, %i)", srcfd, dstfd);
84         return _Syscall(SYS_COPYFD, ">i >i", srcfd, dstfd);
85 }
86
87 int acess__SysFDFlags(int fd, int mask, int newflags) {
88         return _Syscall(SYS_FDFLAGS, ">i >i >i", fd, mask, newflags);
89 }
90
91 size_t acess__SysRead(int FD, void *Dest, size_t Bytes) {
92         if(FD & NATIVE_FILE_MASK)
93                 return native_read(FD & (NATIVE_FILE_MASK-1), Dest, Bytes);
94         SYSTRACE("_SysRead(0x%x, 0x%x, *%p)", FD, Bytes, Dest);
95         return _Syscall(SYS_READ, ">i >i <d", FD, Bytes, Bytes, Dest);
96 }
97
98 size_t acess__SysWrite(int FD, const void *Src, size_t Bytes) {
99         if(FD & NATIVE_FILE_MASK)
100                 return native_write(FD & (NATIVE_FILE_MASK-1), Src, Bytes);
101         SYSTRACE("_SysWrite(0x%x, 0x%x, %p\"%.*s\")", FD, Bytes, Src, Bytes, (char*)Src);
102         return _Syscall(SYS_WRITE, ">i >i >d", FD, Bytes, Bytes, Src);
103 }
104 uint64_t acess__SysTruncate(int fd, uint64_t size) {
105         TODO();
106         return 0;
107 }
108
109 int acess__SysSeek(int FD, int64_t Ofs, int Dir)
110 {
111         if(FD & NATIVE_FILE_MASK) {
112                 return native_seek(FD & (NATIVE_FILE_MASK-1), Ofs, Dir);
113         }
114         SYSTRACE("_SysSeek(0x%x, 0x%llx, %i)", FD, Ofs, Dir);
115         return _Syscall(SYS_SEEK, ">i >I >i", FD, Ofs, Dir);
116 }
117
118 uint64_t acess__SysTell(int FD)
119 {
120         if(FD & NATIVE_FILE_MASK)
121                 return native_tell( FD & (NATIVE_FILE_MASK-1) );
122         SYSTRACE("_SysTell(0x%x)", FD);
123         return _Syscall(SYS_TELL, ">i", FD);
124 }
125
126 int acess__SysIOCtl(int fd, int id, void *data) {
127          int    len;
128         SYSTRACE("_SysIOCtl(%i, %i, %p)", fd, id, data);
129         // NOTE: The length here is hacky and could break
130         len = (data == NULL ? 0 : PAGE_SIZE - ((uintptr_t)data % PAGE_SIZE));
131         return _Syscall(SYS_IOCTL, ">i >i ?d", fd, id, len, data);
132 }
133 int acess__SysFInfo(int fd, t_sysFInfo *info, int maxacls) {
134         SYSTRACE("_SysFInfo(%i, %p, %i)", fd, info, maxacls);
135         return _Syscall(SYS_FINFO, ">i <d >i",
136                 fd,
137                 sizeof(t_sysFInfo)+maxacls*sizeof(t_sysACL), info,
138                 maxacls
139                 );
140 }
141
142 int acess__SysReadDir(int fd, char *dest) {
143         SYSTRACE("_SysReadDir(%i, %p)", fd, dest);
144         return _Syscall(SYS_READDIR, ">i <d", fd, 256, dest);
145 }
146
147 int acess__SysSelect(int nfds, fd_set *read, fd_set *write, fd_set *error, int64_t *timeout, uint32_t events)
148 {
149         SYSTRACE("_SysSelect(%i, %p, %p, %p, %p, 0x%x)", nfds, read, write, error, timeout, events);
150         return _Syscall(SYS_SELECT, ">i ?d ?d ?d >d >i", nfds,
151                 read ? (nfds+7)/8 : 0, read,
152                 write ? (nfds+7)/8 : 0, write,
153                 error ? (nfds+7)/8 : 0, error,
154                 sizeof(*timeout), timeout,
155                 events
156                 );
157 }
158 int acess__SysMkDir(const char *pathname)
159 {
160         TODO();
161         return 0;
162 }
163 int acess__SysUnlink(const char *pathname)
164 {
165         // TODO:
166         TODO();
167         return 0;
168 }
169 void* acess__SysMMap(void *addr, size_t length, unsigned int _flags, int fd, uint64_t offset)
170 {
171         TODO();
172         return NULL;
173 }
174 int acess__SysMUnMap(void *addr, size_t length)
175 {
176         TODO();
177         return 0;
178 }
179 uint64_t acess__SysMarshalFD(int FD)
180 {
181         TODO();
182         return 0;
183 }
184 int acess__SysUnMarshalFD(uint64_t Handle)
185 {
186         TODO();
187         return -1;
188 }
189
190 int acess__SysOpenChild(int fd, char *name, int flags) {
191         SYSTRACE("_SysOpenChild(0x%x, '%s', 0x%x)", fd, name, flags);
192         return _Syscall(SYS_OPENCHILD, ">i >s >i", fd, name, flags);
193 }
194
195 int acess__SysGetACL(int fd, t_sysACL *dest) {
196         SYSTRACE("%s(0x%x, %p)", __func__, fd, dest);
197         return _Syscall(SYS_GETACL, ">i <d", fd, sizeof(t_sysACL), dest);
198 }
199
200 int acess__SysMount(const char *Device, const char *Directory, const char *Type, const char *Options) {
201         SYSTRACE("_SysMount('%s', '%s', '%s', '%s')", Device, Directory, Type, Options);
202         return _Syscall(SYS_MOUNT, ">s >s >s >s", Device, Directory, Type, Options);
203 }
204
205
206 // --- Error Handler
207 int acess__SysSetFaultHandler(int (*Handler)(int)) {
208         printf("TODO: Set fault handler (asked to set to %p)\n", Handler);
209         return 0;
210 }
211
212 void acess__SysSetName(const char *Name)
213 {
214         // TODO:
215         TODO();
216 }
217
218 int acess__SysGetName(char *NameDest)
219 {
220         // TODO: 
221         TODO();
222         return 0;
223 }
224
225 int acess__SysSetPri(int Priority)
226 {
227         // TODO:
228         TODO();
229         return 0;
230 }
231
232 // --- Binaries? ---
233 void *acess_SysLoadBin(const char *path, void **entry)
234 {
235         // ERROR!
236         TODO();
237         return NULL;
238 }
239
240 int acess__SysUnloadBin(void *base)
241 {
242         // ERROR!
243         TODO();
244         return -1;
245 }
246
247 // --- System ---
248 int acess__SysLoadModule(const char *Path)
249 {
250         TODO();
251         return -1;
252 }
253
254 // --- Timekeeping ---
255 int64_t acess__SysTimestamp(void)
256 {
257         return native_timestamp();
258 }
259
260 // --- Memory Management ---
261 uint64_t acess__SysGetPhys(uintptr_t vaddr)
262 {
263         // TODO:
264         TODO();
265         return 0;
266 }
267
268 uint64_t acess__SysAllocate(uintptr_t vaddr)
269 {
270         if( AllocateMemory(vaddr, 0x1000) == -1 )       // Allocate a page
271                 return 0;
272                 
273         return vaddr;   // Just ignore the need for paddrs :)
274 }
275
276 // --- Process Management ---
277 int acess__SysClone(int flags, void *stack)
278 {
279         #ifdef __WIN32__
280         Warning("Win32 does not support anything like fork(2), cannot emulate");
281         exit(-1);
282         #else
283         extern int fork(void);
284         if(flags & CLONE_VM) {
285                  int    ret, newID, kernel_tid=0;
286                 Debug("USERSIDE fork()");
287                 
288                 newID = _Syscall(SYS_AN_FORK, "<d", sizeof(int), &kernel_tid);
289                 ret = fork();
290                 if(ret < 0) {
291                         return ret;
292                 }
293                 
294                 if(ret == 0)
295                 {
296                         _CloseSyscalls();
297                         giSyscall_ClientID = newID;
298                         _InitSyscalls();
299                         return 0;
300                 }
301                 
302                 // Return the acess TID instead
303                 return kernel_tid;
304         }
305         else
306         {
307                 Warning("ERROR: Threads currently unsupported\n");
308                 exit(-1);
309         }
310         #endif
311 }
312
313 int acess__SysKill(int pid, int sig)
314 {
315         // TODO: Impliment SysKill
316         return -1;
317 }
318
319 int acess__SysExecVE(char *path, char **argv, const char **envp)
320 {
321          int    i, argc;
322         
323         DEBUG("acess_execve: (path='%s', argv=%p, envp=%p)", path, argv, envp);
324         
325         // Get argument count
326         for( argc = 0; argv[argc]; argc ++ ) ;
327         DEBUG(" acess_execve: argc = %i", argc);
328
329         const char      *new_argv[7+argc+1];
330         char    client_id_str[11];
331         char    socket_fd_str[11];
332         sprintf(client_id_str, "%i", giSyscall_ClientID);
333         sprintf(socket_fd_str, "%i", gSocket);
334         new_argv[0] = "ld-acess";       // TODO: Get path to ld-acess executable
335         new_argv[1] = "--key";          // Set client ID for Request.c
336         new_argv[2] = client_id_str;
337         new_argv[3] = "--socket";       // Socket
338         new_argv[4] = socket_fd_str;
339         new_argv[5] = "--binary";       // Set the binary path (instead of using argv[0])
340         new_argv[6] = path;
341         for( i = 0; i < argc; i ++ )    new_argv[7+i] = argv[i];
342         new_argv[7+i] = NULL;
343         
344         #if 1
345         argc += 7;
346         for( i = 0; i < argc; i ++ )
347                 printf("\"%s\" ", new_argv[i]);
348         printf("\n");
349         if(envp)
350         {
351                 printf("envp = %p\n", envp);
352                 for( i = 0; envp[i]; i ++ )
353                         printf("%i: \"%s\"\n", i, envp[i]);
354                 printf("envc = %i\n", i);
355         }
356         #endif
357         
358         // Call actual execve
359         return native_execve("./ld-acess", new_argv, envp);
360 }
361
362 int acess__SysSpawn(const char *binary, const char **argv, const char **envp, int nfd, int fds[], struct s_sys_spawninfo *info)
363 {
364          int    argc = 0;
365         while( argv[argc++] );
366
367         Debug("_SysSpawn('%s', %p (%i), %p, %i, %p, %p)",
368                 binary, argv, argc, envp, nfd, fds, info);
369
370          int    kernel_tid;
371          int    newID;
372         newID = _Syscall(SYS_AN_SPAWN, "<d >d >d",
373                 sizeof(int), &kernel_tid,
374                 nfd*sizeof(int), fds,
375                 info ? sizeof(*info) : 0, info);
376
377         const char      *new_argv[5+argc+1];
378          int    new_argc = 0, i;
379         char    client_id_str[11];
380         sprintf(client_id_str, "%i", newID);
381         new_argv[new_argc++] = gsExecutablePath;       // TODO: Get path to ld-acess executable
382         new_argv[new_argc++] = "--key";
383         new_argv[new_argc++] = client_id_str;
384         new_argv[new_argc++] = "--binary";
385         new_argv[new_argc++] = binary;
386         for( i = 0; argv[i]; i ++)
387                 new_argv[new_argc++] = argv[i];
388         new_argv[new_argc++] = NULL;
389         
390         // TODO: Debug output?
391         
392         native_spawn(gsExecutablePath, new_argv, envp);
393
394         return kernel_tid;
395 }
396
397 //void acess_sleep(void)
398 //{
399 //      DEBUG("%s()", __func__);
400 //      _Syscall(SYS_SLEEP, "");
401 //}
402
403 void acess__SysTimedSleep(int64_t Delay)
404 {
405         DEBUG("%s(%lli)", __func__, Delay);
406         // Not accurate, but fuck it
407         //if( Delay > 1000 )    sleep(Delay / 1000);
408         //if( Delay % 1000 )    usleep( (Delay % 1000) * 1000 );
409         //_Syscall(SYS_TIMEDSLEEP, ">I", Delay);
410 }
411
412 int acess__SysWaitTID(int TID, int *ExitStatus)
413 {
414         DEBUG("%s(%i, %p)", __func__, TID, ExitStatus);
415         return _Syscall(SYS_WAITTID, ">i <d", TID, sizeof(int), &ExitStatus);
416 }
417
418 int acess_setuid(int ID) { return _Syscall(SYS_SETUID, ">i", ID); }
419 int acess_setgid(int ID) { return _Syscall(SYS_SETGID, ">i", ID); }
420 int acess_gettid(void) { return _Syscall(SYS_GETTID, ""); }
421 int acess__SysGetPID(void) { return _Syscall(SYS_GETPID, ""); }
422 int acess__SysGetUID(void) { return _Syscall(SYS_GETUID, ""); }
423 int acess__SysGetGID(void) { return _Syscall(SYS_GETGID, ""); }
424 int acess_getgid(void) { return _Syscall(SYS_GETGID, ""); }
425
426 int acess__SysSendMessage(int DestTID, int Length, void *Data)
427 {
428         DEBUG("%s(%i, 0x%x, %p)", __func__, DestTID, Length, Data);
429         return _Syscall(SYS_SENDMSG, ">i >d", DestTID, Length, Data);
430 }
431
432 int acess__SysGetMessage(int *SourceTID, int BufLen, void *Data)
433 {
434         DEBUG("%s(%p, %p)", __func__, SourceTID, Data);
435         return _Syscall(SYS_GETMSG, "<d <d",
436                 SourceTID ? sizeof(uint32_t) : 0, SourceTID,
437                 BufLen, Data
438                 );
439 }
440
441 int acess__SysWaitEvent(int Mask)
442 {
443         DEBUG("%s(%x)", __func__, Mask);
444         return _Syscall(SYS_WAITEVENT, ">i", Mask);
445 }
446
447 // --- Logging
448 static void int_dbgheader(void )
449 {
450         printf("[_SysDebug %i] ", giSyscall_ClientID);
451 }
452 void acess__SysDebug(const char *Format, ...)
453 {
454         va_list args;
455         
456         va_start(args, Format);
457         int_dbgheader();        
458         vprintf(Format, args);
459         printf("\n");
460         
461         va_end(args);
462 }
463
464 void acess__SysDebugHex(const char *tag, const void *data, size_t size)
465 {
466         int_dbgheader();        
467         printf("%s (Hexdump of %p+%zi)\r\n", tag, data, size);
468
469         #define CH(n)   ((' '<=cdat[(n)]&&cdat[(n)]<0x7F) ? cdat[(n)] : '.')
470
471         const uint8_t   *cdat = data;
472         unsigned int    pos = 0;
473
474         while(size >= 16)
475         {
476                 int_dbgheader();
477                 printf("%04x:"
478                         " %02x %02x %02x %02x %02x %02x %02x %02x "
479                         " %02x %02x %02x %02x %02x %02x %02x %02x "
480                         " %c%c%c%c%c%c%c%c %c%c%c%c%c%c%c%c\r\n",
481                         pos,
482                         cdat[ 0], cdat[ 1], cdat[ 2], cdat[ 3], cdat[ 4], cdat[ 5], cdat[ 6], cdat[ 7],
483                         cdat[ 8], cdat[ 9], cdat[10], cdat[11], cdat[12], cdat[13], cdat[14], cdat[15],
484                         CH(0),  CH(1),  CH(2),  CH(3),  CH(4),  CH(5),  CH(6),  CH(7),
485                         CH(8),  CH(9),  CH(10), CH(11), CH(12), CH(13), CH(14), CH(15)
486                         );
487                 size -= 16;
488                 cdat += 16;
489                 pos += 16;
490         }
491
492         {
493                 int_dbgheader();
494                 printf("%04x: ", pos);
495                 for(int i = 0; i < size; i ++)
496                         printf("%02x ", cdat[i]);
497                 for(int i = size; i < 16; i ++)
498                         printf("   ");
499                 printf(" ");
500                 for(int i = 0; i < size; i ++)
501                 {
502                         if( i == 8 )
503                                 printf(" ");
504                         printf("%c", CH(i));
505                 }
506         
507                 printf("\n");
508         }
509 }
510
511 void acess__exit(int Status)
512 {
513         DEBUG("_exit(%i)", Status);
514         _Syscall(SYS_EXIT, ">i", Status);
515         exit(Status);
516 }
517
518 uint32_t acess__SysSetMemFlags(uintptr_t vaddr, uint32_t flags, uint32_t mask)
519 {
520         // TODO: Impliment acess__SysSetMemFlags?
521         return 0;
522 }
523
524
525 // === Symbol List ===
526 #ifndef DEFSYM
527 # define DEFSYM(name)   {#name, &acess_##name}
528 #endif
529 const tSym      caBuiltinSymbols[] = {
530         DEFSYM(_exit),
531         
532         DEFSYM(_SysChdir),
533         DEFSYM(_SysOpen),
534         DEFSYM(_SysOpenChild),
535         DEFSYM(_SysReopen),
536         DEFSYM(_SysClose),
537         DEFSYM(_SysRead),
538         DEFSYM(_SysWrite),
539         DEFSYM(_SysSeek),
540         DEFSYM(_SysTell),
541         DEFSYM(_SysIOCtl),
542         DEFSYM(_SysFInfo),
543         DEFSYM(_SysReadDir),
544         DEFSYM(_SysGetACL),
545         DEFSYM(_SysMount),
546         DEFSYM(_SysSelect),
547         DEFSYM(_SysMkDir),
548         DEFSYM(_SysUnlink),
549         
550         DEFSYM(_SysClone),
551         DEFSYM(_SysExecVE),
552         DEFSYM(_SysSpawn),
553 //      DEFSYM(sleep),
554         
555         DEFSYM(_SysWaitTID),
556         DEFSYM(gettid),
557         DEFSYM(_SysGetPID),
558         DEFSYM(setuid),
559         DEFSYM(setgid),
560         DEFSYM(_SysGetUID),
561         DEFSYM(getgid),
562
563         DEFSYM(_SysSendMessage),
564         DEFSYM(_SysGetMessage),
565         
566         DEFSYM(_SysAllocate),
567         DEFSYM(_SysSetMemFlags),
568         DEFSYM(_SysDebug),
569         {"_ZN4_sys5debugEPKcz", &acess__SysDebug},
570         DEFSYM(_SysDebugHex),
571         {"_ZN4_sys7hexdumpEPKcPKvj", &acess__SysDebugHex},
572         DEFSYM(_SysSetFaultHandler),
573         DEFSYM(_SysWaitEvent),
574         
575         DEFSYM(_errno)
576 };
577
578 const int       ciNumBuiltinSymbols = sizeof(caBuiltinSymbols)/sizeof(caBuiltinSymbols[0]);
579

UCC git Repository :: git.ucc.asn.au