Skip to content

Commit

Permalink
Support LLVM linked ELF executable
Browse files Browse the repository at this point in the history
  • Loading branch information
TAiGA committed Aug 27, 2024
1 parent a6df724 commit 3409eeb
Showing 1 changed file with 82 additions and 15 deletions.
97 changes: 82 additions & 15 deletions libs/libc/machine/risc-v/arch_elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,19 @@ static const char *_get_rname(int type)
return "?????";
}

/****************************************************************************
* Name: _extract_bits
*
* Description:
* Copied from ELF_riscv.cpp (LLVM)
*
****************************************************************************/

static uint32_t _extract_bits(uint32_t num, int low, int size)
{
return (num & (((1 << size) - 1) << low)) >> low;
}

/****************************************************************************
* Name: _get_val, set_val, _add_val
*
Expand Down Expand Up @@ -562,11 +575,21 @@ int up_relocateadd(const Elf_Rela *rel, const Elf_Sym *sym,

/* NOTE: we assume that a compiler adds an immediate value */

ASSERT(offset && val);
if (offset != 0 && val == 0)
{
uint32_t imm12 = _extract_bits(offset, 12, 1) << 31;
uint32_t imm10_5 = _extract_bits(offset, 5, 6) << 25;
uint32_t imm4_1 = _extract_bits(offset, 1, 4) << 8;
uint32_t imm11 = _extract_bits(offset, 11, 1) << 7;

binfo("offset for Bx=%ld (0x%lx) (val=0x%08" PRIx32 ") "
"already set!\n",
offset, offset, val);
_add_val((uint16_t *)addr, imm12 | imm10_5 | imm4_1 | imm11);
}
else
{
binfo("offset for Bx=%ld (0x%lx) (val=0x%08" PRIx32 ") "
"already set!\n",
offset, offset, val);
}
}
break;

Expand All @@ -583,13 +606,23 @@ int up_relocateadd(const Elf_Rela *rel, const Elf_Sym *sym,
offset = (long)sym->st_value + (long)rel->r_addend - (long)addr;
uint32_t val = _get_val((uint16_t *)addr) & 0xfffff000;

ASSERT(offset && val);

/* NOTE: we assume that a compiler adds an immediate value */

binfo("offset for JAL=%ld (0x%lx) (val=0x%08" PRIx32 ") "
"already set!\n",
offset, offset, val);
if (offset != 0 && val == 0)
{
uint32_t imm20 = _extract_bits(offset, 20, 1) << 31;
uint32_t imm10_1 = _extract_bits(offset, 1, 10) << 21;
uint32_t imm11 = _extract_bits(offset, 11, 1) << 20;
uint32_t imm19_12 = _extract_bits(offset, 12, 8) << 12;

_add_val((uint16_t *)addr, imm20 | imm10_1 | imm11 | imm19_12);
}
else
{
binfo("offset for JAL=%ld (0x%lx) (val=0x%08" PRIx32 ") "
"already set!\n",
offset, offset, val);
}
}
break;

Expand Down Expand Up @@ -692,8 +725,29 @@ int up_relocateadd(const Elf_Rela *rel, const Elf_Sym *sym,

uint16_t val = (*(uint16_t *)addr) & 0x1ffc;

binfo("offset for C.J=%ld (0x%lx) (val=0x%04x) already set!\n",
offset, offset, val);
/* NOTE: we assume that a compiler adds an immediate value */

if (offset != 0 && val == 0)
{
uint16_t imm11 = _extract_bits(offset, 11, 1) << 12;
uint16_t imm4 = _extract_bits(offset, 4, 1) << 11;
uint16_t imm9_8 = _extract_bits(offset, 8, 2) << 9;
uint16_t imm10 = _extract_bits(offset, 10, 1) << 8;
uint16_t imm6 = _extract_bits(offset, 6, 1) << 7;
uint16_t imm7 = _extract_bits(offset, 7, 1) << 6;
uint16_t imm3_1 = _extract_bits(offset, 1, 3) << 3;
uint16_t imm5 = _extract_bits(offset, 5, 1) << 2;

_add_val((uint16_t *)addr,
imm11 | imm4 | imm9_8 | imm10 |
imm6 | imm7 | imm3_1 | imm5);
}
else
{
binfo("offset for C.J=%ld (0x%lx) (val=0x%04x) "
"already set!\n",
offset, offset, val);
}
}
break;

Expand All @@ -714,10 +768,23 @@ int up_relocateadd(const Elf_Rela *rel, const Elf_Sym *sym,

/* NOTE: we assume that a compiler adds an immediate value */

ASSERT(offset && val);

binfo("offset for C.Bx=%ld (0x%lx) (val=0x%04x) already set!\n",
offset, offset, val);
if (offset != 0 && val == 0)
{
uint16_t imm8 = _extract_bits(offset, 8, 1) << 12;
uint16_t imm4_3 = _extract_bits(offset, 3, 2) << 10;
uint16_t imm7_6 = _extract_bits(offset, 6, 2) << 5;
uint16_t imm2_1 = _extract_bits(offset, 1, 2) << 3;
uint16_t imm5 = _extract_bits(offset, 5, 1) << 2;

_add_val((uint16_t *)addr,
imm8 | imm4_3 | imm7_6 | imm2_1 | imm5);
}
else
{
binfo("offset for C.Bx=%ld (0x%lx) (val=0x%04x) "
"already set!\n",
offset, offset, val);
}
}
break;
case R_RISCV_32_PCREL:
Expand Down

0 comments on commit 3409eeb

Please sign in to comment.