Hi Norman, Thanks for taking the time to analyze why the stubs were not building in g++. The problem here is the way the enums are padded is incorrect. The value '1U << ((sizeof(int) * 8 -1))' is 0x80000000, which is 1 higher than the value of INT_MAX at 0x7fffffff. However, the C++ compiler cannot make this an unsigned int as the enum has negative values, therefore it is forced to use a signed 64 bit integer. If you attempt to build the following snippet standalone: typedef enum { seL4_SysDebugPutChar = -9, _enum_pad_seL4_Syscall_ID = (1U << ((sizeof(int)*8) - 1)) } seL4_Syscall_ID; static int _assert[sizeof(seL4_Syscall_ID) == 4 ? 0 : -1]; You will get an error that the array size is negative, since the sizeof(seL4_Syscall_ID) is 8 here. All this is required is to subtract 1, so the padding is INT_MAX. So the following snippet will work: typedef enum { seL4_SysDebugPutChar = -9, _enum_pad_seL4_Syscall_ID = (1U << ((sizeof(int)*8) - 1)) - 1 } seL4_Syscall_ID; static int _assert[sizeof(seL4_Syscall_ID) == 4 ? 0 : -1]; This is something we will definitely fix and push out shortly. Position independent code is a bit of a trickier issue. Presently we have no desire to use PIC, so copping a performance hit (incredibly small it may be) is undesirable. I think the best option here would be to make support of PIC at user level a build configuration option, and then make the stubs conditionally build in the additional ebx save/restore code. I do not know if attempting such conditional building will end up turning the assembly into an unreadable mess, but it would resolve the performance argument at least. The 'correct' way to do this with fitting into the current seL4 build system setup would be to add a configuration option to tools/common/Kconfig, use that variable to do the conditional compilation in syscalls.h and have tools/common/common.mk generate the -fPIC / -fno-PIC flags. If you can come up with a nice way of conditionally building both PIC and non-PIC versions of what is in syscalls.h then we would certainly accept it. Adrian On 29/10/14 04:08, Norman Feske wrote:
Dear seL4 developers,
first, I'd like to thank you for publishing seL4 under GPL. I am very happy that I can finally get my hands dirty with working with the kernel of your group. :-) Currently, I am taking the first baby steps to bring the Genode OS framework (http://genode.org) to seL4. For reference, I am using the experimental branch.
The first smallish issue I stumbled upon stems from the fact that Genode is written in C++. By compiling the seL4 syscall bindings with a C++ compiler, I got the following error:
error: inconsistent operand constraints in an ‘asm’
It can be reproduced by putting the following code snippet into a cc file and compiling it with 'g++ -m32 -c' (tested with the Genode tool chain as well as with GCC 4.8.1):
typedef enum { seL4_SysDebugPutChar = -9, _enum_pad_seL4_Syscall_ID = (1U << ((sizeof(int)*8) - 1)) } seL4_Syscall_ID;
void seL4_DebugPutChar(char c) { asm volatile ( "pushl %%ebp \n" "movl %%esp, %%ecx \n" "leal 1f, %%edx \n" "1: \n" "sysenter \n" "popl %%ebp \n" : : "a" (seL4_SysDebugPutChar), "b" (c) : "%ecx", "%edx", "%esi", "%edi", "memory" ); }
When compiling the same code snippet with 'gcc' instead of 'g++', everything is fine. It turns out that the C++ compiler does not like the enum value to be specified as input argument. I found the following ways to circumvent this problem:
* Changing the enum value 'SysDebugPutChar' to a positive value,
* Removing the definition of '_enum_pad_seL4_Syscall_ID',
* Casting 'seL4_SysDebugPutChar' to an integer:
: "a" ((int)seL4_SysDebugPutChar),
In any case, I seem to have to change the bindings. Do you see a way around it? If not, would you consider one of the solutions above for the seL4 headers?
On another note, I noticed that the bindings use the EBX register. Unfortunately, this makes it impossible to compile seL4 userland software as position-independent code (PIC). E.g., when compiling the above code snippet via 'g++ -m32 -fPIC -c', the following error occurs:
error: inconsistent operand constraints in an ‘asm’
However, PIC is required in order to use shared libraries. The solution would be to not use EBX to pass arguments to the 'asm' statements, save EBX on the stack prior moving the respective kernel argument to the register, and, of course, restoring it after sysenter returns.
Before I start changing the bindings, I'd like to know: is there anyone else working on the same problem? Would you be open to accept a change of the bindings to become PIC compliant on the costs of a few added instructions? Or do you have another suggestion how I should go about it?
Best regards Norman
________________________________ The information in this e-mail may be confidential and subject to legal professional privilege and/or copyright. National ICT Australia Limited accepts no liability for any damage caused by this email or its attachments.