I'm using the XC8 compiler. For that, you have to define your own void putch(char data) function in order for functions like printf() to work, as is described here. Basically, putch() is the function which is used to write characters to stdout.
I now want to change this function on the fly. I have two different functions, putch_a() and putch_b() and want to be able to change which one is used for putch() itself, on the fly.
I thought of this:
unsigned use_a_not_b;
void putch(char data) {
if (use_a_not_b) {
putch_a(data);
} else {
putch_b(data);
}
}
However, this reduces execution speed. Would there be a way to use pointers for this? I have read this answer, and made the following code:
void putch_a(char data);
void putch_b(char data);
void (*putch)(char) = putch_a; // to switch to putch_a
void (*putch)(char) = putch_b; // to switch to putch_b
Would that work? Is there a faster or better-practice way?
No, and why not
To answer your question: no you can't, in the way that you are thinking (i.e. function pointer). What a function pointer is is a variable with an address of another variable. To illustrate, consider how this works when you have a function pointer foo pointing to function bar.
int bar() {
}
void baz(int (*foo)()) {
int x = foo(); // Calls the function pointed to bar foo
}
int main() {
int (*foo)();
foo = &bar;
baz(foo); // Cal baz() passing it foo, which points to bar()
}
What foo holds is the address of bar. When you pass foo to some function that expects a function pointer parameter (in this case baz()), the function dereferences the pointer, i.e. looks at the memory address associated with foo, gets the address sored in it, in our case the the address of bar, and then calls a function (in our case, bar) at that address. To be very careful about this: in the above example baz() says
Let me look at the memory associated with foo, it has another address in it
Load that address from memory, and call a function at that address. That function returns an int and takes no parameters.
Let's contrast this with a function that calls bar() directly:
void qux() {
int x = bar(); // Call bar()
}
In this case there is no function pointer. What there is, is an address, supplied by the linker. The linker lays out all the functions in your program, and it knows, for instance that bar() is at address 0xDEADBEEF. So in qux() there is just a jump 0xDEADBEEF call. In contrast in baz() there is something like (pseudo-addembly):
pop bar off the stack into register A
read memory address pointed to by register A into register B
jump to memory location pointed to by register B
The way putch() gets called from printf(), for instance, is exactly like qux() calls bar(), and not like the way baz() does: putch gets statically linked into your program, so the address of putch() is hardcoded in there, simple because fprintf() doesn't take a function pointer to call for a parameter.
Why #define is not the answer
#define is a preprocessor directive, that is, "symbols" defined with #define are replaced with their values before the compiler even sees your code. This means that #define makes your program less dynamically modifiable not more. This is desirable in some cases, but in your case it will not help you. To illustrate if you define a symbol like this:
#define Pi 3.14
Then everywhere you use Pi it is as if you typed 3.14. Bacause Pi does not exist, as far as the compiler is concerned, you cannot even take an address of it to make a pointer to it.
Closest you can get to a dynamic putch
Like the others have said, you can have some sort of case statement, conditional, or a global pointer, but the putch function itself has to be there in the same form.
Global function pointer solution:
void (*myPutch)(char);
putch(char ch) {
myPutch(ch);
}
int main() {
myPutch = putch_Type_A();
...
myPutch = putch_Type_B();
}
If/then/else solution has been provided in other answers
goto solution: This would be an ugly (but fun!) hack, and only possible on von Neumann-type machines, but in these conditions you could have your putch look like this:
putch(char ch) {
goto PutchTypeB
PutchTypeA:
// Code goes here
return;
PutchTypeB:
// Code goes here
return;
}
You would then overwrite the goto instruction with goto to some other memory address. You'd have to figure out the opcodes for doing this (from disassembly, probably), and this isn't possible on Harvard architecture machines, so it is out on AVR processors, but it would be fun, if cludgey.
No. That isn't guaranteed to work due to the way code is generated and linked. However...
void (*output_function)(char) = putch_a;
void putch(char c) {
output_function(c);
}
Now you can change output_function whenever you like...
There is no concept of "speed" in C. That's an attribute introduced by implementations. There are fast implementations (or rather, implementations that produce fast code, in the case of "compilers") and slow implementations (or implementations that produce slow code).
Either way, this is unlikely to be a significant bottleneck. Produce a program that solves a useful program, profile it to determine the most significant bottlenecks and work on optimising those.
Before you optimize this, make sure what you have really does reduce execution speed noticeably. In an i/o function there's usually a lot of other stuff going on (checking if buffer space is free, calculating buffer offsets, informing hardware data is available, being interrupted while data is actually transmitted to hardware, etc.) that would make a single extra if/else inconsequential.
In most cases your first block should be fine.
In comments you mention maybe needing to extend this structure to multiple putch() functions.
Maybe try
enum PUTCH { sel_putch_a, sel_putch_b, ... };
enum PUTCH putch_select;
void putch(char c) {
switch(putch_select) {
case sel_putch_a : putch_a(c); break;
case sel_putch_b : putch_b(c); break;
/* ... */
}
}
The compiler should be able to optimize the switch statement to a simple computation and a goto. If the putch_<n> functions are inlineable, this doesn't even cost an extra call/return.
The solution using a pointer-to-function in another answer is more flexible in terms of being able to change the available putch functions on the fly, or define them in other files (for example, if you're writing a library or framework to be used by others), but it does require an extra call/return overhead (compared to the simple case of just defining a single putch function).
Related
How can I retrieve the function pointer that was used to call a function, from within the function itself? Here's an example of what I need to accomplish:
struct vtable {
void (*func)(void);
};
void foobar(void) {
// How can I get the address of t.func from here?
}
int main(void)
{
struct vtable t = { foobar };
t.func();
return 0;
}
In particular I would like to know if this can be done without using additional parameters in the function definition, ie. not this way:
struct vtable {
void (*func)(struct vtable t);
};
void foobar(struct vtable t) {
...
}
int main(void)
{
struct vtable t = { foobar };
t.func(t);
return 0;
}
This is impossible in portable C. It's also impossible on typical implementations.
When you have a function call
int main(void) {
…foobar(…)…
}
there is no way for foobar to know that it was called by main using C language constructs alone. Many implementations make this information available through debugging features that let you explore the call stack, which the implementation maintains under the hood so as to keep track of where return goes to. In practice this doesn't always match the calling structure in the source code due to compile-time transformations such as inlining.
When the function is determined through a function pointer variable, typical implementations do not keep track of this information at all. A typical way to compile t.func() is:
Load the function pointer t.func into a processor register r.
Push the current instruction pointer to the call stack.
Branch to the address stored in r.
There is no information in memory that links steps 1 and 3. Other things may have happened between steps 1 and 3 depending on how the optimizer handled this particular chunk of code.
If you need to know from which “object” a “method” was called, you need to pass a pointer to the object to the function that is the method. This is how object-oriented languages with actual methods work: under the hood, there is an extra “this” or “self” argument, even if the language doesn't make it explicit.
the problem that I'm trying to solve is how to get the address of the struct without altering the function's list of arguments
The only way to do that, short of doing it the correct way with parameter passing, is to have the caller store the address in a global variable. That's ugly but possible:
#include <stdio.h>
struct vtable {
void (*func)(void);
};
static struct vtable* lastcall;
#define call(x, func) do { lastcall=&(x); (x).func(); } while(0)
void foobar(void) {
printf("foobar caller: %p\n", (void*)lastcall);
}
int main(void)
{
struct vtable t = { foobar };
printf("Address of t: %p\n", &t);
call(t, func);
return 0;
}
I wouldn't recommend the above - it is better if you change the API to include the struct, then hide that part behind a macro if you must.
Discarding everything that's portability, it is of course also possible to dissect the stack and find the caller address there. This is ABI-specific though, and you might have to do it in assembler.
No, it is not possible. How should a function know by which way it is called?
Consider if you call the function without using a structure holding its pointer, like this:
foobar();
You need to invent some way to pass the requested value as a parameter.
I can give you a working answer, but it won't be a pretty one.
C is a pretty chill language when it comes to accessing memory. In fact you can access the entire program stack from any function, this means that you can access main variables from foobar.
Knowing this is as powerfull as it is usually a bad idea.
For your problem, you can search any pointer to your foobar function in a range. Simply by creating a struct vtable pointing to ARBITRARY addresses stored at the stack and then checking if the func field is the same as the address of foobar.
Usually this will yield a SIGSEGV, to avoid this you can limit the addresses used to stack valid addresses using pointer arithmetic.
Here you have a working example in "pure" c (simply play with the RANGE define). But i have to warn you again, dont use this in the real world, unless you want to flex on your hacking skills.
#include <stdio.h>
#define RANGE 100
struct vtable {
void (*func)(void);
};
void foobar(void) {
int a[1]; //We control the stack from this address!
for (int i = 0; i < RANGE; i++) { //We are basically doing a buffer overflow
if (a[i] > a && a[i] < a+RANGE) { //Ignore addresses too far to prevent SEGF
struct vtable *t = (struct vtable*)a[i];
if (t->func == foobar)
printf("[FOOBAR] Address of t is: %x\n", a[i]);
}
}
}
int main(void)
{
struct vtable t = { foobar };
printf("[MAIN] Address of t: %x\n", &t);
t.func();
return 0;
}
Have a nice day!
First of all, you cannot get the address of t if you don't pass any reference to it. This is like trying to follow a pointer back to it's pointer. Pointers in general don't work in the reverse, and this is the reason to write data structures like double linked lists, or similar. Simply you can have millions of such pointers, all pointing to this function, so there's nothing in the function address that allow you to know where the function pointer was stored.
Once said that:
In your first paragraph you say:
How can I retrieve the function pointer that was used to call a function, from within the function itself?
Well, that's preciselly what you get when you use the plain name of the function (as in main) you can then execute that function using a (probably non empty) argument list, as you do in (). You don't know where your function has been called from, but what is true, is that if your program control is inside the body of it, it must have been called from the beginning, so using the function name inside the function could be a way to get a function's pointer. But you cannot get it further and get the structure where that pointer was used... this information is not passed in to your function, you have no means to get to it. This is the same problem as when you are forced to pass an array length to a function because there's nothing in the array that allows you to get how large it is.
I have not checked thoroughly your code, as it is just a snippet of code, that needs some adjustments to evolve into fully executable code, but from my point of view it is correct and will do what you are thinking on. Just test, the computer is not going to break if you make a mistake.
Beware in your code you have passed a full struct record by value, and that will make a full copy of the struct in order to put it in the parameter stack. Probably what you want is something like:
struct vtable {
void (*func)(void); /* correct */
};
void foobar(void) {
// How can I get the address of t.func from here?
/* if you want to get the address of the function, it is
* easy, every function knows its address, is in its
* name */
void (*f)(void) = foobar; /* this pointer is the only one
* that could be used to call
* this function and be now
* executing code here. :) */
/* ... */
f(); /* this will call foobar again, but through the pointer
* f, recursively (the pointer although, is the same) */
}
int main(void)
{
struct vtable t = { foobar };
t.func();
return 0;
}
It is very common to see functions that use callbacks to be executed on behalf of the calling code. Those functions is common also to require pointers to strcutres that represent the context they are called in behalf of. So don't hesitate to pass arguments to your function (try not to pass large structures by value, as you do in your example ---well, I recognize it is not large, it has only a pointer) but anyway, that is very common. OOP implementation rests deeply on these premises.
In GCC C, is there a way to push/pop data to the C return stack?
I'm not talking about implementing my own stack (I know how to do that); I mean using the existing C return stack to explicitly push/pop parameters (within the same level of braces, of course).
For example, something like:
extern int bar;
void foo(void) {
PUSH(bar);
bar = 12;
doSomething(); // that depends on the value of bar
bar = POP(); // restore original value of bar
}
If there were any easy way to do this, I think it would be a cleaner alternative to using a local variable like "oldBar" explicitly.
if you use a temporary variable, it's basically the same thing. The temporary variable is allocated on the stack or optimized to a register.
e.g.
extern int bar;
void foo(void) {
int tmp = bar
bar = 12;
doSomething(); // that depends on the value of bar
bar = tmp; // restore original value of bar
}
Apparently C doesn't actually require a stack structure to be used for calls, so this functionality wouldn't make sense. This is claimed in the memory layout section of this article https://www.seebs.net/c/c_tcn4e.html
Quite simply, not every compiler even has a "stack". Some systems don't really have any such feature. Every compiler for C has some kind of mechanism for handling function calls, but that doesn't mean it's a stack. More significantly, it is quite common for function parameters or local variables not to be stored on any "stack", but to be stored in CPU registers. That distinction can matter a lot, and should have been covered, rather than hand-waved away.
Technically, you could also use alloca() (located in alloca.h) to do this, but the only way to deallocate that memory is for the function call to return. It also doesn't really do what you're suggesting. alloca isn't part of the C standard either
If you are writing in pure C, you can use variadic argument function. It is, of course, not a full solution, as stack is cleared after a function call and argument is pushed only when you call a function.
But if you need to use it as you described, it might work:
extern int bar;
void doSomething(...);
void foo(void) {
doSomething(&bar);
//you do not need here to pop to restore the bar value, as you push a copy of value
}
If you want to do some other actions after push (which I can't even imagine), you can use a wrapper function.
extern int bar;
void doSomething();
void doSomethingWrapper(...) {
//here arguments that are passed in ... are pushed
doSomething();
//and here they are poped
}
void foo(void) {
//....
doSomethingWrapper(&bar);
//....
}
If you just want to manipulate stack in a cunning way the only solution is to use inline assembly. Or you can call function void push(...) to push whatever you want and use longjmp() in body of push() to avoid popping arguments when control flow leaves the function.
OK, this does what I wanted:
#define PUSHINT(var) int old__##var = var
#define POPINT(var) var = old__##var
extern int bar;
void foo(void) {
PUSHINT(bar);
bar = 12;
doSomething(); // that depends on the value of bar
POPINT(bar); // restore original value of bar
}
It would be better if I could guarantee that the "old__" prefix was unique each time, but I don't know how to do that (it's unlikely to be a problem tho).
Also it doesn't truly do a PUSH/POP (altho it does store on the return stack, at least on my hardware). You can't push one value and pop a different one.
But I didn't want to do that in the first place.
I may rename the macros to SAVE() and RESTORE()...
(Thanks to the hint from #BobbySacamano's answer.)
I have a pointer to function, assume any signature.
And I have 5 different functions with same signature.
At run time one of them gets assigned to the pointer, and that function is called.
Without inserting any print statement in those functions, how can I come to know the name of function which the pointer currently points to?
You will have to check which of your 5 functions your pointer points to:
if (func_ptr == my_function1) {
puts("func_ptr points to my_function1");
} else if (func_ptr == my_function2) {
puts("func_ptr points to my_function2");
} else if (func_ptr == my_function3) {
puts("func_ptr points to my_function3");
} ...
If this is a common pattern you need, then use a table of structs instead of a function pointer:
typedef void (*my_func)(int);
struct Function {
my_func func;
const char *func_name;
};
#define FUNC_ENTRY(function) {function, #function}
const Function func_table[] = {
FUNC_ENTRY(function1),
FUNC_ENTRY(function2),
FUNC_ENTRY(function3),
FUNC_ENTRY(function4),
FUNC_ENTRY(function5)
}
struct Function *func = &func_table[3]; //instead of func_ptr = function4;
printf("Calling function %s\n", func->func_name);
func ->func(44); //instead of func_ptr(44);
Generally, in C such things are not available to the programmer.
There might be system-specific ways of getting there by using debug symbols etc., but you probably don't want to depend on the presence of these for the program to function normally.
But, you can of course compare the value of the pointer to another value, e.g.
if (ptr_to_function == some_function)
printf("Function pointer now points to some_function!\n");
The function names will not be available at runtime.
C is not a reflective language.
Either maintain a table of function pointers keyed by their name, or supply a mode of calling each function that returns the name.
The debugger could tell you that (i.e. the name of a function, given its address).
The symbol table of an unstripped ELF executable could also help. See nm(1), objdump(1), readelf(1)
Another Linux GNU/libc specific approach could be to use at runtime the dladdr(3) function. Assuming your program is nicely and dynamically linked (e.g. with -rdynamic), it can find the symbol name and the shared object path given some address (of a globally named function).
Of course, if you have only five functions of a given signature, you could compare your address (to the five addresses of them).
Notice that some functions don't have any ((globally visible) names, e.g. static functions.
And some functions could be dlopen-ed and dlsym-ed (e.g. inside plugins). Or their code be synthetized at runtime by some JIT-ing framework (libjit, gccjit, LLVM, asmjit). And the optimizing compiler can (and does!) inline functions, clone them, tail-call them, etc.... so your question might not make any sense in general...
See also backtrace(3) & Ian Taylor's libbacktrace inside GCC.
But in general, your quest is impossible. If you really need such reflective information in a reliable way, manage it yourself (look into Pitrat's CAIA system as an example, or somehow my MELT system), perhaps by generating some code during the build.
To know where a function pointer points is something you'll have to keep track of with your program. Most common is to declare an array of function pointers and use an int variable as index of this array.
That being said, it is nowadays also possible to tell in runtime which function that is currently executed, by using the __func__ identifier:
#include <stdio.h>
typedef const char* func_t (void);
const char* foo (void)
{
// do foo stuff
return __func__;
}
const char* bar (void)
{
// do bar stuff
return __func__;
}
int main (void)
{
func_t* fptr;
fptr = foo;
printf("%s executed\n", fptr());
fptr = bar;
printf("%s executed\n", fptr());
return 0;
}
Output:
foo executed
bar executed
Not at all - the symbolic name of the function disappears after compilation. Unlike a reflective language, C isn't aware of how its syntax elements were named by the programmer; especially, there's no "function lookup" by name after compilation.
You can of course have a "database" (e.g. an array) of function pointers that you can compare your current pointer to.
This is utterly awful and non-portable, but assuming:
You're on Linux or some similar, ELF-based system.
You're using dynamic linking.
The function is in a shared library or you used -rdynamic when linking.
Probably a lot of other assumptions you shouldn't be making...
You can obtain the name of a function by passing its address to the nonstandard dladdr function.
set your linker to output a MAP file.
pause the program
inspect the address contained in the pointer.
look up the address in the MAP file to find out which function is being pointed to.
A pointer to a C function is an address, like any pointer. You can get the value from a debugger. You can cast the pointer to any integer type with enough bits to express it completely, and print it. Any compilation unit that can use the pointer, ie, has the function name in scope, can print the pointer values or compare them to a runtime variable, without touching anything inside the functions themselves.
I'm working on an embedded processor and having trouble getting interrupts to work in real life. They work fine in simulation but that's another story.
Anyway on this ARC processor you set the interrupt handler with this function _setvect1 that looks like this
extern void _setvect1(int vector, _Interrupt1 void (*target)());
I don't understand what the second part means and what it's looking for. Is that a pointer to a function, I'm not used to seeing something like (*target) I vaguely remember that () is a function?
This is my isr
int volatile flag_sp3 = 0;
_Interrupt1 _Save_all_regs void sp3_isr(void)
{
unsigned volatile long result;
result = _lr(0x0A);//status maybe
display_value(result);
flag_sp3++;
}
They call Interrupt1 and _Save_all_regs calling conventions, another thing I've not really run into before. I am talking to their support but still trying to understand and work it out for myself.
Yes it is asking you to pass a function pointer.
void (*target)() represents a pointer to function which doesn't receive any argument or return anything.
In your case, you can just pass sp3_isr as the second argument to _setvec1 function (remember, function name represents function pointer).
Also make sure that you have to declare/define sp3_isr before it's use.
The rototype:
extern void _setvect1(int vector, _Interrupt1 void (*target)());
declared two arguments named vector and target. The argument target has type _Interrupt1 void (*)() which means a pointer to a function returning void, and having an undefined number of arguments. Undefined because in C (but not C++) a function void fn() is not equivalent to void fn(void), which is a function taking no parameters. However this is somewhat pedantic as there are in fact no arguments passed in this case.
So in this case you would assign sp3_isr() as an interrupt handler thus:
_setvect1( SP3_VECT, sp3_isr ) ;
Where SP3_VECT is the interrupt vector number for the desired IRQ.
On many architectures interrupt handlers may have special requirements with respect to code generation by the compiler, and such architecture specific details are not supported in the standard definition of the C language, hence the compiler specific qualifiers _Interrupt1 and _Save_all_regs. Exactly how these directives affect code generation will be detailed in the compiler documentation - if not, they may be macros, in which case their definitions will be in an included header file.
I previously asked a question about C functions which take an unspecified number of parameters e.g. void foo() { /* code here */ } and which can be called with an unspecified number of arguments of unspecified type.
When I asked whether it is possible for a function like void foo() { /* code here */ } to get the parameters with which it was called e.g. foo(42, "random") somebody said that:
The only you can do is to use the calling conventions and knowledge of the architecture you are running at and get parameters directly from the stack. source
My question is:
If I have this function
void foo()
{
// get the parameters here
};
And I call it: foo("dummy1", "dummy2") is it possible to get the 2 parameters inside the foo function directly from the stack?
If yes, how? Is it possible to have access to the full stack? For example if I call a function recursively, is it possible to have access to each function state somehow?
If not, what's the point with the functions with unspecified number of parameters? Is this a bug in the C programming language? In which cases would anyone want foo("dummy1", "dummy2") to compile and run fine for a function which header is void foo()?
Lots of 'if's:
You stick to one version of a compiler.
One set of compiler options.
Somehow manage to convince your compiler to never pass arguments in registers.
Convince your compiler not to treat two calls f(5, "foo") and f(&i, 3.14) with different arguments to the same function as error. (This used to be a feature of, for example, the early DeSmet C compilers).
Then the activation record of a function is predictable (ie you look at the generated assembly and assume it will always be the same): the return address will be there somewhere and the saved bp (base pointer, if your architecture has one), and the sequence of the arguments will be the same. So how would you know what actual parameters were passed? You will have to encode them (their size, offset), presumably in the first argument, sort of what printf does.
Recursion (ie being in a recursive call makes no difference) each instance has its activation record (did I say you have to convince your compiler never optimise tail calls?), but in C, unlike in Pascal, you don't have a link backwards to the caller's activation record (ie local variables) since there are no nested function declarations. Getting access to the full stack ie all the activation records before the current instance is pretty tedious, error prone and mostly interest to writers of malicious code who would like to manipulate the return address.
So that's a lot of hassle and assumptions for essentially nothing.
Yes you can access passed parameters directly via stack. But no, you can't use old-style function definition to create function with variable number and type of parameters. Following code shows how to access a param via stack pointer. It is totally platform dependent , so i have no clue if it going to work on your machine or not, but you can get the idea
long foo();
int main(void)
{
printf( "%lu",foo(7));
}
long foo(x)
long x;
{
register void* sp asm("rsp");
printf("rsp = %p rsp_ value = %lx\n",sp+8, *((long*)(sp + 8)));
return *((long*)(sp + 8)) + 12;
}
get stack head pointer (rsp register on my machine)
add the offset of passed parameter to rsp => you get pointer to long x on stack
dereference the pointer, add 12 (do whatever you need) and return the value.
The offset is the issue since it depends on compiler, OS, and who knows on what else.
For this example i simple checked checked it in debugger, but if it really important for you i think you can come with some "general" for your machine solution.
If you declare void foo(), then you will get a compilation error for foo("dummy1", "dummy2").
You can declare a function that takes an unspecified number of arguments as follows (for example):
int func(char x,...);
As you can see, at least one argument must be specified. This is so that inside the function, you will be able to access all the arguments that follow the last specified argument.
Suppose you have the following call:
short y = 1000;
int sum = func(1,y,5000,"abc");
Here is how you can implement func and access each of the unspecified arguments:
int func(char x,...)
{
short y = (short)((int*)&x+1)[0]; // y = 1000
int z = (int )((int*)&x+2)[0]; // z = 5000
char* s = (char*)((int*)&x+3)[0]; // s[0...2] = "abc"
return x+y+z+s[0]; // 1+1000+5000+'a' = 6098
}
The problem here, as you can see, is that the type of each argument and the total number of arguments are unknown. So any call to func with an "inappropriate" list of arguments, may (and probably will) result in a runtime exception.
Hence, typically, the first argument is a string (const char*) which indicates the type of each of the following arguments, as well as the total number of arguments. In addition, there are standard macros for extracting the unspecified arguments - va_start and va_end.
For example, here is how you can implement a function similar in behavior to printf:
void log_printf(const char* data,...)
{
static char str[256] = {0};
va_list args;
va_start(args,data);
vsnprintf(str,sizeof(str),data,args);
va_end(args);
fprintf(global_fp,str);
printf(str);
}
P.S.: the example above is not thread-safe, and is only given here as an example...