x86 assembly help request

Joel Sherrill joel.sherrill at oarcorp.com
Tue May 29 22:14:05 UTC 2007


I have been trying to get the unix BSP to run
on Fedora Core 6.  AFAIK it hasn't run in a long
time.  In doing so, I have noticed that
we no longer do the correct magic to fill
in the setjmp structure correctly.  The
setjmp fields are at the following indices
if you view it as a uint32_t array:

#define EBX_OFF    0
#define ESI_OFF    1
#define EDI_OFF    2
#define EBP_OFF    3
#define ESP_OFF    4
#define RET_OFF    5

We appear to be putting in the values correctly
at the correct offsets EXCEPT that setjmp and
longjmp are doing something with the stack pointers:

(gdb) disassemble setjmp
Dump of assembler code for function setjmp:
0x00482ac0 <setjmp+0>:  mov    0x4(%esp),%eax
0x00482ac4 <setjmp+4>:  mov    %ebx,(%eax)
0x00482ac6 <setjmp+6>:  mov    %esi,0x4(%eax)
0x00482ac9 <setjmp+9>:  mov    %edi,0x8(%eax)
0x00482acc <setjmp+12>: lea    0x4(%esp),%ecx
0x00482ad0 <setjmp+16>: xor    %gs:0x18,%ecx          <======
0x00482ad7 <setjmp+23>: mov    %ecx,0x10(%eax)
0x00482ada <setjmp+26>: mov    (%esp),%ecx
0x00482add <setjmp+29>: xor    %gs:0x18,%ecx
0x00482ae4 <setjmp+36>: mov    %ecx,0x14(%eax)        <========
0x00482ae7 <setjmp+39>: mov    %ebp,0xc(%eax)
0x00482aea <setjmp+42>: push   $0x1
0x00482aec <setjmp+44>: pushl  0x8(%esp)
0x00482af0 <setjmp+48>: call   0x482a60 <__sigjmp_save>
0x00482af5 <setjmp+53>: pop    %ecx
0x00482af6 <setjmp+54>: pop    %edx
0x00482af7 <setjmp+55>: ret
0x00482af8 <setjmp+56>: nop

Similarly for longjmp:

gdb) disassemble
Dump of assembler code for function __longjmp:
0x00482ba0 <__longjmp+0>:       mov    0x4(%esp),%eax
0x00482ba4 <__longjmp+4>:       mov    0x14(%eax),%edx
0x00482ba7 <__longjmp+7>:       mov    0x10(%eax),%ecx
0x00482baa <__longjmp+10>:      xor    %gs:0x18,%edx     <=======
0x00482bb1 <__longjmp+17>:      xor    %gs:0x18,%ecx     <=======
0x00482bb8 <__longjmp+24>:      mov    (%eax),%ebx
0x00482bba <__longjmp+26>:      mov    0x4(%eax),%esi
0x00482bbd <__longjmp+29>:      mov    0x8(%eax),%edi
0x00482bc0 <__longjmp+32>:      mov    0xc(%eax),%ebp
0x00482bc3 <__longjmp+35>:      mov    0x8(%esp),%eax
0x00482bc7 <__longjmp+39>:      mov    %ecx,%esp
0x00482bc9 <__longjmp+41>:      jmp    *%edx
0x00482bcb <__longjmp+43>:      nop

The newlib linux/x86 setjmp is the same one we use on
RTEMS which does NOT do the xor magic.  So it isn't
much help.  We get a SEGV when we load the %ESP since
it apparently isn't being adjusted correctly or is
not a valid address for a stack pointer.

This is done by a macro PTR_MANGLE in the glibc source.
I believe I have duplicated this mangling and now may
be getting hit by bounds checks on the stack pointer.
We are really one thread to Linux and we are changing
the stack underneath it.  That would explain a SEGV.

Any ideas, thoughts, patches. :)


More information about the users mailing list