diff --git a/.github/workflows/build_clangrt_builtins.yml b/.github/workflows/build_clangrt_builtins.yml new file mode 100644 index 000000000..cdfcea093 --- /dev/null +++ b/.github/workflows/build_clangrt_builtins.yml @@ -0,0 +1,92 @@ +name: Build clang runtime builtins + +on: + workflow_dispatch: + inputs: + target_sdk_branch: + type: string + required: false + default: 'master' + create_pr: + type: boolean + required: false + default: false + + # TODO: remove this next line before merging! + push: + +env: + GIT_USER_EMAIL: 'ledger@github.com' + GIT_USER_NAME: 'SDKLibsUpdaterGithub' + UPDATE_BRANCH: 'sdk_libs_update' + +jobs: + build: + runs-on: ubuntu-latest + container: + image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-lite:latest + strategy: + fail-fast: false + matrix: + target: + - core: cortex-m3 + se: st33 + - core: cortex-m35p+nodsp + se: st33k1 + + steps: + - uses: actions/checkout@v4 + with: + # TODO: remove this next line before merging! + ref: feat/regain_control_over_libs + sparse-checkout: | + tools/build_clangrt_builtins.sh + sparse-checkout-cone-mode: false + + - run: ./tools/build_clangrt_builtins.sh -t ${{ matrix.target.core }} -o artifact/arch/${{ matrix.target.se }}/lib + + - uses: actions/upload-artifact@v4 + with: + name: arch-${{ matrix.target.se }} + path: artifact/ + + merge: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/upload-artifact/merge@v4 + with: + name: arch + pattern: arch-* + delete-merged: true + + pr_create: + needs: merge + runs-on: ubuntu-latest + if: ${{ success() && inputs.create_pr }} + continue-on-error: true + steps: + - name: Clone repository + uses: actions/checkout@v4 + with: + # by default the action uses fetch-depth = 1, which creates + # shallow repositories from which we can't push + fetch-depth: 0 + ref: ${{ inputs.target_sdk_branch }} + + - name: Download Binaries artifact + uses: actions/download-artifact@v4 + with: + name: arch + + - name: PR creation + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + git config --global user.email ${{ env.GIT_USER_EMAIL }} + git config --global user.name ${{ env.GIT_USER_NAME }} + git switch --create ${{ env.UPDATE_BRANCH }} + git add -A . + git commit -m 'Updating static SDK libraries' + git push -u origin ${{ env.UPDATE_BRANCH }} + gh pr create -B ${{ inputs.target_sdk_branch }} --title '[SDK_LIBS_UPDATE] Updating static SDK libraries' --body 'Created by Github workflow "${{ github.workflow }}", job "${{ github.job }}", run "${{ github.run_id }}".' diff --git a/Makefile.defines b/Makefile.defines index 02b26cb3d..0154f0c25 100644 --- a/Makefile.defines +++ b/Makefile.defines @@ -53,8 +53,9 @@ endif SYSROOT = $(shell $(GCCPATH)arm-none-eabi-gcc -print-sysroot) ifeq ($(SYSROOT),) # path for Debian-based systems - SYSROOT = /usr/lib/arm-none-eabi + SYSROOT = /usr/lib/picolibc/arm-none-eabi endif + CFLAGS += --sysroot="$(SYSROOT)" # optimization and debugging levels @@ -107,6 +108,7 @@ endif ifeq ($(TARGET_NAME),TARGET_NANOX) CPU = cortex-m0plus CFLAGS += -frwpi + LDFLAGS += -L$(SYSROOT)/lib/thumb/v7-m/nofp/ LDFLAGS += -L$(BOLOS_SDK)/arch/st33/lib/ endif @@ -114,6 +116,7 @@ ifeq ($(TARGET_NAME),$(filter $(TARGET_NAME),TARGET_STAX TARGET_FLEX TARGET_NANO CPU = cortex-m35p+nodsp CFLAGS += -msoft-float CFLAGS += -frwpi + LDFLAGS += -L$(SYSROOT)/lib/thumb/v8-m.main/nofp/ LDFLAGS += -L$(BOLOS_SDK)/arch/st33k1/lib/ endif diff --git a/Makefile.standard_app b/Makefile.standard_app index fdae6da3d..57bffdfca 100644 --- a/Makefile.standard_app +++ b/Makefile.standard_app @@ -254,14 +254,16 @@ APP_FLAGS_APP_LOAD_PARAMS = $(shell printf '0x%x' $$(( $(STANDARD_APP_FLAGS) + $ CC = $(CLANGPATH)clang AS = $(CLANGPATH)clang ifeq ($(TARGET_NAME),TARGET_NANOS) - LD = $(GCCPATH)arm-none-eabi-gcc + LD = $(GCCPATH)arm-none-eabi-gcc + LDLIBS += -lgcc else - LD = $(CLANGPATH)clang + LD = $(CLANGPATH)clang + LDLIBS += -lclang_rt.builtins endif AFLAGS += --target=arm-none-eabi -LDLIBS += -lm -lgcc -lc +LDLIBS += -lm -lc ##################################################################### # MISC # diff --git a/arch/libraries.md b/arch/libraries.md new file mode 100644 index 000000000..ff18ef6d2 --- /dev/null +++ b/arch/libraries.md @@ -0,0 +1,23 @@ +# Introduction + +To build Ledger OS application 3 libraries are used: + +| Name | Description | Comes from | Version | CPU (Arch) | +| ----------------------- | -------------------------------------------------- | ---------------------------------------- | -------------------------------------------- | --------------------------------------------------- | +| libclang_rt.builtins | Low-level runtime library | Prebuilt in the SDK (2) | (2) | cortex-m3 (Armv7-M) and cortex-m35p+nodsp (Armv8-M) | +| (or libgcc (1)) | the same as above | Prebuilt in the SDK | Unknown | ARM, EABI5 version 1 (SYSV), not stripped | +| libc | C standard library | picolibc-arm-none-eabi Debian 12 package | 1.8-1 in current app builder docker image | thumb/v7-m/nofp and thumb/v8-m.main/nofp | +| libm | Standard C library of basic mathematical functions | the same as above | the same as above | the same as above | + +* (1) obsolete, replaced by libclang_rt.builtins, used only for Nano S, can be removed soon +* (2) See libclang_rt.builtins build below + + +# libclang_rt.builtins build + +It is built using `.github/workflows/build_clangrt_builtins.yml` and `tools/build_clangrt_builtins.sh` and pushed to the SDK using an explicit PR. +Several symbols that conflict with the ones from picolibc are removed from the library just after build. + +The parameters that have been used for the latest library build: +* on the base of ``llvm-toolchain-14-14.0.6/compiler-rt`` package (see also https://github.com/llvm/llvm-project/tree/main/compiler-rt) +* the explicit PR https://github.com/LedgerHQ/ledger-secure-sdk/pull/1035 diff --git a/arch/st33/lib/libc.a b/arch/st33/lib/libc.a deleted file mode 100644 index 1c9151d7b..000000000 Binary files a/arch/st33/lib/libc.a and /dev/null differ diff --git a/arch/st33/lib/libclang_rt.builtins.a b/arch/st33/lib/libclang_rt.builtins.a new file mode 100644 index 000000000..d312adbcf Binary files /dev/null and b/arch/st33/lib/libclang_rt.builtins.a differ diff --git a/arch/st33/lib/libm.a b/arch/st33/lib/libm.a deleted file mode 100644 index 63f3b5491..000000000 Binary files a/arch/st33/lib/libm.a and /dev/null differ diff --git a/arch/st33k1/lib/libc.a b/arch/st33k1/lib/libc.a deleted file mode 100644 index c45268e7b..000000000 Binary files a/arch/st33k1/lib/libc.a and /dev/null differ diff --git a/arch/st33k1/lib/libclang_rt.builtins.a b/arch/st33k1/lib/libclang_rt.builtins.a new file mode 100644 index 000000000..e1e2058a1 Binary files /dev/null and b/arch/st33k1/lib/libclang_rt.builtins.a differ diff --git a/arch/st33k1/lib/libm.a b/arch/st33k1/lib/libm.a deleted file mode 100644 index ae7388dd2..000000000 Binary files a/arch/st33k1/lib/libm.a and /dev/null differ diff --git a/tools/build_clangrt_builtins.sh b/tools/build_clangrt_builtins.sh new file mode 100755 index 000000000..3b788a8b7 --- /dev/null +++ b/tools/build_clangrt_builtins.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash + +set -e + +TARGET_CPU="" +OUTPUT_DIR="" + +while getopts "t:o:" opt +do + case "$opt" in + t) + TARGET_CPU="$OPTARG" + ;; + o) + OUTPUT_DIR="$OPTARG" + ;; + ?) + exit 1 + ;; + esac +done +shift "$((OPTIND - 1))" + +if [ -z "$TARGET_CPU" ] || [ -z "$OUTPUT_DIR" ] +then + echo "Usage: $0 -t TARGET_CPU -o OUTPUT_FILE" >&2 + exit 1 +fi + +mkdir -p "$OUTPUT_DIR" +OUTPUT_DIR=$(realpath "$OUTPUT_DIR") + +# enable source repository +sed -i 's/^\(Types: deb\)$/\1 deb-src/g' /etc/apt/sources.list.d/debian.sources + +apt update + +apt install -y --no-install-recommends \ + dpkg-dev \ + llvm-dev + +LLVM_VERSION=$(clang --version | head -n1 | rev | cut -d" " -f1 | rev) +LLVM_MAJOR_VERSION=$(echo "$LLVM_VERSION" | cut -d. -f1) + +cd /tmp + +LLVM_DIR="llvm-toolchain-$LLVM_MAJOR_VERSION-$LLVM_VERSION" +if [ ! -d "$LLVM_DIR" ] +then + # install Debian source package + apt source "llvm-toolchain-$LLVM_MAJOR_VERSION" +fi + +cd "$LLVM_DIR" +rm -rf build +mkdir build +cd build + +TARGET=arm-none-eabi +SYSROOT=/usr/lib/arm-none-eabi + +cmake ../compiler-rt \ + -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \ + -DCOMPILER_RT_OS_DIR="baremetal" \ + -DCOMPILER_RT_BUILD_BUILTINS=ON \ + -DCOMPILER_RT_BUILD_CRT=OFF \ + -DCOMPILER_RT_BUILD_SANITIZERS=OFF \ + -DCOMPILER_RT_BUILD_XRAY=OFF \ + -DCOMPILER_RT_BUILD_LIBFUZZER=OFF \ + -DCOMPILER_RT_BUILD_PROFILE=OFF \ + -DCOMPILER_RT_BUILD_MEMPROF=OFF \ + -DCOMPILER_RT_BUILD_ORC=OFF \ + -DCMAKE_C_COMPILER="$(which clang)" \ + -DCMAKE_C_COMPILER_TARGET="${TARGET}" \ + -DCMAKE_ASM_COMPILER_TARGET="${TARGET}" \ + -DCMAKE_AR="$(which llvm-ar)" \ + -DCMAKE_NM="$(which llvm-nm)" \ + -DCMAKE_RANLIB="$(which llvm-ranlib)" \ + -DCOMPILER_RT_BAREMETAL_BUILD=ON \ + -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \ + -DLLVM_CONFIG_PATH="$(which llvm-config)" \ + -DCOMPILER_RT_HAS_FPIC_FLAG=OFF \ + -DCMAKE_C_FLAGS="-mcpu=${TARGET_CPU} -mlittle-endian -mthumb -Oz -g0 -fropi -frwpi" \ + -DCMAKE_ASM_FLAGS="-mcpu=${TARGET_CPU} -mlittle-endian -mthumb" \ + -DCMAKE_SYSROOT="$SYSROOT" +make -j + +# Removing duplicated symbols that are also present in picolibc +ar d lib/baremetal/libclang_rt.builtins-arm.a aeabi_memset.S.o +ar d lib/baremetal/libclang_rt.builtins-arm.a aeabi_memmove.S.o +ar d lib/baremetal/libclang_rt.builtins-arm.a aeabi_memcpy.S.o + +# Output +mkdir -p "$OUTPUT_DIR" +cp lib/baremetal/libclang_rt.builtins-arm.a "$OUTPUT_DIR/libclang_rt.builtins.a"