Hi,
Compiling below program:
#define STREAM_ARRAY_SIZE (1107296256)
double a[STREAM_ARRAY_SIZE],
b[STREAM_ARRAY_SIZE],
c[STREAM_ARRAY_SIZE];
typedef struct {
volatile int locked;
} spinlock_t;
volatile int cnt32=0;
volatile long cnt64=0;
void atom(){
__atomic_fetch_add(&cnt32, 1,__ATOMIC_RELAXED);
}
int main()
{
atom();
a[13] = b [23] = c [17] = (double)cnt32;
return 0;
}
with command line like:
$ gcc -O2 a.c -o a.out -march=armv8-a -mcmodel=large
/usr/lib/gcc/aarch64-linux-gnu/11/libgcc.a(lse-init.o): in function
`init_have_lse_atomics':
(.text.startup+0x14): relocation truncated to fit:
R_AARCH64_ADR_PREL_PG_HI21 against `.bss'
/usr/lib/gcc/aarch64-linux-gnu/11/libgcc.a(ldadd_4_1.o): in function
`__aarch64_ldadd4_relax':
(.text+0x4): relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21
against symbol `__aarch64_have_lse_atomics' defined in .bss section in
/usr/lib/gcc/aarch64-linux-gnu/11/libgcc.a(lse-init.o)
collect2: error: ld returned 1 exit status
R_AARCH64_ADR_PREL_PG_HI21 is generated against __aarch64_ldadd4_relax
in lse-init.c and lse.S. Not sure if this is a break on
-mcmodel=large? Or is this as expected?
-mcmodel=large
Generate code for the large code model. This makes no assumptions
about addresses and sizes of sections. Programs can be statically
linked only. The -mcmodel=large option is incompatible with
-mabi=ilp32, -fpic and -fPIC.
What I am not sure is the meaning of "statically linked".
On the other hand, the error can be fixed by using adrps to :got:
entry for __aarch64_have_lse_atomics in lse.S, but not for lse-init.o
in which the symbol is considered local definition in C code.
Last question is why do we have __aarch64_have_lse_atomics(and some
other symbols) in both libgcc and glibc?
#objdump -t /usr/lib64/libc.so.6 | grep "__aarch64_ldadd"
0000000000111460 l F .text 0000000000000030
__aarch64_ldadd8_acq
0000000000111370 l F .text 0000000000000030
__aarch64_ldadd8_relax
00000000001114c0 l F .text 0000000000000030
__aarch64_ldadd8_rel
00000000001113d0 l F .text 0000000000000030
__aarch64_ldadd4_acq
#objdump -t /usr/lib/gcc/aarch64-linux-gnu/10/libgcc.a | grep "__aarch64_ldadd8"
0000000000000000 g F .text 0000000000000030 .hidden __aarch64_ldadd8_relax
0000000000000000 g F .text 0000000000000030 .hidden __aarch64_ldadd8_acq
0000000000000000 g F .text 0000000000000030 .hidden __aarch64_ldadd8_rel
0000000000000000 g F .text 0000000000000030 .hidden
__aarch64_ldadd8_acq_rel
Any idea when each version will be used?
Thanks,
bin