I have symbols, defined in my makefile to represent the build version and date, however when I access them in my C++ program, the values are incorrect due to an offset being applied. My linker command is as follows
g++ -Xlinker --defsym -Xlinker __BUILD_DATE=$(date +'%Y%m%d') -Xlinker --defsym -Xlinker __BUILD_NUMBER=10000 -o MyProg main.o
and the symbols are defined, as shown below
readelf -s MyProg | grep BUILD
58: 0000000000002710 0 NOTYPE GLOBAL DEFAULT ABS __BUILD_NUMBER
65: 0000000001348c02 0 NOTYPE GLOBAL DEFAULT ABS __BUILD_DATE
However, when I run the folllowing code
#include <cstdio>
extern char __BUILD_DATE;
extern char __BUILD_NUMBER;
int main()
{
printf("Build date : %p\n", (void *)&__BUILD_DATE);
printf("Build number: %p\n", (void *)&__BUILD_NUMBER);
return 0;
}
The output is
Build date : 0x55555689cc02
Build number: 0x555555556710
An offset of 0x555555554000 is being applied. I am running on ubuntu 18.4. The program runs fine on ubuntu 16.4. One of the replies in https://stackoverflow.com/questions/8368423/why-does-the-linker-modify-a-defsym-absolute-address states
The behavior of --defsym changed between gcc 5.4.0 (using Ubuntu 16.04.4) and 7.3.0 (Ubuntu 18.04). At 5.40, --defsym created a symbol representing an absolute, non-relocatable address. At 7.3.0, readelf -s shows the symbol as "ABS", but the symbol is in fact relocated when the program executes.
As a workaround I can add a known defsym value to determine the offest and use this to adjust the other symbols, however it would be good to know the proper way to de-reference symbols in such instances?
0 Answers