From 6845d7ff833b35d226c19795be73a49d5fa1698d Mon Sep 17 00:00:00 2001 From: aviralgarg05 Date: Sat, 11 Jul 2026 21:57:50 +0530 Subject: [PATCH] examples/sotest: support packaged shared library fixtures Extend the examples/sotest packaging path so the shared-library test fixtures can also be prepared through nxpkg-style package artifacts. Generate shared-index.json and pkgsotest.nsh from the built modprint and sotest shared objects, recording the correct target arch/compat metadata and SHA-256 digests for the packaged shared-library fixtures. Allow sotest to run in either its existing builtin-ROMFS flow or from explicit shared-library paths, with a --mount helper mode for preparing the builtin test mount separately. Keep the paired fixture outputs in one grouped make step so parallel builds do not re-enter the generator independently. This makes the sotest shared-library example usable as a package-style fixture producer for the Dynamic ELF/nxpkg series, useful for validating the shared-library side of the packaging flow where the loader should consume installed artifacts rather than only the default builtin test paths. The existing builtin-ROMFS path is preserved with no regression to the normal sotest example flow. Signed-off-by: aviralgarg05 --- examples/sotest/Make.defs | 9 +- examples/sotest/main/CMakeLists.txt | 108 ++++- examples/sotest/main/Makefile | 25 +- examples/sotest/main/host/CMakeLists.txt | 26 ++ examples/sotest/main/mk_pkg_fixture_shared.c | 427 +++++++++++++++++++ examples/sotest/main/sotest_main.c | 98 ++++- examples/sotest/modprint/CMakeLists.txt | 25 ++ examples/sotest/sotest/CMakeLists.txt | 25 ++ 8 files changed, 712 insertions(+), 31 deletions(-) create mode 100644 examples/sotest/main/host/CMakeLists.txt create mode 100644 examples/sotest/main/mk_pkg_fixture_shared.c create mode 100644 examples/sotest/modprint/CMakeLists.txt create mode 100644 examples/sotest/sotest/CMakeLists.txt diff --git a/examples/sotest/Make.defs b/examples/sotest/Make.defs index c674e34e66e..17afaca4367 100644 --- a/examples/sotest/Make.defs +++ b/examples/sotest/Make.defs @@ -20,4 +20,11 @@ # ############################################################################ -include $(wildcard $(APPDIR)/examples/sotest/*/Make.defs) +ifeq ($(CONFIG_EXAMPLES_SOTEST),y) +include $(APPDIR)/examples/sotest/main/Make.defs +endif + +ifneq ($(CONFIG_EXAMPLES_SOTEST),n) +include $(APPDIR)/examples/sotest/modprint/Make.defs +include $(APPDIR)/examples/sotest/sotest/Make.defs +endif diff --git a/examples/sotest/main/CMakeLists.txt b/examples/sotest/main/CMakeLists.txt index caca43d2212..d893ba27abc 100644 --- a/examples/sotest/main/CMakeLists.txt +++ b/examples/sotest/main/CMakeLists.txt @@ -21,27 +21,101 @@ # ############################################################################## if(CONFIG_EXAMPLES_SOTEST) + set(SOTEST_SYMTAB ${CMAKE_CURRENT_BINARY_DIR}/sotest_symtab.c) + set(SOTEST_ROMFS_IMG ${CMAKE_CURRENT_BINARY_DIR}/sotest_romfs.img) + set(SOTEST_ROMFS_SRC ${CMAKE_CURRENT_BINARY_DIR}/sotest_romfs.c) + set(SOTEST_MODPRINT_ELF ${CMAKE_BINARY_DIR}/bin/modprint) + set(SOTEST_SHARED_ELF ${CMAKE_BINARY_DIR}/bin/sotest) + + # Dynamic applications are wrapped in ELF_* helper targets when the build uses + # the non-ELF-capable compiler path. + if(CMAKE_C_ELF_COMPILER) + set(SOTEST_MODPRINT_TARGET modprint) + set(SOTEST_SHARED_TARGET sotest) + else() + set(SOTEST_MODPRINT_TARGET ELF_modprint) + set(SOTEST_SHARED_TARGET ELF_sotest) + endif() - # FIXME: fix all empty a after the kernel build is implemented add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/sotest_symtab.c - COMMAND - ${NUTTX_APPS_DIR}/tools/mksymtab.sh ${CMAKE_CURRENT_BINARY_DIR}/empty - g_sot > ${CMAKE_CURRENT_BINARY_DIR}/sotest_symtab.c) + OUTPUT ${SOTEST_SYMTAB} + COMMAND ${NUTTX_APPS_DIR}/tools/mksymtab.sh ${SOTEST_MODPRINT_ELF} + ${SOTEST_SHARED_ELF} g_sot > ${SOTEST_SYMTAB} + DEPENDS ${SOTEST_MODPRINT_TARGET} ${SOTEST_SHARED_TARGET}) - add_custom_target( - sotest_romfs - COMMAND genromfs -f sotest_romfs.img -d empty - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + set_source_files_properties(${SOTEST_SYMTAB} PROPERTIES GENERATED TRUE) - add_custom_command( - OUTPUT sotest_romfs.c - COMMAND xxd -i sotest_romfs.img > sotest_romfs.c - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS sotest_romfs) + set(SOTEST_GENERATED_OUTPUTS ${SOTEST_SYMTAB}) + set(SOTEST_SRCS sotest_main.c ${SOTEST_SYMTAB}) + + if(CONFIG_EXAMPLES_SOTEST_BUILTINFS) + set(SOTEST_ROMFS_DEPS ${SOTEST_MODPRINT_TARGET} ${SOTEST_SHARED_TARGET}) + + if(CONFIG_SYSTEM_NXPKG) + set(SOTEST_SHARED_INDEX ${CMAKE_BINARY_DIR}/bin/shared-index.json) + set(SOTEST_SHARED_SCRIPT ${CMAKE_BINARY_DIR}/bin/pkgsotest.nsh) + set(SOTEST_FIXTURE_HOST_DIR ${CMAKE_CURRENT_BINARY_DIR}/host) + set(SOTEST_FIXTURE_HOST_SRC + ${CMAKE_CURRENT_SOURCE_DIR}/host/CMakeLists.txt) + set(SOTEST_FIXTURE_TOOL + ${SOTEST_FIXTURE_HOST_DIR}/mk_pkg_fixture_shared${CMAKE_EXECUTABLE_SUFFIX} + ) + + add_custom_command( + OUTPUT ${SOTEST_FIXTURE_TOOL} + COMMAND ${CMAKE_COMMAND} -S ${CMAKE_CURRENT_SOURCE_DIR}/host -B + ${SOTEST_FIXTURE_HOST_DIR} + COMMAND ${CMAKE_COMMAND} --build ${SOTEST_FIXTURE_HOST_DIR} --target + mk_pkg_fixture_shared + DEPENDS ${SOTEST_FIXTURE_HOST_SRC} + ${CMAKE_CURRENT_SOURCE_DIR}/mk_pkg_fixture_shared.c + VERBATIM) + + add_custom_command( + OUTPUT ${SOTEST_SHARED_INDEX} ${SOTEST_SHARED_SCRIPT} + COMMAND + ${SOTEST_FIXTURE_TOOL} ${SOTEST_MODPRINT_ELF} ${SOTEST_SHARED_ELF} + ${SOTEST_SHARED_INDEX} ${SOTEST_SHARED_SCRIPT} ${CONFIG_ARCH} + ${CONFIG_ARCH_BOARD} + DEPENDS ${SOTEST_MODPRINT_TARGET} ${SOTEST_SHARED_TARGET} + ${SOTEST_FIXTURE_TOOL} + VERBATIM) + + list(APPEND SOTEST_ROMFS_DEPS ${SOTEST_SHARED_INDEX} + ${SOTEST_SHARED_SCRIPT}) + endif() + + add_custom_command( + OUTPUT ${SOTEST_ROMFS_IMG} + COMMAND genromfs -f ${SOTEST_ROMFS_IMG} -d ${CMAKE_BINARY_DIR}/bin + DEPENDS ${SOTEST_ROMFS_DEPS} + VERBATIM) + + get_filename_component(SOTEST_ROMFS_IMG_NAME ${SOTEST_ROMFS_IMG} NAME) + + # xxd -i derives the generated array/length symbol names from the exact path + # it is given - sotest_main.c declares them as plain + # "sotest_romfs_img"/"sotest_romfs_img_len", so xxd must be run against just + # the bare filename (via WORKING_DIRECTORY) rather than the absolute + # ${SOTEST_ROMFS_IMG} path, or every non- alphanumeric character in that + # path (e.g. every "/" in the build directory) gets folded into the symbol + # name instead, leaving the names sotest_main.c expects undefined at link + # time. + + add_custom_command( + OUTPUT ${SOTEST_ROMFS_SRC} + COMMAND xxd -i ${SOTEST_ROMFS_IMG_NAME} > ${SOTEST_ROMFS_SRC} + DEPENDS ${SOTEST_ROMFS_IMG} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + + set_source_files_properties(${SOTEST_ROMFS_SRC} PROPERTIES GENERATED TRUE) + + list(APPEND SOTEST_GENERATED_OUTPUTS ${SOTEST_ROMFS_SRC}) + list(APPEND SOTEST_SRCS ${SOTEST_ROMFS_SRC}) + endif() - nuttx_add_application( - NAME sotest SRCS sotest_main.c ${CMAKE_CURRENT_BINARY_DIR}/sotest_symtab.c - ${CMAKE_CURRENT_BINARY_DIR}/sotest_romfs.c) + add_custom_target(sotest_artifacts DEPENDS ${SOTEST_GENERATED_OUTPUTS}) + nuttx_add_application(NAME sotest SRCS ${SOTEST_SRCS} DEPENDS + sotest_artifacts) endif() diff --git a/examples/sotest/main/Makefile b/examples/sotest/main/Makefile index 064b0b434b7..50ad14da989 100644 --- a/examples/sotest/main/Makefile +++ b/examples/sotest/main/Makefile @@ -50,8 +50,29 @@ ifeq ($(CONFIG_EXAMPLES_SOTEST_BUILTINFS),y) ROMFSIMG = sotest_romfs.img ROMFSSRC = sotest_romfs.c ROMFSOBJ = $(ROMFSSRC:.c=$(OBJEXT)) +ifdef CONFIG_SYSTEM_NXPKG +HOSTOBJSEXT ?= hobj +PKGSHAREDINDEX = $(BINDIR)/shared-index.json +PKGSHAREDTEST = $(BINDIR)/pkgsotest.nsh +PKG_FIXTURE_GEN = mk_pkg_fixture_shared$(HOSTEXEEXT) +PKG_FIXTURE_SRCS = mk_pkg_fixture_shared.c +PKG_FIXTURE_OBJS = $(PKG_FIXTURE_SRCS:.c=.$(HOSTOBJSEXT)) +PKG_FIXTURE_OUTPUTS = $(PKGSHAREDINDEX) $(PKGSHAREDTEST) + +$(PKG_FIXTURE_OBJS): %.$(HOSTOBJSEXT): %.c + @echo "CC: $<" + $(Q) $(HOSTCC) -c $(HOSTCFLAGS) $< -o $@ + +$(PKG_FIXTURE_GEN): $(PKG_FIXTURE_OBJS) + $(Q) $(HOSTCC) $(HOSTLDFLAGS) $(PKG_FIXTURE_OBJS) -o $@ + +$(PKG_FIXTURE_OUTPUTS) &: $(BINDIR)/modprint $(BINDIR)/sotest $(PKG_FIXTURE_GEN) + $(Q) ./$(PKG_FIXTURE_GEN) $(BINDIR)/modprint $(BINDIR)/sotest \ + $(PKGSHAREDINDEX) $(PKGSHAREDTEST) $(CONFIG_ARCH) \ + $(CONFIG_ARCH_BOARD) +endif -$(ROMFSIMG): +$(ROMFSIMG): $(PKG_FIXTURE_OUTPUTS) $(Q) genromfs -d $(BINDIR) -f $@ $(ROMFSSRC): $(ROMFSIMG) @@ -67,6 +88,6 @@ postinstall:: $(ROMFSOBJ) $(SYMTABOBJ) $(FSIMG_OBJ) $(call ARLOCK, $(call CONVERT_PATH,$(BIN)), $^) distclean:: - $(Q) $(call DELFILE, $(SYMTABSRC) $(SYMTABOBJ) $(ROMFSSRC) $(ROMFSIMG) $(ROMFSOBJ)) + $(Q) $(call DELFILE, $(SYMTABSRC) $(SYMTABOBJ) $(ROMFSSRC) $(ROMFSIMG) $(ROMFSOBJ) $(PKG_FIXTURE_GEN) $(PKG_FIXTURE_OBJS)) include $(APPDIR)/Application.mk diff --git a/examples/sotest/main/host/CMakeLists.txt b/examples/sotest/main/host/CMakeLists.txt new file mode 100644 index 00000000000..e83524d2973 --- /dev/null +++ b/examples/sotest/main/host/CMakeLists.txt @@ -0,0 +1,26 @@ +# ############################################################################## +# apps/examples/sotest/main/host/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +cmake_minimum_required(VERSION 3.16) +project(sotest_fixture_host LANGUAGES C) + +add_executable(mk_pkg_fixture_shared ../mk_pkg_fixture_shared.c) diff --git a/examples/sotest/main/mk_pkg_fixture_shared.c b/examples/sotest/main/mk_pkg_fixture_shared.c new file mode 100644 index 00000000000..d369898f704 --- /dev/null +++ b/examples/sotest/main/mk_pkg_fixture_shared.c @@ -0,0 +1,427 @@ +/**************************************************************************** + * apps/examples/sotest/main/mk_pkg_fixture_shared.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SHA256_BLOCK_SIZE 64 +#define SHA256_DIGEST_SIZE 32 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct sha256_state_s +{ + uint32_t state[8]; + uint64_t bitcount; + uint8_t buffer[SHA256_BLOCK_SIZE]; + size_t buffer_len; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const uint32_t g_sha256_init[8] = +{ + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 +}; + +static const uint32_t g_sha256_k[64] = +{ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static uint32_t sha256_rotr(uint32_t value, unsigned int bits) +{ + return (value >> bits) | (value << (32 - bits)); +} + +static uint32_t sha256_ch(uint32_t x, uint32_t y, uint32_t z) +{ + return (x & y) ^ (~x & z); +} + +static uint32_t sha256_maj(uint32_t x, uint32_t y, uint32_t z) +{ + return (x & y) ^ (x & z) ^ (y & z); +} + +static uint32_t sha256_bs0(uint32_t x) +{ + return sha256_rotr(x, 2) ^ sha256_rotr(x, 13) ^ sha256_rotr(x, 22); +} + +static uint32_t sha256_bs1(uint32_t x) +{ + return sha256_rotr(x, 6) ^ sha256_rotr(x, 11) ^ sha256_rotr(x, 25); +} + +static uint32_t sha256_ss0(uint32_t x) +{ + return sha256_rotr(x, 7) ^ sha256_rotr(x, 18) ^ (x >> 3); +} + +static uint32_t sha256_ss1(uint32_t x) +{ + return sha256_rotr(x, 17) ^ sha256_rotr(x, 19) ^ (x >> 10); +} + +static uint32_t sha256_load32(const uint8_t *src) +{ + return ((uint32_t)src[0] << 24) | ((uint32_t)src[1] << 16) | + ((uint32_t)src[2] << 8) | (uint32_t)src[3]; +} + +static void sha256_store32(uint8_t *dst, uint32_t value) +{ + dst[0] = (uint8_t)(value >> 24); + dst[1] = (uint8_t)(value >> 16); + dst[2] = (uint8_t)(value >> 8); + dst[3] = (uint8_t)value; +} + +static void sha256_transform(struct sha256_state_s *ctx, + const uint8_t block[SHA256_BLOCK_SIZE]) +{ + uint32_t schedule[64]; + uint32_t a; + uint32_t b; + uint32_t c; + uint32_t d; + uint32_t e; + uint32_t f; + uint32_t g; + uint32_t h; + int i; + + for (i = 0; i < 16; i++) + { + schedule[i] = sha256_load32(block + i * 4); + } + + for (; i < 64; i++) + { + schedule[i] = sha256_ss1(schedule[i - 2]) + schedule[i - 7] + + sha256_ss0(schedule[i - 15]) + schedule[i - 16]; + } + + a = ctx->state[0]; + b = ctx->state[1]; + c = ctx->state[2]; + d = ctx->state[3]; + e = ctx->state[4]; + f = ctx->state[5]; + g = ctx->state[6]; + h = ctx->state[7]; + + for (i = 0; i < 64; i++) + { + uint32_t t1 = h + sha256_bs1(e) + sha256_ch(e, f, g) + g_sha256_k[i] + + schedule[i]; + uint32_t t2 = sha256_bs0(a) + sha256_maj(a, b, c); + + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + } + + ctx->state[0] += a; + ctx->state[1] += b; + ctx->state[2] += c; + ctx->state[3] += d; + ctx->state[4] += e; + ctx->state[5] += f; + ctx->state[6] += g; + ctx->state[7] += h; +} + +static void sha256_init(struct sha256_state_s *ctx) +{ + memcpy(ctx->state, g_sha256_init, sizeof(g_sha256_init)); + ctx->bitcount = 0; + ctx->buffer_len = 0; +} + +static void sha256_update(struct sha256_state_s *ctx, const uint8_t *data, + size_t len) +{ + ctx->bitcount += (uint64_t)len * 8; + + while (len > 0) + { + size_t space = SHA256_BLOCK_SIZE - ctx->buffer_len; + size_t chunk = len < space ? len : space; + + memcpy(ctx->buffer + ctx->buffer_len, data, chunk); + ctx->buffer_len += chunk; + data += chunk; + len -= chunk; + + if (ctx->buffer_len == SHA256_BLOCK_SIZE) + { + sha256_transform(ctx, ctx->buffer); + ctx->buffer_len = 0; + } + } +} + +static void sha256_final(struct sha256_state_s *ctx, + uint8_t digest[SHA256_DIGEST_SIZE]) +{ + uint8_t length_bytes[8]; + uint8_t padding[SHA256_BLOCK_SIZE] = + { + 0x80 + }; + + int i; + + for (i = 0; i < 8; i++) + { + length_bytes[7 - i] = (uint8_t)(ctx->bitcount >> (i * 8)); + } + + if (ctx->buffer_len < 56) + { + sha256_update(ctx, padding, 56 - ctx->buffer_len); + } + else + { + sha256_update(ctx, padding, SHA256_BLOCK_SIZE - ctx->buffer_len); + sha256_update(ctx, padding + 1, 56); + } + + sha256_update(ctx, length_bytes, sizeof(length_bytes)); + + for (i = 0; i < 8; i++) + { + sha256_store32(digest + i * 4, ctx->state[i]); + } +} + +static int sha256_file(const char *path, char *digest_hex, size_t digest_len) +{ + struct sha256_state_s ctx; + uint8_t digest[SHA256_DIGEST_SIZE]; + uint8_t buffer[4096]; + static const char g_hex[] = "0123456789abcdef"; + FILE *stream; + size_t nread; + int i; + + if (digest_len < SHA256_DIGEST_SIZE * 2 + 1) + { + fprintf(stderr, "digest buffer is too small\n"); + return -1; + } + + stream = fopen(path, "rb"); + if (stream == NULL) + { + fprintf(stderr, "failed to open %s: %s\n", path, strerror(errno)); + return -1; + } + + sha256_init(&ctx); + + while ((nread = fread(buffer, 1, sizeof(buffer), stream)) > 0) + { + sha256_update(&ctx, buffer, nread); + } + + if (ferror(stream) != 0) + { + fprintf(stderr, "failed to read %s: %s\n", path, strerror(errno)); + fclose(stream); + return -1; + } + + fclose(stream); + sha256_final(&ctx, digest); + + for (i = 0; i < SHA256_DIGEST_SIZE; i++) + { + digest_hex[i * 2] = g_hex[digest[i] >> 4]; + digest_hex[i * 2 + 1] = g_hex[digest[i] & 0x0f]; + } + + digest_hex[SHA256_DIGEST_SIZE * 2] = '\0'; + return 0; +} + +static int write_text_file(const char *path, const char *content) +{ + FILE *stream = fopen(path, "w"); + + if (stream == NULL) + { + fprintf(stderr, "failed to open %s: %s\n", path, strerror(errno)); + return -1; + } + + if (fputs(content, stream) == EOF) + { + fprintf(stderr, "failed to write %s: %s\n", path, strerror(errno)); + fclose(stream); + return -1; + } + + if (fclose(stream) != 0) + { + fprintf(stderr, "failed to close %s: %s\n", path, strerror(errno)); + return -1; + } + + return 0; +} + +static int write_index_file(const char *path, const char *arch, + const char *compat, const char *modprint_digest, + const char *sotest_digest) +{ + FILE *stream = fopen(path, "w"); + + if (stream == NULL) + { + fprintf(stderr, "failed to open %s: %s\n", path, strerror(errno)); + return -1; + } + + if (fprintf(stream, + "{\"packages\":[" + "{\"name\":\"modprint\",\"version\":\"1.0.0\",\"arch\":\"%s\"," + "\"compat\":\"%s\"," + "\"artifact\":\"/mnt/sotest/romfs/modprint\"," + "\"sha256\":\"%s\",\"type\":\"shared-lib\"}," + "{\"name\":\"modprint\",\"version\":\"9.9.9\"," + "\"arch\":\"arm\"," + "\"compat\":\"stm32f4discovery\"," + "\"artifact\":\"/mnt/sotest/romfs/modprint\"," + "\"sha256\":\"%s\",\"type\":\"shared-lib\"}," + "{\"name\":\"sotest\",\"version\":\"1.0.0\",\"arch\":\"%s\"," + "\"compat\":\"%s\",\"artifact\":\"/mnt/sotest/romfs/sotest\"," + "\"sha256\":\"%s\",\"type\":\"shared-lib\"}," + "{\"name\":\"sotest\",\"version\":\"9.9.9\",\"arch\":\"arm\"," + "\"compat\":\"stm32f4discovery\"," + "\"artifact\":\"/mnt/sotest/romfs/sotest\"," + "\"sha256\":\"%s\",\"type\":\"shared-lib\"}" + "]}\n", + arch, compat, modprint_digest, modprint_digest, arch, compat, + sotest_digest, sotest_digest) < 0) + { + fprintf(stderr, "failed to write %s: %s\n", path, strerror(errno)); + fclose(stream); + return -1; + } + + if (fclose(stream) != 0) + { + fprintf(stderr, "failed to close %s: %s\n", path, strerror(errno)); + return -1; + } + + return 0; +} + +static void usage(const char *progname) +{ + fprintf(stderr, + "usage: %s " + " \n", + progname); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int main(int argc, char *argv[]) +{ + char modprint_digest[SHA256_DIGEST_SIZE * 2 + 1]; + char sotest_digest[SHA256_DIGEST_SIZE * 2 + 1]; + static const char g_pkgsotest[] = + "mount -t tmpfs /etc\n" + "mount -t tmpfs /var\n" + "mkdir /etc/nxpkg\n" + "cp /mnt/sotest/romfs/shared-index.json /etc/nxpkg/index.json\n" + "nxpkg install modprint\n" + "nxpkg install sotest\n" + "cp /var/lib/nxpkg/pkgs/modprint/1.0.0/modprint /etc/m\n" + "cp /var/lib/nxpkg/pkgs/sotest/1.0.0/sotest /etc/s\n" + "sotest /etc/m /etc/s\n" + "nxpkg list\n"; + + if (argc != 7) + { + usage(argv[0]); + return EXIT_FAILURE; + } + + if (sha256_file(argv[1], modprint_digest, sizeof(modprint_digest)) < 0 || + sha256_file(argv[2], sotest_digest, sizeof(sotest_digest)) < 0 || + write_index_file(argv[3], argv[5], argv[6], modprint_digest, + sotest_digest) < 0 || + write_text_file(argv[4], g_pkgsotest) < 0) + { + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/examples/sotest/main/sotest_main.c b/examples/sotest/main/sotest_main.c index 0d399568fcd..6b2417ddb21 100644 --- a/examples/sotest/main/sotest_main.c +++ b/examples/sotest/main/sotest_main.c @@ -82,6 +82,21 @@ #define SOTEST_DEVPATH_FMT "/dev/ram%d" +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void sotest_show_usage(FAR const char *progname) +{ +#if CONFIG_LIBC_ELF_MAXDEPEND > 0 + fprintf(stderr, + "Usage: %s [--mount] [ ]\n", + progname); +#else + fprintf(stderr, "Usage: %s [--mount] []\n", progname); +#endif +} + /**************************************************************************** * Symbols from Auto-Generated Code ****************************************************************************/ @@ -104,7 +119,11 @@ extern const int g_sot_nexports; int main(int argc, FAR char *argv[]) { + FAR const char *modprint_path = NULL; + FAR const char *sotest_path = NULL; + bool mount_only = false; #ifdef CONFIG_EXAMPLES_SOTEST_BUILTINFS + bool mounted_builtinfs = false; char devname[32]; #endif #if CONFIG_LIBC_ELF_MAXDEPEND > 0 @@ -117,6 +136,38 @@ int main(int argc, FAR char *argv[]) #ifdef CONFIG_EXAMPLES_SOTEST_BUILTINFS struct boardioc_romdisk_s desc; #endif + +#if CONFIG_LIBC_ELF_MAXDEPEND > 0 + if (argc == 2 && strcmp(argv[1], "--mount") == 0) + { + mount_only = true; + } + else if (argc == 3) + { + modprint_path = argv[1]; + sotest_path = argv[2]; + } + else if (argc != 1) + { + sotest_show_usage(argv[0]); + return EXIT_FAILURE; + } +#else + if (argc == 2 && strcmp(argv[1], "--mount") == 0) + { + mount_only = true; + } + else if (argc == 2) + { + sotest_path = argv[1]; + } + else if (argc != 1) + { + sotest_show_usage(argv[0]); + return EXIT_FAILURE; + } +#endif + /* Set the shared library symbol table */ ret = dlsymtab((FAR struct symtab_s *)g_sot_exports, g_sot_nexports); @@ -127,6 +178,8 @@ int main(int argc, FAR char *argv[]) } #ifdef CONFIG_EXAMPLES_SOTEST_BUILTINFS + if (sotest_path == NULL || mount_only) + { /* Create a ROM disk for the ROMFS filesystem */ desc.minor = 0; /* Minor device number of the ROM disk. */ @@ -168,28 +221,48 @@ int main(int argc, FAR char *argv[]) devname, BINDIR, strerror(errno)); exit(EXIT_FAILURE); } + + mounted_builtinfs = true; + } #endif /* CONFIG_EXAMPLES_SOTEST_BUILTINFS */ + if (mount_only) + { + return EXIT_SUCCESS; + } + +#if CONFIG_LIBC_ELF_MAXDEPEND > 0 + if (modprint_path == NULL) + { + modprint_path = BINDIR "/modprint"; + } +#endif + + if (sotest_path == NULL) + { + sotest_path = BINDIR "/sotest"; + } + #if CONFIG_LIBC_ELF_MAXDEPEND > 0 /* Install the first test shared library. The first shared library only * verifies that symbols exported by one shared library can be used to * resolve undefined symbols in a second shared library. */ - handle1 = dlopen(BINDIR "/modprint", RTLD_NOW | RTLD_LOCAL); + handle1 = dlopen(modprint_path, RTLD_NOW | RTLD_LOCAL); if (handle1 == NULL) { - fprintf(stderr, "ERROR: dlopen(%s/modprint) failed\n", BINDIR); + fprintf(stderr, "ERROR: dlopen(%s) failed\n", modprint_path); exit(EXIT_FAILURE); } #endif /* Install the second test shared library */ - handle2 = dlopen(BINDIR "/sotest", RTLD_NOW | RTLD_LOCAL); + handle2 = dlopen(sotest_path, RTLD_NOW | RTLD_LOCAL); if (handle2 == NULL) { - fprintf(stderr, "ERROR: dlopen(%s/sotest) failed\n", BINDIR); + fprintf(stderr, "ERROR: dlopen(%s) failed\n", sotest_path); exit(EXIT_FAILURE); } @@ -288,15 +361,18 @@ int main(int argc, FAR char *argv[]) #endif #ifdef CONFIG_EXAMPLES_SOTEST_BUILTINFS - ret = umount(BINDIR); - if (ret < 0) + if (mounted_builtinfs) { - fprintf(stderr, "ERROR: umount(%s) failed: %d\n", - BINDIR, errno); - exit(EXIT_FAILURE); - } + ret = umount(BINDIR); + if (ret < 0) + { + fprintf(stderr, "ERROR: umount(%s) failed: %d\n", + BINDIR, errno); + exit(EXIT_FAILURE); + } - unlink(devname); + unlink(devname); + } #endif /* CONFIG_EXAMPLES_SOTEST_BUILTINFS */ return EXIT_SUCCESS; diff --git a/examples/sotest/modprint/CMakeLists.txt b/examples/sotest/modprint/CMakeLists.txt new file mode 100644 index 00000000000..0fbeef868c7 --- /dev/null +++ b/examples/sotest/modprint/CMakeLists.txt @@ -0,0 +1,25 @@ +# ############################################################################## +# apps/examples/sotest/modprint/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_EXAMPLES_SOTEST) + nuttx_add_application(NAME modprint SRCS modprint.c DYNLIB y) +endif() diff --git a/examples/sotest/sotest/CMakeLists.txt b/examples/sotest/sotest/CMakeLists.txt new file mode 100644 index 00000000000..d4f30c1c599 --- /dev/null +++ b/examples/sotest/sotest/CMakeLists.txt @@ -0,0 +1,25 @@ +# ############################################################################## +# apps/examples/sotest/sotest/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_EXAMPLES_SOTEST) + nuttx_add_application(NAME sotest SRCS sotest.c DYNLIB y) +endif()