For doing Unit Testing of an embedded project on the host, I started to use function pointers to be able to change between the 'real' implementation of a function and a mock at runtime.
So, my function 'foo' looks like this in the .c file:
// the 'real' implementation of the function to be used during runtime
void fooImplementation ( )
{
/* ... */
}
// the function pointer, initialized to the 'real' implementation
void (*foo) ( ) = fooImplementation;
It came out that the target processor (Blackfin) generates an exception, because the function pointer resides in the internal L1 data memory which isn't allowed to carry code but only data.
A solution that works is to assign an attribute to each function pointer so it is put into a different section that doesn't reside in L1 data memory, e.g.:
void (*foo) ( ) __attribute__ (( section(".ext_mem"))) = fooImplementation;
But this makes the code a little bit hard to read and is error prone (if you forget to assign the attribute, unit tests will run fine but the code will generate the exception as soon as the function is called on the target).
So my question is if there is some way to tell gcc to put all function pointers to a different section by default.
There is no such option, in gcc, to specially put all function pointers in a particular section, by default. Unless, ofcourse you rewrite the compiler and linker rules.
You have to use the __attribute__ keyword, as you mentioned in the question. If the code looks complex, you could create a macro around it:
#define SPECIAL_FOO(x) void (*x) ( ) __attribute__ (( section(".ext_mem")))
and then use it like this:
SPECIAL_FOO(foo) = fooImplementation;
There's however another way, too. You could see this SO thread to understand more about creating custom linker scripts to accomplish your task:Forcing certain compiler-generated variables into specific ELF sections (with gcc)
Related
I have a function whose behavior may need to be modified based on the file it is called from (e.g., to increase debugging trace output). This modification would need to be done without recompiling (e.g., by editing a configuration file or changing an environment variable).
Just as an example that would fill this need, I could write Function() as:
FunctionModifiable( const char* pszFile, int i );
Then make a macro thusly:
#define Function( i ) FunctionModifiable( __FILE__, (i) )
And FunctionModifiable() would have the duty to check pszFile in say an unordered_set<> that was populated during initialization to see if special functionality need be activated.
However, the overhead of that search is a minus (this is high-performance software and the function is called a huge number of times), and there is some per-file data that would need to be cached in this situation. We can eliminate the search, and have get storage for the cached info, by passing in not __FILE__ but a pointer to a helper object. This object needs the filename so that, when it undergoes one-off initialization, it can consult config or environment variables or what have you to know whether it needs special handling.
FunctionHelperObject fho( __FILE__ );
#define Function( i ) FunctionModifiable( &fho, (i) ) // C-style solution
#define Function( i ) fho.MethodModifiable( (i) ) // C++-style solution
OK, now say I want to avoid users having to define that fho in every file. (Inter alia, we can't re-write all existing files calling Function(), though say we're willing to recompile them).
The idea I had was the unusual step of putting a variable definition in the header file, so that any program including the header for Function() would get a FunctionHelperObject fho( __FILE__ ) for free. (Such definition would be #pragma once or guarded by a preprocessor variable.
The problem is that __FILE__ at that point would be the name of the header, not of the top-level compilation unit. If there was a __CFILE__ symbol, that would be the solution, but there's not.
Ultimately the best I can think of has shortcomings: 1) the "modifiable" aspect would only be available in source code explicitly written to use it, and 2) you'd have to do that explicit writing, and 3) starting to get a little complicated. In code you want to add the ability to modify behavior to you'd write USE_MODIFIABLE_FUNCTION somewhere after including the header in question. That'd be a macro that creates the FunctionHelperObject above, this time in the right "file" so __FILE__ would have the required value, and furthermore defines a macro as seen above that would mask the non-customizable function Function() with one of the two macros seen above. In short: the previous example, plus
#define USE_MODIFIABLE_FUNCTION FunctionHelperObject fho( __FILE__ );\n#define Function( i ) fho.MethodModifiable( (i) )
Code written without USE_MODIFIABLE_FUNCTION would simply call the uncustomizable Function() the normal way.
But surely this is some other accepted, portable way to provide this behavior? Although I've talked exclusively about the C preprocessor, is there perhaps any C++ template magic or any other approach that would work?
Cache the result.
// in the header with Function macro
static FunctionHelperObject functionhelper;
static inline void FunctionModifiableInterface(const char *file, int i) {
static initialized = 0;
if (initialized == 0) {
initialized = 1;
functionhelper = FunctionHelperObject(file);
}
FunctionModifiable(&functionhelper, i);
}
#define Function(i) FunctionModifiableInterface(__FILE__, (i))
You can't predict where the user would want to call you Function(i), so you can't predict the value of __FILE__. Just initialize it on the first call, which also is great, because you will not initialize it if Function is not called. You could do the same initialized check inside FunctionHelperObject constructor.
The really cool and hard to do trick is to modify your build system to allow you to pass a macro with the filename of compiled C file. Because build systems compile one C file at a time, it is possible (and it's a shame compilers doesn't do that by themselves). If you are using cmake with make backend (or really just make by itself), you could do something like this:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__MY_FILE__='\"$(notdir $(abspath $<))\"'")
And then use FunctionHelperObject fho(__MY_FILE__) like you wanted to, because __MY_FILE__ depends only on the output filename from make.
One option is something like this (rough example, keeping the C++ syntax from the OP) :
#define Function(i) do { \
static FunctionHelperObject obj(__FILE__); \
FunctionModifiable(&obj, (i)); \
} while (0)
Note the above will have to be modified to accommodate for a return value if the function has one.
Also : an alternative to __FILE__ might be __func__ if that fits better with your needs.
In my case I am writing a simple plugin system in C using dlfcn.h (linux). The plugins are compiled separately from the main program and result in a bunch of .so files.
There are certain functions that must be defined in the plugin in order for the the plugin to be called properly by the main program. Ideally I would like each plugin to have included in it a .h file or something that somehow states what functions a valid plugin must have, if these functions are not defined in the plugin I would like the plugin to fail compilation.
I don't think you can enforce that a function be defined at compile time. However, if you use gcc toolchain, you can use the --undefined flag when linking to enforce that a symbol be defined.
ld --undefined foo
will treat foo as though it is an undefined symbol that must be defined for the linker to succeed.
You cannot do that.
It's common practice, to only define two exported functions in a library opened by dlopen(), one to import functions in your plugin and one to export functions of your plugin.
A few lines of code are better than any explanation:
struct plugin_import {
void (*draw)(float);
void (*update)(float);
};
struct plugin_export {
int (*get_version)(void);
void (*set_version)(int);
};
extern void import(struct plugin_import *);
extern void export(struct plugin_export *);
int setup(void)
{
struct plugin_export out = {0};
struct plugin_import in;
/* give the plugin our function pointers */
in.draw = &draw, in.update = &update;
import(&in);
/* get our functions out of the plugin */
export(&out);
/* verify that all functions are defined */
if (out.get_version == NULL || out.set_version == NULL)
return 1;
return 0;
}
This is very similar to the system Quake 2 used. You can look at the source here.
With the only difference, Quake 2 only exported a single function, which im- and exports the functions defined by the dynamic library at once.
Well after doing some research and asking a few people that I know of on IRC I have found the following solution:
Since I am using gcc I am able to use a linker script.
linker.script:
ASSERT(DEFINED(funcA), "must define funcA" ) ;
ASSERT(DEFINED(funcB), "must define funcB" ) ;
If either of those functions are not defined, then a custom error message will be output when the program tries to link.
(more info on linker script syntax can be found here: http://www.math.utah.edu/docs/info/ld_3.html)
When compiling simply add the linker script file after the source file:
gcc -o test main.c linker.script
Another possibility:
Something that I didn't think of (seems a bit obvious now) that was brought to my attention is you can create small program that loads your plugin and checks to see that you have valid function pointers to all of the functions that you want your plugin to have. Then incorporate this into your build system, be it a makefile or a script or whatever. This has the benefit that you are no longer limited to using a particular compiler to make this work. As well as you can do some more sophisticated checks for other other things. The only downside being you have a little more work to do to get it set up.
I'm attempting to build a test framework in TCL that will allow me to perform scripted tests on a remote device over a TCP socket. There already exists a Visual Basic interface and with SWIG in Ubuntu I'm reusing the C functions that it calls to build a shared library that will work as an extension to TCL. I have had success at incorporating basic functions, such as opening/closing sockets, and basic read/writes to single memory addresses on the device using SWIG's typemaps.i to provide pointers (*OUTPUT) to the readAddress function to return address values to TCL.
The problem is that for this to be useful I am going to have to incorporate a large number of Remote Procedure Calls which pass complicated data types into (and back out of!) the device. As a proof of concept I'm attempting to get a relatively simple function working. This attempts to read default test parameters via an RPC; a pointer to a struct is provided for the function to use for the results: rpc_testDefaults ( testDefaults_t *testDefaults ).
The typedef for testDefaults_t is in testDefaults.h, which is in the style of the following:
// testDefaults.h
#include <stdint.h>
typedef uint32_t customType_t;
typedef struct
{
customType_t varName1; // Description
uint32_t varName2; // Description
// 13 more uint32_t elements
} testDefaults_t;
// Two more struct type definitions
testDefaults.c is along the lines of this:
// testDefaults.c
#include "testDefaults.h"
// #ifdefs to compile as 'client' OR 'server' (defaults to 'client')
rpc_testDefaults ( testDefaults_t, *testDefaults )
{
// function
}
My SWIG interface file looks like this:
// rpcTest.i
%module rpcTest
%include <cpointer.i>
%include "testDefaults.h"
%pointer_functions(testDefaults_t, testDefaults);
//%apply int *OUTPUT {testDefaults_t, *testDefaults};
%{
#include "testDefaults.h"
extern int rpc_testDefaults ( testDefaults_t, *testDefaults )
}%
extern int rpc_testDefaults ( testDefaults_t, *testDefaults )
There are many other .c and header files in the same folder which support this function and the others which I mentioned I got working.
I run swig -tcl -debug-typedef rpcTest.i which gives me rpcTest_wrap.c, I can see that the testDefaults_t has been recognised as a type/scope as is has a section in the debug output (it's also included in the unnamed scope section: testDefaults_t -> testDefaults_t).
I run gcc -fPIC -DCLIENT_FLAG -c *.c -I/usr/include/tcl8.5 and I get an error from a line in the SWIG output file: rpcTest_wrap.c:1803:3: error: unknown type name 'testDefaults_t' (plus a lot more errors derived from this). The line in question is the first line in this function:
static testDefaults_t *new_testDefaults() {
return (testDefaults_t *)malloc(sizeof(testDefaults_t));
}
Which I believe is cpointers.i creating a function for TCL to 'create' a pointer to that struct.
I have a feeling this is something to do with gcc including files in the wrong order, but I'm at a loss as to what to do next. I've tried many combinations of defining the header in various places in the interface file and this is the combination that gives the least errors :). You can see my commented-out partial attempt at using typemaps instead of cpointers but I'm even more clueless with these, I managed it for a pointer to a single value but it didn't seem to be working for a struct with it's own type. It did compile without error though.
So is it possible to get what I'm trying to achieve working using cpointers.i? Any suggestions on how to overcome the compiler issue? Would I be better off learning how to use typemaps? Let me know where I can provide more detail if it would help, I may be leaving out crucial information as I've had to summarize and change all the names as this is company stuff.
Any help/criticism would be greatly appreciated!
Looking into the rpcTest_wrap.c file I noticed that the include for testDefaults.h was right after the group of functions that were attempting to use it. I replaced "int" in the interface file with testDefaults_t (I think this is correct), ran SWIG, edited the output (dangerous I know!) so that the include happened just before these functions, and it compiles fine. I can load the shared library into TCL and run the new functions.
However, and this is perhaps a new question, [in TCL] using the new functions to create a pointer, feed it into rpc_testDefaults, and attempting to dereference the resulting pointer using testDefaults_value just returns another pointer. I realize that I can't just dereference a struct, but I have no idea how to dereference individual elements. Any tutorials I can find only refer to dereferencing non-structs (and none of these tutorials are for TCL). Something somewhere mentioned that there are similarities between structs and TK widgets so I'll have a look into this, but I'm still not sure is what I'm attempting to do even possible, and if it is is this the right way to do it.
Again, what I am attempting to do is in TCL, access individual elements of a struct which has been returned from (or fed into) a C function via a pointer.
UPDATE: I got this working in the end by using the functions SWIG generates which I discovered in the end of the wrapper file. cpointer.i wasn't needed at all. In TCL I first create a pointer using the new function new_testDefaults which returns a string with in the form of a TCL style pointer. I pass this pointer into rpc_testDefaults, which returns nothing as it was actually a void function. I can then access individual elements from the struct referenced by the above pointer by setting it as an argument to the elementName_get and elementName_set functions generated by SWIG. The next task is to get more complicated functions working, structs in structs etc, but now that I'm familiar with the methodology it shouldn't be too hard.
I understand that a function pointer points to the starting address of the code for a function. But is there any way to be able to point to the end of the code of a function as well?
Edit: Specifically on an embedded system with a single processor and no virtual memory. No optimisation too. A gcc compiler for our custom processor.
I wish to know the complete address range of my function.
If you put the function within its own special linker section, then your toolchain might provide a pointer to the end (and the beginning) of the linker section. For example, with Green Hills Software (GHS) MULTI compiler I believe you can do something like this:
#pragma ghs section text=".mysection"
void MyFunction(void) { }
#pragma ghs section
That will tell the linker to locate the code for MyFunction in .mysection. Then in your code you can declare the following pointers, which point to the beginning and end of the section. The GHS linker provides the definitions automatically.
extern char __ghsbegin_mysection[];
extern char __ghsend_mysection[];
I don't know whether GCC supports similar functionality.
You didn't say why you need this information, but on some embedded system it's required to copy a single function from flash to ram in order to (re)program the flash.
Normally you are placing this functions into a new unique section and depending of your linker you can copy this section with pure C or with assembler to the new (RAM) location.
You also need to tell the linker that the code will run from another address than that it is placed in flash.
In a project the flash.c could look like
#pragma define_section pram_code "pram_code.text" RWX
#pragma section pram_code begin
uint16_t flash_command(uint16_t cmd, uint16_t *addr, uint16_t *data, uint16_t cnt)
{
...
}
#pragma section pram_code end
The linker command file looks like
.prog_in_p_flash_ROM : AT(Fpflash_mirror) {
Fpram_start = .;
# OBJECT(Fflash_command,flash.c)
* (pram_code.text)
. = ALIGN(2);
# save data end and calculate data block size
Fpram_end = .;
Fpram_size = Fpram_end - Fpram_start;
} > .pRAM
But as others said, this is very toolchain specific
There is no way with C to point to the end of a function. A C compiler has a lot of latitude as to how it arranges the machine code it emits during compilation. With various optimization settings, a C compiler may actually merge machine code intermingling the machine code of the various functions.
Since along with what ever the C compiler does there is also what is done by the linker as well as the loader as a part of linking the various compiled pieces of object code together and then loading the application which may also be using various kinds of shared libraries.
In the complex running environment of modern operating systems and modern development tool chains, unless the language provides a specific mechanism for doing something, it is prudent to not try to get fancy leaving yourself open to an application which suddenly stops working due to changes in the operating environment.
In most cases if you use a non-optimizing setting of the compiler with static linked libraries, the symbol map that most linkers provide will give you a good idea as to where functions begin and end. However the only thing you can really depend on is knowing the address of the function entry points.
In some implementations (including gcc) you could do something like this (but its not guaranteed and lots of implementation details could affect it):
int foo() {
printf("testing\n");
return 7;
}
void foo_end() { }
int sizeof_foo() {
// assumes no code size optimizations across functions
// function could be smaller than reported
// reports size, not range
return (int (*)())foo_end - foo;
}
I have an interface with which I want to be able to statically link modules. For example, I want to be able to call all functions (albeit in seperate files) called FOO or that match a certain prototype, ultimately make a call into a function in the file without a header in the other files. Dont say that it is impossible since I found a hack that can do it, but I want a non hacked method. (The hack is to use nm to get functions and their prototypes then I can dynamically call the function). Also, I know you can do this with dynamic linking, however, I want to statically link the files. Any ideas?
Put a table of all functions into each translation unit:
struct functions MOD1FUNCS[]={
{"FOO", foo},
{"BAR", bar},
{0, 0}
};
Then put a table into the main program listing all these tables:
struct functions* ALLFUNCS[]={
MOD1FUNCS,
MOD2FUNCS,
0
};
Then, at run time, search through the tables, and lookup the corresponding function pointer.
This is somewhat common in writing test code. e.g., you want to call all functions that start with test_. So you have a shell script that grep's through all your .C files and pulls out the function names that match test_.*. Then that script generates a test.c file that contains a function that calls all the test functions.
e.g., generated program would look like:
int main() {
initTestCode();
testA();
testB();
testC();
}
Another way to do it would be to use some linker tricks. This is what the Linux kernel does for its initialization. Functions that are init code are marked with the qualifier __init. This is defined in linux/init.h as follows:
#define __init __section(.init.text) __cold notrace
This causes the linker to put that function in the section .init.text. The kernel will reclaim memory from that section after the system boots.
For calling the functions, each module will declare an initcall function with some other macros core_initcall(func), arch_initcall(func), et cetera (also defined in linux/init.h). These macros put a pointer to the function into a linker section called .initcall.
At boot-time, the kernel will "walk" through the .initcall section calling all of the pointers there. The code that walks through looks like this:
extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];
static void __init do_initcalls(void)
{
initcall_t *fn;
for (fn = __early_initcall_end; fn < __initcall_end; fn++)
do_one_initcall(*fn);
/* Make sure there is no pending stuff from the initcall sequence */
flush_scheduled_work();
}
The symbols __initcall_start, __initcall_end, etc. get defined in the linker script.
In general, the Linux kernel does some of the cleverest tricks with the GCC pre-processor, compiler and linker that are possible. It's always been a great reference for C tricks.
You really need static linking and, at the same time, to select all matching functions at runtime, right? Because the latter is a typical case for dynamic linking, i'd say.
You obviusly need some mechanism to register the available functions. Dynamic linking would provide just this.
I really don't think you can do it. C isn't exactly capable of late-binding or the sort of introspection you seem to be requiring.
Although I don't really understand your question. Do you want the features of dynamically linked libraries while statically linking? Because that doesn't make sense to me... to static link, you need to already have the binary in hand, which would make dynamic loading of functions a waste of time, even if you could easily do it.