libc/machine/arm: align related implementations of armv7 architecture

1. sync arch elf changes
2. fix cmake compilation break
3. remove the definition of related math files

Signed-off-by: chao an <anchao@xiaomi.com>
This commit is contained in:
chao an 2023-11-28 12:35:06 +08:00 committed by Xiang Xiao
parent 74874e0874
commit 29bda7cf27
10 changed files with 470 additions and 223 deletions

View File

@ -157,11 +157,11 @@ 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 [%" 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),
sym, (long)sym->st_value);
binfo("Performing PC24 [%" PRId32 "] link at "
"addr %08" PRIxPTR " [%08" PRIx32 "] to "
"sym '%p' st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
*(uint32_t *)addr, sym, sym->st_value);
offset = (*(uint32_t *)addr & 0x00ffffff) << 2;
if (offset & 0x02000000)
@ -179,7 +179,7 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
offset >= (int32_t) 0x02000000)
{
berr("ERROR: PC24 [%" PRId32 "] relocation out of range, "
"offset=%08lx\n",
"offset=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), offset);
return -EINVAL;
@ -196,9 +196,9 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
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);
"at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
"sym=%p st_value=%08" PRIx32 "\n",
addr, *(uint32_t *)addr, sym, sym->st_value);
*(uint32_t *)addr += sym->st_value;
}
@ -206,8 +206,9 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
case R_ARM_V4BX:
{
binfo("Performing V4BX link at addr=%08lx [%08lx]\n",
(long)addr, (long)(*(uint32_t *)addr));
binfo("Performing V4BX link at addr=%08" PRIxPTR
" [%08" PRIx32 "]\n",
addr, *(uint32_t *)addr);
/* Preserve only Rm and the condition code */
@ -222,9 +223,9 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
case R_ARM_PREL31:
{
binfo("Performing PREL31 link "
"at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n",
(long)addr, (long)(*(uint32_t *)addr), sym,
(long)sym->st_value);
"at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
"sym=%p st_value=%08" PRIx32 "\n",
addr, *(uint32_t *)addr, sym, sym->st_value);
offset = *(uint32_t *)addr + sym->st_value - addr;
*(uint32_t *)addr = offset & 0x7fffffff;
@ -235,10 +236,10 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
case R_ARM_MOVT_ABS:
{
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),
sym, (long)sym->st_value);
"at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
"sym=%p st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
*(uint32_t *)addr, sym, sym->st_value);
offset = *(uint32_t *)addr;
offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff);
@ -292,10 +293,11 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
lower_insn = (uint32_t)(*(uint16_t *)(addr + 2));
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,
"at addr=%08" PRIxPTR " [%04x %04x] to "
"sym=%p st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
(int)upper_insn, (int)lower_insn,
sym, (long)sym->st_value);
sym, sym->st_value);
/* Extract the 16-bit offset from the 32-bit instruction */
@ -361,7 +363,7 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
* |OP | | 32-Bit
* +---+--+---+---+---+---------------------------------+
* |1 1 |J1 | 1 |J2 | imm11 | BL
* +------+---+---+---+--------------------------------+
* +------+---+---+---+---------------------------------+
*
* The branch target is encoded in these bits:
*
@ -376,10 +378,11 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
lower_insn = (uint32_t)(*(uint16_t *)(addr + 2));
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,
"at addr=%08" PRIxPTR " [%04x %04x] to "
"sym=%p st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
(int)upper_insn, (int)lower_insn,
sym, (long)sym->st_value);
sym, sym->st_value);
/* Extract the 25-bit offset from the 32-bit instruction:
*

View File

@ -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
****************************************************************************/
@ -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;
}
@ -152,11 +142,11 @@ 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 "
"addr %08lx [%08lx] to sym '%p' st_value=%08lx\n",
ELF32_R_TYPE(rel->r_info), (long)addr,
(long)(*(uint32_t *)addr),
sym, (long)sym->st_value);
binfo("Performing PC24 [%" PRId32 "] link at "
"addr %08" PRIxPTR " [%08" PRIx32 "] to "
"sym '%p' st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
*(uint32_t *)addr, sym, sym->st_value);
offset = (*(uint32_t *)addr & 0x00ffffff) << 2;
if (offset & 0x02000000)
@ -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;
@ -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=%08" PRIxPTR " [%08" PRIx32 "] to "
"sym=%p st_value=%08" PRIx32 "\n",
addr, *(uint32_t *)addr, sym, 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=%08" PRIx32 " [%08" PRIx32 "] to "
"sym=%p st_value=%08" PRIx32 "\n",
addr, *(uint32_t *)addr, sym, sym->st_value);
*(uint32_t *)addr += sym->st_value - addr;
}
break;
#endif
case R_ARM_THM_CALL:
case R_ARM_THM_JUMP24:
{
@ -216,11 +220,11 @@ 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:
@ -235,11 +239,12 @@ 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 "
"at addr=%08lx [%04x %04x] to sym=%p st_value=%08lx\n",
ELF32_R_TYPE(rel->r_info), (long)addr,
binfo("Performing THM_JUMP24 [%" PRId32 "] link "
"at addr=%08" PRIxPTR " [%04x %04x] to "
"sym=%p st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
(int)upper_insn, (int)lower_insn,
sym, (long)sym->st_value);
sym, sym->st_value);
/* Extract the 25-bit offset from the 32-bit instruction:
*
@ -271,8 +276,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;
@ -282,8 +288,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;
@ -293,8 +299,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;
@ -316,15 +322,17 @@ 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;
case R_ARM_V4BX:
{
binfo("Performing V4BX link at addr=%08lx [%08lx]\n",
(long)addr, (long)(*(uint32_t *)addr));
binfo("Performing V4BX link at addr=%08" PRIxPTR
" [%08" PRIx32 "]\n",
addr, *(uint32_t *)addr);
/* Preserve only Rm and the condition code */
@ -339,9 +347,9 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
case R_ARM_PREL31:
{
binfo("Performing PREL31 link "
"at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n",
(long)addr, (long)(*(uint32_t *)addr),
sym, (long)sym->st_value);
"at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
"sym=%p st_value=%08" PRIx32 "\n",
addr, *(uint32_t *)addr, sym, sym->st_value);
offset = *(uint32_t *)addr + sym->st_value - addr;
*(uint32_t *)addr = offset & 0x7fffffff;
@ -351,11 +359,11 @@ 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 "
"at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n",
ELF32_R_TYPE(rel->r_info),
(long)addr, (long)(*(uint32_t *)addr),
sym, (long)sym->st_value);
binfo("Performing MOVx_ABS [%" PRId32 "] link "
"at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
"sym=%p st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
*(uint32_t *)addr, sym, sym->st_value);
offset = *(uint32_t *)addr;
offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff);
@ -379,7 +387,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
* +----------+---+--+-----+-----------------+----------+
@ -388,13 +396,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:
*
@ -407,11 +415,12 @@ 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 "
"at addr=%08lx [%04x %04x] to sym=%p st_value=%08lx\n",
ELF32_R_TYPE(rel->r_info), (long)addr,
binfo("Performing THM_MOVx [%" PRId32 "] link "
"at addr=%08" PRIxPTR " [%04x %04x] to "
"sym=%p st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
(int)upper_insn, (int)lower_insn,
sym, (long)sym->st_value);
sym, sym->st_value);
/* Extract the 16-bit offset from the 32-bit instruction */
@ -450,8 +459,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;
}

