Lines Matching +full:loc +full:- +full:code
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2014-2017 Linaro Ltd. <ard.biesheuvel@linaro.org>
52 if (a->add != b->add || a->br != b->br) in plt_entries_equal()
62 if (a->adrp == b->adrp && p == q) in plt_entries_equal()
65 return (p + aarch64_insn_adrp_get_offset(le32_to_cpu(a->adrp))) == in plt_entries_equal()
66 (q + aarch64_insn_adrp_get_offset(le32_to_cpu(b->adrp))); in plt_entries_equal()
70 void *loc, const Elf64_Rela *rela, in module_emit_plt_entry() argument
73 struct mod_plt_sec *pltsec = !within_module_init((unsigned long)loc, mod) ? in module_emit_plt_entry()
74 &mod->arch.core : &mod->arch.init; in module_emit_plt_entry()
75 struct plt_entry *plt = (struct plt_entry *)sechdrs[pltsec->plt_shndx].sh_addr; in module_emit_plt_entry()
76 int i = pltsec->plt_num_entries; in module_emit_plt_entry()
77 int j = i - 1; in module_emit_plt_entry()
78 u64 val = sym->st_value + rela->r_addend; in module_emit_plt_entry()
93 pltsec->plt_num_entries += i - j; in module_emit_plt_entry()
94 if (WARN_ON(pltsec->plt_num_entries > pltsec->plt_max_entries)) in module_emit_plt_entry()
102 void *loc, u64 val) in module_emit_veneer_for_adrp() argument
104 struct mod_plt_sec *pltsec = !within_module_init((unsigned long)loc, mod) ? in module_emit_veneer_for_adrp()
105 &mod->arch.core : &mod->arch.init; in module_emit_veneer_for_adrp()
106 struct plt_entry *plt = (struct plt_entry *)sechdrs[pltsec->plt_shndx].sh_addr; in module_emit_veneer_for_adrp()
107 int i = pltsec->plt_num_entries++; in module_emit_veneer_for_adrp()
111 if (WARN_ON(pltsec->plt_num_entries > pltsec->plt_max_entries)) in module_emit_veneer_for_adrp()
115 i = pltsec->plt_num_entries++; in module_emit_veneer_for_adrp()
119 le32_to_cpup((__le32 *)loc)); in module_emit_veneer_for_adrp()
121 br = aarch64_insn_gen_branch_imm((u64)&plt[i].br, (u64)loc + 4, in module_emit_veneer_for_adrp()
131 #define cmp_3way(a, b) ((a) < (b) ? -1 : (a) > (b))
139 i = cmp_3way(ELF64_R_TYPE(x->r_info), ELF64_R_TYPE(y->r_info)); in cmp_rela()
141 i = cmp_3way(ELF64_R_SYM(x->r_info), ELF64_R_SYM(y->r_info)); in cmp_rela()
143 i = cmp_3way(x->r_addend, y->r_addend); in cmp_rela()
154 return num > 0 && cmp_rela(rela + num, rela + num - 1) == 0; in duplicate_rel()
182 if (s->st_shndx == dstidx) in count_plts()
186 * Jump relocations with non-zero addends against in count_plts()
192 * this code. So let's only check for duplicates when in count_plts()
232 dstsec->sh_addralign = max(dstsec->sh_addralign, in count_plts()
253 Elf64_Sym *s = syms + ELF64_R_SYM(rela->r_info); in branch_rela_needs_plt()
255 if (s->st_shndx == dstidx) in branch_rela_needs_plt()
258 return ELF64_R_TYPE(rela->r_info) == R_AARCH64_JUMP26 || in branch_rela_needs_plt()
259 ELF64_R_TYPE(rela->r_info) == R_AARCH64_CALL26; in branch_rela_needs_plt()
266 int i = 0, j = numrels - 1; in partition_branch_plt_relas()
274 j--; in partition_branch_plt_relas()
293 for (i = 0; i < ehdr->e_shnum; i++) { in module_frob_arch_sections()
295 mod->arch.core.plt_shndx = i; in module_frob_arch_sections()
297 mod->arch.init.plt_shndx = i; in module_frob_arch_sections()
305 if (!mod->arch.core.plt_shndx || !mod->arch.init.plt_shndx) { in module_frob_arch_sections()
306 pr_err("%s: module PLT section(s) missing\n", mod->name); in module_frob_arch_sections()
307 return -ENOEXEC; in module_frob_arch_sections()
310 pr_err("%s: module symtab section missing\n", mod->name); in module_frob_arch_sections()
311 return -ENOEXEC; in module_frob_arch_sections()
314 for (i = 0; i < ehdr->e_shnum; i++) { in module_frob_arch_sections()
322 /* ignore relocations that operate on non-exec sections */ in module_frob_arch_sections()
323 if (!(dstsec->sh_flags & SHF_EXECINSTR)) in module_frob_arch_sections()
335 if (!module_init_layout_section(secstrings + dstsec->sh_name)) in module_frob_arch_sections()
343 pltsec = sechdrs + mod->arch.core.plt_shndx; in module_frob_arch_sections()
344 pltsec->sh_type = SHT_NOBITS; in module_frob_arch_sections()
345 pltsec->sh_flags = SHF_EXECINSTR | SHF_ALLOC; in module_frob_arch_sections()
346 pltsec->sh_addralign = L1_CACHE_BYTES; in module_frob_arch_sections()
347 pltsec->sh_size = (core_plts + 1) * sizeof(struct plt_entry); in module_frob_arch_sections()
348 mod->arch.core.plt_num_entries = 0; in module_frob_arch_sections()
349 mod->arch.core.plt_max_entries = core_plts; in module_frob_arch_sections()
351 pltsec = sechdrs + mod->arch.init.plt_shndx; in module_frob_arch_sections()
352 pltsec->sh_type = SHT_NOBITS; in module_frob_arch_sections()
353 pltsec->sh_flags = SHF_EXECINSTR | SHF_ALLOC; in module_frob_arch_sections()
354 pltsec->sh_addralign = L1_CACHE_BYTES; in module_frob_arch_sections()
355 pltsec->sh_size = (init_plts + 1) * sizeof(struct plt_entry); in module_frob_arch_sections()
356 mod->arch.init.plt_num_entries = 0; in module_frob_arch_sections()
357 mod->arch.init.plt_max_entries = init_plts; in module_frob_arch_sections()
360 tramp->sh_type = SHT_NOBITS; in module_frob_arch_sections()
361 tramp->sh_flags = SHF_EXECINSTR | SHF_ALLOC; in module_frob_arch_sections()
362 tramp->sh_addralign = __alignof__(struct plt_entry); in module_frob_arch_sections()
363 tramp->sh_size = NR_FTRACE_PLTS * sizeof(struct plt_entry); in module_frob_arch_sections()