I have a very simple dummy program call main.c as below:
#include <stdlib.h>
#include <stdio.h>
#define TEST __atomic_compare_exchange
void test() {
__int128 unsigned a = 1, b = 2, c = 3;
__atomic_compare_exchange_16(&a, &b, c, 1, 1, 1);
printf("hello");
}
When compile using the following command, it works fine on my local Linux machine (Debian gcc version 6):
g++ --shared -o libmain.so -latomic main.c -Wl,--no-as-needed
However when using Microsoft hosted agent ubuntu-18.04, it fails regardless of whatever command I tried. Below is a list of commands that I have tried:
g++ --shared -o libmain.so -latomic main.c -Wl,--no-as-needed
g++ --shared -o libmain.so /usr/lib/x86_64-linux-gnu/libatomic.so.1 main.c -Wl,--no-as-needed
g++ --shared -o libmain.so -L/usr/lib/x86_64-linux-gnu/ -l:libatomic.so.1 main.c -Wl,--no-as-needed
When run ldd libmain.so
not libatomic is showed in the list:
linux-vdso.so.1 (0x00007ffc3c5b6000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f889324e000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f8892eb0000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f8892c98000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f88928a7000)
/lib64/ld-linux-x86-64.so.2 (0x00007f889385d000)
When run readelf -W -s libatomic.so
, the __atomic_compare_exchange_16 shows as undefined without any suffix @...
indicating the libatomic libary to look for.
Symbol table '.dynsym' contains 14 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
2: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.2.5 (2)
3: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND __atomic_compare_exchange_16
4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __stack_chk_fail@GLIBC_2.4 (3)
5: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTable
6: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
7: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
8: 0000000000201038 0 NOTYPE GLOBAL DEFAULT 22 _edata
9: 0000000000201040 0 NOTYPE GLOBAL DEFAULT 23 _end
10: 000000000000070a 150 FUNC GLOBAL DEFAULT 12 _Z4testv
11: 00000000000005c0 0 FUNC GLOBAL DEFAULT 9 _init
12: 0000000000201038 0 NOTYPE GLOBAL DEFAULT 23 __bss_start
13: 00000000000007a0 0 FUNC GLOBAL DEFAULT 13 _fini
I have also check the g++ --print-search-dirs
and the libraries search dirs look all correct to me.
Is Microsoft Hosted Agent environment just different or am I missing any obvious linker option?
Update This is a fundamental concept to linker symbol search order that I have missed. Usually, linker searches for symbols from left to right, but for some modern linkers, all libraries are searched regardless of order. I have tested this on one my other ubuntu VM and changing the order does work as expected.
Will update once I have tested with the Microsoft hosted user-agent.
Update 2 I can confirm that it is the difference between gcc linker in Ubuntu and my local machine Debian.