Small task #3

Write a simple trampoline generator.

Trampolines

Trampolines are small pieces of code whose only task is to transfer control to another location, perhaps modifying the process context in some way or passing additional parameters.

An interesting example of using trampolines are the FFI (foreign function interface) libraries for scripting languages. Let’s assume that an API written in C, which we want to use with Python / Lua / etc, requires passing a pointer to a function that it will call in a given situation (a so-called callback). Because our program is written in an interpreted dynamic language, the FFI library supporting callbacks must support the dynamic generation of functions callable from C. To this end, the library generates a trampoline, which will remember the appropriate registers containing parameters, write the trampoline identifier (to select the appropriate high-level function to invocation), and then call the FFI library function that starts the dynamic language interpreter with the appropriate parameters. Thanks to such a solution, we can generate any number of functions for callbacks at runtime and pass pointers to them to C functions.

Task

Write an implementation of the make_formatter function:

typedef void (*formatter) (int);

formatter make_formatter (const char *format);

The make_formatter function should return a pointer to a formatting function using a given format – format has a syntax like printf and should contain exactly 1 format specification matching the int type. The formatting function should print the appropriately formatted parameter to the standard output. E.g:

formatter x08_format = make_formatter ("%08x\n");
formatter xalt_format = make_formatter ("%#x\n");
formatter d_format = make_formatter ("%d\n");
formatter verbose_format = make_formatter ("Number: %9d!\n");

x08_format (0x1234);
xalt_format (0x5678);
d_format (0x9abc);
verbose_format (0xdef0);

should be equivalent to:

printf ("%08x\n", 0x1234);
printf ("%#x\n", 0x5678);
printf ("%d\n", 0x9abc);
printf ("Number: %9d!\n", 0xdef0);

Hints

Compile the following code (with the -mcmodel=large option) and disassemble the resulting .o file:

void formatter (int param) {
    printf ("%08x\n", param);
}

From the compiled machine code, make a template that will be filled with a pointer to the appropriate format by make_formatter. Remember to ensure appropriate access rights for the memory area where the trampolines will be stored.