Add loading of ET_DYN shared object test to sotest
-
examples/sotest/lib/Makefile
- Add dynload directory to build
-
examples/sotest/lib/dynload/Makefile
- Build the dynload shared object test
-
examples/sotest/lib/dynload/dynload.c
- Test case for loading of ET_DYN shared objects
-
examples/sotest/lib/dynload/.gitignore
- Exclude built object from git
-
examples/sotest/sotest_main.c
- Load and invoke the dynload test
Summary
Support of ET_DYN shared objects was added to NuttX, this PR adds a test.
Impact
New test dynload is built.
Testing
Run sotest and the dynload shared object will be loaded, a symbol located and invoked, and the module unloaded.
@nealef please fix the ci warning, you can run the check locally by:
../nuttx/tools/checkpatch.sh -g HEAD~2...HEAD
We need to fix CI build first
ld: i386 architecture of input file 'dynload.o' is incompatible with i386:x86-64 output
ld: i386 architecture of input file 'dynload.o' is incompatible with i386:x86-64 output
Where was this error? I build dynload.o like modprint.o: i.e. using $(MODULECC) so I am not sure why it would generate the incorrect output.
ld: i386 architecture of input file 'dynload.o' is incompatible with i386:x86-64 outputWhere was this error? I build
dynload.olikemodprint.o: i.e. using$(MODULECC)so I am not sure why it would generate the incorrect output.
I copied that error message from CI failure log
What I've found is when modprint is built we get this command line:
ld -r -e module_initialize --gc-sections -T /home/neale/nuttx/libs/libc/modlib/gnu-elf.ld -melf_i386 -o modprint modprint.o
But for dynload we get:
ld -Bsymbolic -G -Bdynamic --no-gc-sections -L /home/neale/nuttx/staging -o dynload dynload.o -lc
This is due to the settings of various flags in boards/sim/sim/sim/scripts/Make.defs. I'll add some for shared object linking and make corresponding changes in nuttx-apps/examples/sotest/lib/dynload/Makefile.
Made the changes and get a clean build but when I build and run sim:sotest32 on my x64 Ubuntu 20.04 system I crash with:
NuttShell (NSH)
nsh> sotest
main: Registering romdisk at /dev/ram3
main: Mounting ROMFS filesystem at target=/mnt/romfs with source=/dev/ram3
module_initialize:
Process 3421077 stopped
* thread #1, name = 'nuttx', stop reason = signal SIGILL: illegal instruction operand
frame #0: 0xf3df4651
-> 0xf3df4651: lock
0xf3df4652: fpatan
So I am wondering if I need to run it on something else? My Mac isn't an option either as there's no support for 32-bit.
@nealef please fix the build error reported by ci.
That was supposed to be fixed by an earlier commit that changed SHLDMODULEFLAGS to SHMODULEDLAGS. It was clean yesterday where the only failure was to do with libcxxtest or a similar name.
-------- Original message -------- From: Xiang Xiao @.> Date: 21/9/23 13:32 (GMT+10:00) To: apache/nuttx-apps @.> Cc: Neale Ferguson @.>, Mention @.> Subject: Re: [apache/nuttx-apps] Add loading of ET_DYN shared object test to sotest (PR #2026)
@nealefhttps://github.com/nealef please fix the build error reported by ci.
— Reply to this email directly, view it on GitHubhttps://github.com/apache/nuttx-apps/pull/2026#issuecomment-1728713491, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AACLN6QGBQ2G56Q7LO442N3X3OYKXANCNFSM6AAAAAA4JVY5HA. You are receiving this because you were mentioned.Message ID: @.***>
That was a fix to nuttx-apps under commit bb32dd2112884546b8c0b024ed45187c46a7bd23. https://github.com/apache/nuttx-apps/pull/2026
But the link error is directly related to this patch:
====================================================================================
Configuration/Tool: sim/sotest32
------------------------------------------------------------------------------------
make[1]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule.
Cleaning...
Configuring...
make[1]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule.
make[1]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule.
Building NuttX...
ld: i386 architecture of input file `dynload.o' is incompatible with i386:x86-64 output
ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000
make[4]: *** [Makefile:45: dynload] Error 1
make[4]: Target 'install' not remade because of errors.
make[3]: *** [Makefile:50: dynload_install] Error 2
make[3]: Target 'all' not remade because of errors.
make[2]: *** [Makefile:53: build] Error 2
make[2]: Target 'all' not remade because of errors.
make[1]: *** [Makefile:51: /github/workspace/sources/apps/examples/sotest_all] Error 2
make[1]: Target 'all' not remade because of errors.
make: *** [tools/LibTargets.mk:232: /github/workspace/sources/apps/libapps.a] Error 2
make: Target 'all' not remade because of errors.
How can I tell what's in the nuttx-apps it's building against? In NuttX there is:
SHMODULEFLAGS = -Bsymbolic -G -Bdynamic
:
:
ifeq ($(CONFIG_SIM_M32),y)
LDLINKFLAGS += -melf_i386
LDFLAGS += -m32
LDMODULEFLAGS += -melf_i386
SHMODULEFLAGS += -melf_i386
LDELFFLAGS += -melf_i386
endif
and in my branch of nuttx-apps is:
$(BIN): $(OBJS)
@echo "MODULELD: $<"
$(Q) $(MODULELD) $(SHMODULEFLAGS) $(LDLIBPATH) -o $@ $^ $(LDLIBS)
Which had solved the earlier problem of (1) the no _start symbol and (2) the mismatch between architectures. Is there a way of seeing the code this latest failure was built from to see if I've missed a commit or regressed something?
you can reproduce the problem by ./tools/conffigure.sh sim/sotest32 make
I rebased my repo and it reported:
git status
On branch dynload-fix
Your branch is up to date with 'origin/dynload-fix'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
gpsutils/
nothing added to commit but untracked files present (use "git add" to track)
I then remade nuttx after configuring for sim:sotest32 and get:
/Users/neale/Wilderness/nuttx-build/apps/gpsutils/Kconfig:9: can't open file "/Users/neale/Wilderness/nuttx-build/apps/gpsutils/minmea/Kconfig"
I rebased my repo and it reported:
git status On branch dynload-fix Your branch is up to date with 'origin/dynload-fix'. Untracked files: (use "git add <file>..." to include in what will be committed) gpsutils/ nothing added to commit but untracked files present (use "git add" to track)I then remade nuttx after configuring for sim:sotest32 and get:
/Users/neale/Wilderness/nuttx-build/apps/gpsutils/Kconfig:9: can't open file "/Users/neale/Wilderness/nuttx-build/apps/gpsutils/minmea/Kconfig"
do you fetch both git(nuttx and apps) and rebase to the last master? A recent change move minmea from apps/gpsutils/ to nuttx/libc/minmea: https://github.com/apache/nuttx-apps/pull/1234 https://github.com/apache/nuttx/pull/9954
Brought my master up to date:
IN: /Users/neale/Wilderness/nuttx-build/apps/libapps.a -> staging/libapps.a install: /Users/neale/Wilderness/nuttx-build/apps/libapps.a: No such file or directory
In any event it got past my dynload build:
MODULECC: sotest.c
MODULELD: sotest.o
MODULECC: modprint.c
MODULELD: modprint.o
MODULECC: dynload.c
MODULELD: dynload.o
Is the current libcxxtest failure something that a fetch/rebase will fix?
Is the current
libcxxtestfailure something that a fetch/rebase will fix?
Yes, it fix by https://github.com/apache/nuttx/pull/8244, let me retrigger the ci.
Latest failure is in risc-v with the _start error message indicating dynload is not being liked with the flags to build a shared object. Is there a way to get it to do a make V=1? I don't have access to any risc-v hardware to do it myself.
Latest failure is in
risc-vwith the_starterror message indicatingdynloadis not being liked with the flags to build a shared object. Is there a way to get it to do amake V=1? I don't have access to anyrisc-vhardware to do it myself.
you need apply the similar change for dynload: https://github.com/apache/nuttx/pull/10345
Alternatively, could I scrub setting SHMODULEFLAGS at the board level and just define it in the dynload/Makefile:
--- a/examples/sotest/lib/dynload/Makefile
+++ b/examples/sotest/lib/dynload/Makefile
@@ -33,16 +33,23 @@ BIN = dynload
SRCS = $(BIN).c
OBJS = $(SRCS:.c=$(OBJEXT))
+SHCCFLAGS = -fPIC -fPIE -fvisibility=default
+SHLDFLAGS = -shared -Bsymbolic -Bdynamic -G
+
+ifeq ($(CONFIG_SIM_M32),y)
+ SHLDFLAGS += -melf_i386
+endif
+
all: $(BIN)
.PHONY: all clean install
$(OBJS): %$(OBJEXT): %.c
@echo "MODULECC: $<"
- $(Q) $(MODULECC) -c $(CMODULEFLAGS) -fPIC -fPIE -fvisibility=default $< -o $@
+ $(Q) $(MODULECC) -c $(CMODULEFLAGS) $(SHCCFLAGS) $< -o $@
$(BIN): $(OBJS)
@echo "MODULELD: $<"
- $(Q) $(MODULELD) $(SHMODULEFLAGS) $(LDLIBPATH) -o $@ $^ $(LDLIBS)
+ $(Q) $(MODULELD) $(SHLDFLAGS) $(LDLIBPATH) -o $@ $^ $(LDLIBS)
$(FSROOT_DIR)/$(BIN): $(BIN)
$(Q) mkdir -p $(FSROOT_DIR)
Or is this being too GNU-toolchain-specific?
it's better to keep the arch/toolchain specific option to: Toolchain.defs(e.g. https://github.com/apache/nuttx/blob/master/arch/arm/src/armv7-m/Toolchain.defs) or Make.defs(e.g. https://github.com/apache/nuttx/blob/master/boards/arm/stm32/stm32f4discovery/scripts/Make.defs)
That would mean placing this information in 27 different Toolchain.defs files? If so, I can do it but I don't want to find out that I've done it wrongly after the fact.
./arch/xtensa/src/lx7/Toolchain.defs
./arch/xtensa/src/lx6/Toolchain.defs
./arch/avr/src/avr32/Toolchain.defs
./arch/avr/src/avr/Toolchain.defs
./arch/z16/src/z16f/Toolchain.defs
./arch/z80/src/ez80/Toolchain.defs
./arch/z80/src/z80/Toolchain.defs
./arch/z80/src/z8/Toolchain.defs
./arch/z80/src/z180/Toolchain.defs
./arch/or1k/src/mor1kx/Toolchain.defs
./arch/misoc/src/lm32/Toolchain.defs
./arch/misoc/src/minerva/Toolchain.defs
./arch/risc-v/src/common/Toolchain.defs
./arch/mips/src/mips32/Toolchain.defs
./arch/ceva/src/xc5/Toolchain.defs
./arch/ceva/src/xm6/Toolchain.defs
./arch/arm/src/armv7-m/Toolchain.defs
./arch/arm/src/armv8-r/Toolchain.defs
./arch/arm/src/armv7-r/Toolchain.defs
./arch/arm/src/common/Toolchain.defs
./arch/arm/src/armv7-a/Toolchain.defs
./arch/arm/src/armv6-m/Toolchain.defs
./arch/arm/src/tlsr82/Toolchain.defs
./arch/arm/src/arm/Toolchain.defs
./arch/arm/src/armv8-m/Toolchain.defs
./arch/sparc/src/sparc_v8/Toolchain.defs
./arch/arm64/src/Toolchain.defs
Or should I only do it for those archs under CI?
That would mean placing this information in 27 different
Toolchain.defsfiles? If so, I can do it but I don't want to find out that I've done it wrongly after the fact../arch/xtensa/src/lx7/Toolchain.defs ./arch/xtensa/src/lx6/Toolchain.defs ./arch/avr/src/avr32/Toolchain.defs ./arch/avr/src/avr/Toolchain.defs ./arch/z16/src/z16f/Toolchain.defs ./arch/z80/src/ez80/Toolchain.defs ./arch/z80/src/z80/Toolchain.defs ./arch/z80/src/z8/Toolchain.defs ./arch/z80/src/z180/Toolchain.defs ./arch/or1k/src/mor1kx/Toolchain.defs ./arch/misoc/src/lm32/Toolchain.defs ./arch/misoc/src/minerva/Toolchain.defs ./arch/risc-v/src/common/Toolchain.defs ./arch/mips/src/mips32/Toolchain.defs ./arch/ceva/src/xc5/Toolchain.defs ./arch/ceva/src/xm6/Toolchain.defs ./arch/arm/src/armv7-m/Toolchain.defs ./arch/arm/src/armv8-r/Toolchain.defs ./arch/arm/src/armv7-r/Toolchain.defs ./arch/arm/src/common/Toolchain.defs ./arch/arm/src/armv7-a/Toolchain.defs ./arch/arm/src/armv6-m/Toolchain.defs ./arch/arm/src/tlsr82/Toolchain.defs ./arch/arm/src/arm/Toolchain.defs ./arch/arm/src/armv8-m/Toolchain.defs ./arch/sparc/src/sparc_v8/Toolchain.defs ./arch/arm64/src/Toolchain.defsOr should I only do it for those archs under CI?
I think only arm/riscv/xtensa/sim need change since other arch doesn't support dynamical loading yet.
@nealef i try new patch, but sotest is failed, and the env is boards/arm64/qemu/qemu-armv8a/configs/nsh, and i found this dyload is a Executable file not than share object.
I missed updating dynload's Makefile with SHMODULEFLAGS. I rebased but am now crapping out with:
sched/sched_cpuload.c:109:25: error: use of undeclared identifier 'CONFIG_SCHED_CPULOAD_TIMECONSTANT'
if (g_cpuload_total > CPULOAD_TIMECONSTANT)
^
sched/sched_cpuload.c:59:7: note: expanded from macro 'CPULOAD_TIMECONSTANT'
CONFIG_SCHED_CPULOAD_TIMECONSTANT * \
^
1 error generated.
Checking to make sure SHMODULEFLAGS is defined where it's needed.
Also, as far as I can tell the following archs can support sotest (i.e. it's a selectable Kconfig option):
- ./boards/xtensa/esp32/esp32-devkitc/configs/sotest/defconfig
- ./boards/xtensa/esp32s2/esp32s2-saola-1/configs/sotest/defconfig
- ./boards/risc-v/esp32c3/esp32c3-devkit/configs/sotest/defconfig
- ./boards/risc-v/c906/smartl-c906/configs/sotest/defconfig
- ./boards/sim/sim/sim/configs/sotest32/defconfig
- ./boards/sim/sim/sim/configs/sotest/defconfig
- ./boards/arm64/qemu/qemu-armv8a/configs/sotest/defconfig
Should I be specifying the SHMODULEFLAGS in the corresponding Make.defs file for each of those "boards" or in the arch generic files such as ./arch/risc-v/src/common/Toolchain.defs?
@xiaoxiang781216
Also, as far as I can tell the following archs can support sotest (i.e. it's a selectable Kconfig option):
1. ./boards/xtensa/esp32/esp32-devkitc/configs/sotest/defconfig 2. ./boards/xtensa/esp32s2/esp32s2-saola-1/configs/sotest/defconfig 3. ./boards/risc-v/esp32c3/esp32c3-devkit/configs/sotest/defconfig 4. ./boards/risc-v/c906/smartl-c906/configs/sotest/defconfig 5. ./boards/sim/sim/sim/configs/sotest32/defconfig 6. ./boards/sim/sim/sim/configs/sotest/defconfig 7. ./boards/arm64/qemu/qemu-armv8a/configs/sotest/defconfigShould I be specifying the
SHMODULEFLAGSin the correspondingMake.defsfile for each of those "boards" or in the arch generic files such as./arch/risc-v/src/common/Toolchain.defs?@xiaoxiang781216
@Donny9 @xiaoxiang781216 what do you think? Since SHMODULEFLAGS is defined to sim "board" I think it also will be needed for other arch's boards.
Yes, or even better to move to Toolchain.defs, so it could be shared between boards
Yes, or even better to move to Toolchain.defs, so it could be shared between boards
sim doesn't have Toolchain.defs so I used: boards/sim/sim/sim/scripts/Make.defs. For RISC I was using arch/risc-v/src/common/Toolchain.defs and for armv8: boards/arm64/qemu/qemu-armv8a/scripts/Make.defs.