View File

@ -24,22 +24,28 @@ if(CONFIG_ARMV7M_MEMCPY)
list(APPEND SRCS gnu/arch_memcpy.S)
endif()
if(CONFIG_ARMV7M_MEMSET)
list(APPEND SRCS arch_memset.S)
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_ARMV7M_STRCPY)
list(APPEND SRCS arch_strcpy.S)
endif()
if(CONFIG_ARMV7M_STRLEN)
list(APPEND SRCS arch_strlen.S)
endif()
if(CONFIG_LIBC_ARCH_ELF)
list(APPEND SRCS arch_elf.c)
endif()
if(CONFIG_MACHINE_OPTS_ARMV7M)
if(CONFIG_LIBM_ARCH_FABSF)
list(APPEND SRCS arch_fabsf.c)
endif()
if(CONFIG_LIBM_ARCH_SQRTF)
list(APPEND SRCS arch_sqrtf.c)
endif()
endif()
if(CONFIG_ARCH_SETJMP_H)
list(APPEND SRCS gnu/arch_setjmp.S)
endif()
target_sources(c PRIVATE ${SRCS})

View File

@ -143,10 +143,10 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
case R_ARM_JUMP24:
{
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),
sym, (long)sym->st_value);
"addr %08" PRIxPTR " [%08" PRIx32 "] to "
"sym '%p' st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
*(uint32_t *)addr, sym, sym->st_value);
offset = (*(uint32_t *)addr & 0x00ffffff) << 2;
if (offset & 0x02000000)
@ -176,9 +176,9 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
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);
"at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
"sym=%p st_value=%08" PRIx32 "\n",
addr, *(uint32_t *)addr, sym, sym->st_value);
*(uint32_t *)addr += sym->st_value;
}
@ -189,9 +189,9 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
* 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);
"at addr=%08" PRIx32 " [%08" PRIx32 "] to "
"sym=%p st_value=%08" PRIx32 "\n",
addr, *(uint32_t *)addr, sym, sym->st_value);
*(uint32_t *)addr += sym->st_value - addr;
}
@ -225,7 +225,7 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
* |OP | | 32-Bit
* +---+--+---+---+---+---------------------------------+
* |1 1 |J1 | 1 |J2 | imm11 | BL
* +------+---+---+---+--------------------------------+
* +------+---+---+---+---------------------------------+
*
* The branch target is encoded in these bits:
*
@ -240,10 +240,11 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
lower_insn = (uint32_t)(*(uint16_t *)(addr + 2));
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,
"at addr=%08" PRIxPTR " [%04x %04x] to "
"sym=%p st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
(int)upper_insn, (int)lower_insn,
sym, (long)sym->st_value);
sym, sym->st_value);
/* Extract the 25-bit offset from the 32-bit instruction:
*
@ -329,8 +330,9 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
case R_ARM_V4BX:
{
binfo("Performing V4BX link at addr=%08lx [%08lx]\n",
(long)addr, (long)(*(uint32_t *)addr));
binfo("Performing V4BX link at addr=%08" PRIxPTR
" [%08" PRIx32 "]\n",
addr, *(uint32_t *)addr);
/* Preserve only Rm and the condition code */
@ -345,9 +347,9 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
case R_ARM_PREL31:
{
binfo("Performing PREL31 link "
"at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n",
(long)addr, (long)(*(uint32_t *)addr),
sym, (long)sym->st_value);
"at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
"sym=%p st_value=%08" PRIx32 "\n",
addr, *(uint32_t *)addr, sym, sym->st_value);
offset = *(uint32_t *)addr + sym->st_value - addr;
*(uint32_t *)addr = offset & 0x7fffffff;
@ -358,10 +360,10 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
case R_ARM_MOVT_ABS:
{
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),
sym, (long)sym->st_value);
"at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
"sym=%p st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
*(uint32_t *)addr, sym, sym->st_value);
offset = *(uint32_t *)addr;
offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff);
@ -414,10 +416,11 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
lower_insn = (uint32_t)(*(uint16_t *)(addr + 2));
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,
"at addr=%08" PRIxPTR " [%04x %04x] to "
"sym=%p st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
(int)upper_insn, (int)lower_insn,
sym, (long)sym->st_value);
sym, sym->st_value);
/* Extract the 16-bit offset from the 32-bit instruction */

