[llvmlinux] Global vs. Local named registers

Renato Golin renato.golin at linaro.org
Wed May 21 11:47:43 UTC 2014

On 21 May 2014 12:36, PaX Team <pageexec at gmail.com> wrote:
> perhaps i'm asking the obvious, but where does linux have such a
> construct? it sounds pretty crazy to attempt to modify the stack
> pointer and similar registers this way...

Heh, we all asked that question one day... :)

The point here is when writing very low-level code (like unwinding)
while still wanting to interoperate with C code. Interoperating
between asm and C can be complex, especially when structure layout,
type sizes and others can change, so if your code only access certain
registers, like the stack pointer, it'd be a lot easier to maintain if
the underlying code was written in C and the stack was accessed via a
special construct.

For instance:

register unsigned long current_sp asm ("sp");

void *return_address(unsigned int level)
  struct return_address_data data;
  struct stackframe frame;

  data.level = level + 2;
  data.addr = NULL;

  frame.fp = (unsigned long)__builtin_frame_address(0);
  frame.sp = current_sp;
  frame.lr = (unsigned long)__builtin_return_address(0);
  frame.pc = (unsigned long)return_address;

  walk_stackframe(&frame, save_return_addr, &data);

  if (!data.level)
    return data.addr;
    return NULL;

This is accessing both the stack pointer and the frame pointer (in
some hardware specific way), which is a lot more readable than if it
was written in ASM. Also, if the structure stackframe changes, it'll
be a compiler error (not an execution error) if this function is not
changed accordingly. So, in some special cases, having access to some
registers is actually better than the alternative.


More information about the LLVMLinux mailing list