[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

@@ -365,7 +365,8 @@ extern char __text16_array ( sipi, [] );
#define sipi __use_text16 ( sipi )
/** Length of startup IPI real-mode handler */
extern char sipi_len[];
extern size_t ABS_SYMBOL ( sipi_len );
#define sipi_len ABS_VALUE ( sipi_len )
/** Startup IPI real-mode handler copy of real-mode data segment */
extern uint16_t __text16 ( sipi_ds );

View File

@@ -76,10 +76,10 @@ extern struct segoff __text16 ( int15_vector );
/* The linker defines these symbols for us */
extern char _textdata[];
extern char _etextdata[];
extern char _text16_memsz[];
#define _text16_memsz ( ( size_t ) _text16_memsz )
extern char _data16_memsz[];
#define _data16_memsz ( ( size_t ) _data16_memsz )
extern size_t ABS_SYMBOL ( _text16_memsz );
#define _text16_memsz ABS_VALUE ( _text16_memsz )
extern size_t ABS_SYMBOL ( _data16_memsz );
#define _data16_memsz ABS_VALUE ( _data16_memsz )
/**
* Hide region of memory from system memory map

View File

@@ -55,12 +55,12 @@ extern void pxe_int_1a ( void );
static int int_1a_hooked = 0;
/** Real-mode code segment size */
extern char _text16_memsz[];
#define _text16_memsz ( ( size_t ) _text16_memsz )
extern size_t ABS_SYMBOL ( _text16_memsz );
#define _text16_memsz ABS_VALUE ( _text16_memsz )
/** Real-mode data segment size */
extern char _data16_memsz[];
#define _data16_memsz ( ( size_t ) _data16_memsz )
extern size_t ABS_SYMBOL (_data16_memsz );
#define _data16_memsz ABS_VALUE ( _data16_memsz )
/** PXENV_UNDI_TRANSMIT API call profiler */
static struct profiler pxe_api_tx_profiler __profiler =

View File

@@ -426,7 +426,7 @@ void setup_sipi ( unsigned int vector, uint32_t handler,
memcpy ( &sipi_regs, regs, sizeof ( sipi_regs ) );
/* Copy real-mode handler */
copy_to_real ( ( vector << 8 ), 0, sipi, ( ( size_t ) sipi_len ) );
copy_to_real ( ( vector << 8 ), 0, sipi, sipi_len );
}
PROVIDE_IOMAP_INLINE ( pages, io_to_bus );