From 3b3a863d580ef570c9aa3c9ed5348dc3188afbba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Desbiens?= Date: Wed, 26 Aug 2026 10:04:17 -0400 Subject: [PATCH] Fixed the AArch64 samples, none of which had ever linked with GCC Every AArch64 gnu example build failed at the sample link, all 27 of them -- 13 under ports/ and 14 under ports_smp/: libg.a(libc_a-init.o): in function `__libc_init_array': undefined reference to `_init' relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `_init' libg.a(libc_a-fini.o): in function `__libc_fini_array': undefined reference to `_fini' build_threadx_sample.sh links with -nostartfiles, which is correct for a port carrying its own reset path, and that drops crti.o and crtn.o along with everything else. startup.S calls __libc_init_array by design, and newlib's implementation calls _init, which crti.o is what defines. The AArch32 scripts are unaffected: they use nosys.specs and never reach __libc_init_array. The fix links crti.o and crtn.o explicitly, bracketing the object list -- the first must precede every .init contribution and the second must follow all of them, so their position is load-bearing rather than stylistic. Both paths come from the compiler's own -print-file-name, so nothing here hard-codes a toolchain layout. The atfe branch sets both to empty, deliberately: picolibc's __libc_init_array does not call _init, those 27 images link today, and adding crti.o would change a working link for no reason. That is also why check_clang.sh is green on these and does not list them as expected to fail -- the LLVM path never reached the gap, so nothing has ever linked them and failed. Fixed in ports_arch/ARMv8-A/threadx/ports/gnu/example_build, which is the single source for both the ports/ and ports_smp/ copies, then regenerated with update.sh --port-sets tx,tx_smp. The 27 generated copies are in this commit because ports_arch_check compares them. Verified: all 27 link with arm-gnu-toolchain 14.3.rel1 aarch64-none-elf, where 0 of 27 did before; _init and _fini disassemble to the expected crti prologue and crtn epilogue over a ret; check_clang.sh with ATfE 22.1.0 is still green on all five stages, including the 42 script-driven example builds; check_ports.sh is green including the reproducibility check. No regression test: these are link-only example images that no host test executes. What guards them is check_clang.sh's example stage today, and check_gcc.sh's, which is the next change and is the reason this was found. Assisted-by: Claude Code (Opus 5) --- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- .../gnu/example_build/build_threadx_sample.sh | 24 ++++++++++++++++++- 28 files changed, 644 insertions(+), 28 deletions(-) diff --git a/ports/cortex_a34/gnu/example_build/build_threadx_sample.sh b/ports/cortex_a34/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports/cortex_a34/gnu/example_build/build_threadx_sample.sh +++ b/ports/cortex_a34/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports/cortex_a35/gnu/example_build/build_threadx_sample.sh b/ports/cortex_a35/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports/cortex_a35/gnu/example_build/build_threadx_sample.sh +++ b/ports/cortex_a35/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports/cortex_a53/gnu/example_build/build_threadx_sample.sh b/ports/cortex_a53/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports/cortex_a53/gnu/example_build/build_threadx_sample.sh +++ b/ports/cortex_a53/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports/cortex_a55/gnu/example_build/build_threadx_sample.sh b/ports/cortex_a55/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports/cortex_a55/gnu/example_build/build_threadx_sample.sh +++ b/ports/cortex_a55/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports/cortex_a57/gnu/example_build/build_threadx_sample.sh b/ports/cortex_a57/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports/cortex_a57/gnu/example_build/build_threadx_sample.sh +++ b/ports/cortex_a57/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports/cortex_a65/gnu/example_build/build_threadx_sample.sh b/ports/cortex_a65/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports/cortex_a65/gnu/example_build/build_threadx_sample.sh +++ b/ports/cortex_a65/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports/cortex_a65ae/gnu/example_build/build_threadx_sample.sh b/ports/cortex_a65ae/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports/cortex_a65ae/gnu/example_build/build_threadx_sample.sh +++ b/ports/cortex_a65ae/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports/cortex_a72/gnu/example_build/build_threadx_sample.sh b/ports/cortex_a72/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports/cortex_a72/gnu/example_build/build_threadx_sample.sh +++ b/ports/cortex_a72/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports/cortex_a73/gnu/example_build/build_threadx_sample.sh b/ports/cortex_a73/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports/cortex_a73/gnu/example_build/build_threadx_sample.sh +++ b/ports/cortex_a73/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports/cortex_a75/gnu/example_build/build_threadx_sample.sh b/ports/cortex_a75/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports/cortex_a75/gnu/example_build/build_threadx_sample.sh +++ b/ports/cortex_a75/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports/cortex_a76/gnu/example_build/build_threadx_sample.sh b/ports/cortex_a76/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports/cortex_a76/gnu/example_build/build_threadx_sample.sh +++ b/ports/cortex_a76/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports/cortex_a76ae/gnu/example_build/build_threadx_sample.sh b/ports/cortex_a76ae/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports/cortex_a76ae/gnu/example_build/build_threadx_sample.sh +++ b/ports/cortex_a76ae/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports/cortex_a77/gnu/example_build/build_threadx_sample.sh b/ports/cortex_a77/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports/cortex_a77/gnu/example_build/build_threadx_sample.sh +++ b/ports/cortex_a77/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/build_threadx_sample.sh b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/build_threadx_sample.sh +++ b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports_smp/cortex_a34_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a34_smp/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports_smp/cortex_a34_smp/gnu/example_build/build_threadx_sample.sh +++ b/ports_smp/cortex_a34_smp/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports_smp/cortex_a35_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a35_smp/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports_smp/cortex_a35_smp/gnu/example_build/build_threadx_sample.sh +++ b/ports_smp/cortex_a35_smp/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports_smp/cortex_a53_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a53_smp/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports_smp/cortex_a53_smp/gnu/example_build/build_threadx_sample.sh +++ b/ports_smp/cortex_a53_smp/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports_smp/cortex_a55_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a55_smp/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports_smp/cortex_a55_smp/gnu/example_build/build_threadx_sample.sh +++ b/ports_smp/cortex_a55_smp/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports_smp/cortex_a57_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a57_smp/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports_smp/cortex_a57_smp/gnu/example_build/build_threadx_sample.sh +++ b/ports_smp/cortex_a57_smp/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports_smp/cortex_a65_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a65_smp/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports_smp/cortex_a65_smp/gnu/example_build/build_threadx_sample.sh +++ b/ports_smp/cortex_a65_smp/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports_smp/cortex_a65ae_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a65ae_smp/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports_smp/cortex_a65ae_smp/gnu/example_build/build_threadx_sample.sh +++ b/ports_smp/cortex_a65ae_smp/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports_smp/cortex_a72_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a72_smp/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports_smp/cortex_a72_smp/gnu/example_build/build_threadx_sample.sh +++ b/ports_smp/cortex_a72_smp/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports_smp/cortex_a73_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a73_smp/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports_smp/cortex_a73_smp/gnu/example_build/build_threadx_sample.sh +++ b/ports_smp/cortex_a73_smp/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports_smp/cortex_a75_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a75_smp/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports_smp/cortex_a75_smp/gnu/example_build/build_threadx_sample.sh +++ b/ports_smp/cortex_a75_smp/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports_smp/cortex_a76_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a76_smp/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports_smp/cortex_a76_smp/gnu/example_build/build_threadx_sample.sh +++ b/ports_smp/cortex_a76_smp/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports_smp/cortex_a76ae_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a76ae_smp/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports_smp/cortex_a76ae_smp/gnu/example_build/build_threadx_sample.sh +++ b/ports_smp/cortex_a76ae_smp/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports_smp/cortex_a77_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a77_smp/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports_smp/cortex_a77_smp/gnu/example_build/build_threadx_sample.sh +++ b/ports_smp/cortex_a77_smp/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects} diff --git a/ports_smp/cortex_a78_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a78_smp/gnu/example_build/build_threadx_sample.sh index fa5b92ec3..94248a888 100755 --- a/ports_smp/cortex_a78_smp/gnu/example_build/build_threadx_sample.sh +++ b/ports_smp/cortex_a78_smp/gnu/example_build/build_threadx_sample.sh @@ -44,6 +44,23 @@ case "${TOOLCHAIN}" in # initialise_monitor_handles that startup.S calls. SYSCALL_LIB="--specs=rdimon.specs" SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" ;; atfe) CC="${ATFE_CLANG:-clang}" @@ -52,6 +69,11 @@ case "${TOOLCHAIN}" in # picolibc has no initialise_monitor_handles, and neither does the # toolchain's semihosting library, so the weak stub stands in for it. SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" ;; *) echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 @@ -80,7 +102,7 @@ done "${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ -o sample_threadx.out -Wl,-Map=sample_threadx.map \ - ${objects} tx.a + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} rm -f ${objects}