mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-30 14:19:16 +00:00
riscv: Avoid unaligned access when relocating modules
With the C-extension regular 32bit instructions are not necessarily aligned on 4-byte boundaries. RISC-V instructions are in fact an ordered list of 16bit little-endian "parcels", so access the instruction as such. This should also make the code work in case someone builds a big-endian RISC-V machine. Signed-off-by: Emil Renner Berthing <kernel@esmil.dk> Signed-off-by: Charlie Jenkins <charlie@rivosinc.com> Link: https://lore.kernel.org/r/20231101-module_relocations-v9-1-8dfa3483c400@rivosinc.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
parent
0bb80ecc33
commit
8cbe0accc4
1 changed files with 81 additions and 76 deletions
|
@ -27,68 +27,90 @@ static bool riscv_insn_valid_32bit_offset(ptrdiff_t val)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_32_rela(struct module *me, u32 *location, Elf_Addr v)
|
static int riscv_insn_rmw(void *location, u32 keep, u32 set)
|
||||||
|
{
|
||||||
|
u16 *parcel = location;
|
||||||
|
u32 insn = (u32)le16_to_cpu(parcel[0]) | (u32)le16_to_cpu(parcel[1]) << 16;
|
||||||
|
|
||||||
|
insn &= keep;
|
||||||
|
insn |= set;
|
||||||
|
|
||||||
|
parcel[0] = cpu_to_le16(insn);
|
||||||
|
parcel[1] = cpu_to_le16(insn >> 16);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int riscv_insn_rvc_rmw(void *location, u16 keep, u16 set)
|
||||||
|
{
|
||||||
|
u16 *parcel = location;
|
||||||
|
u16 insn = le16_to_cpu(*parcel);
|
||||||
|
|
||||||
|
insn &= keep;
|
||||||
|
insn |= set;
|
||||||
|
|
||||||
|
*parcel = cpu_to_le16(insn);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int apply_r_riscv_32_rela(struct module *me, void *location, Elf_Addr v)
|
||||||
{
|
{
|
||||||
if (v != (u32)v) {
|
if (v != (u32)v) {
|
||||||
pr_err("%s: value %016llx out of range for 32-bit field\n",
|
pr_err("%s: value %016llx out of range for 32-bit field\n",
|
||||||
me->name, (long long)v);
|
me->name, (long long)v);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
*location = v;
|
*(u32 *)location = v;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_64_rela(struct module *me, u32 *location, Elf_Addr v)
|
static int apply_r_riscv_64_rela(struct module *me, void *location, Elf_Addr v)
|
||||||
{
|
{
|
||||||
*(u64 *)location = v;
|
*(u64 *)location = v;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_branch_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_branch_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
ptrdiff_t offset = (void *)v - (void *)location;
|
ptrdiff_t offset = (void *)v - location;
|
||||||
u32 imm12 = (offset & 0x1000) << (31 - 12);
|
u32 imm12 = (offset & 0x1000) << (31 - 12);
|
||||||
u32 imm11 = (offset & 0x800) >> (11 - 7);
|
u32 imm11 = (offset & 0x800) >> (11 - 7);
|
||||||
u32 imm10_5 = (offset & 0x7e0) << (30 - 10);
|
u32 imm10_5 = (offset & 0x7e0) << (30 - 10);
|
||||||
u32 imm4_1 = (offset & 0x1e) << (11 - 4);
|
u32 imm4_1 = (offset & 0x1e) << (11 - 4);
|
||||||
|
|
||||||
*location = (*location & 0x1fff07f) | imm12 | imm11 | imm10_5 | imm4_1;
|
return riscv_insn_rmw(location, 0x1fff07f, imm12 | imm11 | imm10_5 | imm4_1);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_jal_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_jal_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
ptrdiff_t offset = (void *)v - (void *)location;
|
ptrdiff_t offset = (void *)v - location;
|
||||||
u32 imm20 = (offset & 0x100000) << (31 - 20);
|
u32 imm20 = (offset & 0x100000) << (31 - 20);
|
||||||
u32 imm19_12 = (offset & 0xff000);
|
u32 imm19_12 = (offset & 0xff000);
|
||||||
u32 imm11 = (offset & 0x800) << (20 - 11);
|
u32 imm11 = (offset & 0x800) << (20 - 11);
|
||||||
u32 imm10_1 = (offset & 0x7fe) << (30 - 10);
|
u32 imm10_1 = (offset & 0x7fe) << (30 - 10);
|
||||||
|
|
||||||
*location = (*location & 0xfff) | imm20 | imm19_12 | imm11 | imm10_1;
|
return riscv_insn_rmw(location, 0xfff, imm20 | imm19_12 | imm11 | imm10_1);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_rvc_branch_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_rvc_branch_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
ptrdiff_t offset = (void *)v - (void *)location;
|
ptrdiff_t offset = (void *)v - location;
|
||||||
u16 imm8 = (offset & 0x100) << (12 - 8);
|
u16 imm8 = (offset & 0x100) << (12 - 8);
|
||||||
u16 imm7_6 = (offset & 0xc0) >> (6 - 5);
|
u16 imm7_6 = (offset & 0xc0) >> (6 - 5);
|
||||||
u16 imm5 = (offset & 0x20) >> (5 - 2);
|
u16 imm5 = (offset & 0x20) >> (5 - 2);
|
||||||
u16 imm4_3 = (offset & 0x18) << (12 - 5);
|
u16 imm4_3 = (offset & 0x18) << (12 - 5);
|
||||||
u16 imm2_1 = (offset & 0x6) << (12 - 10);
|
u16 imm2_1 = (offset & 0x6) << (12 - 10);
|
||||||
|
|
||||||
*(u16 *)location = (*(u16 *)location & 0xe383) |
|
return riscv_insn_rvc_rmw(location, 0xe383,
|
||||||
imm8 | imm7_6 | imm5 | imm4_3 | imm2_1;
|
imm8 | imm7_6 | imm5 | imm4_3 | imm2_1);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_rvc_jump_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_rvc_jump_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
ptrdiff_t offset = (void *)v - (void *)location;
|
ptrdiff_t offset = (void *)v - location;
|
||||||
u16 imm11 = (offset & 0x800) << (12 - 11);
|
u16 imm11 = (offset & 0x800) << (12 - 11);
|
||||||
u16 imm10 = (offset & 0x400) >> (10 - 8);
|
u16 imm10 = (offset & 0x400) >> (10 - 8);
|
||||||
u16 imm9_8 = (offset & 0x300) << (12 - 11);
|
u16 imm9_8 = (offset & 0x300) << (12 - 11);
|
||||||
|
@ -98,16 +120,14 @@ static int apply_r_riscv_rvc_jump_rela(struct module *me, u32 *location,
|
||||||
u16 imm4 = (offset & 0x10) << (12 - 5);
|
u16 imm4 = (offset & 0x10) << (12 - 5);
|
||||||
u16 imm3_1 = (offset & 0xe) << (12 - 10);
|
u16 imm3_1 = (offset & 0xe) << (12 - 10);
|
||||||
|
|
||||||
*(u16 *)location = (*(u16 *)location & 0xe003) |
|
return riscv_insn_rvc_rmw(location, 0xe003,
|
||||||
imm11 | imm10 | imm9_8 | imm7 | imm6 | imm5 | imm4 | imm3_1;
|
imm11 | imm10 | imm9_8 | imm7 | imm6 | imm5 | imm4 | imm3_1);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_pcrel_hi20_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_pcrel_hi20_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
ptrdiff_t offset = (void *)v - (void *)location;
|
ptrdiff_t offset = (void *)v - location;
|
||||||
s32 hi20;
|
|
||||||
|
|
||||||
if (!riscv_insn_valid_32bit_offset(offset)) {
|
if (!riscv_insn_valid_32bit_offset(offset)) {
|
||||||
pr_err(
|
pr_err(
|
||||||
|
@ -116,23 +136,20 @@ static int apply_r_riscv_pcrel_hi20_rela(struct module *me, u32 *location,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
hi20 = (offset + 0x800) & 0xfffff000;
|
return riscv_insn_rmw(location, 0xfff, (offset + 0x800) & 0xfffff000);
|
||||||
*location = (*location & 0xfff) | hi20;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_pcrel_lo12_i_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_pcrel_lo12_i_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* v is the lo12 value to fill. It is calculated before calling this
|
* v is the lo12 value to fill. It is calculated before calling this
|
||||||
* handler.
|
* handler.
|
||||||
*/
|
*/
|
||||||
*location = (*location & 0xfffff) | ((v & 0xfff) << 20);
|
return riscv_insn_rmw(location, 0xfffff, (v & 0xfff) << 20);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_pcrel_lo12_s_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_pcrel_lo12_s_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -142,15 +159,12 @@ static int apply_r_riscv_pcrel_lo12_s_rela(struct module *me, u32 *location,
|
||||||
u32 imm11_5 = (v & 0xfe0) << (31 - 11);
|
u32 imm11_5 = (v & 0xfe0) << (31 - 11);
|
||||||
u32 imm4_0 = (v & 0x1f) << (11 - 4);
|
u32 imm4_0 = (v & 0x1f) << (11 - 4);
|
||||||
|
|
||||||
*location = (*location & 0x1fff07f) | imm11_5 | imm4_0;
|
return riscv_insn_rmw(location, 0x1fff07f, imm11_5 | imm4_0);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_hi20_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_hi20_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
s32 hi20;
|
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_CMODEL_MEDLOW)) {
|
if (IS_ENABLED(CONFIG_CMODEL_MEDLOW)) {
|
||||||
pr_err(
|
pr_err(
|
||||||
"%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n",
|
"%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n",
|
||||||
|
@ -158,22 +172,20 @@ static int apply_r_riscv_hi20_rela(struct module *me, u32 *location,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
hi20 = ((s32)v + 0x800) & 0xfffff000;
|
return riscv_insn_rmw(location, 0xfff, ((s32)v + 0x800) & 0xfffff000);
|
||||||
*location = (*location & 0xfff) | hi20;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_lo12_i_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_lo12_i_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
/* Skip medlow checking because of filtering by HI20 already */
|
/* Skip medlow checking because of filtering by HI20 already */
|
||||||
s32 hi20 = ((s32)v + 0x800) & 0xfffff000;
|
s32 hi20 = ((s32)v + 0x800) & 0xfffff000;
|
||||||
s32 lo12 = ((s32)v - hi20);
|
s32 lo12 = ((s32)v - hi20);
|
||||||
*location = (*location & 0xfffff) | ((lo12 & 0xfff) << 20);
|
|
||||||
return 0;
|
return riscv_insn_rmw(location, 0xfffff, (lo12 & 0xfff) << 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_lo12_s_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_lo12_s_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
/* Skip medlow checking because of filtering by HI20 already */
|
/* Skip medlow checking because of filtering by HI20 already */
|
||||||
|
@ -181,20 +193,18 @@ static int apply_r_riscv_lo12_s_rela(struct module *me, u32 *location,
|
||||||
s32 lo12 = ((s32)v - hi20);
|
s32 lo12 = ((s32)v - hi20);
|
||||||
u32 imm11_5 = (lo12 & 0xfe0) << (31 - 11);
|
u32 imm11_5 = (lo12 & 0xfe0) << (31 - 11);
|
||||||
u32 imm4_0 = (lo12 & 0x1f) << (11 - 4);
|
u32 imm4_0 = (lo12 & 0x1f) << (11 - 4);
|
||||||
*location = (*location & 0x1fff07f) | imm11_5 | imm4_0;
|
|
||||||
return 0;
|
return riscv_insn_rmw(location, 0x1fff07f, imm11_5 | imm4_0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_got_hi20_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_got_hi20_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
ptrdiff_t offset = (void *)v - (void *)location;
|
ptrdiff_t offset = (void *)v - location;
|
||||||
s32 hi20;
|
|
||||||
|
|
||||||
/* Always emit the got entry */
|
/* Always emit the got entry */
|
||||||
if (IS_ENABLED(CONFIG_MODULE_SECTIONS)) {
|
if (IS_ENABLED(CONFIG_MODULE_SECTIONS)) {
|
||||||
offset = module_emit_got_entry(me, v);
|
offset = (void *)module_emit_got_entry(me, v) - location;
|
||||||
offset = (void *)offset - (void *)location;
|
|
||||||
} else {
|
} else {
|
||||||
pr_err(
|
pr_err(
|
||||||
"%s: can not generate the GOT entry for symbol = %016llx from PC = %p\n",
|
"%s: can not generate the GOT entry for symbol = %016llx from PC = %p\n",
|
||||||
|
@ -202,22 +212,19 @@ static int apply_r_riscv_got_hi20_rela(struct module *me, u32 *location,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
hi20 = (offset + 0x800) & 0xfffff000;
|
return riscv_insn_rmw(location, 0xfff, (offset + 0x800) & 0xfffff000);
|
||||||
*location = (*location & 0xfff) | hi20;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_call_plt_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_call_plt_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
ptrdiff_t offset = (void *)v - (void *)location;
|
ptrdiff_t offset = (void *)v - location;
|
||||||
u32 hi20, lo12;
|
u32 hi20, lo12;
|
||||||
|
|
||||||
if (!riscv_insn_valid_32bit_offset(offset)) {
|
if (!riscv_insn_valid_32bit_offset(offset)) {
|
||||||
/* Only emit the plt entry if offset over 32-bit range */
|
/* Only emit the plt entry if offset over 32-bit range */
|
||||||
if (IS_ENABLED(CONFIG_MODULE_SECTIONS)) {
|
if (IS_ENABLED(CONFIG_MODULE_SECTIONS)) {
|
||||||
offset = module_emit_plt_entry(me, v);
|
offset = (void *)module_emit_plt_entry(me, v) - location;
|
||||||
offset = (void *)offset - (void *)location;
|
|
||||||
} else {
|
} else {
|
||||||
pr_err(
|
pr_err(
|
||||||
"%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n",
|
"%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n",
|
||||||
|
@ -228,15 +235,14 @@ static int apply_r_riscv_call_plt_rela(struct module *me, u32 *location,
|
||||||
|
|
||||||
hi20 = (offset + 0x800) & 0xfffff000;
|
hi20 = (offset + 0x800) & 0xfffff000;
|
||||||
lo12 = (offset - hi20) & 0xfff;
|
lo12 = (offset - hi20) & 0xfff;
|
||||||
*location = (*location & 0xfff) | hi20;
|
riscv_insn_rmw(location, 0xfff, hi20);
|
||||||
*(location + 1) = (*(location + 1) & 0xfffff) | (lo12 << 20);
|
return riscv_insn_rmw(location + 4, 0xfffff, lo12 << 20);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_call_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_call_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
ptrdiff_t offset = (void *)v - (void *)location;
|
ptrdiff_t offset = (void *)v - location;
|
||||||
u32 hi20, lo12;
|
u32 hi20, lo12;
|
||||||
|
|
||||||
if (!riscv_insn_valid_32bit_offset(offset)) {
|
if (!riscv_insn_valid_32bit_offset(offset)) {
|
||||||
|
@ -248,18 +254,17 @@ static int apply_r_riscv_call_rela(struct module *me, u32 *location,
|
||||||
|
|
||||||
hi20 = (offset + 0x800) & 0xfffff000;
|
hi20 = (offset + 0x800) & 0xfffff000;
|
||||||
lo12 = (offset - hi20) & 0xfff;
|
lo12 = (offset - hi20) & 0xfff;
|
||||||
*location = (*location & 0xfff) | hi20;
|
riscv_insn_rmw(location, 0xfff, hi20);
|
||||||
*(location + 1) = (*(location + 1) & 0xfffff) | (lo12 << 20);
|
return riscv_insn_rmw(location + 4, 0xfffff, lo12 << 20);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_relax_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_relax_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_align_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_align_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
pr_err(
|
pr_err(
|
||||||
|
@ -268,49 +273,49 @@ static int apply_r_riscv_align_rela(struct module *me, u32 *location,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_add16_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_add16_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
*(u16 *)location += (u16)v;
|
*(u16 *)location += (u16)v;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_add32_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_add32_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
*(u32 *)location += (u32)v;
|
*(u32 *)location += (u32)v;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_add64_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_add64_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
*(u64 *)location += (u64)v;
|
*(u64 *)location += (u64)v;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_sub16_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_sub16_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
*(u16 *)location -= (u16)v;
|
*(u16 *)location -= (u16)v;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_sub32_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_sub32_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
*(u32 *)location -= (u32)v;
|
*(u32 *)location -= (u32)v;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apply_r_riscv_sub64_rela(struct module *me, u32 *location,
|
static int apply_r_riscv_sub64_rela(struct module *me, void *location,
|
||||||
Elf_Addr v)
|
Elf_Addr v)
|
||||||
{
|
{
|
||||||
*(u64 *)location -= (u64)v;
|
*(u64 *)location -= (u64)v;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int (*reloc_handlers_rela[]) (struct module *me, u32 *location,
|
static int (*reloc_handlers_rela[]) (struct module *me, void *location,
|
||||||
Elf_Addr v) = {
|
Elf_Addr v) = {
|
||||||
[R_RISCV_32] = apply_r_riscv_32_rela,
|
[R_RISCV_32] = apply_r_riscv_32_rela,
|
||||||
[R_RISCV_64] = apply_r_riscv_64_rela,
|
[R_RISCV_64] = apply_r_riscv_64_rela,
|
||||||
|
@ -342,9 +347,9 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
|
||||||
struct module *me)
|
struct module *me)
|
||||||
{
|
{
|
||||||
Elf_Rela *rel = (void *) sechdrs[relsec].sh_addr;
|
Elf_Rela *rel = (void *) sechdrs[relsec].sh_addr;
|
||||||
int (*handler)(struct module *me, u32 *location, Elf_Addr v);
|
int (*handler)(struct module *me, void *location, Elf_Addr v);
|
||||||
Elf_Sym *sym;
|
Elf_Sym *sym;
|
||||||
u32 *location;
|
void *location;
|
||||||
unsigned int i, type;
|
unsigned int i, type;
|
||||||
Elf_Addr v;
|
Elf_Addr v;
|
||||||
int res;
|
int res;
|
||||||
|
|
Loading…
Reference in a new issue