The following code doesn't compile on aarch64:
use strings;
use types::c;
export fn main() void = {
let fmt = "hello";
let fmt = c::fromstr(fmt);
defer free(fmt);
printf(fmt): void;
};
@symbol("printf") fn printf(c: const nullable *c::char, ...) int;
This is currently failing with the following error:
/usr/bin/ld: /tmp/5268cb9bce41ba28/temp..19.o: relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol `printf@@GLIBC_2.17' which may bind externally can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: /tmp/5268cb9bce41ba28/temp..19.o(.text.main+0xb4): unresolvable R_AARCH64_ADR_PREL_PG_HI21 relocation against symbol `printf@@GLIBC_2.17'
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status
Error: cc: exited with status 1
hare build: build failed
Another user reported this recently. It is caused by our incomplete linker script. The problem is not aarch64 specific, but it hasn't been reproduced elsewhere yet. The linker script was discussed in #musl and dalias suggested we should use the target's default linker script instead, but that's not entirely possible because we use our linker script for the test function array.
A possible solution would be to use the system linker script in our linker script by using an INCLUDE directive. Unfortunately the system script's path and name don't appear to be standarized, but it may be possible to obtain the path by calling
ld
with appropriate arguments inconfigure
.For reference:
To work-around this, we have to
export LDFLAGS='-no-pie'
The source that pointed me to the correct direction is https://stackoverflow.com/a/59473090
It looks like the problem come from the Alpine Linux gcc, or the patchs applied to it. Its behavior changed for aarch64, and
-no-pie
which should be the default, isn't.