Skip to content

Commit f8e2299

Browse files
committed
examples/fdpicxip: Build the module fixtures without nuttx/tools/fdpic.
The modules this example and testing/fs/xipfs carry are built by an explicit 'make regen', which reached into nuttx/tools/fdpic for a makefile that builds a module, a script that turns one into a header, and two more that checked its imports. Review of apache/nuttx#19940 asked that NuttX not carry a module build of its own, and it no longer does: with CONFIG_FDPIC an ordinary FDPIC module is built by apps/Application.mk like any other. These are not ordinary modules, which is why they keep a build of their own. They are fixtures for loader edge cases: a library with a SONAME, a module with more DT_NEEDED entries than the loader will follow, one whose imports stay in the lazy binding table, and one naming a symbol the firmware does not export, which exists to be refused. Application.mk cannot say any of that. So the build stays, and it is here beside them rather than in NuttX. It is also much smaller. The generic module makefile is gone: it existed to be included by anything, and only this one directory ever did, so its dozen useful lines are rules here. fdpic-embed.py is gone: xxd does that, as examples/elf already does it, and the license header it also wrote is a template beside it. fdpic-verify.sh and nuttx-exports.sh are gone with no replacement; they checked at build time what the xipfs suite already asserts at run time, for two hundred lines. What the fixtures no longer carry is a crt0 and a linker script. Both come from the tree named by NUTTX_DIR, which is where the in-tree module build takes them, so a fixture is built the way a module is. The crt0 source is compiled here rather than the built object taken, because these are deliberately built for cortex-m3 while the firmware is not: a v7-M module runs on both the v7-M and v8-M targets, so one set of headers serves the RP2350 and mps2-an500 alike. Regenerated qsorter, libshape and cxxuser against a tree configured with CONFIG_FDPIC. qsorter is ARM FDPIC, v7-M, two PT_LOAD segments, entering at _start; libshape carries its SONAME and its DT_INIT_ARRAY. The committed headers are left as they are. They will change when they are next regenerated, because a fixture now carries the tree's crt0 rather than one of its own, and that is a change the xipfs suite should be run against rather than made blind. Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
1 parent c913222 commit f8e2299

2 files changed

Lines changed: 119 additions & 50 deletions

File tree

examples/fdpicxip/modules/Makefile

Lines changed: 95 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
# asked for: the *_bin.h headers are committed, so both apps build with a
2828
# plain toolchain and CI covers them, while the link needs
2929
# arm-uclinuxfdpiceabi binutils, which the tree does not require. See
30-
# nuttx/tools/fdpic/README.md and Documentation/components/fdpic.rst.
30+
# Documentation/components/fdpic.rst.
3131
#
3232
# To rebuild the headers from these sources:
3333
#
@@ -44,19 +44,70 @@
4444

4545
CPU ?= cortex-m3
4646

47-
FDPICDIR = $(NUTTX_DIR)/tools/fdpic
48-
MODULE_MK = $(FDPICDIR)/nuttx-fdpic.mk
49-
EMBED = $(FDPICDIR)/fdpic-embed.py
47+
# make has built-in defaults for CC and CXX, so ?= never fires for them and
48+
# the host compiler silently gets the job. Test the origin instead.
5049

51-
# Where each generated header goes, and its path from the repository root --
52-
# fdpic-embed.py puts that on line 2, which is what nxstyle wants.
50+
ifeq ($(origin CC),default)
51+
CC := arm-none-eabi-gcc
52+
endif
53+
54+
ifeq ($(origin CXX),default)
55+
CXX := arm-none-eabi-g++
56+
endif
57+
58+
ifeq ($(origin LD),default)
59+
LD := arm-uclinuxfdpiceabi-ld
60+
endif
61+
62+
# -mfdpic -fPIC is the whole of what makes an FDPIC object; the rest is what
63+
# a module needs anywhere. -fno-use-cxa-atexit puts a static object's
64+
# destructor in .fini_array, which is where the loader looks for it.
65+
66+
MODCFLAGS = -mcpu=$(CPU) -mthumb -mfdpic -fPIC -Os -fno-builtin -Wall \
67+
-Wa,--noexecstack -D__STDC_NO_ATOMICS__ -D__NuttX__ \
68+
-I$(NUTTX_DIR)/include
69+
MODCXXFLAGS = $(MODCFLAGS) -fno-exceptions -fno-rtti -fno-use-cxa-atexit \
70+
-I$(NUTTX_DIR)/include/cxx
71+
72+
# The crt0 and the linker script are the tree's own, the ones the in-tree
73+
# module build uses. crt0 is compiled here rather than taken built, because
74+
# these are built for a different CPU from the firmware.
75+
76+
MODLDFLAGS = -m armelf_linux_fdpiceabi -shared -z now \
77+
-T $(NUTTX_DIR)/libs/libc/elf/gnu-elf.ld
5378

