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:
Jinji Cui
2026-05-16 22:02:18 +08:00
committed by Xiang Xiao
parent 1ae43935fd
commit aff8ea572a
+6 -1
View File
@@ -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