From b81b16ba975fdba0b2a72af29eab5d0f29aa636d Mon Sep 17 00:00:00 2001 From: anjiahao Date: Wed, 5 Jun 2024 19:50:19 +0800 Subject: [PATCH] arm7/8-m:support all nuttx iamge build with pic Need to start up a new to setup special registers use `arm_pic_setupxcp`. Note that CONFIG_BUILD_PIC compiles the entire NuttX image as position-independent(PIC), enable CONFIG_PIC to load PIC application code. Signed-off-by: anjiahao --- Kconfig | 7 +++++++ arch/arm/include/arch.h | 2 +- arch/arm/src/armv6-m/arm_initialstate.c | 6 ++++++ arch/arm/src/armv7-m/arm_initialstate.c | 6 ++++++ arch/arm/src/armv8-m/arm_initialstate.c | 6 ++++++ arch/arm/src/common/Toolchain.defs | 18 +++++++++++++----- 6 files changed, 39 insertions(+), 6 deletions(-) diff --git a/Kconfig b/Kconfig index 090ae6c0e6..17aa39e3aa 100644 --- a/Kconfig +++ b/Kconfig @@ -329,6 +329,13 @@ config BUILD_KERNEL endchoice # Build configuration +config BUILD_PIC + bool "NuttX PIC build" + default n + ---help--- + Builds NuttX with position-independent code (PIC). This will allow + load NuttX into memory at any address and run it. + config BUILD_2PASS bool "Two pass build" default n diff --git a/arch/arm/include/arch.h b/arch/arm/include/arch.h index d511574e7d..f64a6298ee 100644 --- a/arch/arm/include/arch.h +++ b/arch/arm/include/arch.h @@ -62,7 +62,7 @@ do { \ "\tmov %0, " PIC_REG_STRING "\n\t" \ : "=r"(picbase) \ ); \ - *ppicbase = (void *)picbase; \ + *(uint32_t *)ppicbase = picbase; \ } while (0) #define up_setpicbase(picbase) \ diff --git a/arch/arm/src/armv6-m/arm_initialstate.c b/arch/arm/src/armv6-m/arm_initialstate.c index 15b3bb74c4..f501ba700e 100644 --- a/arch/arm/src/armv6-m/arm_initialstate.c +++ b/arch/arm/src/armv6-m/arm_initialstate.c @@ -104,6 +104,12 @@ void up_initial_state(struct tcb_s *tcb) xcp->regs[REG_XPSR] = ARMV6M_XPSR_T; + /* All tasks need set to pic address to special register */ + +#ifdef CONFIG_BUILD_PIC + __asm__ ("mov %0, r9" : "=r"(xcp->regs[REG_R9])); +#endif + /* If this task is running PIC, then set the PIC base register to the * address of the allocated D-Space region. */ diff --git a/arch/arm/src/armv7-m/arm_initialstate.c b/arch/arm/src/armv7-m/arm_initialstate.c index 4baec4aee4..ef8bbc939e 100644 --- a/arch/arm/src/armv7-m/arm_initialstate.c +++ b/arch/arm/src/armv7-m/arm_initialstate.c @@ -111,6 +111,12 @@ void up_initial_state(struct tcb_s *tcb) xcp->regs[REG_XPSR] = ARMV7M_XPSR_T; + /* All tasks need set to pic address to special register */ + +#ifdef CONFIG_BUILD_PIC + __asm__ ("mov %0, r9" : "=r"(xcp->regs[REG_R9])); +#endif + /* If this task is running PIC, then set the PIC base register to the * address of the allocated D-Space region. */ diff --git a/arch/arm/src/armv8-m/arm_initialstate.c b/arch/arm/src/armv8-m/arm_initialstate.c index 4916fc36ea..53a8cab030 100644 --- a/arch/arm/src/armv8-m/arm_initialstate.c +++ b/arch/arm/src/armv8-m/arm_initialstate.c @@ -117,6 +117,12 @@ void up_initial_state(struct tcb_s *tcb) xcp->regs[REG_XPSR] = ARMV8M_XPSR_T; + /* All tasks need to set pic address to special register */ + +#ifdef CONFIG_BUILD_PIC + __asm__ ("mov %0, r9" : "=r"(xcp->regs[REG_R9])); +#endif + /* If this task is running PIC, then set the PIC base register to the * address of the allocated D-Space region. */ diff --git a/arch/arm/src/common/Toolchain.defs b/arch/arm/src/common/Toolchain.defs index 540e4405d4..5548aec7e7 100644 --- a/arch/arm/src/common/Toolchain.defs +++ b/arch/arm/src/common/Toolchain.defs @@ -495,6 +495,14 @@ ifeq ($(CONFIG_LIBCXXTOOLCHAIN),y) EXTRA_LIBS += $(wildcard $(shell $(CC) $(ARCHCPUFLAGS) --print-file-name=libstdc++.a)) endif +PICFLAGS = -fpic -fPIE -mno-pic-data-is-text-relative -msingle-pic-base + +ifneq ($(CONFIG_BUILD_PIC),) + ARCHCFLAGS += $(PICFLAGS) -mpic-register=r9 + ARCHCXXFLAGS += $(PICFLAGS) -mpic-register=r9 + LDFLAGS += --emit-relocs +endif + # Loadable module definitions CMODULEFLAGS = $(CFLAGS) -fvisibility=hidden -mlong-calls # --target1-abs @@ -502,10 +510,13 @@ LDMODULEFLAGS = -r -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/modlib/gnu-elf.ld) # ELF module definitions +CELFFLAGS = $(CFLAGS) -fvisibility=hidden -mlong-calls # --target1-abs +CXXELFFLAGS = $(CXXFLAGS)-fvisibility=hidden + ifeq ($(CONFIG_PIC),y) CFLAGS += --fixed-r10 - PICFLAGS = -fpic -fPIE -mno-pic-data-is-text-relative \ - -msingle-pic-base -mpic-register=r10 + CELFFLAGS += $(PICFLAGS) -mpic-register=r10 + CXXELFFLAGS += $(PICFLAGS) -mpic-register=r10 # Generate an executable elf, need to ignore undefined symbols LDELFFLAGS += --unresolved-symbols=ignore-in-object-files --emit-relocs @@ -513,9 +524,6 @@ else LDELFFLAGS += -r endif -CELFFLAGS = $(CFLAGS) $(PICFLAGS) -fvisibility=hidden -mlong-calls # --target1-abs -CXXELFFLAGS = $(CXXFLAGS) $(PICFLAGS) -fvisibility=hidden - LDELFFLAGS += -e main -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld) # Zig toolchain