View File

@ -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_ARMV8M_MEMCHR)
list(APPEND SRCS arch_memchr.S)
endif()
if(CONFIG_LIBM_ARCH_CEILF)
list(APPEND SRCS arch_ceilf.c)
endif()
if(CONFIG_ARMV8M_MEMCPY)
list(APPEND SRCS arch_memcpy.S)
endif()
if(CONFIG_LIBM_ARCH_FLOOR)
list(APPEND SRCS arch_floor.c)
endif()
if(CONFIG_ARMV8M_MEMSET)
list(APPEND SRCS arch_memset.S)
endif()
if(CONFIG_LIBM_ARCH_FLOORF)
list(APPEND SRCS arch_floorf.c)
endif()
if(CONFIG_ARMV8M_MEMMOVE)
list(APPEND SRCS arch_memmove.S)
endif()
if(CONFIG_LIBM_ARCH_NEARBYINT)
list(APPEND SRCS arch_nearbyint.c)
endif()
if(CONFIG_ARMV8M_STRCMP)
list(APPEND SRCS arch_strcmp.S)
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_LIBM_ARCH_ROUNDF)
list(APPEND SRCS arch_roundf.c)
endif()
if(CONFIG_LIBM_ARCH_TRUNCF)
list(APPEND SRCS arch_truncf.c)
endif()
if(CONFIG_LIBM_ARCH_RINT)
list(APPEND SRCS arch_rint.c)
endif()
if(CONFIG_LIBM_ARCH_ROUND)
list(APPEND SRCS arch_round.c)
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})