5479
DEMODIR = ..
5580
DEMOREL = apps/examples/fdpicxip
5681
TESTDIR = ../../../testing/fs/xipfs
5782
TESTREL = apps/testing/fs/xipfs
5883

59-
BUILD = $(MAKE) -f $(MODULE_MK) NUTTX_DIR=$(NUTTX_DIR) CPU=$(CPU)
84+
%.o: %.c
85+
$(CC) $(MODCFLAGS) -c $< -o $@
86+
87+
%.o: %.cpp
88+
$(CXX) $(MODCXXFLAGS) -c $< -o $@
89+
90+
crt0.o: $(NUTTX_DIR)/arch/arm/src/common/crt0.c
91+
$(CC) $(MODCFLAGS) -c $< -o $@
92+
93+
# A module is entered at _start and carries crt0. A library is never
94+
# entered, so it has neither, and it is named by its SONAME, which is what a
95+
# consumer records in DT_NEEDED and the loader searches for.
96+
97+
LINKMOD = $(LD) $(MODLDFLAGS) -e _start -o $@ crt0.o
98+
LINKLIB = $(LD) $(MODLDFLAGS) -e 0 -soname $(@F) -o $@
99+
100+
# EMBED turns a built module into the committed header that carries it: $1
101+
# the artifact, $2 the symbol, $3 the header's path from the repository root,
102+
# which nxstyle wants on line 2.
103+
104+
define EMBED
105+
{ sed -e "s|@PATH@|$3|" header.template; \
106+
echo "static const unsigned char $2[] ="; echo "{"; \
107+
xxd -i < $1 | sed -e 's/^ / /'; echo "};"; echo; \
108+
echo "static const unsigned int $2_len = $$(wc -c < $1 | tr -d ' ');"; \
109+
} > $@
110+
endef
60111

61112
# manyneeded needs one library per DT_NEEDED entry, one more than the loader
62113
# will follow. They exist only to make the linker record nine entries; the
@@ -93,50 +144,45 @@ endif
93144
# which is what a consumer records in DT_NEEDED and what the loader searches
94145
# for at run time.
95146

96-
qsorter.fdpic: qsorter.c
97-
$(BUILD) MODULE=qsorter SRCS=qsorter.c
147+
qsorter.fdpic: qsorter.o crt0.o
148+
$(LINKMOD) qsorter.o
98149

99-
callback.fdpic: callback.c
100-
$(BUILD) MODULE=callback SRCS=callback.c
150+
callback.fdpic: callback.o crt0.o
151+
$(LINKMOD) callback.o
101152

102-
funcdesc.fdpic: funcdesc.c
103-
$(BUILD) MODULE=funcdesc SRCS=funcdesc.c
153+
funcdesc.fdpic: funcdesc.o crt0.o
154+
$(LINKMOD) funcdesc.o
104155

105-
libcounter.so: libcounter.c
106-
$(BUILD) MODULE=libcounter SRCS=libcounter.c ENTRY=0 \
107-
EXTRA_LDFLAGS="-soname libcounter.so"
108-
mv libcounter.fdpic libcounter.so
156+
libcounter.so: libcounter.o
157+
$(LINKLIB) libcounter.o
109158

110-
user.fdpic: user.c libcounter.so
111-
$(BUILD) MODULE=user SRCS=user.c LIBS=libcounter.so
159+
user.fdpic: user.o crt0.o libcounter.so
160+
$(LINKMOD) user.o libcounter.so
112161

