/* hello-gate.S : example of using linux-gate.so to perform syscalls */
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#define SYS_EXIT 1
#define SYS_WRITE 4
#define AT_SYSINFO 32

.text
.globl _start
_start:
	movl (%esp), %ecx		/* argc */
	leal 8(%esp,%ecx,4), %esi	/* envp */
find_auxv: /* walk past envp pointer */
	movl (%esi), %eax
	leal 4(%esi), %esi
	test %eax, %eax
	jnz find_auxv			/* is envp[eax] == NULL ? */
	/* leave with esi = auxv */
find_gate: /* walk array of Elf32_auxv_t pointers */
	movl (%esi), %eax		/* grab a_type from Elf32_auxv_t; */
	cmpl $AT_SYSINFO, %eax
	je found_gate
	leal 8(%esi), %esi
	testl %eax, %eax
	jnz find_gate
missing_gate: /* fall back to int 0x80 and print an error */
	movl $SYS_WRITE, %eax
	movl $STDERR_FILENO, %ebx
	movl $msg_fail, %ecx
	movl $msg_fail_len, %edx
	int $0x80
	movl $SYS_EXIT, %eax
	movl $1, %ebx
	int $0x80
found_gate: /* print out message using the call gates */
	mov 4(%esi), %ebp
	movl $SYS_WRITE, %eax
	movl $STDOUT_FILENO, %ebx
	movl $hello_world, %ecx
	movl $hello_world_len, %edx
	call *%ebp
	movl $SYS_EXIT, %eax
	xorl %ebx, %ebx
	call *%ebp

.data

msg_fail:
	.ascii "linux gate not found\n"
msg_fail_len = . - msg_fail
hello_world:
	.ascii "Hello World\n"
hello_world_len = . - hello_world