Skip to content

Commit

Permalink
libc/machine/arm: align related implementations of armv7 architecture
Browse files Browse the repository at this point in the history
1. sync arch elf changes
2. fix cmake compilation break
3. remove the definition of related math files

Signed-off-by: chao an <[email protected]>
  • Loading branch information
anchao committed Nov 28, 2023
1 parent e39ef85 commit 8d377e3
Show file tree
Hide file tree
Showing 9 changed files with 363 additions and 129 deletions.
3 changes: 2 additions & 1 deletion arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,8 @@ config ARCH_CHIP_NRF53

config ARCH_CHIP_NRF91
bool "Nordic nRF91"
select ARCH_CORTEXM33
select ARCH_CORTEXM85
select ARM_HAVE_PACBTI
select ARCH_HAVE_PWM_MULTICHAN
select ARCH_HAVE_TRUSTZONE
select ARCH_HAVE_TICKLESS
Expand Down
141 changes: 96 additions & 45 deletions libs/libc/machine/arm/armv6-m/arch_elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,13 @@

#include <nuttx/config.h>

#include <inttypes.h>
#include <stdlib.h>
#include <errno.h>
#include <debug.h>

#include <nuttx/elf.h>

/****************************************************************************
* Pre-processor Definitions
****************************************************************************/

/****************************************************************************
* Private Data
****************************************************************************/

/****************************************************************************
* Private Functions
****************************************************************************/

/****************************************************************************
* Public Functions
****************************************************************************/
Expand Down Expand Up @@ -133,7 +122,8 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
*/

