[build] Formalise mechanism for accessing absolute symbols

In a position-dependent executable, where all addresses are fixed
at link time, we can use the standard technique as documented by
GNU ld to get the value of an absolute symbol, e.g.:

    extern char _my_symbol[];

    printf ( "Absolute symbol value is %x\n", ( ( int ) _my_symbol ) );

This technique may not work in a position-independent executable.
When dynamic relocations are applied, the runtime addresses will no
longer be equal to the link-time addresses.  If the code to obtain the
address of _my_symbol uses PC-relative addressing, then it will
calculate the runtime "address" of the absolute symbol, which will no
longer be equal the the link-time "address" (i.e. the correct value)
of the absolute symbol.

Define macros ABS_SYMBOL(), ABS_VALUE_INIT(), and ABS_VALUE() that
provide access to the correct values of absolute symbols even in
position-independent code, and use these macros wherever absolute
symbols are accessed.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2025-05-09 14:25:59 +01:00
parent 1d58d928fe
commit 134d76379e
9 changed files with 112 additions and 20 deletions

View File

@@ -49,16 +49,16 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
FEATURE_VERSION ( VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH );
/** Build timestamp (generated by linker) */
extern char _build_timestamp[];
extern unsigned long ABS_SYMBOL ( _build_timestamp );
/** Build ID (generated by linker) */
extern char _build_id[];
extern unsigned long ABS_SYMBOL ( _build_id );
/** Build timestamp */
unsigned long build_timestamp = ( ( unsigned long ) _build_timestamp );
unsigned long build_timestamp = ABS_VALUE_INIT ( _build_timestamp );
/** Build ID */
unsigned long build_id = ( ( unsigned long ) _build_id );
unsigned long build_id = ABS_VALUE_INIT ( _build_id );
/** Product major version */
const int product_major_version = VERSION_MAJOR;