Skip to content

Commit a67ef2e

Browse files
committed
Zephyr: Fix size_test direct link with SDK 1.0.1
The Zephyr preset size test builds test/size_test.cpp directly with arm-zephyr-eabi, outside Zephyr's normal application link flow. With Zephyr SDK 1.0.1 this link no longer gets nosys-style syscall stubs or a permissive linker script. FileDataLoader and libc therefore pull in symbols such as open, read, close, fstat, gettimeofday, _exit, and Picolibc heap symbols, causing the size-test link to fail. Add size-test-only no-OS syscall stubs behind EXECUTORCH_SIZE_TEST_NO_OS_LINK and use a small generic linker script for this direct Zephyr SDK link. The option is enabled only for the zephyr-preset size-test CI path, so normal Zephyr app builds are unchanged. Signed-off-by: Zingo Andersen <Zingo.Andersen@arm.com> Change-Id: Id67a8bf595f2e8060f0e84a20dffb97ceac158e0
1 parent 0a9bf90 commit a67ef2e

6 files changed

Lines changed: 208 additions & 3 deletions

File tree

.github/workflows/pull.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@ jobs:
642642
elif [[ ${{ matrix.os}} == "zephyr-preset" ]]; then
643643
CXXFLAGS=${cxx_flags} cmake --preset zephyr -DCMAKE_BUILD_TYPE=Release -DEXECUTORCH_OPTIMIZE_SIZE=ON -DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON -DCMAKE_INSTALL_PREFIX=cmake-out -Bcmake-out .
644644
cmake --build cmake-out -j9 --target install --config Release
645-
CXXFLAGS=${cxx_flags} cmake -DCMAKE_TOOLCHAIN_FILE=${toolchain_cmake} -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=cmake-out -Bcmake-out/test test
645+
CXXFLAGS=${cxx_flags} cmake -DCMAKE_TOOLCHAIN_FILE=${toolchain_cmake} -DEXECUTORCH_SIZE_TEST_NO_OS_LINK=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=cmake-out -Bcmake-out/test test
646646
cmake --build cmake-out/test -j9 --config Release
647647
else
648648
echo "Fail unsupported OS selection ${{ matrix.os }}"

examples/arm/ethos-u-setup/arm-none-eabi-gcc.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2020-2022 Arm Limited. All rights reserved.
2+
# Copyright (c) 2020-2022,2026 Arm Limited. All rights reserved.
33
#
44
# SPDX-License-Identifier: Apache-2.0
55
#
@@ -59,7 +59,7 @@ add_link_options(-mcpu=${GCC_CPU} -mthumb)
5959

6060
if(SEMIHOSTING)
6161
add_link_options(--specs=rdimon.specs)
62-
else()
62+
elseif(NOT EXECUTORCH_SIZE_TEST_NO_OS_LINK)
6363
add_link_options(--specs=nosys.specs)
6464
endif()
6565

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* Copyright 2026 Arm Limited and/or its affiliates.
2+
*
3+
* This source code is licensed under the BSD-style license found in the
4+
* LICENSE file in the root directory of this source tree.
5+
*/
6+
7+
/* Link-only size-test script; this is not a runnable Zephyr memory map. */
8+
9+
ENTRY(main)
10+
11+
SECTIONS
12+
{
13+
. = 0x0;
14+
.text : { KEEP(*(.vectors)) *(.text*) *(.rodata*) }
15+
.ARM.exidx : {
16+
__exidx_start = .;
17+
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
18+
__exidx_end = .;
19+
}
20+
.preinit_array : { KEEP(*(.preinit_array*)) }
21+
.init_array : { KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*))) KEEP(*(.init_array)) }
22+
.fini_array : { KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*))) KEEP(*(.fini_array)) }
23+
.data : { *(.data*) }
24+
.bss : { *(.bss*) *(COMMON) }
25+
}

examples/zephyr/x86_64-linux-arm-zephyr-eabi-gcc.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ add_compile_definitions("$<$<NOT:$<CONFIG:DEBUG>>:NDEBUG>")
5656

