x86 assembly help request

Till Straumann strauman at slac.stanford.edu
Wed May 30 07:55:49 UTC 2007

I downloaded a recent glibc (cvs head actually) and could reproduce
your problem. However, this new version mangles the stack pointer
and destination address yet differently than what you posted
(bit rot in addition to xor).

Therefore, I believe it is not a good idea to try to edit glibc's
jmp_buf in any way.

Rather, I'd switch temporarily to the target context's stack
and call setjmp from there. A quick (and dirty) hack worked
for me (attached).

Disclaimer: this is not necessarily the best (most elegant + portable)
solution but the last I can squeeze out of my brain after a 21h day...

-- T.

Joel Sherrill wrote:
> Hi,
> 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. :)
> --joel
> _______________________________________________
> rtems-users mailing list
> rtems-users at rtems.com
> http://rtems.rtems.org/mailman/listinfo/rtems-users

-------------- next part --------------
A non-text attachment was scrubbed...
Name: unix-bsp-glibc-fix.diff
Type: text/x-patch
Size: 3545 bytes
Desc: not available
URL: <http://lists.rtems.org/pipermail/users/attachments/20070530/a4e42ac7/attachment-0001.bin>

More information about the users mailing list