/* two ways to say what a system call is */
#define SYSCALL(x) void x(struct Ureg *ureg)
typedef void(*Syscall)(struct Ureg*);
/* macros for use within system calls */
#define ARG1 ((ureg)->bx)
#define ARG2 ((ureg)->cx)
#define ARG3 ((ureg)->dx)
#define ARG4 ((ureg)->si)
#define ARG5 ((ureg)->di)
#define ARG6 ((ureg)->bp)
#define RETURN(X) { ureg->ax = (ulong) (X); return; }
/* ioctls */
#define IOCTL(x) int x(int fd, uint cmd, ulong arg)
typedef struct Ioctl Ioctl;
struct Ioctl
{
uint num;
int (*f)(int, uint, ulong);
};
typedef struct Ioctlname Ioctlname;
struct Ioctlname
{
uint num;
char *name;
};
/* a mechanically generated list of names. */
extern char *syscallname[];
extern Ioctlname ioctlname[];
/*
* provided by systab.c, which is mechanically
* generated from systab
*/
extern Syscall syscalltab[];
extern Ioctl ioctltab[];
enum
{
PAGE_SIZE = 4096,
PAGE_MASK = ~(PAGE_SIZE-1),
};
#define TRUNC_PAGE(x) \
((x) & PAGE_MASK)
#define ROUND_PAGE(x) \
(((x) & (PAGE_SIZE-1)) ? (TRUNC_PAGE(x) + PAGE_SIZE) : (x))
/* an assembly hack */
void jumpstack(ulong addr, ulong *stack);
void jumpureg(struct Ureg *ureg);
void callsignal(int sig, void *handler);
/* atomic inc/dec */
void _xinc(long *);
long _xdec(long *);
/* proc */
void set9stack(void *);
int do9stack(int (*fn)(void *), void *);
int createxproc(void (*fn)(void *), void *arg, int flags, int stacksize);
/* load.c, elf loading */
typedef struct ElfEx ElfEx;
struct ElfEx
{
ulong ientry; // interpreter
ulong ibase;
ulong entry;
ulong base;
ulong phdr;
ulong phnum;
ulong phent;
};
int loadelf(char *file, ElfEx *ex);
/*
* contains argv[] not including the emulated program
* arguments. used in execve() syscall to restart the emulator
* with another program.
*/
extern char **emuargv;
enum
{
SIGQUEUESIZE = 256,
};
typedef struct Sigqueue Sigqueue;
struct Sigqueue
{
struct {
int sig;
void *info;
} e[SIGQUEUESIZE];
int rp;
int wp;
};
typedef struct Sigstate Sigstate;
struct Sigstate
{
long level;
/* signal actions */
struct {
void *handler;
ulong flags;
uvlong blocked;
} action[63];
/* for normal signals only */
void *info[31];
ulong pending;
/* for realtime signals only */
Sigqueue rtsq;
/* all blocked signals */
uvlong blocked;
};
typedef struct Thread Thread;
struct Thread
{
union {
int tgid; /* threadgroupid */
int pid;
};
int tid; /* threadid */
int ptid; /* parent threadid */
int uid;
int gid;
int umask;
int exitsig;
int *cleartidaddr; /* see set_tid_address() */
Sigstate ss;
};
extern Thread *threadp;
/* debugging */
#define DPRINT if(!debug) {} else print
extern int debug;
/* error.c translate from plan9 errors to linux ones */
int stringerr(char *);
int mkerror(void);
/* signal.c translate from plan9 waitmsg to linux signal numbers */
int stringsig(char *);
char *sigstring(int sig);
void sigprocess(Sigstate *ss);
uvlong sigpending(Sigstate *ss);
void sigdisable(Sigstate *ss);
void sigenable(Sigstate *ss);
int signote(Sigstate *ss, char *msg);
void sigclearall(Sigstate *ss);
int _kill(int pid, int sig);
/* sysfile.c linux versions of close/read/write */
int _close(int fd);
int _read(int fd, void *data, int len);
int _write(int fd, void *data, int len);
/* mmap.c */
void mmapinit(void);
void mmapexit(void);
void *mmap(void *addr, int len, int prot, int flags, int fd, int offset);
int munmap(void *addr, int len);
void *allocstack(int);
int msync(void *addr);
/* epoll.c */
typedef struct epoll_event epoll_event;
struct epoll_event
{
ulong events;
uvlong data;
};
int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, epoll_event *events, int maxevents, int timeout);
/* notify epoll - callback used in buffd */
void epollevent(int fd, ulong setevents, ulong resetevents);
/* buffd.c */
void buffd(int fd);
void shutdownbuffd(int fd, int how);
void pollbuffd(int fd);
int buffdionread(int fd);
int readbuffd(int fd, void *data, int len, int noblock);
int peekbuffd(int fd, void *data, int len, int noblock);
int writebuffd(int fd, void *data, int len, int noblock);
/* util.c, filedescriptor tags */
enum
{
TAG_ALL = 0,
TAG_READDIR = 1,
TAG_BUFFD = 2,
TAG_EPOLL = 3,
TAG_FDFLAGS = 4,
TAG_SOCK = 5,
};
void *openfdtag(int fd, int tag, int create);
void closefdtag(void *tag);
void **fdtagp(void *tag);
int fdtagfd(void *tag);
void atdestroyfdtag(void *tag, void (*destroy)(void *tag));
void atforkfdtag(void *tag, void (*fork)(void *tag));
void destroyfdtag(void *tag);
void forkfdtag(void *tag);
void unlinkfdtag(void *tag);
void forkallfdtags(void);
/* util.c converting from plan9 /env to char** and back */
char **readenv(char *buf, int nbuf);
void writeenv(char **);
|