113162
# C++ compiles with the stock arm-none-eabi-g++; only the link is FDPIC.
114163

115-
libshape.so: libshape.cpp
116-
$(BUILD) MODULE=libshape CXXSRCS=libshape.cpp ENTRY=0 \
117-
EXTRA_LDFLAGS="-soname libshape.so"
118-
mv libshape.fdpic libshape.so
164+
libshape.so: libshape.o
165+
$(LINKLIB) libshape.o
119166

120-
cxxuser.fdpic: cxxuser.cpp libshape.so
121-
$(BUILD) MODULE=cxxuser CXXSRCS=cxxuser.cpp LIBS=libshape.so
167+
cxxuser.fdpic: cxxuser.o crt0.o libshape.so
168+
$(LINKMOD) cxxuser.o libshape.so
122169

123170
# BINDNOW is emptied so the imported descriptors stay in the lazy binding
124171
# table, which is the case this module exists to cover.
125172

126-
lazymod.fdpic: lazymod.c
127-
$(BUILD) MODULE=lazymod SRCS=lazymod.c BINDNOW=
173+
lazymod.fdpic: lazymod.o crt0.o
174+
$(LD) $(filter-out -z now,$(MODLDFLAGS)) -e _start -o $@ crt0.o lazymod.o
128175

129176
# missingsym is linked with the bare .fdpic target rather than the default
130177
# 'verify' one, because it is exactly what fdpic-verify.sh is meant to catch.
131178

132-
missingsym.fdpic: missingsym.c
133-
$(BUILD) MODULE=missingsym SRCS=missingsym.c missingsym.fdpic
179+
missingsym.fdpic: missingsym.o crt0.o
180+
$(LINKMOD) missingsym.o
134181

135182
need%.so:
136183
echo "int need_leaf_$*(void){return $*;}" > need$*.c
137-
$(BUILD) MODULE=need$* SRCS=need$*.c ENTRY=0 \
138-
EXTRA_LDFLAGS="-soname need$*.so"
139-
mv need$*.fdpic need$*.so
184+
$(CC) $(MODCFLAGS) -c need$*.c -o need$*.o
185+
$(LINKLIB) need$*.o
140186

141187
manyneeded.c: $(NEEDLIBS)
142188
{ for n in 0 1 2 3 4 5 6 7 8; do \
@@ -147,57 +193,56 @@ manyneeded.c: $(NEEDLIBS)
147193
echo " need_leaf_6() + need_leaf_7() + need_leaf_8();"; \
148194
echo "}"; } > manyneeded.c
149195

150-
manyneeded.fdpic: manyneeded.c $(NEEDLIBS)
151-
$(BUILD) MODULE=manyneeded SRCS=manyneeded.c LIBS="$(NEEDLIBS)" \
152-
manyneeded.fdpic
196+
manyneeded.fdpic: manyneeded.o crt0.o $(NEEDLIBS)
197+
$(LINKMOD) manyneeded.o $(NEEDLIBS)
153198

154199
# The headers. One artifact can be embedded under more than one name: the
155200
# demo's user_bin.h and the suite's counteruser_bin.h are the same module.
156201

157202
$(DEMODIR)/qsorter_bin.h: qsorter.fdpic
158-
$(EMBED) $< g_qsorter_nxf $(DEMOREL)/$(@F) > $@
203+
$(call EMBED,$<,g_qsorter_nxf,$(DEMOREL)/$(@F))
159204

160205
$(DEMODIR)/libcounter_bin.h: libcounter.so
161-
$(EMBED) $< g_libcounter $(DEMOREL)/$(@F) > $@
206+
$(call EMBED,$<,g_libcounter,$(DEMOREL)/$(@F))
162207

163208
$(DEMODIR)/user_bin.h: user.fdpic
164-
$(EMBED) $< g_user $(DEMOREL)/$(@F) > $@
209+
$(call EMBED,$<,g_user,$(DEMOREL)/$(@F))
165210

