Skip to content

Commit 326eeec

Browse files
authored
Add new cases in ARC relocation of AOT (#4653)
* add new case for arc relocation. R_ARC_S21H_PCREL, R_ARC_S21W_PCREL
1 parent fbef624 commit 326eeec

File tree

1 file changed

+76
-2
lines changed

1 file changed

+76
-2
lines changed

core/iwasm/aot/arch/aot_reloc_arc.c

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,80 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
310310
int32 symbol_index, char *error_buf, uint32 error_buf_size)
311311
{
312312
switch (reloc_type) {
313+
case R_ARC_S21H_PCREL:
314+
{
315+
uint32 insn = LOAD_I32(target_section_addr + reloc_offset);
316+
int32 addend, value;
317+
uintptr_t S, P;
318+
intptr_t A;
319+
320+
CHECK_RELOC_OFFSET(sizeof(void *));
321+
322+
/* Convert from middle endian */
323+
insn = middle_endian_convert(insn);
324+
325+
/* Extract the first 10 bits from Position 6 to 15 in insn */
326+
addend = (insn << 16) >> 22;
327+
addend = addend << 10;
328+
/* Extract the remaining 10 bits from Position 17 to 26 in insn */
329+
addend |= ((insn << 5) >> 22);
330+
/* Fill in 1 bits to get the 21 bit Offset Value */
331+
addend = addend << 1;
332+
333+
/* (S + A) - P */
334+
S = (uintptr_t)(uint8 *)symbol_addr;
335+
A = (intptr_t)reloc_addend;
336+
P = (uintptr_t)(target_section_addr + reloc_offset);
337+
P &= (uintptr_t)~1;
338+
value = (int32)(S + A + addend - P);
339+
340+
insn = insn & 0xf801003f;
341+
insn |= ((((value >> 1) & 0x3ff) << 17)
342+
| (((value >> 1) & 0xffc00) >> 4));
343+
344+
/* Convert to middle endian */
345+
insn = middle_endian_convert(insn);
346+
347+
STORE_U32(target_section_addr + reloc_offset, insn);
348+
break;
349+
}
350+
case R_ARC_S21W_PCREL:
351+
{
352+
uint32 insn = LOAD_I32(target_section_addr + reloc_offset);
353+
int32 addend, value;
354+
uintptr_t S, P;
355+
intptr_t A;
356+
357+
CHECK_RELOC_OFFSET(sizeof(void *));
358+
359+
/* Convert from middle endian */
360+
insn = middle_endian_convert(insn);
361+
362+
/* Extract the first 10 bits from Position 6 to 15 in insn */
363+
addend = (insn << 16) >> 22;
364+
addend = addend << 9;
365+
/* Extract the remaining 9 bits from Position 18 to 26 in insn */
366+
addend |= ((insn << 5) >> 23);
367+
/* Fill in 2 bits to get the 21 bit Offset Value */
368+
addend = addend << 2;
369+
370+
/* (S + A) - P */
371+
S = (uintptr_t)(uint8 *)symbol_addr;
372+
A = (intptr_t)reloc_addend;
373+
P = (uintptr_t)(target_section_addr + reloc_offset);
374+
P &= (uintptr_t)~3;
375+
value = (int32)(S + A + addend - P);
376+
377+
insn = insn & 0xf803003f;
378+
insn |= ((((value >> 2) & 0x1ff) << 18)
379+
| (((value >> 2) & 0x7fe00) >> 3));
380+
381+
/* Convert to middle endian */
382+
insn = middle_endian_convert(insn);
383+
384+
STORE_U32(target_section_addr + reloc_offset, insn);
385+
break;
386+
}
313387
case R_ARC_S25H_PCREL:
314388
{
315389
uint32 insn = LOAD_I32(target_section_addr + reloc_offset);
@@ -340,8 +414,8 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
340414

341415
insn = insn & 0xf8010030;
342416
insn |= ((((value >> 1) & 0x3ff) << 17)
343-
| (((value >> 1) & 0xffc00) >> 3)
344-
| (((value >> 1) & 0xf00000) >> 19));
417+
| (((value >> 1) & 0xffc00) >> 4)
418+
| (((value >> 1) & 0xf00000) >> 20));
345419

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

0 commit comments

Comments
 (0)