From: Paul H. Hargrove (PHHargrove_at_lbl_dot_gov)
Date: Wed Sep 03 2008 - 13:31:04 PDT
The syscall macros you wrote may have taken my suggestion too literally, or perhaps I was not as clear as I intended. I sometimes take for granted how much of the non-obvious stuff I already know. 1) The macros from glibc are gcc-specific "expression statements" (or something like that), which is why they are bracketed as ({ body }). Such an compound expression evaluates to its last statement, which is __o0 in the case of the glibc syscall macros. 2) BLCR needs a macro that expands to define entire function, with a returned value, not just an expression which evaluates to the desired value. So, we need to pass __o0 into the cri_syscall_cleanup() macro, and then return it. 3) BLCR want's to look at the value and if it is bigger than 0xFFFFF000 (or 0xFFFFFFFFFFFFF000 on 64-bit) put its negative into *errno_p (if non-NULL) and change the return value to -1. That is the purpose of cri_syscall_cleanup(). This differs just slightly from the normal kernel return ABI. 4) The "memory", "cc", "cx", "dx" stuff is x86-specific register clobbers which you should remove. 5) The "string" is supplied by one of the ALL_CAPS macros earlier in .../sparc/sysdep.h, which in turn use values that are defined in .../sparc/sparc32/sysdep.h or .../sparc/sparc64/sysdep.h (same files which provide the value for __SYSCALL_CLOBBERS. I believe you want "string" to be __INTERNAL_SYSCALL_STRING, being sure to get the correct 32-bit or 64-bit version. However, the __INTERNAL_SYSCALL_STRING appears to handle the errno-related stuff a little bit on its own, so we don't want to use it exactly. In fact, I think that we can discard attempts as being optimal and just strip the error handing out of __INTERNAL_SYSCALL_STRING and leave it all in cri_syscall_cleanup(). So changes needed: a) remove the x86-specific asm() from cri_syscall_cleanup() b) remove lone "__o0;" line c) pass __o0 in place of __g1 to cri_syscall_cleanup() d) return __o0 (with an explicit cast to "type" to avoid gcc warnings) e) insert the proper value in place of "string" and __SYSCALL_CLOBBERS So, I think you want the following: #if (SIZEOF_VOID_P == 4) #define CRI_SYSCALL_CLOBBERS "g2", "g3", "g4", "g5", "g6", \ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \ "cc", "memory" #define CRI_SYSCALL_STRING "ta 0x10;" #elif (SIZEOF_VOID_P == 8) #define CRI_SYSCALL_CLOBBERS "g2", "g3", "g4", "g5", "g6", \ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \ "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", \ "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62", \ "cc", "memory" #define CRI_SYSCALL_STRING "ta 0x6d;" #else #error "Unknown SIZEOF_VOID_P" #endif #define cri_syscall_cleanup(res,errno_p) \ if ((unsigned long)res >= (unsigned long)(-4096)) { \ if (errno_p != NULL) { *errno_p = -res; } \ res = -1; \ } #define cri_syscall0(type,name,nr) \ type name(int *errno_p) \ { \ register long __o0 __asm__ ("o0"); \ register long __g1 __asm__ ("g1") = name; \ __asm __volatile (CRI_SYSCALL_STRING : \ "=r" (__g1), "=r" (__o0) : \ "0" (__g1) : \ CRI_SYSCALL_CLOBBERS); \ cri_syscall_cleanup(__o0, errno_p); \ return (type)__o0; \ } #define cri_syscall1(type,name,nr,arg1) \ type name(type1 arg1,int *errno_p) \ { \ register long __o0 __asm__ ("o0") = (long)(arg1); \ register long __g1 __asm__ ("g1") = name; \ __asm __volatile (CRI_SYSCALL_STRING : \ "=r" (__g1), "=r" (__o0) : \ "0" (__g1), "1" (__o0) : \ _CRI_SYSCALL_CLOBBERS); \ cri_syscall_cleanup(__o0, errno_p); \ return (type)__o0; \ } Just to be 100% proper about this code I've included here: Signed-off-by: Paul H. Hargrove <PHHargrove_at_lbl_dot_gov> -Paul Vincentius Robby wrote: > Hello Paul, > > Apologies, regarding the directory I forgot to add the CR_ARCH32 > option because I was working on a 64-bit sparc machine for testing this. > While my question regarding the fetch and add still stands, I am > playing around with the syscall handlers now. Currently the errors I > am encountering are: > then mv -f ".deps/libcr_la-cr_syscall.Tpo" > ".deps/libcr_la-cr_syscall.Plo"; else rm -f > ".deps/libcr_la-cr_syscall.Tpo"; exit 1; fi > gcc -DHAVE_CONFIG_H -I. -I../../libcr -I.. -D_GNU_SOURCE -D_REENTRANT > -I../include -I../../include -I../../libcr/arch/sparc/ -Wall > -Wno-unused-function -fno-stack-protector -g -O2 -MT > libcr_la-cr_syscall.lo -MD -MP -MF .deps/libcr_la-cr_syscall.Tpo -c > ../../libcr/cr_syscall.c -fPIC -DPIC -o .libs/libcr_la-cr_syscall.o > ../../libcr/cr_syscall.c:169: error: expected ')' before 'int' > ../../libcr/cr_syscall.c:170: error: expected ')' before 'const' > ../../libcr/cr_syscall.c:171: error: expected ')' before 'int' > ../../libcr/cr_syscall.c: In function '__cri_sched_yield': > ../../libcr/cr_syscall.c:172: warning: initialization makes integer > from pointer without a cast > ../../libcr/cr_syscall.c:172: error: expected string literal before > 'string' > ../../libcr/cr_syscall.c:172: warning: statement with no effect > ../../libcr/cr_syscall.c: At top level: > ../../libcr/cr_syscall.c:173: error: expected ')' before 'const' > ../../libcr/cr_syscall.c:174: error: expected ')' before 'int' > ../../libcr/cr_syscall.c:176: error: expected ')' before 'int' > ../../libcr/cr_syscall.c:183: error: expected ')' before 'int' > ../../libcr/cr_syscall.c:189: error: expected ')' before 'int' > make[2]: *** [libcr_la-cr_syscall.lo] Error 1 > make[2]: Leaving directory `/opt/blcr-0.7.3_vincent/builddir/libcr' > > and this is what the beginning of libcr/arch/sparc/cr_arch.h looks like: > #define cri_syscall_cleanup(res,errno_p) \ > __asm__ volatile ("" ::: "memory", "cc", "cx", "dx");\ > if ((unsigned long)res >= (unsigned long)(-4096)) { \ > if (errno_p != NULL) { *errno_p = -res; } \ > res = -1; \ > } > > #define cri_syscall0(type,name,nr) \ > type name(int *errno_p) \ > { \ > register long __o0 __asm__ ("o0"); \ > register long __g1 __asm__ ("g1") = name; \ > __asm __volatile (string : "=r" (__g1), "=r" (__o0) : \ > "0" (__g1) : \ > __SYSCALL_CLOBBERS); \ > __o0; \ > cri_syscall_cleanup(__g1, errno_p); \ > } > > #define cri_syscall1(type,name,nr,arg1) \ > type name(type1 arg1,int *errno_p) \ > { \ > register long __o0 __asm__ ("o0") = (long)(arg1); \ > register long __g1 __asm__ ("g1") = name; \ > __asm __volatile (string : "=r" (__g1), "=r" (__o0) : \ > "0" (__g1), "1" (__o0) : \ > __SYSCALL_CLOBBERS); \ > __o0; \ > cri_syscall_cleanup(__g1, errno_p); \ > } > > One question I have is where it is written __asm __volatile (string :, > is the string to be replaced by 'type'? Originally the inline_syscall > has arguments (string,name) so I assumed I had to change the 'string' > to 'type' in the __asm __volatile arguments but after these errors I > changed it back, but either way it was not a solution to the errors. > Is this what you mentioned for the inclusion syscall_cleanup routine > as well? > > Thank you. > -- Paul H. Hargrove PHHargrove_at_lbl_dot_gov Future Technologies Group HPC Research Department Tel: +1-510-495-2352 Lawrence Berkeley National Laboratory Fax: +1-510-486-6900