Lines Matching +full:lower +full:- +full:case
1 // SPDX-License-Identifier: GPL-2.0-only
76 * A single PC-relative symbol reference is divided in up to 3 add or subtract
86 * -/+ 256 MiB, (2x8 + 12 == 28 bits), which means it has sufficient range for
87 * any in-kernel symbol reference (unless module PLTs are being used).
90 * load is that literal loads may miss in the D-cache, and generally lead to
91 * lower cache efficiency for variables that are referenced often from many
99 shift = val ? (31 - __fls(val)) & ~1 : 32; in get_group_rem()
104 } while (group--); in get_group_rem()
115 Elf32_Shdr *dstsec = sechdrs + relsec->sh_info; in apply_relocate()
116 Elf32_Rel *rel = (void *)relsec->sh_addr; in apply_relocate()
119 for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++, rel++) { in apply_relocate()
129 u32 upper, lower, sign, j1, j2; in apply_relocate() local
132 offset = ELF32_R_SYM(rel->r_info); in apply_relocate()
133 if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) { in apply_relocate()
135 module->name, relindex, i); in apply_relocate()
136 return -ENOEXEC; in apply_relocate()
139 sym = ((Elf32_Sym *)symsec->sh_addr) + offset; in apply_relocate()
140 symname = strtab + sym->st_name; in apply_relocate()
142 if (rel->r_offset < 0 || rel->r_offset > dstsec->sh_size - sizeof(u32)) { in apply_relocate()
144 module->name, relindex, i, symname, in apply_relocate()
145 rel->r_offset, dstsec->sh_size); in apply_relocate()
146 return -ENOEXEC; in apply_relocate()
149 loc = dstsec->sh_addr + rel->r_offset; in apply_relocate()
151 switch (ELF32_R_TYPE(rel->r_info)) { in apply_relocate()
152 case R_ARM_NONE: in apply_relocate()
156 case R_ARM_ABS32: in apply_relocate()
157 case R_ARM_TARGET1: in apply_relocate()
158 *(u32 *)loc += sym->st_value; in apply_relocate()
161 case R_ARM_PC24: in apply_relocate()
162 case R_ARM_CALL: in apply_relocate()
163 case R_ARM_JUMP24: in apply_relocate()
164 if (sym->st_value & 3) { in apply_relocate()
165 pr_err("%s: section %u reloc %u sym '%s': unsupported interworking call (ARM -> Thumb)\n", in apply_relocate()
166 module->name, relindex, i, symname); in apply_relocate()
167 return -ENOEXEC; in apply_relocate()
174 offset += sym->st_value - loc; in apply_relocate()
187 - loc - 8; in apply_relocate()
191 pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n", in apply_relocate()
192 module->name, relindex, i, symname, in apply_relocate()
193 ELF32_R_TYPE(rel->r_info), loc, in apply_relocate()
194 sym->st_value); in apply_relocate()
195 return -ENOEXEC; in apply_relocate()
205 case R_ARM_V4BX: in apply_relocate()
207 * other bits to re-code instruction as in apply_relocate()
214 case R_ARM_PREL31: in apply_relocate()
216 offset += sym->st_value - loc; in apply_relocate()
217 if (offset >= 0x40000000 || offset < -0x40000000) { in apply_relocate()
218 pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n", in apply_relocate()
219 module->name, relindex, i, symname, in apply_relocate()
220 ELF32_R_TYPE(rel->r_info), loc, in apply_relocate()
221 sym->st_value); in apply_relocate()
222 return -ENOEXEC; in apply_relocate()
228 case R_ARM_REL32: in apply_relocate()
229 *(u32 *)loc += sym->st_value - loc; in apply_relocate()
232 case R_ARM_MOVW_ABS_NC: in apply_relocate()
233 case R_ARM_MOVT_ABS: in apply_relocate()
234 case R_ARM_MOVW_PREL_NC: in apply_relocate()
235 case R_ARM_MOVT_PREL: in apply_relocate()
240 offset += sym->st_value; in apply_relocate()
241 if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_PREL || in apply_relocate()
242 ELF32_R_TYPE(rel->r_info) == R_ARM_MOVW_PREL_NC) in apply_relocate()
243 offset -= loc; in apply_relocate()
244 if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS || in apply_relocate()
245 ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_PREL) in apply_relocate()
256 case R_ARM_ALU_PC_G0_NC: in apply_relocate()
259 case R_ARM_ALU_PC_G1_NC: in apply_relocate()
263 offset = -offset; in apply_relocate()
264 offset += sym->st_value - loc; in apply_relocate()
266 offset = -offset; in apply_relocate()
274 offset >>= 24 - shift; in apply_relocate()
280 case R_ARM_LDR_PC_G2: in apply_relocate()
284 offset = -offset; in apply_relocate()
285 offset += sym->st_value - loc; in apply_relocate()
287 offset = -offset; in apply_relocate()
295 pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n", in apply_relocate()
296 module->name, relindex, i, symname, in apply_relocate()
297 ELF32_R_TYPE(rel->r_info), loc, in apply_relocate()
298 sym->st_value); in apply_relocate()
299 return -ENOEXEC; in apply_relocate()
305 case R_ARM_THM_CALL: in apply_relocate()
306 case R_ARM_THM_JUMP24: in apply_relocate()
311 * For non-function symbols, the destination in apply_relocate()
316 if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && in apply_relocate()
317 !(sym->st_value & 1)) { in apply_relocate()
318 pr_err("%s: section %u reloc %u sym '%s': unsupported interworking call (Thumb -> ARM)\n", in apply_relocate()
319 module->name, relindex, i, symname); in apply_relocate()
320 return -ENOEXEC; in apply_relocate()
324 lower = __mem_to_opcode_thumb16(*(u16 *)(loc + 2)); in apply_relocate()
327 * 25 bit signed address range (Thumb-2 BL and B.W in apply_relocate()
335 * imm11 = lower[10:0] = offset[11:1] in apply_relocate()
336 * J1 = lower[13] in apply_relocate()
337 * J2 = lower[11] in apply_relocate()
340 j1 = (lower >> 13) & 1; in apply_relocate()
341 j2 = (lower >> 11) & 1; in apply_relocate()
345 ((lower & 0x07ff) << 1); in apply_relocate()
347 offset += sym->st_value - loc; in apply_relocate()
358 - loc - 4; in apply_relocate()
362 pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n", in apply_relocate()
363 module->name, relindex, i, symname, in apply_relocate()
364 ELF32_R_TYPE(rel->r_info), loc, in apply_relocate()
365 sym->st_value); in apply_relocate()
366 return -ENOEXEC; in apply_relocate()
374 lower = (u16)((lower & 0xd000) | in apply_relocate()
379 *(u16 *)(loc + 2) = __opcode_to_mem_thumb16(lower); in apply_relocate()
382 case R_ARM_THM_MOVW_ABS_NC: in apply_relocate()
383 case R_ARM_THM_MOVT_ABS: in apply_relocate()
384 case R_ARM_THM_MOVW_PREL_NC: in apply_relocate()
385 case R_ARM_THM_MOVT_PREL: in apply_relocate()
387 lower = __mem_to_opcode_thumb16(*(u16 *)(loc + 2)); in apply_relocate()
390 * MOVT/MOVW instructions encoding in Thumb-2: in apply_relocate()
394 * imm3 = lower[14:12] in apply_relocate()
395 * imm8 = lower[7:0] in apply_relocate()
401 ((lower & 0x7000) >> 4) | (lower & 0x00ff); in apply_relocate()
403 offset += sym->st_value; in apply_relocate()
405 if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_PREL || in apply_relocate()
406 ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVW_PREL_NC) in apply_relocate()
407 offset -= loc; in apply_relocate()
408 if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS || in apply_relocate()
409 ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_PREL) in apply_relocate()
415 lower = (u16)((lower & 0x8f00) | in apply_relocate()
419 *(u16 *)(loc + 2) = __opcode_to_mem_thumb16(lower); in apply_relocate()
425 module->name, ELF32_R_TYPE(rel->r_info)); in apply_relocate()
426 return -ENOEXEC; in apply_relocate()
441 const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; in find_mod_section()
443 for (s = sechdrs, se = sechdrs + hdr->e_shnum; s < se; s++) in find_mod_section()
444 if (strcmp(name, secstrs + s->sh_name) == 0) in find_mod_section()
458 const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; in module_finalize()
459 const Elf_Shdr *sechdrs_end = sechdrs + hdr->e_shnum; in module_finalize()
460 struct list_head *unwind_list = &mod->arch.unwind_list; in module_finalize()
463 mod->arch.init_table = NULL; in module_finalize()
466 const char *secname = secstrs + s->sh_name; in module_finalize()
470 if (!(s->sh_flags & SHF_ALLOC) || in module_finalize()
471 s->sh_type != ELF_SECTION_UNWIND) in module_finalize()
482 unwind_table_add(s->sh_addr, in module_finalize()
483 s->sh_size, in module_finalize()
484 txt_sec->sh_addr, in module_finalize()
485 txt_sec->sh_size); in module_finalize()
487 list_add(&table->mod_list, unwind_list); in module_finalize()
491 mod->arch.init_table = table; in module_finalize()
498 fixup_pv_table((void *)s->sh_addr, s->sh_size); in module_finalize()
503 fixup_smp((void *)s->sh_addr, s->sh_size); in module_finalize()
505 return -EINVAL; in module_finalize()
518 &mod->arch.unwind_list, mod_list) { in module_arch_cleanup()
519 list_del(&tmp->mod_list); in module_arch_cleanup()
522 mod->arch.init_table = NULL; in module_arch_cleanup()
529 struct unwind_table *init = mod->arch.init_table; in module_arch_freeing_init()
532 mod->arch.init_table = NULL; in module_arch_freeing_init()
533 list_del(&init->mod_list); in module_arch_freeing_init()