Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 76 additions & 2 deletions core/iwasm/aot/arch/aot_reloc_arc.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,80 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
int32 symbol_index, char *error_buf, uint32 error_buf_size)
{
switch (reloc_type) {
case R_ARC_S21H_PCREL:
{
uint32 insn = LOAD_I32(target_section_addr + reloc_offset);
int32 addend, value;
uintptr_t S, P;
intptr_t A;

CHECK_RELOC_OFFSET(sizeof(void *));

/* Convert from middle endian */
insn = middle_endian_convert(insn);

/* Extract the first 10 bits from Position 6 to 15 in insn */
addend = (insn << 16) >> 22;
addend = addend << 10;
/* Extract the remaining 10 bits from Position 17 to 26 in insn */
addend |= ((insn << 5) >> 22);
/* Fill in 1 bits to get the 21 bit Offset Value */
addend = addend << 1;

/* (S + A) - P */
S = (uintptr_t)(uint8 *)symbol_addr;
A = (intptr_t)reloc_addend;
P = (uintptr_t)(target_section_addr + reloc_offset);
P &= (uintptr_t)~1;
value = (int32)(S + A + addend - P);

insn = insn & 0xf801003f;
insn |= ((((value >> 1) & 0x3ff) << 17)
| (((value >> 1) & 0xffc00) >> 4));

/* Convert to middle endian */
insn = middle_endian_convert(insn);

STORE_U32(target_section_addr + reloc_offset, insn);
break;
}
case R_ARC_S21W_PCREL:
{
uint32 insn = LOAD_I32(target_section_addr + reloc_offset);
int32 addend, value;
uintptr_t S, P;
intptr_t A;

CHECK_RELOC_OFFSET(sizeof(void *));

/* Convert from middle endian */
insn = middle_endian_convert(insn);

/* Extract the first 10 bits from Position 6 to 15 in insn */
addend = (insn << 16) >> 22;
addend = addend << 9;
/* Extract the remaining 9 bits from Position 18 to 26 in insn */
addend |= ((insn << 5) >> 23);
/* Fill in 2 bits to get the 21 bit Offset Value */
addend = addend << 2;

/* (S + A) - P */
S = (uintptr_t)(uint8 *)symbol_addr;
A = (intptr_t)reloc_addend;
P = (uintptr_t)(target_section_addr + reloc_offset);
P &= (uintptr_t)~3;
value = (int32)(S + A + addend - P);

insn = insn & 0xf803003f;
insn |= ((((value >> 2) & 0x1ff) << 18)
| (((value >> 2) & 0x7fe00) >> 3));

/* Convert to middle endian */
insn = middle_endian_convert(insn);

STORE_U32(target_section_addr + reloc_offset, insn);
break;
}
case R_ARC_S25H_PCREL:
{
uint32 insn = LOAD_I32(target_section_addr + reloc_offset);
Expand Down Expand Up @@ -340,8 +414,8 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,

insn = insn & 0xf8010030;
insn |= ((((value >> 1) & 0x3ff) << 17)
| (((value >> 1) & 0xffc00) >> 3)
| (((value >> 1) & 0xf00000) >> 19));
| (((value >> 1) & 0xffc00) >> 4)
| (((value >> 1) & 0xf00000) >> 20));

/* Convert to middle endian */
insn = middle_endian_convert(insn);
Expand Down
Loading