166211
$(DEMODIR)/libshape_bin.h: libshape.so
167-
$(EMBED) $< g_libshape $(DEMOREL)/$(@F) > $@
212+
$(call EMBED,$<,g_libshape,$(DEMOREL)/$(@F))
168213

169214
$(DEMODIR)/cxxuser_bin.h: cxxuser.fdpic
170-
$(EMBED) $< g_cxxuser $(DEMOREL)/$(@F) > $@
215+
$(call EMBED,$<,g_cxxuser,$(DEMOREL)/$(@F))
171216

172217
$(DEMODIR)/lazymod_bin.h: lazymod.fdpic
173-
$(EMBED) $< g_lazymod $(DEMOREL)/$(@F) > $@
218+
$(call EMBED,$<,g_lazymod,$(DEMOREL)/$(@F))
174219

175220
$(TESTDIR)/callback_bin.h: callback.fdpic
176-
$(EMBED) $< g_callback $(TESTREL)/$(@F) > $@
221+
$(call EMBED,$<,g_callback,$(TESTREL)/$(@F))
177222

178223
$(TESTDIR)/counteruser_bin.h: user.fdpic
179-
$(EMBED) $< g_counteruser $(TESTREL)/$(@F) > $@
224+
$(call EMBED,$<,g_counteruser,$(TESTREL)/$(@F))
180225

181226
$(TESTDIR)/cxxuser_bin.h: cxxuser.fdpic
182-
$(EMBED) $< g_cxxuser $(TESTREL)/$(@F) > $@
227+
$(call EMBED,$<,g_cxxuser,$(TESTREL)/$(@F))
183228

184229
$(TESTDIR)/funcdesc_bin.h: funcdesc.fdpic
185-
$(EMBED) $< g_funcdesc $(TESTREL)/$(@F) > $@
230+
$(call EMBED,$<,g_funcdesc,$(TESTREL)/$(@F))
186231

187232
$(TESTDIR)/lazymod_bin.h: lazymod.fdpic
188-
$(EMBED) $< g_lazymod $(TESTREL)/$(@F) > $@
233+
$(call EMBED,$<,g_lazymod,$(TESTREL)/$(@F))
189234

190235
$(TESTDIR)/libcounter_bin.h: libcounter.so
191-
$(EMBED) $< g_libcounter $(TESTREL)/$(@F) > $@
236+
$(call EMBED,$<,g_libcounter,$(TESTREL)/$(@F))
192237

193238
$(TESTDIR)/libshape_bin.h: libshape.so
194-
$(EMBED) $< g_libshape $(TESTREL)/$(@F) > $@
239+
$(call EMBED,$<,g_libshape,$(TESTREL)/$(@F))
195240

196241
$(TESTDIR)/manyneeded_bin.h: manyneeded.fdpic
197-
$(EMBED) $< g_manyneeded $(TESTREL)/$(@F) > $@
242+
$(call EMBED,$<,g_manyneeded,$(TESTREL)/$(@F))
198243

199244
$(TESTDIR)/missingsym_bin.h: missingsym.fdpic
200-
$(EMBED) $< g_missingsym $(TESTREL)/$(@F) > $@
245+
$(call EMBED,$<,g_missingsym,$(TESTREL)/$(@F))
201246

202247
# No NUTTX_DIR needed to clean.
203248

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/****************************************************************************
2+
* @PATH@
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Licensed to the Apache Software Foundation (ASF) under one or more
7+
* contributor license agreements. See the NOTICE file distributed with
8+
* this work for additional information regarding copyright ownership. The
9+
* ASF licenses this file to you under the Apache License, Version 2.0 (the
10+
* "License"); you may not use this file except in compliance with the
11+
* License. You may obtain a copy of the License at
12+
*
13+
* http://www.apache.org/licenses/LICENSE-2.0
14+
*
15+
* Unless required by applicable law or agreed to in writing, software
16+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18+
* License for the specific language governing permissions and limitations
19+
* under the License.
20+
*
21+
****************************************************************************/
22+
23+
/* Generated from an FDPIC module -- do not edit. See the Makefile. */
24+

0 commit comments

Comments
 (0)