View File

@ -122,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;
}
@ -142,10 +143,10 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
case R_ARM_JUMP24:
{
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),
sym, (long)sym->st_value);
"addr %08" PRIxPTR " [%08" PRIx32 "] to "
"sym '%p' st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
*(uint32_t *)addr, sym, sym->st_value);
offset = (*(uint32_t *)addr & 0x00ffffff) << 2;
if (offset & 0x02000000)
@ -175,9 +176,9 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
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);
"at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
"sym=%p st_value=%08" PRIx32 "\n",
addr, *(uint32_t *)addr, sym, sym->st_value);
*(uint32_t *)addr += sym->st_value;
}
@ -188,9 +189,9 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
* 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);
"at addr=%08" PRIx32 " [%08" PRIx32 "] to "
"sym=%p st_value=%08" PRIx32 "\n",
addr, *(uint32_t *)addr, sym, sym->st_value);
*(uint32_t *)addr += sym->st_value - addr;
}
@ -208,23 +209,23 @@ 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
* +-------+---+----------------------+-----------+
* |1 1 1|OP1| OP2 | | 32Bit Instruction
* +-------+---+-+---+----------------+-----------+
* |1 1 1| 1 0| S | imm10 | BL Instruction
* +-------+-----+---+----------------------------+
* 1 1 1 1 1 1
* 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 Instructions
* +----------+---+--------------------------+----------+
* |1 1 1 |OP1| OP2 | | 32-Bit
* +----------+---+--+-----+-----------------+----------+
* |1 1 1 | 1 0| S | imm10 | BL
* +----------+------+-----+----------------------------+
*
* lower_insn:
*
* 1 1 1 1 1 1
* 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +--+-------------------------------------------+
* |OP| | 32Bit Instruction
* +--+-+--+--+--+--------------------------------+
* |1 1|J1| 1|J2| imm11 | BL Instruction
* +----+--+--+--+--------------------------------+
* 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
* +---+--+---+---+---+---------------------------------+
* |1 1 |J1 | 1 |J2 | imm11 | BL
* +------+---+---+---+---------------------------------+
*
* The branch target is encoded in these bits:
*
@ -239,10 +240,11 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
lower_insn = (uint32_t)(*(uint16_t *)(addr + 2));
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,
"at addr=%08" PRIxPTR " [%04x %04x] to "
"sym=%p st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
(int)upper_insn, (int)lower_insn,
sym, (long)sym->st_value);
sym, sym->st_value);
/* Extract the 25-bit offset from the 32-bit instruction:
*
@ -328,8 +330,9 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
case R_ARM_V4BX:
{
binfo("Performing V4BX link at addr=%08lx [%08lx]\n",
(long)addr, (long)(*(uint32_t *)addr));
binfo("Performing V4BX link at addr=%08" PRIxPTR
" [%08" PRIx32 "]\n",
addr, *(uint32_t *)addr);
/* Preserve only Rm and the condition code */
@ -344,9 +347,9 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
case R_ARM_PREL31:
{
binfo("Performing PREL31 link "
"at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n",
(long)addr, (long)(*(uint32_t *)addr),
sym, (long)sym->st_value);
"at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
"sym=%p st_value=%08" PRIx32 "\n",
addr, *(uint32_t *)addr, sym, sym->st_value);
offset = *(uint32_t *)addr + sym->st_value - addr;
*(uint32_t *)addr = offset & 0x7fffffff;
@ -357,10 +360,10 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
case R_ARM_MOVT_ABS:
{
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),
sym, (long)sym->st_value);
"at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
"sym=%p st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
*(uint32_t *)addr, sym, sym->st_value);
offset = *(uint32_t *)addr;
offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff);
@ -383,23 +386,23 @@ 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
* +-------+---+-----------------------+----------+
* |1 1 1|OP1| OP2 | | 32Bit Instruction
* +-------+---+-+---+-----------------+----------+
* |1 1 1| 1 0| i | 1 0 1 1 0 0 | imm4 | MOVT Instruction
* +-------+-----+---+-----------------+----------+
* 1 1 1 1 1 1
* 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 Instruction
* +----------+---+--------------------------+----------+
* |1 1 1 |OP1| OP2 | | 32-Bit
* +----------+---+--+-----+-----------------+----------+
* |1 1 1 | 1 0| i |1 0 1 1 0 0 | imm4 | MOVT
* +----------+------+-----+-----------------+----------+
*
* lower_insn:
*
* 1 1 1 1 1 1
* 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +--+-------------------------------------------+
* |OP| | 32Bit Instruction
* +--+--------+----------+-----------------------+
* |0 | imm3 | Rd | imm8 | MOVT Instruction
* +--+--------+----------+-----------------------+
* 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:
*
@ -413,10 +416,11 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
lower_insn = (uint32_t)(*(uint16_t *)(addr + 2));
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,
"at addr=%08" PRIxPTR " [%04x %04x] to "
"sym=%p st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
(int)upper_insn, (int)lower_insn,
sym, (long)sym->st_value);
sym, sym->st_value);
/* Extract the 16-bit offset from the 32-bit instruction */
@ -492,6 +496,13 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
}
break;
case R_ARM_RELATIVE:
case R_ARM_JUMP_SLOT:
{
*(uint32_t *)addr = (uint32_t)sym->st_value;
}
break;
default:
berr("ERROR: Unsupported relocation: %" PRId32 "\n",
ELF32_R_TYPE(rel->r_info));

