2

I'm using the following code to obtain pointers to functions and store them as usizes:

let mut stack_mem = vec![0usize; stack_size];
let entry: unsafe extern "C" fn(*mut Box<F>) = process_entry_trampoline::<F>;
stack_mem[stack_size - 2] = entry as usize; // PC
let exit: extern "C" fn() = process_exit;
stack_mem[stack_size - 3] = exit as usize; // LR

When I check these values later, I find that they are odd numbers, such as 0x080004b9 or 0x08001de3. The actual functions show up in the disassembly of the executable at these addresses, but off by one:

080004b8 <_ZN6ia_euc7process24process_entry_trampoline17h475c405f87caeb6aE>:
 80004b8:   b5d0        push    {r4, r6, r7, lr}
 80004ba:   af02        add r7, sp, #8

So when I jump to these addresses, weird things happen, and I suspect it is because the addresses are not half-word aligned. Why is this happening, and is it necessarily safe to just clear the final bit of the address before using it?

I'm programming on an ARMv7 (Cortex-M4F) chip in Thumb mode.

laptou
  • 6,389
  • 2
  • 28
  • 59

1 Answers1

1

It seems that this last bit is actually the Thumb bit, and setting it to 0 deactivates the Thumb instruction mode (which is the only mode allowed on a Cortex-M processor, so this ruins everything).

laptou
  • 6,389
  • 2
  • 28
  • 59