[OpenAFS-devel] System Call Stubs for IA64

Srikanth Vishwanathan vsrikanth@in.ibm.com
Thu, 9 May 2002 20:20:20 -0400


Hi -

I see that the entry points for all system calls that AFS defines
or replaces is a stub written in assembler (for taking care of the
global pointer)

I don't think this is really necessary. I was thinking that instead,
we could have stubs written entirely in C that would fabricate function
pointers with the function descriptor initialized properly.

I tried the following and it worked. I believe it should work in the
kernel too.

# uname -m
ia64
# cat syscall.c
#include <stdio.h>

typedef long (*syscall_t)(unsigned long, unsigned long,
                          unsigned long, unsigned long,
                          unsigned long, unsigned long);

long call_syscall_gp(const syscall_t func,
                     unsigned long arg1, unsigned long arg2,
                     unsigned long arg3, unsigned long arg4,
                     unsigned long arg5, unsigned long arg6)
{
        long rc;
        void *newfunc;
        unsigned long funcdesc[2];

        funcdesc[0] = ((unsigned long *) func)[0];
        funcdesc[1] = ((unsigned long *) func)[1];

        newfunc = funcdesc;

        rc = ((syscall_t) newfunc)(arg1, arg2, arg3, arg4, arg5, arg6);

        return rc;
}

int main(void)
{
        long rc1, rc2;
        unsigned long main_gp = ((unsigned long *) main)[0];
        unsigned long printf_gp = ((unsigned long *) printf)[0];

        rc1 = call_syscall_gp((syscall_t) printf,
                (unsigned long) "main_gp: 0x%016lx, ",
                main_gp, 0, 0, 0, 0);

        rc2 = call_syscall_gp((syscall_t) printf,
                (unsigned long) "printf_gp: 0x%016lx\n",
                printf_gp, 0, 0, 0, 0);

        printf("rc1 = %d, rc2 = %d\n", (int) rc1, (int) rc2);

        return 0;
}
# make
cc -Wall -O2 -S syscall.c
cc -Wall -O2 -o syscall syscall.c
# ./syscall
main_gp: 0x4000000000000750, printf_gp: 0x200000000011af20
rc1 = 29, rc2 = 30
#


If this works, the new system call stub can be changed to something
like:

extern long afs_syscall(unsigned long, unsigned long, unsigned long,
                        unsigned long, unsigned long, unsigned long);

asmlinkage long afs_syscall_stub(unsigned long arg1, unsigned long arg2,
                                 unsigned long arg3, unsigned long arg4,
                                 unsigned long arg5, unsigned long arg6)
{
        return call_syscall_gp(afs_syscall, arg1, arg2, arg3,
                                            arg4, arg5, arg6);
}


Am I missing anything here ?

Thanks,

Srikanth.