View File

@ -0,0 +1,183 @@
/****************************************************************************
* libs/libc/machine/arm/armv8-m/gnu/acle-compat.h
*
* Copyright (c) 2014 ARM Ltd
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the company may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
****************************************************************************/
#ifndef __LIBS_LIBC_MACHINE_ARM_ARMV7M_GNU_ACLE_COMPAT_H
#define __LIBS_LIBC_MACHINE_ARM_ARMV7M_GNU_ACLE_COMPAT_H
#ifndef __ARM_ARCH
/* ACLE standardises a set of pre-defines that describe the ARM architecture.
* These were mostly implemented in GCC around GCC-4.8; older versions
* have no, or only partial support. To provide a level of backwards
* compatibility we try to work out what the definitions should be, given
* the older pre-defines that GCC did produce. This isn't complete, but
* it should be enough for use by routines that depend on this header.
*/
/* No need to handle ARMv8, GCC had ACLE support before that. */
# ifdef __ARM_ARCH_7__
/* The common subset of ARMv7 in all profiles. */
# define __ARM_ARCH 7
# define __ARM_ARCH_ISA_THUMB 2
# define __ARM_FEATURE_CLZ
# define __ARM_FEATURE_LDREX 7
# define __ARM_FEATURE_UNALIGNED
# endif
# if defined (__ARM_ARCH_7A__) || defined (__ARM_ARCH_7R__)
# define __ARM_ARCH 7
# define __ARM_ARCH_ISA_THUMB 2
# define __ARM_ARCH_ISA_ARM
# define __ARM_FEATURE_CLZ
# define __ARM_FEATURE_SIMD32
# define __ARM_FEATURE_DSP
# define __ARM_FEATURE_QBIT
# define __ARM_FEATURE_SAT
# define __ARM_FEATURE_LDREX 15
# define __ARM_FEATURE_UNALIGNED
# ifdef __ARM_ARCH_7A__
# define __ARM_ARCH_PROFILE 'A'
# else
# define __ARM_ARCH_PROFILE 'R'
# endif
# endif
# ifdef __ARM_ARCH_7EM__
# define __ARM_ARCH 7
# define __ARM_ARCH_ISA_THUMB 2
# define __ARM_FEATURE_CLZ
# define __ARM_FEATURE_SIMD32
# define __ARM_FEATURE_DSP
# define __ARM_FEATURE_QBIT
# define __ARM_FEATURE_SAT
# define __ARM_FEATURE_LDREX 7
# define __ARM_FEATURE_UNALIGNED
# define __ARM_ARCH_PROFILE 'M'
# endif
# ifdef __ARM_ARCH_7M__
# define __ARM_ARCH 7
# define __ARM_ARCH_ISA_THUMB 2
# define __ARM_FEATURE_CLZ
# define __ARM_FEATURE_QBIT
# define __ARM_FEATURE_SAT
# define __ARM_FEATURE_LDREX 7
# define __ARM_FEATURE_UNALIGNED
# define __ARM_ARCH_PROFILE 'M'
# endif
# ifdef __ARM_ARCH_6T2__
# define __ARM_ARCH 6
# define __ARM_ARCH_ISA_THUMB 2
# define __ARM_ARCH_ISA_ARM
# define __ARM_FEATURE_CLZ
# define __ARM_FEATURE_SIMD32
# define __ARM_FEATURE_DSP
# define __ARM_FEATURE_QBIT
# define __ARM_FEATURE_SAT
# define __ARM_FEATURE_LDREX 4
# define __ARM_FEATURE_UNALIGNED
# endif
# ifdef __ARM_ARCH_6M__
# define __ARM_ARCH 6
# define __ARM_ARCH_ISA_THUMB 1
# define __ARM_ARCH_PROFILE 'M'
# endif
# if defined (__ARM_ARCH_6__) || defined (__ARM_ARCH_6J__) \
|| defined (__ARM_ARCH_6K__) || defined (__ARM_ARCH_6Z__) \
|| defined (__ARM_ARCH_6ZK__)
# define __ARM_ARCH 6
# define __ARM_ARCH_ISA_THUMB 1
# define __ARM_ARCH_ISA_ARM
# define __ARM_FEATURE_CLZ
# define __ARM_FEATURE_SIMD32
# define __ARM_FEATURE_DSP
# define __ARM_FEATURE_QBIT
# define __ARM_FEATURE_SAT
# define __ARM_FEATURE_UNALIGNED
# ifndef __thumb__
# if defined (__ARM_ARCH_6K__) || defined (__ARM_ARCH_6ZK__)
# define __ARM_FEATURE_LDREX 15
# else
# define __ARM_FEATURE_LDREX 4
# endif
# endif
# endif
# if defined (__ARM_ARCH_5TE__) || defined (__ARM_ARCH_5E__)
# define __ARM_ARCH 5
# define __ARM_ARCH_ISA_ARM
# ifdef __ARM_ARCH_5TE__
# define __ARM_ARCH_ISA_THUMB 1
# endif
# define __ARM_FEATURE_CLZ
# define __ARM_FEATURE_DSP
# endif
# if defined (__ARM_ARCH_5T__) || defined (__ARM_ARCH_5__)
# define __ARM_ARCH 5
# define __ARM_ARCH_ISA_ARM
# ifdef __ARM_ARCH_5TE__
# define __ARM_ARCH_ISA_THUMB 1
# endif
# define __ARM_FEATURE_CLZ
# endif
# ifdef __ARM_ARCH_4T__
# define __ARM_ARCH 4
# define __ARM_ARCH_ISA_ARM
# define __ARM_ARCH_ISA_THUMB 1
# endif
# ifdef __ARM_ARCH_4__
# define __ARM_ARCH 4
# define __ARM_ARCH_ISA_ARM
# endif
# if defined (__ARM_ARCH_3__) || defined (__ARM_ARCH_3M__)
# define __ARM_ARCH 3
# define __ARM_ARCH_ISA_ARM
# endif
# ifdef __ARM_ARCH_2__
# define __ARM_ARCH 2
# define __ARM_ARCH_ISA_ARM
# endif
# ifdef __ARMEB__
# define __ARM_BIG_ENDIAN
# endif
#endif
#endif /* __LIBS_LIBC_MACHINE_ARM_ARMV7M_GNU_ACLE_COMPAT_H */

View File

@ -84,6 +84,8 @@
.syntax unified
#include "acle-compat.h"
@ NOTE: This ifdef MUST match the one in memchr-stub.c
#if defined (__ARM_NEON__) || defined (__ARM_NEON)
#if __ARM_ARCH >= 8 && __ARM_ARCH_PROFILE == 'R'

View File

@ -18,6 +18,10 @@
*
***************************************************************************/
#include "libc.h"
#ifdef LIBC_BUILD_STRCPY
/* This strcpy borrowed some ideas from arch_strcmp.S(). */
/* Parameters and result. */
@ -304,3 +308,5 @@ offset_3:
.cpy_done:
*dst++ = 0;
#endif /* Pseudo code end */
#endif

View File

@ -66,6 +66,8 @@
#ifdef LIBC_BUILD_STRLEN
#include "acle-compat.h"
.macro def_fn f p2align=0
.text
.p2align \p2align