AcessNative - Hexdump sycall, stub shm
[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         // TODO: Better impl
258         TODO();
259 //      return now()*1000;
260         return 0;
261 }
262
263 // --- Memory Management ---
264 uint64_t acess__SysGetPhys(uintptr_t vaddr)
265 {
266         // TODO:
267         TODO();
268         return 0;
269 }
270
271 uint64_t acess__SysAllocate(uintptr_t vaddr)
272 {
273         if( AllocateMemory(vaddr, 0x1000) == -1 )       // Allocate a page
274                 return 0;
275                 
276         return vaddr;   // Just ignore the need for paddrs :)
277 }
278
279 // --- Process Management ---
280 int acess__SysClone(int flags, void *stack)
281 {
282         #ifdef __WIN32__
283         Warning("Win32 does not support anything like fork(2), cannot emulate");
284         exit(-1);
285         #else
286         extern int fork(void);
287         if(flags & CLONE_VM) {
288                  int    ret, newID, kernel_tid=0;
289                 Debug("USERSIDE fork()");
290                 
291                 newID = _Syscall(SYS_AN_FORK, "<d", sizeof(int), &kernel_tid);
292                 ret = fork();
293                 if(ret < 0) {
294                         return ret;
295                 }
296                 
297                 if(ret == 0)
298                 {
299                         _CloseSyscalls();
300                         giSyscall_ClientID = newID;
301                         _InitSyscalls();
302                         return 0;
303                 }
304                 
305                 // Return the acess TID instead
306                 return kernel_tid;
307         }
308         else
309         {
310                 Warning("ERROR: Threads currently unsupported\n");
311                 exit(-1);
312         }
313         #endif
314 }
315
316 int acess__SysKill(int pid, int sig)
317 {
318         // TODO: Impliment SysKill
319         return -1;
320 }
321
322 int acess__SysExecVE(char *path, char **argv, const char **envp)
323 {
324          int    i, argc;
325         
326         DEBUG("acess_execve: (path='%s', argv=%p, envp=%p)", path, argv, envp);
327         
328         // Get argument count
329         for( argc = 0; argv[argc]; argc ++ ) ;
330         DEBUG(" acess_execve: argc = %i", argc);
331
332         const char      *new_argv[7+argc+1];
333         char    client_id_str[11];
334         char    socket_fd_str[11];
335         sprintf(client_id_str, "%i", giSyscall_ClientID);
336         sprintf(socket_fd_str, "%i", gSocket);
337         new_argv[0] = "ld-acess";       // TODO: Get path to ld-acess executable
338         new_argv[1] = "--key";          // Set client ID for Request.c
339         new_argv[2] = client_id_str;
340         new_argv[3] = "--socket";       // Socket
341         new_argv[4] = socket_fd_str;
342         new_argv[5] = "--binary";       // Set the binary path (instead of using argv[0])
343         new_argv[6] = path;
344         for( i = 0; i < argc; i ++ )    new_argv[7+i] = argv[i];
345         new_argv[7+i] = NULL;
346         
347         #if 1
348         argc += 7;
349         for( i = 0; i < argc; i ++ )
350                 printf("\"%s\" ", new_argv[i]);
351         printf("\n");
352         if(envp)
353         {
354                 printf("envp = %p\n", envp);
355                 for( i = 0; envp[i]; i ++ )
356                         printf("%i: \"%s\"\n", i, envp[i]);
357                 printf("envc = %i\n", i);
358         }
359         #endif
360         
361         // Call actual execve
362         return native_execve("./ld-acess", new_argv, envp);
363 }
364
365 int acess__SysSpawn(const char *binary, const char **argv, const char **envp, int nfd, int fds[], struct s_sys_spawninfo *info)
366 {
367          int    argc = 0;
368         while( argv[argc++] );
369
370         Debug("_SysSpawn('%s', %p (%i), %p, %i, %p, %p)",
371                 binary, argv, argc, envp, nfd, fds, info);
372
373          int    kernel_tid;
374          int    newID;
375         newID = _Syscall(SYS_AN_SPAWN, "<d >d >d",
376                 sizeof(int), &kernel_tid,
377                 nfd*sizeof(int), fds,
378                 info ? sizeof(*info) : 0, info);
379
380         const char      *new_argv[5+argc+1];
381          int    new_argc = 0, i;
382         char    client_id_str[11];
383         sprintf(client_id_str, "%i", newID);
384         new_argv[new_argc++] = gsExecutablePath;       // TODO: Get path to ld-acess executable
385         new_argv[new_argc++] = "--key";
386         new_argv[new_argc++] = client_id_str;
387         new_argv[new_argc++] = "--binary";
388         new_argv[new_argc++] = binary;
389         for( i = 0; argv[i]; i ++)
390                 new_argv[new_argc++] = argv[i];
391         new_argv[new_argc++] = NULL;
392         
393         // TODO: Debug output?
394         
395         native_spawn(gsExecutablePath, new_argv, envp);
396
397         return kernel_tid;
398 }
399
400 //void acess_sleep(void)
401 //{
402 //      DEBUG("%s()", __func__);
403 //      _Syscall(SYS_SLEEP, "");
404 //}
405
406 void acess__SysTimedSleep(int64_t Delay)
407 {
408         DEBUG("%s(%lli)", __func__, Delay);
409         // Not accurate, but fuck it
410         //if( Delay > 1000 )    sleep(Delay / 1000);
411         //if( Delay % 1000 )    usleep( (Delay % 1000) * 1000 );
412         //_Syscall(SYS_TIMEDSLEEP, ">I", Delay);
413 }
414
415 int acess__SysWaitTID(int TID, int *ExitStatus)
416 {
417         DEBUG("%s(%i, %p)", __func__, TID, ExitStatus);
418         return _Syscall(SYS_WAITTID, ">i <d", TID, sizeof(int), &ExitStatus);
419 }
420
421 int acess_setuid(int ID) { return _Syscall(SYS_SETUID, ">i", ID); }
422 int acess_setgid(int ID) { return _Syscall(SYS_SETGID, ">i", ID); }
423 int acess_gettid(void) { return _Syscall(SYS_GETTID, ""); }
424 int acess__SysGetPID(void) { return _Syscall(SYS_GETPID, ""); }
425 int acess__SysGetUID(void) { return _Syscall(SYS_GETUID, ""); }
426 int acess__SysGetGID(void) { return _Syscall(SYS_GETGID, ""); }
427 int acess_getgid(void) { return _Syscall(SYS_GETGID, ""); }
428
429 int acess__SysSendMessage(int DestTID, int Length, void *Data)
430 {
431         DEBUG("%s(%i, 0x%x, %p)", __func__, DestTID, Length, Data);
432         return _Syscall(SYS_SENDMSG, ">i >d", DestTID, Length, Data);
433 }
434
435 int acess__SysGetMessage(int *SourceTID, int BufLen, void *Data)
436 {
437         DEBUG("%s(%p, %p)", __func__, SourceTID, Data);
438         return _Syscall(SYS_GETMSG, "<d <d",
439                 SourceTID ? sizeof(uint32_t) : 0, SourceTID,
440                 BufLen, Data
441                 );
442 }
443
444 int acess__SysWaitEvent(int Mask)
445 {
446         DEBUG("%s(%x)", __func__, Mask);
447         return _Syscall(SYS_WAITEVENT, ">i", Mask);
448 }
449
450 // --- Logging
451 static void int_dbgheader(void )
452 {
453         printf("[_SysDebug %i] ", giSyscall_ClientID);
454 }
455 void acess__SysDebug(const char *Format, ...)
456 {
457         va_list args;
458         
459         va_start(args, Format);
460         int_dbgheader();        
461         vprintf(Format, args);
462         printf("\n");
463         
464         va_end(args);
465 }
466
467 void acess__SysDebugHex(const char *tag, const void *data, size_t size)
468 {
469         int_dbgheader();        
470         printf("%s (Hexdump of %p+%zi)\r\n", tag, data, size);
471
472         #define CH(n)   ((' '<=cdat[(n)]&&cdat[(n)]<0x7F) ? cdat[(n)] : '.')
473
474         const uint8_t   *cdat = data;
475         unsigned int    pos = 0;
476
477         while(size >= 16)
478         {
479                 int_dbgheader();
480                 printf("%04x:"
481                         " %02x %02x %02x %02x %02x %02x %02x %02x "
482                         " %02x %02x %02x %02x %02x %02x %02x %02x "
483                         " %c%c%c%c%c%c%c%c %c%c%c%c%c%c%c%c\r\n",
484                         pos,
485                         cdat[ 0], cdat[ 1], cdat[ 2], cdat[ 3], cdat[ 4], cdat[ 5], cdat[ 6], cdat[ 7],
486                         cdat[ 8], cdat[ 9], cdat[10], cdat[11], cdat[12], cdat[13], cdat[14], cdat[15],
487                         CH(0),  CH(1),  CH(2),  CH(3),  CH(4),  CH(5),  CH(6),  CH(7),
488                         CH(8),  CH(9),  CH(10), CH(11), CH(12), CH(13), CH(14), CH(15)
489                         );
490                 size -= 16;
491                 cdat += 16;
492                 pos += 16;
493         }
494
495         {
496                 int_dbgheader();
497                 printf("%04x: ", pos);
498                 for(int i = 0; i < size; i ++)
499                         printf("%02x ", cdat[i]);
500                 for(int i = size; i < 16; i ++)
501                         printf("   ");
502                 printf(" ");
503                 for(int i = 0; i < size; i ++)
504                 {
505                         if( i == 8 )
506                                 printf(" ");
507                         printf("%c", CH(i));
508                 }
509         
510                 printf("\n");
511         }
512 }
513
514 void acess__exit(int Status)
515 {
516         DEBUG("_exit(%i)", Status);
517         _Syscall(SYS_EXIT, ">i", Status);
518         exit(Status);
519 }
520
521 uint32_t acess__SysSetMemFlags(uintptr_t vaddr, uint32_t flags, uint32_t mask)
522 {
523         // TODO: Impliment acess__SysSetMemFlags?
524         return 0;
525 }
526
527
528 // === Symbol List ===
529 #ifndef DEFSYM
530 # define DEFSYM(name)   {#name, &acess_##name}
531 #endif
532 const tSym      caBuiltinSymbols[] = {
533         DEFSYM(_exit),
534         
535         DEFSYM(_SysChdir),
536         DEFSYM(_SysOpen),
537         DEFSYM(_SysOpenChild),
538         DEFSYM(_SysReopen),
539         DEFSYM(_SysClose),
540         DEFSYM(_SysRead),
541         DEFSYM(_SysWrite),
542         DEFSYM(_SysSeek),
543         DEFSYM(_SysTell),
544         DEFSYM(_SysIOCtl),
545         DEFSYM(_SysFInfo),
546         DEFSYM(_SysReadDir),
547         DEFSYM(_SysGetACL),
548         DEFSYM(_SysMount),
549         DEFSYM(_SysSelect),
550         DEFSYM(_SysMkDir),
551         DEFSYM(_SysUnlink),
552         
553         DEFSYM(_SysClone),
554         DEFSYM(_SysExecVE),
555         DEFSYM(_SysSpawn),
556 //      DEFSYM(sleep),
557         
558         DEFSYM(_SysWaitTID),
559         DEFSYM(gettid),
560         DEFSYM(_SysGetPID),
561         DEFSYM(setuid),
562         DEFSYM(setgid),
563         DEFSYM(_SysGetUID),
564         DEFSYM(getgid),
565
566         DEFSYM(_SysSendMessage),
567         DEFSYM(_SysGetMessage),
568         
569         DEFSYM(_SysAllocate),
570         DEFSYM(_SysSetMemFlags),
571         DEFSYM(_SysDebug),
572         {"_ZN4_sys5debugEPKcz", &acess__SysDebug},
573         DEFSYM(_SysDebugHex),
574         {"_ZN4_sys7hexdumpEPKcPKvj", &acess__SysDebugHex},
575         DEFSYM(_SysSetFaultHandler),
576         DEFSYM(_SysWaitEvent),
577         
578         DEFSYM(_errno)
579 };
580
581 const int       ciNumBuiltinSymbols = sizeof(caBuiltinSymbols)/sizeof(caBuiltinSymbols[0]);
582

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