Lines Matching +full:lower +full:- +full:case

1 // SPDX-License-Identifier: GPL-2.0-only
77 Elf32_Shdr *dstsec = sechdrs + relsec->sh_info; in apply_relocate()
78 Elf32_Rel *rel = (void *)relsec->sh_addr; in apply_relocate()
81 for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++, rel++) { in apply_relocate()
88 u32 upper, lower, sign, j1, j2; in apply_relocate() local
91 offset = ELF32_R_SYM(rel->r_info); in apply_relocate()
92 if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) { in apply_relocate()
94 module->name, relindex, i); in apply_relocate()
95 return -ENOEXEC; in apply_relocate()
98 sym = ((Elf32_Sym *)symsec->sh_addr) + offset; in apply_relocate()
99 symname = strtab + sym->st_name; in apply_relocate()
101 if (rel->r_offset < 0 || rel->r_offset > dstsec->sh_size - sizeof(u32)) { in apply_relocate()
103 module->name, relindex, i, symname, in apply_relocate()
104 rel->r_offset, dstsec->sh_size); in apply_relocate()
105 return -ENOEXEC; in apply_relocate()
108 loc = dstsec->sh_addr + rel->r_offset; in apply_relocate()
110 switch (ELF32_R_TYPE(rel->r_info)) { in apply_relocate()
111 case R_ARM_NONE: in apply_relocate()
115 case R_ARM_ABS32: in apply_relocate()
116 case R_ARM_TARGET1: in apply_relocate()
117 *(u32 *)loc += sym->st_value; in apply_relocate()
120 case R_ARM_PC24: in apply_relocate()
121 case R_ARM_CALL: in apply_relocate()
122 case R_ARM_JUMP24: in apply_relocate()
123 if (sym->st_value & 3) { in apply_relocate()
124 pr_err("%s: section %u reloc %u sym '%s': unsupported interworking call (ARM -> Thumb)\n", in apply_relocate()
125 module->name, relindex, i, symname); in apply_relocate()
126 return -ENOEXEC; in apply_relocate()
132 offset -= 0x04000000; in apply_relocate()
134 offset += sym->st_value - loc; in apply_relocate()
147 - loc - 8; in apply_relocate()
151 pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n", in apply_relocate()
152 module->name, relindex, i, symname, in apply_relocate()
153 ELF32_R_TYPE(rel->r_info), loc, in apply_relocate()
154 sym->st_value); in apply_relocate()
155 return -ENOEXEC; in apply_relocate()
165 case R_ARM_V4BX: in apply_relocate()
167 * other bits to re-code instruction as in apply_relocate()
174 case R_ARM_PREL31: in apply_relocate()
176 offset += sym->st_value - loc; in apply_relocate()
177 if (offset >= 0x40000000 || offset < -0x40000000) { in apply_relocate()
178 pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n", in apply_relocate()
179 module->name, relindex, i, symname, in apply_relocate()
180 ELF32_R_TYPE(rel->r_info), loc, in apply_relocate()
181 sym->st_value); in apply_relocate()
182 return -ENOEXEC; in apply_relocate()
188 case R_ARM_REL32: in apply_relocate()
189 *(u32 *)loc += sym->st_value - loc; in apply_relocate()
192 case R_ARM_MOVW_ABS_NC: in apply_relocate()
193 case R_ARM_MOVT_ABS: in apply_relocate()
194 case R_ARM_MOVW_PREL_NC: in apply_relocate()
195 case R_ARM_MOVT_PREL: in apply_relocate()
198 offset = (offset ^ 0x8000) - 0x8000; in apply_relocate()
200 offset += sym->st_value; in apply_relocate()
201 if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_PREL || in apply_relocate()
202 ELF32_R_TYPE(rel->r_info) == R_ARM_MOVW_PREL_NC) in apply_relocate()
203 offset -= loc; in apply_relocate()
204 if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS || in apply_relocate()
205 ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_PREL) in apply_relocate()
216 case R_ARM_THM_CALL: in apply_relocate()
217 case R_ARM_THM_JUMP24: in apply_relocate()
222 * For non-function symbols, the destination in apply_relocate()
227 if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && in apply_relocate()
228 !(sym->st_value & 1)) { in apply_relocate()
229 pr_err("%s: section %u reloc %u sym '%s': unsupported interworking call (Thumb -> ARM)\n", in apply_relocate()
230 module->name, relindex, i, symname); in apply_relocate()
231 return -ENOEXEC; in apply_relocate()
235 lower = __mem_to_opcode_thumb16(*(u16 *)(loc + 2)); in apply_relocate()
238 * 25 bit signed address range (Thumb-2 BL and B.W in apply_relocate()
246 * imm11 = lower[10:0] = offset[11:1] in apply_relocate()
247 * J1 = lower[13] in apply_relocate()
248 * J2 = lower[11] in apply_relocate()
251 j1 = (lower >> 13) & 1; in apply_relocate()
252 j2 = (lower >> 11) & 1; in apply_relocate()
256 ((lower & 0x07ff) << 1); in apply_relocate()
258 offset -= 0x02000000; in apply_relocate()
259 offset += sym->st_value - loc; in apply_relocate()
270 - loc - 4; in apply_relocate()
274 pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n", in apply_relocate()
275 module->name, relindex, i, symname, in apply_relocate()
276 ELF32_R_TYPE(rel->r_info), loc, in apply_relocate()
277 sym->st_value); in apply_relocate()
278 return -ENOEXEC; in apply_relocate()
286 lower = (u16)((lower & 0xd000) | in apply_relocate()
291 *(u16 *)(loc + 2) = __opcode_to_mem_thumb16(lower); in apply_relocate()
294 case R_ARM_THM_MOVW_ABS_NC: in apply_relocate()
295 case R_ARM_THM_MOVT_ABS: in apply_relocate()
296 case R_ARM_THM_MOVW_PREL_NC: in apply_relocate()
297 case R_ARM_THM_MOVT_PREL: in apply_relocate()
299 lower = __mem_to_opcode_thumb16(*(u16 *)(loc + 2)); in apply_relocate()
302 * MOVT/MOVW instructions encoding in Thumb-2: in apply_relocate()
306 * imm3 = lower[14:12] in apply_relocate()
307 * imm8 = lower[7:0] in apply_relocate()
313 ((lower & 0x7000) >> 4) | (lower & 0x00ff); in apply_relocate()
314 offset = (offset ^ 0x8000) - 0x8000; in apply_relocate()
315 offset += sym->st_value; in apply_relocate()
317 if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_PREL || in apply_relocate()
318 ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVW_PREL_NC) in apply_relocate()
319 offset -= loc; in apply_relocate()
320 if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS || in apply_relocate()
321 ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_PREL) in apply_relocate()
327 lower = (u16)((lower & 0x8f00) | in apply_relocate()
331 *(u16 *)(loc + 2) = __opcode_to_mem_thumb16(lower); in apply_relocate()
337 module->name, ELF32_R_TYPE(rel->r_info)); in apply_relocate()
338 return -ENOEXEC; in apply_relocate()
353 const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; in find_mod_section()
355 for (s = sechdrs, se = sechdrs + hdr->e_shnum; s < se; s++) in find_mod_section()
356 if (strcmp(name, secstrs + s->sh_name) == 0) in find_mod_section()
370 const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; in module_finalize()
371 const Elf_Shdr *sechdrs_end = sechdrs + hdr->e_shnum; in module_finalize()
378 const char *secname = secstrs + s->sh_name; in module_finalize()
380 if (!(s->sh_flags & SHF_ALLOC)) in module_finalize()
407 mod->arch.unwind[i] = in module_finalize()
408 unwind_table_add(maps[i].unw_sec->sh_addr, in module_finalize()
409 maps[i].unw_sec->sh_size, in module_finalize()
410 maps[i].txt_sec->sh_addr, in module_finalize()
411 maps[i].txt_sec->sh_size); in module_finalize()
416 fixup_pv_table((void *)s->sh_addr, s->sh_size); in module_finalize()
421 fixup_smp((void *)s->sh_addr, s->sh_size); in module_finalize()
423 return -EINVAL; in module_finalize()
435 unwind_table_del(mod->arch.unwind[i]); in module_arch_cleanup()
436 mod->arch.unwind[i] = NULL; in module_arch_cleanup()
444 unwind_table_del(mod->arch.unwind[ARM_SEC_INIT]); in module_arch_freeing_init()
445 mod->arch.unwind[ARM_SEC_INIT] = NULL; in module_arch_freeing_init()