Hi,
On Tue, Dec 7, 2010 at 7:15 PM, Nicolas Pitre nicolas.pitre@linaro.org wrote:
On Tue, 7 Dec 2010, Dave Martin wrote:
On Tue, Dec 7, 2010 at 2:53 PM, Dave Martin dave.martin@linaro.org wrote: [...]
Note that converting to C doesn't mean that code which attempts to copy function bodies will work: you still need to handle the fact that if f() is a C function symbol, then the value of the symbol f is actually the function's base address + 1. See my changes in sram.c,
To clarify, this applies *if* f is a Thumb symbol.
To make it generic, a new macro could be used:
#define SYM_ADDR(x) ((void *)((long)(x) & ~1L))
Could do ... I wasn't sure if it was useful for just this one case, but I guess we may encounter others. And it would make the code a lot less messy...
if so, a macro for exracting just the Thumb bit, and a macro for rebasing a symbol while preserving the Thumb bit could also be useful.
#define SYM_STATE(x) ((long)(x) & 1) #define SYM_REBASE(new_addr, sym) ((void *)((long)SYM_ADDR(new_addr) | SYM_STATE(sym)))
The relationship could be a bit clearer if we use the name SYM_BASE instead of SYM_ADDR.
With these, the affected code becomes something like:
memcpy(buffer, SYM_BASE(f), size_of_f); new_f = SYM_REBASE(f, buffer);
What do you think?
Is there a recommended type for a pointer-sized integer? I notice linux/types.h defines uintptr_t (as unsigned long).
Cheers ---Dave