[PATCH] ARM + Thumb Segmented Stacks (v2)

Alex Crichton alex at crichton.co
Thu Mar 27 13:07:58 PDT 2014

> Ah, so upstreaming this will get rust one step closer to being able to use
> unmodified LLVM.

Indeed, we hope to be able to to it soon!

> If you search for CFI_INSTRUCTION in ARMFrameLowering.cpp, you will find all
> of the places where we currently emit call frame instructions. There are two
> things these instructions do:
> * Let the debugger know, at any point in the function, how to calculate the
> CFA (Canonical Frame Address). This is defined for ARM as the value of sp at
> entry to the current function. This will need doing every time you update
> the stack pointer (i.e. once for each push and pop instruction).
> * Let the debugger know how to find the value of each register as it would
> have been immediately before this function was called. This will need doing
> each time you save or restore the value of a callee-saved register.
> This should be simple enough to implement, so I'd like it to be done as part
> of this patch.

OK, I have attempted to add information, as well as add a test. I
wasn't entirely sure what to for the pops, though. Most other pops I
saw in the tests were immediately followed by cfi_endproc, which isn't
quite accurate here. You may want to double check the test to make
sure I didn't get anything wrong.

> 4) I don't think we need to push/pop lr around the call to __morestack.

Wouldn't the "bl __morestack" clobber the link register? If it were
just "b __morestack" then how would __morestack know how to call the
original function on the new stack?

> 5) You are currently emitting 32-bit push and pop instructions, where 16-bit
> encodings will do. The only push/pop instruction which you are using which
> does not have a 16-bit encoding is "ldm.w   sp!, {lr}" (aka push.w {lr}).
> Optimisations (4) and (5) should be fairly simple, so I think they should be
> done as part of this patch, but the others are a bit more involved, so could
> wait until a later patch.

I didn't implement (4) due to my above confusion (but if I'm wrong,
I'm happy to change it).

I've attempted to implement (5), but if I chose the wrong opcodes,
just let me know.

> 7) I'm slightly confused as to why ARM and Thumb use different methods to
> get the stack limit.  It seems to me that this should be decided based on
> platform (e.g. linux or android), not instruction set, especially given that
> ARM and Thumb code can be freely combined in the same executable.

According to the original author [1], apparently some Thumb units
don't have the coprocessor that the ARM version uses. The location of
the stack limit seems like it can be all over the place and is pretty
dependent to the platform that it's running on, so I'm not quite sure
what the best way is to reconcile all these without adding a zillion
configuration options.

[1] - https://github.com/rust-lang/llvm/pull/4
-------------- next part --------------
A non-text attachment was scrubbed...
Name: arm.patch
Type: application/octet-stream
Size: 36229 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140327/809dda51/attachment.obj>

More information about the llvm-commits mailing list