Question

A few years back I read a blog (now the link is lost in oblivion) and have even seen the example of heavily using the function pointers in developing the patch for the firmware in my previous organisation.

But due to security reasons/NDA signed I couldn't take the copy of code (and I am proud of not doing so and following best practices).

I have seen that the functions are coded in some naming conventions like:

filename_func_<version>_<minor_string>(arguments,other arguments)

and similar file is coded (part of patch) and flashed in the ROM and when the function is called it takes the address of the new definition of the function from the Patch location.

Any idea/detail on this?

Was it helpful?

Solution

The system has to be designed to make this work.

There are various aspects that must be coordinated:

  • There has to be a way to change the function pointers.
  • The code has to invoke the functions through the pointers.

There are multiple ways to do it in detail, but they end up being variants on a theme.

/* Declaration of function pointer used to invoke the function */
extern int (*filename_func_ptr)(int arg1, char const *arg2);

/* Two versions of the function */
extern int filename_func_1_1(int arg1, char const *arg2);
extern int filename_func_1_2(int arg1, char const *arg2);

/* Definition of function pointer - pointing to version 1.1 of the function */
int (*filename_func_ptr)(int arg1, char const *arg2) = filename_func_1_1;

/* Use of function pointer */
static void some_function(void)
{
    printf("%d\n", (*filename_func_ptr)(1, "pi"));
}

Note that you might never have both filename_func_1_1() and filename_func_1_2() declared in the same file. The effect I'm describing is 'as if'.

After patching, by whatever means you choose, the result is as if you had this written:

int (*filename_func_ptr)(int arg1, char const *arg2) = filename_func_1_2;

You can get into issues with dynamic loading (dlsym(), plus dlopen() etc) to get the new symbols. That would need a file name for the library to dynamically load, plus a way to convert the function names into pointers to the right functions.

Each patchable function needs to be invoked uniformly through the pointer. This is what allows you to replace the function. Consider whether a dynamic (shared) library is sufficient (because it will probably be simpler). If you're on firmware, you probably don't have that luxury.

You need to consider how you'll handle multiple functions with divergent interfaces; will you use single global variables as shown here, or some generic function pointer type which has to be cast appropriately at each invocation, or a union type, or a structure holding pointers, or ... There are a lot of ways of organizing things.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top