GNU gcc ld: constant CRC value for special sections with references to external code

Viewed 29

I am working on a project which contains of subset of code which needs to be validated from flash at runtime with a CRC value. This code is placed into its own section of flash using the linker and during build the CRC value is calculated and injected into the appropriate area of memory. Then at runtime the flash is read and CRCed and compared to the stored value. This is all working correctly and as intended.

The code which is placed into this special section of flash is considered critical which is why it needs to be verified periodically as correct at runtime. The CRC value is also supposed to be used to validate that no changes were made to the critical section from version to version. This is what is not working as expected.

When the changes to non-critical sections of code are made (for example things placed into the normal .text region of flash) there are small differences in the critical code. Upon examining the changes it appears that most, perhaps all, of the changes are due to external function/variable references which are not in the critical code section of flash. This of course makes sense because the linker will be inserting the calls to other functions wherever they might get placed in flash which of course can change.

Is it possible to force the linker to make references to external functions/variables static in this section of flash? I was thinking this could be accomplished with some kind of lookup table which contained virtual memory/function addresses and then actual memory/function addresses and the critical code section would only reference the virtual addresses?

1 Answers

You don't say what CPU you are using, but suppose you want to call routine do_stuff from your critical section, with signature int do_stuff(int a, intb). Then you need a header in your critical section:

int tramp_do_stuff(int a, int b);

and an assembly file with a trampoline for each function in your normal section:

.org 7ffff00H         ;; however you specify a fixed address in your asm
_tramp_do_stuff:         ;; this address is fixed
        JMP do_stuff     ;; This address gets set by linker
_tramp_next_trampoline:
Related