I have encountered something I thoroughly don't understand. There is a function prototype:
typedef void ( * TMain ) ( void );
and a function variable:
TMain myFunc = MyFunc;
...
myFunc ();
This works fine, of course. Why should it not.
From the MAP-file I know that "MyFunc" is at location 0x20100. And now the funny thing. After the assignment "myFunc = MyFunc;" the variable "myFunc" does not contain the value 0x20100 but rather 0x20101!
My problem is, that I need to call a function of which I know the address from a table. So I thought I could do it like that
myFunc = ( TMain ) myTable [ 5 ]; // that would be 0x20100
myFunc (); // which produces a proper crash
However If I do
myFunc = ( TMain ) ( ( Int8 * ) myTable [ 5 ] + 1 );
myFunc ();
then it works.
What happens here? Do I always have to add an offset of 1 or is this more or less accidental? Or is there a better (and working) way to accomplish the task?
Thanks a lot for any hint. Walter
int foo(int); Here foo is a function that returns int and takes one argument of int type. So as a logical guy will think, by putting a * operator between int and foo(int) should create a pointer to a function i.e. int * foo(int);
Function Pointer Syntaxvoid (*foo)( int ); In this example, foo is a pointer to a function taking one argument, an integer, and that returns void. It's as if you're declaring a function called "*foo", which takes an int and returns void; now, if *foo is a function, then foo must be a pointer to a function.
My guess is you're on an ARM target and you've built your program in Thumb mode? (Thumb is default on ARM Ubuntu or Linaro.)
The bottom bit of a function's address tell the CPU in which instruction set it should interpret the function. 0 is ARM mode. 1 is Thumb mode. Thus all Thumb-mode function pointers will be odd.
Other architectures use this idiom also, in one way or another. Usually it safe to just zero the bottom two bits of an address (making it 4-byte aligned) and assume that that is the true location of the function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With