Messages in this thread Patch in this message | | | From | Emil Renner Berthing <> | Subject | [PATCH v1 7/7] riscv: kernel/modules.c simplification | Date | Mon, 31 Jan 2022 19:21:45 +0100 |
| |
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk> --- arch/riscv/kernel/module.c | 93 ++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 54 deletions(-)
diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c index 2212d88776e0..e371977aecfd 100644 --- a/arch/riscv/kernel/module.c +++ b/arch/riscv/kernel/module.c @@ -298,24 +298,23 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, unsigned int symindex, unsigned int relsec, struct module *me) { - Elf_Rela *rel = (void *) sechdrs[relsec].sh_addr; - int (*handler)(struct module *me, void *location, Elf_Addr v); - Elf_Sym *sym; - void *location; - unsigned int i, type; - Elf_Addr v; - int res; + Elf_Rela *rel = (void *)sechdrs[relsec].sh_addr; + unsigned int entries = sechdrs[relsec].sh_size / sizeof(*rel); + unsigned int i; pr_debug("Applying relocate section %u to %u\n", relsec, sechdrs[relsec].sh_info); - for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { - /* This is where to make the change */ - location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr - + rel[i].r_offset; - /* This is the symbol it is referring to */ - sym = (Elf_Sym *)sechdrs[symindex].sh_addr + for (i = 0; i < entries; i++) { + Elf_Sym *sym = (Elf_Sym *)sechdrs[symindex].sh_addr + ELF_RISCV_R_SYM(rel[i].r_info); + Elf_Addr loc = sechdrs[sechdrs[relsec].sh_info].sh_addr + + rel[i].r_offset; + unsigned int type = ELF_RISCV_R_TYPE(rel[i].r_info); + int (*handler)(struct module *me, void *location, Elf_Addr v); + Elf_Addr v; + int res; + if (IS_ERR_VALUE(sym->st_value)) { /* Ignore unresolved weak symbol */ if (ELF_ST_BIND(sym->st_info) == STB_WEAK) @@ -325,8 +324,6 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, return -ENOENT; } - type = ELF_RISCV_R_TYPE(rel[i].r_info); - if (type < ARRAY_SIZE(reloc_handlers_rela)) handler = reloc_handlers_rela[type]; else @@ -343,48 +340,36 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, if (type == R_RISCV_PCREL_LO12_I || type == R_RISCV_PCREL_LO12_S) { unsigned int j; - for (j = 0; j < sechdrs[relsec].sh_size / sizeof(*rel); j++) { - unsigned long hi20_loc = - sechdrs[sechdrs[relsec].sh_info].sh_addr + /* find the corresponding HI20 entry */ + for (j = 0; j < entries; j++) { + Elf_Sym *hi20_sym = (Elf_Sym *)sechdrs[symindex].sh_addr + + ELF_RISCV_R_SYM(rel[j].r_info); + Elf_Addr hi20_loc = sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[j].r_offset; - u32 hi20_type = ELF_RISCV_R_TYPE(rel[j].r_info); - - /* Find the corresponding HI20 relocation entry */ - if (hi20_loc == sym->st_value - && (hi20_type == R_RISCV_PCREL_HI20 - || hi20_type == R_RISCV_GOT_HI20)) { - s32 hi20, lo12; - Elf_Sym *hi20_sym = - (Elf_Sym *)sechdrs[symindex].sh_addr - + ELF_RISCV_R_SYM(rel[j].r_info); - unsigned long hi20_sym_val = - hi20_sym->st_value - + rel[j].r_addend; - - /* Calculate lo12 */ - size_t offset = hi20_sym_val - hi20_loc; - if (IS_ENABLED(CONFIG_MODULE_SECTIONS) - && hi20_type == R_RISCV_GOT_HI20) { - offset = module_emit_got_entry( - me, hi20_sym_val); - offset = offset - hi20_loc; - } - hi20 = (offset + 0x800) & 0xfffff000; - lo12 = offset - hi20; - v = lo12; - - break; - } - } - if (j == sechdrs[relsec].sh_size / sizeof(*rel)) { - pr_err( - "%s: Can not find HI20 relocation information\n", - me->name); - return -EINVAL; + unsigned int hi20_type = ELF_RISCV_R_TYPE(rel[j].r_info); + + if (hi20_loc != sym->st_value || + (hi20_type != R_RISCV_PCREL_HI20 && + hi20_type != R_RISCV_GOT_HI20)) + continue; + + /* calculate relative offset */ + v = hi20_sym->st_value + rel[j].r_addend; + + if (IS_ENABLED(CONFIG_MODULE_SECTIONS) && + hi20_type == R_RISCV_GOT_HI20) + v = module_emit_got_entry(me, v); + + v -= hi20_loc; + goto handle_reloc; } - } - res = handler(me, location, v); + pr_err("%s: Cannot find HI20 relocation information\n", + me->name); + return -EINVAL; + } +handle_reloc: + res = handler(me, (void *)loc, v); if (res) return res; } -- 2.35.1
| |