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.

_______________________________________________
Devel mailing list
[email protected]
https://sel4.systems/lists/listinfo/devel

Reply via email to