relotype = ELF32_R_TYPE(rel->r_info);
if (sym == NULL && relotype != R_ARM_NONE && relotype != R_ARM_V4BX)
if (sym == NULL && relotype != R_ARM_NONE && relotype != R_ARM_V4BX &&
relotype != R_ARM_RELATIVE && relotype != R_ARM_JUMP_SLOT)
{
return -EINVAL;
}
Expand All @@ -152,7 +142,7 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
case R_ARM_CALL:
case R_ARM_JUMP24:
{
binfo("Performing PC24 [%d] link at "
binfo("Performing PC24 [%" PRId32 "] link at "
"addr %08lx [%08lx] to sym '%p' st_value=%08lx\n",
ELF32_R_TYPE(rel->r_info), (long)addr,
(long)(*(uint32_t *)addr),
Expand All @@ -168,8 +158,8 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
if (offset & 3 || offset < (int32_t) 0xfe000000 ||
offset >= (int32_t) 0x02000000)
{
berr("ERROR: ERROR: PC24 [%d] relocation out of range, "
"offset=%08lx\n",
berr("ERROR: ERROR: PC24 [%" PRId32 "] "
"relocation out of range, offset=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), offset);

return -EINVAL;
Expand All @@ -185,15 +175,29 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
case R_ARM_ABS32:
case R_ARM_TARGET1: /* New ABI: TARGET1 always treated as ABS32 */
{
binfo("Performing ABS32 link at addr=%08lx [%08lx] "
"to sym=%p st_value=%08lx\n",
(long)addr, (long)(*(uint32_t *)addr), sym,
(long)sym->st_value);
binfo("Performing ABS32 link "
"at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n",
(long)addr, (long)(*(uint32_t *)addr),
sym, (long)sym->st_value);

*(uint32_t *)addr += sym->st_value;
}
break;

#ifdef CONFIG_ARMV7M_TARGET2_PREL
case R_ARM_TARGET2: /* TARGET2 is a platform-specific relocation: gcc-arm-none-eabi
* performs a self relocation */
{
binfo("Performing TARGET2 link "
"at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n",
(long)addr, (long)(*(uint32_t *)addr),
sym, (long)sym->st_value);

*(uint32_t *)addr += sym->st_value - addr;
}
break;
#endif

case R_ARM_THM_CALL:
case R_ARM_THM_JUMP24:
{
Expand All @@ -216,12 +220,12 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
* lower_insn:
*
* 1 1 1 1 1 1
* 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 Instructions
* 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 Instructions
* +---+------------------------------------------------+
* |OP | | 32-Bit
* +---+--+---+---+---+---------------------------------+
* |1 1 |J1 | 1 |J2 | imm11 | BL
* +------+---+---+---+---------------------------------+
* |1 1 |J1 | 1 |J2 | imm11 | BL
* +------+---+---+---+--------------------------------+
*
* The branch target is encoded in these bits:
*
Expand All @@ -235,7 +239,7 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
upper_insn = (uint32_t)(*(uint16_t *)addr);
lower_insn = (uint32_t)(*(uint16_t *)(addr + 2));

binfo("Performing THM_JUMP24 [%d] link "
binfo("Performing THM_JUMP24 [%" PRId32 "] link "
"at addr=%08lx [%04x %04x] to sym=%p st_value=%08lx\n",
ELF32_R_TYPE(rel->r_info), (long)addr,
(int)upper_insn, (int)lower_insn,
Expand Down Expand Up @@ -271,8 +275,9 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)

/* And perform the relocation */

binfo(" S=%d J1=%d J2=%d offset=%08lx branch target=%08lx\n",
S, J1, J2, (long)offset, offset + sym->st_value - addr);
binfo(" S=%" PRId32 " J1=%" PRId32 " J2=%" PRId32
" offset=%08" PRIx32 " branch target=%08" PRIx32 "\n",
S, J1, J2, offset, offset + sym->st_value - addr);

offset += sym->st_value - addr;

Expand All @@ -282,8 +287,8 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)

if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && (offset & 1) == 0)
{
berr("ERROR: ERROR: JUMP24 [%d] "
"requires odd offset, offset=%08lx\n",
berr("ERROR: ERROR: JUMP24 [%" PRId32 "] "
"requires odd offset, offset=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), offset);

return -EINVAL;
Expand All @@ -293,8 +298,8 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)

if (offset < (int32_t)0xff000000 || offset >= (int32_t)0x01000000)
{
berr("ERROR: ERROR: JUMP24 [%d] "
"relocation out of range, branch target=%08lx\n",
berr("ERROR: ERROR: JUMP24 [%" PRId32 "] "
"relocation out of range, branch target=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), offset);

return -EINVAL;
Expand All @@ -316,8 +321,9 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
((offset >> 1) & 0x07ff));
*(uint16_t *)(addr + 2) = (uint16_t)lower_insn;

binfo(" S=%d J1=%d J2=%d insn [%04x %04x]\n",
S, J1, J2, (int)upper_insn, (int)lower_insn);
binfo(" S=%" PRId32 " J1=%" PRId32 " J2=%" PRId32
" insn [%04" PRIx32 " %04" PRIx32 "]\n",
S, J1, J2, upper_insn, lower_insn);
}
break;

Expand Down Expand Up @@ -351,10 +357,10 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
case R_ARM_MOVW_ABS_NC:
case R_ARM_MOVT_ABS:
{
binfo("Performing MOVx_ABS [%d] link "
binfo("Performing MOVx_ABS [%" PRId32 "] link "
"at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n",
ELF32_R_TYPE(rel->r_info),
(long)addr, (long)(*(uint32_t *)addr),
ELF32_R_TYPE(rel->r_info), (long)addr,
(long)(*(uint32_t *)addr),
sym, (long)sym->st_value);

offset = *(uint32_t *)addr;
Expand All @@ -379,7 +385,7 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
* upper_insn:
*
* 1 1 1 1 1 1
* 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 Instructions
* 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 Instruction
* +----------+---+--------------------------+----------+
* |1 1 1 |OP1| OP2 | | 32-Bit
* +----------+---+--+-----+-----------------+----------+
Expand All @@ -388,13 +394,13 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
*
* lower_insn:
*
* 1 1 1 1 1 1
* 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 Instructions
* +---+-----------------------------------------------+
* |OP | | 32-Bit
* +---+----------+-----------+------------------------+
* |0 | imm3 | Rd | imm8 | MOVT
* +---+----------+-----------+------------------------+
* 1 1 1 1 1 1
* 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 Instructions
* +---+-------------------------------------------------+
* |OP | | 32-Bit
* +---+----------+--------+-----------------------------+
* |0 | imm3 | Rd | imm8 | MOVT
* +---+----------+--------+-----------------------------+
*
* The 16-bit immediate value is encoded in these bits:
*
Expand All @@ -407,7 +413,7 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
upper_insn = (uint32_t)(*(uint16_t *)addr);
lower_insn = (uint32_t)(*(uint16_t *)(addr + 2));

binfo("Performing THM_MOVx [%d] link "
binfo("Performing THM_MOVx [%" PRId32 "] link "
"at addr=%08lx [%04x %04x] to sym=%p st_value=%08lx\n",
ELF32_R_TYPE(rel->r_info), (long)addr,
(int)upper_insn, (int)lower_insn,
Expand Down Expand Up @@ -450,8 +456,53 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
}
break;

case R_ARM_THM_JUMP11:
{
offset = (uint32_t)(*(uint16_t *)addr & 0x7ff) << 1;
if (offset & 0x0800)
{
offset -= 0x1000;
}

offset += sym->st_value - addr;

if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && (offset & 1) == 0)
{
berr("ERROR: JUMP11 [%" PRId32 "] "
"requires odd offset, offset=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), offset);

return -EINVAL;
}

/* Check the range of the offset */

if (offset < (int32_t)0xfffff800 || offset >= (int32_t)0x0800)
{
berr("ERROR: JUMP11 [%" PRId32 "] "
"relocation out of range, branch target=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), offset);

return -EINVAL;
}

offset >>= 1;

*(uint16_t *)addr &= 0xf800;
*(uint16_t *)addr |= offset & 0x7ff;
}
break;

case R_ARM_RELATIVE:
case R_ARM_JUMP_SLOT:
{
*(uint32_t *)addr = (uint32_t)sym->st_value;
}
break;

default:
berr("ERROR: Unsupported relocation: %d\n", ELF32_R_TYPE(rel->r_info));
berr("ERROR: Unsupported relocation: %" PRId32 "\n",
ELF32_R_TYPE(rel->r_info));
return -EINVAL;
}

Expand Down
28 changes: 17 additions & 11 deletions libs/libc/machine/arm/armv7-m/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,28 @@ if(CONFIG_ARMV7M_MEMCPY)
list(APPEND SRCS gnu/arch_memcpy.S)
endif()

if(CONFIG_LIBC_ARCH_ELF)
list(APPEND SRCS arch_elf.c)
if(CONFIG_ARMV7M_MEMSET)
list(APPEND SRCS arch_memset.S)
endif()

if(CONFIG_MACHINE_OPTS_ARMV7M)
if(CONFIG_LIBM_ARCH_FABSF)
list(APPEND SRCS arch_fabsf.c)
endif()
if(CONFIG_ARMV7M_MEMMOVE)
list(APPEND SRCS arch_memmove.S)
endif()

if(CONFIG_ARMV7M_STRCMP)
list(APPEND SRCS arch_strcmp.S)
endif()

if(CONFIG_LIBM_ARCH_SQRTF)
list(APPEND SRCS arch_sqrtf.c)
endif()
if(CONFIG_ARMV7M_STRCPY)
list(APPEND SRCS arch_strcpy.S)
endif()

if(CONFIG_ARCH_SETJMP_H)
list(APPEND SRCS gnu/arch_setjmp.S)
if(CONFIG_ARMV7M_STRLEN)
list(APPEND SRCS arch_strlen.S)
endif()

if(CONFIG_LIBC_ARCH_ELF)
list(APPEND SRCS arch_elf.c)
endif()

target_sources(c PRIVATE ${SRCS})
63 changes: 20 additions & 43 deletions libs/libc/machine/arm/armv8-m/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,55 +24,32 @@ if(CONFIG_LIBC_ARCH_ELF)
list(APPEND SRCS arch_elf.c)
endif()

if(CONFIG_ARMV8M_LIBM)
if(CONFIG_LIBM_ARCH_CEIL)
list(APPEND SRCS arch_ceil.c)
endif()

if(CONFIG_LIBM_ARCH_CEILF)
list(APPEND SRCS arch_ceilf.c)
endif()

if(CONFIG_LIBM_ARCH_FLOOR)
list(APPEND SRCS arch_floor.c)
endif()

if(CONFIG_LIBM_ARCH_FLOORF)
list(APPEND SRCS arch_floorf.c)
endif()

if(CONFIG_LIBM_ARCH_NEARBYINT)
list(APPEND SRCS arch_nearbyint.c)
endif()

if(CONFIG_LIBM_ARCH_NEARBYINTF)
list(APPEND SRCS arch_nearbyintf.c)
endif()

if(CONFIG_LIBM_ARCH_RINTF)
list(APPEND SRCS arch_rintf.c)
endif()
if(CONFIG_ARMV8M_MEMCHR)
list(APPEND SRCS arch_memchr.S)
endif()

if(CONFIG_LIBM_ARCH_ROUNDF)
list(APPEND SRCS arch_roundf.c)
endif()
if(CONFIG_ARMV8M_MEMCPY)
list(APPEND SRCS arch_memcpy.S)
endif()

if(CONFIG_LIBM_ARCH_TRUNCF)
list(APPEND SRCS arch_truncf.c)
endif()
if(CONFIG_ARMV8M_MEMSET)
list(APPEND SRCS arch_memset.S)
endif()

if(CONFIG_LIBM_ARCH_RINT)
list(APPEND SRCS arch_rint.c)
endif()
if(CONFIG_ARMV8M_MEMMOVE)
list(APPEND SRCS arch_memmove.S)
endif()

if(CONFIG_LIBM_ARCH_ROUND)
list(APPEND SRCS arch_round.c)
endif()
if(CONFIG_ARMV8M_STRCMP)
list(APPEND SRCS arch_strcmp.S)
endif()

if(CONFIG_LIBM_ARCH_TRUNC)
list(APPEND SRCS arch_trunc.c)
endif()
if(CONFIG_ARMV8M_STRCPY)
list(APPEND SRCS arch_strcpy.S)
endif()

if(CONFIG_ARMV8M_STRLEN)
list(APPEND SRCS arch_strlen.S)
endif()

target_sources(c PRIVATE ${SRCS})
Loading

0 comments on commit 8d377e3

Please sign in to comment.