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_CALL:
case R_ARM_JUMP24: case R_ARM_JUMP24:
{ {
binfo("Performing PC24 [%" PRId32 "] link " binfo("Performing PC24 [%" PRId32 "] link at "
"at addr %08lx [%08lx] to sym '%p' st_value=%08lx\n", "addr %08" PRIxPTR " [%08" PRIx32 "] to "
ELF32_R_TYPE(rel->r_info), (long)addr, "sym '%p' st_value=%08" PRIx32 "\n",
(long)(*(uint32_t *)addr), ELF32_R_TYPE(rel->r_info), addr,
sym, (long)sym->st_value); *(uint32_t *)addr, sym, sym->st_value);
offset = (*(uint32_t *)addr & 0x00ffffff) << 2; offset = (*(uint32_t *)addr & 0x00ffffff) << 2;
if (offset & 0x02000000) 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) offset >= (int32_t) 0x02000000)
{ {
berr("ERROR: PC24 [%" PRId32 "] relocation out of range, " berr("ERROR: PC24 [%" PRId32 "] relocation out of range, "
"offset=%08lx\n", "offset=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), offset); ELF32_R_TYPE(rel->r_info), offset);
return -EINVAL; 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 */ case R_ARM_TARGET1: /* New ABI: TARGET1 always treated as ABS32 */
{ {
binfo("Performing ABS32 link " binfo("Performing ABS32 link "
"at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", "at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
(long)addr, (long)(*(uint32_t *)addr), sym, "sym=%p st_value=%08" PRIx32 "\n",
(long)sym->st_value); addr, *(uint32_t *)addr, sym, sym->st_value);
*(uint32_t *)addr += 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: case R_ARM_V4BX:
{ {
binfo("Performing V4BX link at addr=%08lx [%08lx]\n", binfo("Performing V4BX link at addr=%08" PRIxPTR
(long)addr, (long)(*(uint32_t *)addr)); " [%08" PRIx32 "]\n",
addr, *(uint32_t *)addr);
/* Preserve only Rm and the condition code */ /* 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: case R_ARM_PREL31:
{ {
binfo("Performing PREL31 link " binfo("Performing PREL31 link "
"at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", "at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
(long)addr, (long)(*(uint32_t *)addr), sym, "sym=%p st_value=%08" PRIx32 "\n",
(long)sym->st_value); addr, *(uint32_t *)addr, sym, sym->st_value);
offset = *(uint32_t *)addr + sym->st_value - addr; offset = *(uint32_t *)addr + sym->st_value - addr;
*(uint32_t *)addr = offset & 0x7fffffff; *(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: case R_ARM_MOVT_ABS:
{ {
binfo("Performing MOVx_ABS [%" PRId32 "] link " binfo("Performing MOVx_ABS [%" PRId32 "] link "
"at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", "at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
ELF32_R_TYPE(rel->r_info), (long)addr, "sym=%p st_value=%08" PRIx32 "\n",
(long)(*(uint32_t *)addr), ELF32_R_TYPE(rel->r_info), addr,
sym, (long)sym->st_value); *(uint32_t *)addr, sym, sym->st_value);
offset = *(uint32_t *)addr; offset = *(uint32_t *)addr;
offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff); 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)); lower_insn = (uint32_t)(*(uint16_t *)(addr + 2));
binfo("Performing THM_MOVx [%" PRId32 "] link " binfo("Performing THM_MOVx [%" PRId32 "] link "
"at addr=%08lx [%04x %04x] to sym=%p st_value=%08lx\n", "at addr=%08" PRIxPTR " [%04x %04x] to "
ELF32_R_TYPE(rel->r_info), (long)addr, "sym=%p st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
(int)upper_insn, (int)lower_insn, (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 */ /* 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 * |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: * 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)); lower_insn = (uint32_t)(*(uint16_t *)(addr + 2));
binfo("Performing THM_JUMP24 [%" PRId32 "] link " binfo("Performing THM_JUMP24 [%" PRId32 "] link "
"at addr=%08lx [%04x %04x] to sym=%p st_value=%08lx\n", "at addr=%08" PRIxPTR " [%04x %04x] to "
ELF32_R_TYPE(rel->r_info), (long)addr, "sym=%p st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
(int)upper_insn, (int)lower_insn, (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: /* Extract the 25-bit offset from the 32-bit instruction:
* *

View File

@ -24,24 +24,13 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <inttypes.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <debug.h> #include <debug.h>
#include <nuttx/elf.h> #include <nuttx/elf.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/**************************************************************************** /****************************************************************************
* Public 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); 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; 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_CALL:
case R_ARM_JUMP24: 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", "addr %08" PRIxPTR " [%08" PRIx32 "] to "
ELF32_R_TYPE(rel->r_info), (long)addr, "sym '%p' st_value=%08" PRIx32 "\n",
(long)(*(uint32_t *)addr), ELF32_R_TYPE(rel->r_info), addr,
sym, (long)sym->st_value); *(uint32_t *)addr, sym, sym->st_value);
offset = (*(uint32_t *)addr & 0x00ffffff) << 2; offset = (*(uint32_t *)addr & 0x00ffffff) << 2;
if (offset & 0x02000000) 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 || if (offset & 3 || offset < (int32_t) 0xfe000000 ||
offset >= (int32_t) 0x02000000) offset >= (int32_t) 0x02000000)
{ {
berr("ERROR: ERROR: PC24 [%d] relocation out of range, " berr("ERROR: ERROR: PC24 [%" PRId32 "] "
"offset=%08lx\n", "relocation out of range, offset=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), offset); ELF32_R_TYPE(rel->r_info), offset);
return -EINVAL; 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_ABS32:
case R_ARM_TARGET1: /* New ABI: TARGET1 always treated as ABS32 */ case R_ARM_TARGET1: /* New ABI: TARGET1 always treated as ABS32 */
{ {
binfo("Performing ABS32 link at addr=%08lx [%08lx] " binfo("Performing ABS32 link "
"to sym=%p st_value=%08lx\n", "at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
(long)addr, (long)(*(uint32_t *)addr), sym, "sym=%p st_value=%08" PRIx32 "\n",
(long)sym->st_value); addr, *(uint32_t *)addr, sym, sym->st_value);
*(uint32_t *)addr += sym->st_value; *(uint32_t *)addr += sym->st_value;
} }
break; 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_CALL:
case R_ARM_THM_JUMP24: 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: * lower_insn:
* *
* 1 1 1 1 1 1 * 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 * |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: * 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); upper_insn = (uint32_t)(*(uint16_t *)addr);
lower_insn = (uint32_t)(*(uint16_t *)(addr + 2)); 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", "at addr=%08" PRIxPTR " [%04x %04x] to "
ELF32_R_TYPE(rel->r_info), (long)addr, "sym=%p st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
(int)upper_insn, (int)lower_insn, (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: /* 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 */ /* And perform the relocation */
binfo(" S=%d J1=%d J2=%d offset=%08lx branch target=%08lx\n", binfo(" S=%" PRId32 " J1=%" PRId32 " J2=%" PRId32
S, J1, J2, (long)offset, offset + sym->st_value - addr); " offset=%08" PRIx32 " branch target=%08" PRIx32 "\n",
S, J1, J2, offset, offset + sym->st_value - addr);
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) if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && (offset & 1) == 0)
{ {
berr("ERROR: ERROR: JUMP24 [%d] " berr("ERROR: ERROR: JUMP24 [%" PRId32 "] "
"requires odd offset, offset=%08lx\n", "requires odd offset, offset=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), offset); ELF32_R_TYPE(rel->r_info), offset);
return -EINVAL; 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) if (offset < (int32_t)0xff000000 || offset >= (int32_t)0x01000000)
{ {
berr("ERROR: ERROR: JUMP24 [%d] " berr("ERROR: ERROR: JUMP24 [%" PRId32 "] "
"relocation out of range, branch target=%08lx\n", "relocation out of range, branch target=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), offset); ELF32_R_TYPE(rel->r_info), offset);
return -EINVAL; return -EINVAL;
@ -316,15 +322,17 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
((offset >> 1) & 0x07ff)); ((offset >> 1) & 0x07ff));
*(uint16_t *)(addr + 2) = (uint16_t)lower_insn; *(uint16_t *)(addr + 2) = (uint16_t)lower_insn;
binfo(" S=%d J1=%d J2=%d insn [%04x %04x]\n", binfo(" S=%" PRId32 " J1=%" PRId32 " J2=%" PRId32
S, J1, J2, (int)upper_insn, (int)lower_insn); " insn [%04" PRIx32 " %04" PRIx32 "]\n",
S, J1, J2, upper_insn, lower_insn);
} }
break; break;
case R_ARM_V4BX: case R_ARM_V4BX:
{ {
binfo("Performing V4BX link at addr=%08lx [%08lx]\n", binfo("Performing V4BX link at addr=%08" PRIxPTR
(long)addr, (long)(*(uint32_t *)addr)); " [%08" PRIx32 "]\n",
addr, *(uint32_t *)addr);
/* Preserve only Rm and the condition code */ /* 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: case R_ARM_PREL31:
{ {
binfo("Performing PREL31 link " binfo("Performing PREL31 link "
"at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", "at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
(long)addr, (long)(*(uint32_t *)addr), "sym=%p st_value=%08" PRIx32 "\n",
sym, (long)sym->st_value); addr, *(uint32_t *)addr, sym, sym->st_value);
offset = *(uint32_t *)addr + sym->st_value - addr; offset = *(uint32_t *)addr + sym->st_value - addr;
*(uint32_t *)addr = offset & 0x7fffffff; *(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_MOVW_ABS_NC:
case R_ARM_MOVT_ABS: 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", "at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
ELF32_R_TYPE(rel->r_info), "sym=%p st_value=%08" PRIx32 "\n",
(long)addr, (long)(*(uint32_t *)addr), ELF32_R_TYPE(rel->r_info), addr,
sym, (long)sym->st_value); *(uint32_t *)addr, sym, sym->st_value);
offset = *(uint32_t *)addr; offset = *(uint32_t *)addr;
offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff); 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: * upper_insn:
* *
* 1 1 1 1 1 1 * 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 * |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: * lower_insn:
* *
* 1 1 1 1 1 1 * 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 * |OP | | 32-Bit
* +---+----------+-----------+------------------------+ * +---+----------+--------+-----------------------------+
* |0 | imm3 | Rd | imm8 | MOVT * |0 | imm3 | Rd | imm8 | MOVT
* +---+----------+-----------+------------------------+ * +---+----------+--------+-----------------------------+
* *
* The 16-bit immediate value is encoded in these bits: * 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); upper_insn = (uint32_t)(*(uint16_t *)addr);
lower_insn = (uint32_t)(*(uint16_t *)(addr + 2)); 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", "at addr=%08" PRIxPTR " [%04x %04x] to "
ELF32_R_TYPE(rel->r_info), (long)addr, "sym=%p st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
(int)upper_insn, (int)lower_insn, (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 */ /* 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; 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: 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; return -EINVAL;
} }

View File

@ -24,22 +24,28 @@ if(CONFIG_ARMV7M_MEMCPY)
list(APPEND SRCS gnu/arch_memcpy.S) list(APPEND SRCS gnu/arch_memcpy.S)
endif() 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) if(CONFIG_LIBC_ARCH_ELF)
list(APPEND SRCS arch_elf.c) list(APPEND SRCS arch_elf.c)
endif() 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}) 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: case R_ARM_JUMP24:
{ {
binfo("Performing PC24 [%" PRId32 "] link at " binfo("Performing PC24 [%" PRId32 "] link at "
"addr %08lx [%08lx] to sym '%p' st_value=%08lx\n", "addr %08" PRIxPTR " [%08" PRIx32 "] to "
ELF32_R_TYPE(rel->r_info), (long)addr, "sym '%p' st_value=%08" PRIx32 "\n",
(long)(*(uint32_t *)addr), ELF32_R_TYPE(rel->r_info), addr,
sym, (long)sym->st_value); *(uint32_t *)addr, sym, sym->st_value);
offset = (*(uint32_t *)addr & 0x00ffffff) << 2; offset = (*(uint32_t *)addr & 0x00ffffff) << 2;
if (offset & 0x02000000) 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 */ case R_ARM_TARGET1: /* New ABI: TARGET1 always treated as ABS32 */
{ {
binfo("Performing ABS32 link " binfo("Performing ABS32 link "
"at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", "at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
(long)addr, (long)(*(uint32_t *)addr), "sym=%p st_value=%08" PRIx32 "\n",
sym, (long)sym->st_value); addr, *(uint32_t *)addr, sym, sym->st_value);
*(uint32_t *)addr += 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 */ * performs a self relocation */
{ {
binfo("Performing TARGET2 link " binfo("Performing TARGET2 link "
"at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", "at addr=%08" PRIx32 " [%08" PRIx32 "] to "
(long)addr, (long)(*(uint32_t *)addr), "sym=%p st_value=%08" PRIx32 "\n",
sym, (long)sym->st_value); addr, *(uint32_t *)addr, sym, sym->st_value);
*(uint32_t *)addr += sym->st_value - addr; *(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 * |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: * 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)); lower_insn = (uint32_t)(*(uint16_t *)(addr + 2));
binfo("Performing THM_JUMP24 [%" PRId32 "] link " binfo("Performing THM_JUMP24 [%" PRId32 "] link "
"at addr=%08lx [%04x %04x] to sym=%p st_value=%08lx\n", "at addr=%08" PRIxPTR " [%04x %04x] to "
ELF32_R_TYPE(rel->r_info), (long)addr, "sym=%p st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
(int)upper_insn, (int)lower_insn, (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: /* 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: case R_ARM_V4BX:
{ {
binfo("Performing V4BX link at addr=%08lx [%08lx]\n", binfo("Performing V4BX link at addr=%08" PRIxPTR
(long)addr, (long)(*(uint32_t *)addr)); " [%08" PRIx32 "]\n",
addr, *(uint32_t *)addr);
/* Preserve only Rm and the condition code */ /* 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: case R_ARM_PREL31:
{ {
binfo("Performing PREL31 link " binfo("Performing PREL31 link "
"at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", "at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
(long)addr, (long)(*(uint32_t *)addr), "sym=%p st_value=%08" PRIx32 "\n",
sym, (long)sym->st_value); addr, *(uint32_t *)addr, sym, sym->st_value);
offset = *(uint32_t *)addr + sym->st_value - addr; offset = *(uint32_t *)addr + sym->st_value - addr;
*(uint32_t *)addr = offset & 0x7fffffff; *(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: case R_ARM_MOVT_ABS:
{ {
binfo("Performing MOVx_ABS [%" PRId32 "] link " binfo("Performing MOVx_ABS [%" PRId32 "] link "
"at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", "at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
ELF32_R_TYPE(rel->r_info), (long)addr, "sym=%p st_value=%08" PRIx32 "\n",
(long)(*(uint32_t *)addr), ELF32_R_TYPE(rel->r_info), addr,
sym, (long)sym->st_value); *(uint32_t *)addr, sym, sym->st_value);
offset = *(uint32_t *)addr; offset = *(uint32_t *)addr;
offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff); 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)); lower_insn = (uint32_t)(*(uint16_t *)(addr + 2));
binfo("Performing THM_MOVx [%" PRId32 "] link " binfo("Performing THM_MOVx [%" PRId32 "] link "
"at addr=%08lx [%04x %04x] to sym=%p st_value=%08lx\n", "at addr=%08" PRIxPTR " [%04x %04x] to "
ELF32_R_TYPE(rel->r_info), (long)addr, "sym=%p st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
(int)upper_insn, (int)lower_insn, (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 */ /* 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) list(APPEND SRCS arch_elf.c)
endif() endif()
if(CONFIG_ARMV8M_LIBM) if(CONFIG_ARMV8M_MEMCHR)
if(CONFIG_LIBM_ARCH_CEIL) list(APPEND SRCS arch_memchr.S)
list(APPEND SRCS arch_ceil.c) endif()
endif()
if(CONFIG_LIBM_ARCH_CEILF) if(CONFIG_ARMV8M_MEMCPY)
list(APPEND SRCS arch_ceilf.c) list(APPEND SRCS arch_memcpy.S)
endif() endif()
if(CONFIG_LIBM_ARCH_FLOOR) if(CONFIG_ARMV8M_MEMSET)
list(APPEND SRCS arch_floor.c) list(APPEND SRCS arch_memset.S)
endif() endif()
if(CONFIG_LIBM_ARCH_FLOORF) if(CONFIG_ARMV8M_MEMMOVE)
list(APPEND SRCS arch_floorf.c) list(APPEND SRCS arch_memmove.S)
endif() endif()
if(CONFIG_LIBM_ARCH_NEARBYINT) if(CONFIG_ARMV8M_STRCMP)
list(APPEND SRCS arch_nearbyint.c) list(APPEND SRCS arch_strcmp.S)
endif() endif()
if(CONFIG_LIBM_ARCH_NEARBYINTF) if(CONFIG_ARMV8M_STRCPY)
list(APPEND SRCS arch_nearbyintf.c) list(APPEND SRCS arch_strcpy.S)
endif() 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_STRLEN)
list(APPEND SRCS arch_strlen.S)
endif() endif()
target_sources(c PRIVATE ${SRCS}) 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); 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; return -EINVAL;
} }
@ -142,10 +143,10 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym *sym, uintptr_t addr)
case R_ARM_JUMP24: case R_ARM_JUMP24:
{ {
binfo("Performing PC24 [%" PRId32 "] link at " binfo("Performing PC24 [%" PRId32 "] link at "
"addr %08lx [%08lx] to sym '%p' st_value=%08lx\n", "addr %08" PRIxPTR " [%08" PRIx32 "] to "
ELF32_R_TYPE(rel->r_info), (long)addr, "sym '%p' st_value=%08" PRIx32 "\n",
(long)(*(uint32_t *)addr), ELF32_R_TYPE(rel->r_info), addr,
sym, (long)sym->st_value); *(uint32_t *)addr, sym, sym->st_value);
offset = (*(uint32_t *)addr & 0x00ffffff) << 2; offset = (*(uint32_t *)addr & 0x00ffffff) << 2;
if (offset & 0x02000000) 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 */ case R_ARM_TARGET1: /* New ABI: TARGET1 always treated as ABS32 */
{ {
binfo("Performing ABS32 link " binfo("Performing ABS32 link "
"at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", "at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
(long)addr, (long)(*(uint32_t *)addr), "sym=%p st_value=%08" PRIx32 "\n",
sym, (long)sym->st_value); addr, *(uint32_t *)addr, sym, sym->st_value);
*(uint32_t *)addr += 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 */ * performs a self relocation */
{ {
binfo("Performing TARGET2 link " binfo("Performing TARGET2 link "
"at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", "at addr=%08" PRIx32 " [%08" PRIx32 "] to "
(long)addr, (long)(*(uint32_t *)addr), "sym=%p st_value=%08" PRIx32 "\n",
sym, (long)sym->st_value); addr, *(uint32_t *)addr, sym, sym->st_value);
*(uint32_t *)addr += sym->st_value - addr; *(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: * upper_insn:
* *
* 1 1 1 1 1 1 * 1 1 1 1 1 1
* 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 Instructions
* +-------+---+----------------------+-----------+ * +----------+---+--------------------------+----------+
* |1 1 1|OP1| OP2 | | 32Bit Instruction * |1 1 1 |OP1| OP2 | | 32-Bit
* +-------+---+-+---+----------------+-----------+ * +----------+---+--+-----+-----------------+----------+
* |1 1 1| 1 0| S | imm10 | BL Instruction * |1 1 1 | 1 0| S | imm10 | BL
* +-------+-----+---+----------------------------+ * +----------+------+-----+----------------------------+
* *
* lower_insn: * lower_insn:
* *
* 1 1 1 1 1 1 * 1 1 1 1 1 1
* 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 Instructions
* +--+-------------------------------------------+ * +---+------------------------------------------------+
* |OP| | 32Bit Instruction * |OP | | 32-Bit
* +--+-+--+--+--+--------------------------------+ * +---+--+---+---+---+---------------------------------+
* |1 1|J1| 1|J2| imm11 | BL Instruction * |1 1 |J1 | 1 |J2 | imm11 | BL
* +----+--+--+--+--------------------------------+ * +------+---+---+---+---------------------------------+
* *
* The branch target is encoded in these bits: * 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)); lower_insn = (uint32_t)(*(uint16_t *)(addr + 2));
binfo("Performing THM_JUMP24 [%" PRId32 "] link " binfo("Performing THM_JUMP24 [%" PRId32 "] link "
"at addr=%08lx [%04x %04x] to sym=%p st_value=%08lx\n", "at addr=%08" PRIxPTR " [%04x %04x] to "
ELF32_R_TYPE(rel->r_info), (long)addr, "sym=%p st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
(int)upper_insn, (int)lower_insn, (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: /* 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: case R_ARM_V4BX:
{ {
binfo("Performing V4BX link at addr=%08lx [%08lx]\n", binfo("Performing V4BX link at addr=%08" PRIxPTR
(long)addr, (long)(*(uint32_t *)addr)); " [%08" PRIx32 "]\n",
addr, *(uint32_t *)addr);
/* Preserve only Rm and the condition code */ /* 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: case R_ARM_PREL31:
{ {
binfo("Performing PREL31 link " binfo("Performing PREL31 link "
"at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", "at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
(long)addr, (long)(*(uint32_t *)addr), "sym=%p st_value=%08" PRIx32 "\n",
sym, (long)sym->st_value); addr, *(uint32_t *)addr, sym, sym->st_value);
offset = *(uint32_t *)addr + sym->st_value - addr; offset = *(uint32_t *)addr + sym->st_value - addr;
*(uint32_t *)addr = offset & 0x7fffffff; *(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: case R_ARM_MOVT_ABS:
{ {
binfo("Performing MOVx_ABS [%" PRId32 "] link " binfo("Performing MOVx_ABS [%" PRId32 "] link "
"at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n", "at addr=%08" PRIxPTR " [%08" PRIx32 "] to "
ELF32_R_TYPE(rel->r_info), (long)addr, "sym=%p st_value=%08" PRIx32 "\n",
(long)(*(uint32_t *)addr), ELF32_R_TYPE(rel->r_info), addr,
sym, (long)sym->st_value); *(uint32_t *)addr, sym, sym->st_value);
offset = *(uint32_t *)addr; offset = *(uint32_t *)addr;
offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff); 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: * upper_insn:
* *
* 1 1 1 1 1 1 * 1 1 1 1 1 1
* 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 Instruction
* +-------+---+-----------------------+----------+ * +----------+---+--------------------------+----------+
* |1 1 1|OP1| OP2 | | 32Bit Instruction * |1 1 1 |OP1| OP2 | | 32-Bit
* +-------+---+-+---+-----------------+----------+ * +----------+---+--+-----+-----------------+----------+
* |1 1 1| 1 0| i | 1 0 1 1 0 0 | imm4 | MOVT Instruction * |1 1 1 | 1 0| i |1 0 1 1 0 0 | imm4 | MOVT
* +-------+-----+---+-----------------+----------+ * +----------+------+-----+-----------------+----------+
* *
* lower_insn: * lower_insn:
* *
* 1 1 1 1 1 1 * 1 1 1 1 1 1
* 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 Instructions
* +--+-------------------------------------------+ * +---+-------------------------------------------------+
* |OP| | 32Bit Instruction * |OP | | 32-Bit
* +--+--------+----------+-----------------------+ * +---+----------+--------+-----------------------------+
* |0 | imm3 | Rd | imm8 | MOVT Instruction * |0 | imm3 | Rd | imm8 | MOVT
* +--+--------+----------+-----------------------+ * +---+----------+--------+-----------------------------+
* *
* The 16-bit immediate value is encoded in these bits: * 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)); lower_insn = (uint32_t)(*(uint16_t *)(addr + 2));
binfo("Performing THM_MOVx [%" PRId32 "] link " binfo("Performing THM_MOVx [%" PRId32 "] link "
"at addr=%08lx [%04x %04x] to sym=%p st_value=%08lx\n", "at addr=%08" PRIxPTR " [%04x %04x] to "
ELF32_R_TYPE(rel->r_info), (long)addr, "sym=%p st_value=%08" PRIx32 "\n",
ELF32_R_TYPE(rel->r_info), addr,
(int)upper_insn, (int)lower_insn, (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 */ /* 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; break;
case R_ARM_RELATIVE:
case R_ARM_JUMP_SLOT:
{
*(uint32_t *)addr = (uint32_t)sym->st_value;
}
break;
default: default:
berr("ERROR: Unsupported relocation: %" PRId32 "\n", berr("ERROR: Unsupported relocation: %" PRId32 "\n",
ELF32_R_TYPE(rel->r_info)); 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 .syntax unified
#include "acle-compat.h"
@ NOTE: This ifdef MUST match the one in memchr-stub.c @ NOTE: This ifdef MUST match the one in memchr-stub.c
#if defined (__ARM_NEON__) || defined (__ARM_NEON) #if defined (__ARM_NEON__) || defined (__ARM_NEON)
#if __ARM_ARCH >= 8 && __ARM_ARCH_PROFILE == 'R' #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(). */ /* This strcpy borrowed some ideas from arch_strcmp.S(). */
/* Parameters and result. */ /* Parameters and result. */
@ -304,3 +308,5 @@ offset_3:
.cpy_done: .cpy_done:
*dst++ = 0; *dst++ = 0;
#endif /* Pseudo code end */ #endif /* Pseudo code end */
#endif

View File

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