diff options
author | Zong Li <zong@andestech.com> | 2018-03-15 04:50:44 -0400 |
---|---|---|
committer | Palmer Dabbelt <palmer@sifive.com> | 2018-04-02 23:00:54 -0400 |
commit | e1910c72bdc405b5028510ccc3ed42f0ed25cc6c (patch) | |
tree | 7a4a2f38c8bc30bcb3fe237afa71f10099e5bf99 | |
parent | da975dd4818cf42a181910789c096eb6997ed663 (diff) |
RISC-V: Support CALL relocation type in kernel module
Signed-off-by: Zong Li <zong@andestech.com>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
-rw-r--r-- | arch/riscv/kernel/module.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c index be717bd7cea7..3f2730840c25 100644 --- a/arch/riscv/kernel/module.c +++ b/arch/riscv/kernel/module.c | |||
@@ -141,6 +141,27 @@ static int apply_r_riscv_call_plt_rela(struct module *me, u32 *location, | |||
141 | return 0; | 141 | return 0; |
142 | } | 142 | } |
143 | 143 | ||
144 | static int apply_r_riscv_call_rela(struct module *me, u32 *location, | ||
145 | Elf_Addr v) | ||
146 | { | ||
147 | s64 offset = (void *)v - (void *)location; | ||
148 | s32 fill_v = offset; | ||
149 | u32 hi20, lo12; | ||
150 | |||
151 | if (offset != fill_v) { | ||
152 | pr_err( | ||
153 | "%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n", | ||
154 | me->name, v, location); | ||
155 | return -EINVAL; | ||
156 | } | ||
157 | |||
158 | hi20 = (offset + 0x800) & 0xfffff000; | ||
159 | lo12 = (offset - hi20) & 0xfff; | ||
160 | *location = (*location & 0xfff) | hi20; | ||
161 | *(location + 1) = (*(location + 1) & 0xfffff) | (lo12 << 20); | ||
162 | return 0; | ||
163 | } | ||
164 | |||
144 | static int apply_r_riscv_relax_rela(struct module *me, u32 *location, | 165 | static int apply_r_riscv_relax_rela(struct module *me, u32 *location, |
145 | Elf_Addr v) | 166 | Elf_Addr v) |
146 | { | 167 | { |
@@ -157,6 +178,7 @@ static int (*reloc_handlers_rela[]) (struct module *me, u32 *location, | |||
157 | [R_RISCV_PCREL_LO12_S] = apply_r_riscv_pcrel_lo12_s_rela, | 178 | [R_RISCV_PCREL_LO12_S] = apply_r_riscv_pcrel_lo12_s_rela, |
158 | [R_RISCV_GOT_HI20] = apply_r_riscv_got_hi20_rela, | 179 | [R_RISCV_GOT_HI20] = apply_r_riscv_got_hi20_rela, |
159 | [R_RISCV_CALL_PLT] = apply_r_riscv_call_plt_rela, | 180 | [R_RISCV_CALL_PLT] = apply_r_riscv_call_plt_rela, |
181 | [R_RISCV_CALL] = apply_r_riscv_call_rela, | ||
160 | [R_RISCV_RELAX] = apply_r_riscv_relax_rela, | 182 | [R_RISCV_RELAX] = apply_r_riscv_relax_rela, |
161 | }; | 183 | }; |
162 | 184 | ||