5757
# Link options
5858
add_link_options(-mcpu=${GCC_CPU} -mthumb)
59+
if(EXECUTORCH_SIZE_TEST_NO_OS_LINK)
60+
set(SIZE_TEST_LINKER_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/generic-no-memory.ld")
61+
add_link_options(-T${SIZE_TEST_LINKER_SCRIPT})
62+
endif()
5963

6064
# Set floating point unit
6165
if(CMAKE_SYSTEM_PROCESSOR MATCHES "\\+fp")

test/CMakeLists.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Copyright (c) Meta Platforms, Inc. and affiliates.
22
# All rights reserved.
3+
# Copyright 2026 Arm Limited and/or its affiliates.
34
#
45
# This source code is licensed under the BSD-style license found in the
56
# LICENSE file in the root directory of this source tree.
@@ -49,6 +50,9 @@ list(TRANSFORM _size_test__srcs PREPEND "${EXECUTORCH_ROOT}/")
4950
# TODO(larryliu0820): Add EXECUTORCH_BUILD_EXECUTABLES to not build executable
5051
# when we cross compile to ios
5152
add_executable(size_test ${_size_test__srcs})
53+
if(EXECUTORCH_SIZE_TEST_NO_OS_LINK)
54+
target_compile_definitions(size_test PRIVATE EXECUTORCH_SIZE_TEST_NO_OS_LINK)
55+
endif()
5256
target_link_libraries(size_test executorch extension_data_loader)
5357
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
5458
target_link_options_gc_sections(size_test)
@@ -58,6 +62,11 @@ endif()
5862
# size_test_all_ops: binary with portable ops and no delegate backend
5963
#
6064
add_executable(size_test_all_ops ${_size_test__srcs})
65+
if(EXECUTORCH_SIZE_TEST_NO_OS_LINK)
66+
target_compile_definitions(
67+
size_test_all_ops PRIVATE EXECUTORCH_SIZE_TEST_NO_OS_LINK
68+
)
69+
endif()
6170
target_link_libraries(
6271
size_test_all_ops executorch extension_data_loader portable_ops_lib
6372
portable_kernels
@@ -71,6 +80,11 @@ endif()
7180
#
7281
if(EXECUTORCH_BUILD_KERNELS_OPTIMIZED)
7382
add_executable(size_test_all_optimized_ops ${_size_test__srcs})
83+
if(EXECUTORCH_SIZE_TEST_NO_OS_LINK)
84+
target_compile_definitions(
85+
size_test_all_optimized_ops PRIVATE EXECUTORCH_SIZE_TEST_NO_OS_LINK
86+
)
87+
endif()
7488
target_link_libraries(
7589
size_test_all_optimized_ops executorch extension_data_loader
7690
optimized_native_cpu_ops_lib

test/size_test.cpp

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/*
22
* Copyright (c) Meta Platforms, Inc. and affiliates.
33
* All rights reserved.
4+
* Copyright 2026 Arm Limited and/or its affiliates.
45
*
56
* This source code is licensed under the BSD-style license found in the
67
* LICENSE file in the root directory of this source tree.
@@ -15,12 +16,173 @@
1516
#include <executorch/runtime/platform/runtime.h>
1617
#include <stdio.h>
1718

19+
#if defined(EXECUTORCH_SIZE_TEST_NO_OS_LINK)
20+
#include <errno.h>
21+
#include <stddef.h>
22+
#include <sys/stat.h>
23+
#include <sys/types.h>
24+
#endif
25+
1826
using namespace torch::executor;
1927
using torch::executor::util::FileDataLoader;
2028

2129
static uint8_t method_allocator_pool[1024];
2230
static uint8_t activation_pool[512];
2331

32+
#if defined(EXECUTORCH_SIZE_TEST_NO_OS_LINK)
33+
#define ET_WEAK_SYSCALL __attribute__((weak))
34+
35+
extern "C" {
36+
37+
// The Zephyr size test links directly with arm-zephyr-eabi, outside Zephyr's
38+
// normal application link flow. This binary is link/size-only and is never run;
39+
// these stubs only satisfy libc hooks pulled in by FileDataLoader and
40+
// profiling.
41+
#ifdef stderr
42+
#undef stderr
43+
#endif
44+
#if !defined(__GLIBC__)
45+
extern FILE* const stderr ET_WEAK_SYSCALL = nullptr;
46+
#endif
47+
48+
ET_WEAK_SYSCALL int close(int fd) {
49+
(void)fd;
50+
errno = ENOSYS;
51+
return -1;
52+
}
53+
54+
ET_WEAK_SYSCALL int _close(int fd) {
55+
return close(fd);
56+
}
57+
58+
ET_WEAK_SYSCALL int fstat(int fd, struct stat* st) {
59+
(void)fd;
60+
st->st_mode = S_IFCHR;
61+
return 0;
62+
}
63+
64+
ET_WEAK_SYSCALL int _fstat(int fd, struct stat* st) {
65+
return fstat(fd, st);
66+
}
67+
68+
ET_WEAK_SYSCALL int gettimeofday(void* tv, void* tz) {
69+
(void)tv;
70+
(void)tz;
71+
errno = ENOSYS;
72+
return -1;
73+
}
74+
75+
ET_WEAK_SYSCALL int getentropy(void* buffer, size_t length) {
76+
(void)buffer;
77+
(void)length;
78+
errno = ENOSYS;
79+
return -1;
80+
}
81+
82+
ET_WEAK_SYSCALL int _getentropy(void* buffer, size_t length) {
83+
return getentropy(buffer, length);
84+
}
85+
86+
ET_WEAK_SYSCALL int isatty(int fd) {
87+
(void)fd;
88+
return 1;
89+
}
90+
91+
ET_WEAK_SYSCALL int _isatty(int fd) {
92+
return isatty(fd);
93+
}
94+
95+
ET_WEAK_SYSCALL off_t lseek(int fd, off_t offset, int whence) {
96+
(void)fd;
97+
(void)offset;
98+
(void)whence;
99+
errno = ENOSYS;
100+
return -1;
101+
}
102+
103+
ET_WEAK_SYSCALL off_t _lseek(int fd, off_t offset, int whence) {
104+
return lseek(fd, offset, whence);
105+
}
106+
107+
ET_WEAK_SYSCALL int open(const char* path, int flags, ...) {
108+
(void)path;
109+
(void)flags;
110+
errno = ENOSYS;
111+
return -1;
112+
}
113+
114+
ET_WEAK_SYSCALL int _open(const char* path, int flags, ...) {
115+
(void)path;
116+
(void)flags;
117+
errno = ENOSYS;
118+
return -1;
119+
}
120+
121+
ET_WEAK_SYSCALL ssize_t read(int fd, void* buf, size_t count) {
122+
(void)fd;
123+
(void)buf;
124+
(void)count;
125+
errno = ENOSYS;
126+
return -1;
127+
}
128+
129+
ET_WEAK_SYSCALL ssize_t _read(int fd, void* buf, size_t count) {
130+
return read(fd, buf, count);
131+
}
132+
133+
ET_WEAK_SYSCALL ssize_t write(int fd, const void* buf, size_t count) {
134+
(void)fd;
135+
(void)buf;
136+
(void)count;
137+
errno = ENOSYS;
138+
return -1;
139+
}
140+
141+
ET_WEAK_SYSCALL ssize_t _write(int fd, const void* buf, size_t count) {
142+
return write(fd, buf, count);
143+
}
144+
145+
ET_WEAK_SYSCALL void* _sbrk(ptrdiff_t increment) {
146+
(void)increment;
147+
errno = ENOMEM;
148+
return (void*)-1;
149+
}
150+
151+
ET_WEAK_SYSCALL void* sbrk(ptrdiff_t increment) {
152+
return _sbrk(increment);
153+
}
154+
155+
ET_WEAK_SYSCALL int getpid(void) {
156+
return 1;
157+
}
158+
159+
ET_WEAK_SYSCALL int _getpid(void) {
160+
return getpid();
161+
}
162+
163+
ET_WEAK_SYSCALL int kill(int pid, int sig) {
164+
(void)pid;
165+
(void)sig;
166+
errno = ENOSYS;
167+
return -1;
168+
}
169+
170+
ET_WEAK_SYSCALL int _kill(int pid, int sig) {
171+
return kill(pid, sig);
172+
}
173+
174+
ET_WEAK_SYSCALL void _exit(int status) {
175+
(void)status;
176+
__builtin_trap();
177+
for (;;) {
178+
}
179+
}
180+
181+
} // extern "C"
182+
183+
#undef ET_WEAK_SYSCALL
184+
#endif
185+
24186
int main(int argc, char** argv) {
25187
runtime_init();
26188

0 commit comments

Comments
 (0)