/* Here are the definitions for a bunch of syscalls that are required
   by the dynamic linker.  The idea is that we want to be able
   to call these before the errno symbol is dynamicly linked, so
   we use our own version here.  Note that we cannot assume any
   dynamic linking at all, so we cannot return any error codes.
   We just punt if there is an error. */

extern inline volatile void _dl_exit(int status)
{
  __asm__ volatile ("pushl %0\n\tpushl $0\n\tmovl %1,%%eax\n\t" \
		    "lcall $7,$0" : : "r" (status), "a" (__IBCS_exit));
}

extern inline volatile void _dl_close(int fd)
{
    int status;

    __asm__ volatile ("pushl %1\n\t" \
	    "pushl $0\n\t" \
	    "movl %2,%%eax\n\t" \
	    "lcall $7,$0\n\t" \
	    "jnb .+4\n\t" \
	    "xor %%eax, %%eax\n\t" \
	    "addl $8,%%esp\n\t" \
	    : "=a" (status) : "r" (fd), "a" (__IBCS_close));
}

extern inline int _dl_mmap(void * addr, unsigned int size,
				    unsigned int prot,
				    unsigned int flags, int fd,
				    unsigned int f_offset)
{
  int malloc_buffer;
  __asm__ volatile ("pushl %7\n\t" \
		    "pushl %6\n\t" \
		    "pushl %5\n\t" \
		    "pushl %4\n\t" \
		    "pushl %3\n\t" \
		    "pushl %2\n\t" \
		    "pushl $0\n\t" \
		    "movl %1,%%eax\n\t" \
		    "lcall $7,$0\n\t" \
		    "jnb .+4\n\t" \
		    "xor %%eax, %%eax\n\t" \
		    "addl $28,%%esp\n\t" \
		    : "=a" (malloc_buffer) : "a" (__IBCS_mmap),
		    "rm" (addr), "rm" (size), "rm" (prot), "rm" (flags), 
		    "rm" (fd), "rm" (f_offset));
  return malloc_buffer;
}


extern inline int _dl_open(char * addr, unsigned int flags)
{
  int zfileno;
  __asm__ volatile ("pushl %3\n\t" \
	    "pushl %2\n\t" \
	    "pushl $0\n\t" \
	    "movl %1,%%eax\n\t" \
	    "lcall $7,$0\n\t" \
	    "jnb .+7\n\t" \
	    "movl $-1, %%eax\n\t" \
	    "addl $12,%%esp\n\t" \
	    :"=a" (zfileno) : "i" (__IBCS_open), "rm" (addr), "rm" (flags));
  return zfileno;
}

extern inline int _dl_write(int fd, const char * buf, int len)
{
  int status;
  __asm__ volatile ("pushl %4\n\t" \
	  "pushl %3\n\t" \
	  "pushl %2\n\t" \
	  "pushl $0\n\t" \
	  "movl %1,%%eax\n\t" \
	  "lcall $7,$0\n\t" \
	  "jnb .+4\n\t" \
	  "xor %%eax, %%eax\n\t" \
	  "addl $12,%%esp\n\t" \
	  :"=a" (status) : "i" (__IBCS_write), "rm" (fd), "rm" (buf), "rm" (len));
}


extern inline int _dl_read(int fd, const char * buf, int len)
{
  int status;
  __asm__ volatile ("pushl %4\n\t" \
	  "pushl %3\n\t" \
	  "pushl %2\n\t" \
	  "pushl $0\n\t" \
	  "movl %1,%%eax\n\t" \
	  "lcall $7,$0\n\t" \
	  "jnb .+4\n\t" \
	  "xor %%eax, %%eax\n\t" \
	  "addl $12,%%esp\n\t" \
	  : "=a" (status) : "i" (__IBCS_read), "rm" (fd), "rm" (buf), "rm" (len));
}



extern inline int _dl_mprotect(const char * addr, int size, int prot)
{
  int status;
  __asm__ volatile ("pushl %4\n\t" \
	  "pushl %3\n\t" \
	  "pushl %2\n\t" \
	  "pushl $0\n\t" \
	  "movl %1,%%eax\n\t" \
	  "lcall $7,$0\n\t" \
	  "jnb .+7\n\t" \
	  "movl $-1, %%eax\n\t" \
	  "addl $16,%%esp\n\t" \
	  :"=a" (status) : "i" (__IBCS_mprotect), "rm" (addr), "rm" (size), "rm" (prot));
  return status;
}
