mirror of
https://github.com/apache/nuttx.git
synced 2026-05-21 21:34:07 +08:00
boards/sim: skip -no-pie on HOST_ARM64 to fix sim:nsh link on aarch64 host
boards/sim/sim/sim/scripts/Make.defs adds `-no-pie` to ARCHCFLAGS /
ARCHPICFLAGS / LDFLAGS for every 64-bit non-Mac sim build. The
original comment ("To compile 64-bit Sim, adding no-pie is necessary
to prevent linking errors but this may cause other issues on
Ubuntu 20.") already flagged the workaround as fragile.
On HOST_ARM64 the option is in fact actively harmful. When gcc is
asked to produce a non-PIE executable on aarch64 it switches the
libgcc resolution path from the dynamic library
`libgcc_s.so.1` to the static archive `libgcc_s.a`. Ubuntu's
arm64 toolchain (and Debian / Raspbian arm64) **does not ship**
`libgcc_s.a` (only `libgcc_s.so.1`), so the link aborts with:
/usr/bin/ld: cannot find -lgcc_s
/usr/bin/ld: cannot find -lgcc_s (push-state / as-needed both fail)
collect2: error: ld returned 1 exit status
`ld --verbose` shows ld searching 20+ paths for `libgcc_s.a`,
finding only `libgcc_s.so` (a linker script pointing at
`libgcc_s.so.1`) which is invalid in non-PIE mode.
x86_64 Linux is unaffected because Ubuntu ships the static
`libgcc_s.a` (or a compatible static-fallback library) in its
amd64 libgcc-N-dev packaging. macOS, Windows and Cygwin go
through completely different code paths and never reach this
branch.
Extend the existing `else ifeq ($(CONFIG_HOST_MACOS),)` exclusion
to also cover HOST_ARM64 by concatenating the two variables in the
condition: `else ifeq ($(CONFIG_HOST_MACOS)$(CONFIG_HOST_ARM64),)`.
The condition is true only when both variables are empty (i.e. on
a 64-bit non-macOS non-aarch64 Linux host), so aarch64 hosts fall
through to gcc's default PIE-aware link path, which works
correctly. This concatenation idiom matches the style already
used elsewhere in the file (suggested by @xiaoxiang781216 in
review). The default text-segment placement
`-Ttext-segment=0x40000000` and `-Wl,--gc-sections` (set in the
common LDFLAGS just above this block) are honored regardless of
PIE / non-PIE.
Verified on NVIDIA Jetson Orin (Ubuntu 20.04 L4T, GCC 9.4) and
Raspberry Pi 4B (Debian 13 trixie, GCC 14.2):
$ ./build.sh sim:nsh -j$(nproc)
$ ./nuttx
NuttShell (NSH)
nsh> ostest
... [38 user_main stages, 14 PASS, 0 FAIL] ...
ostest_main: Exiting with status 0
x86_64 Linux behaviour is unchanged (the concatenation is empty
there, so the block is taken exactly as before).
Companion patch: arch/sim: rename nuttx libc memchr to avoid host
glibc collision (independent fix needed on the same aarch64 hosts).
Signed-off-by: Jinji Cui <113000688+cjj66619@users.noreply.github.com>
This commit is contained in:
@@ -326,9 +326,14 @@ ifeq ($(CONFIG_SIM_M32),y)
|
||||
LDMODULEFLAGS += -melf_i386
|
||||
SHMODULEFLAGS += -melf_i386
|
||||
LDELFFLAGS += -melf_i386
|
||||
else ifeq ($(CONFIG_HOST_MACOS),)
|
||||
|
||||
else ifeq ($(CONFIG_HOST_MACOS)$(CONFIG_HOST_ARM64),)
|
||||
# To compile 64-bit Sim, adding no-pie is necessary to prevent linking errors
|
||||
# but this may cause other issues on Ubuntu 20.
|
||||
# NOTE: HOST_ARM64 is also excluded -- Ubuntu/Debian arm64 toolchains ship
|
||||
# only libgcc_s.so.1 (no libgcc_s.a), and -no-pie forces gcc to look for
|
||||
# the static archive; skipping it lets gcc use the default PIE link path
|
||||
# which works correctly on aarch64 hosts.
|
||||
ARCHCFLAGS += -no-pie
|
||||
ARCHPICFLAGS += -no-pie
|
||||
LDFLAGS += -Wl,-no-pie
|
||||
|
||||
Reference in New Issue
Block a user