Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only
2 : : /*
3 : : * Copyright (C) 2014-2017 Linaro Ltd. <ard.biesheuvel@linaro.org>
4 : : */
5 : :
6 : : #include <linux/elf.h>
7 : : #include <linux/kernel.h>
8 : : #include <linux/module.h>
9 : : #include <linux/sort.h>
10 : :
11 : : #include <asm/cache.h>
12 : : #include <asm/opcodes.h>
13 : :
14 : : #define PLT_ENT_STRIDE L1_CACHE_BYTES
15 : : #define PLT_ENT_COUNT (PLT_ENT_STRIDE / sizeof(u32))
16 : : #define PLT_ENT_SIZE (sizeof(struct plt_entries) / PLT_ENT_COUNT)
17 : :
18 : : #ifdef CONFIG_THUMB2_KERNEL
19 : : #define PLT_ENT_LDR __opcode_to_mem_thumb32(0xf8dff000 | \
20 : : (PLT_ENT_STRIDE - 4))
21 : : #else
22 : : #define PLT_ENT_LDR __opcode_to_mem_arm(0xe59ff000 | \
23 : : (PLT_ENT_STRIDE - 8))
24 : : #endif
25 : :
26 : : struct plt_entries {
27 : : u32 ldr[PLT_ENT_COUNT];
28 : : u32 lit[PLT_ENT_COUNT];
29 : : };
30 : :
31 : : static bool in_init(const struct module *mod, unsigned long loc)
32 : : {
33 : 1134460 : return loc - (u32)mod->init_layout.base < mod->init_layout.size;
34 : : }
35 : :
36 : 1134460 : u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val)
37 : : {
38 [ + + ]: 1134460 : struct mod_plt_sec *pltsec = !in_init(mod, loc) ? &mod->arch.core :
39 : : &mod->arch.init;
40 : :
41 : 1134460 : struct plt_entries *plt = (struct plt_entries *)pltsec->plt->sh_addr;
42 : : int idx = 0;
43 : :
44 : : /*
45 : : * Look for an existing entry pointing to 'val'. Given that the
46 : : * relocations are sorted, this will be the last entry we allocated.
47 : : * (if one exists).
48 : : */
49 [ + + ]: 1134460 : if (pltsec->plt_count > 0) {
50 : 1125628 : plt += (pltsec->plt_count - 1) / PLT_ENT_COUNT;
51 : 1125628 : idx = (pltsec->plt_count - 1) % PLT_ENT_COUNT;
52 : :
53 [ + + ]: 1125628 : if (plt->lit[idx] == val)
54 : 935138 : return (u32)&plt->ldr[idx];
55 : :
56 : 190490 : idx = (idx + 1) % PLT_ENT_COUNT;
57 [ + + ]: 190490 : if (!idx)
58 : 9292 : plt++;
59 : : }
60 : :
61 : 199322 : pltsec->plt_count++;
62 [ - + ]: 199322 : BUG_ON(pltsec->plt_count * PLT_ENT_SIZE > pltsec->plt->sh_size);
63 : :
64 [ + + ]: 199322 : if (!idx)
65 : : /* Populate a new set of entries */
66 : 18124 : *plt = (struct plt_entries){
67 : : { [0 ... PLT_ENT_COUNT - 1] = PLT_ENT_LDR, },
68 : : { val, }
69 : : };
70 : : else
71 : 181198 : plt->lit[idx] = val;
72 : :
73 : 199322 : return (u32)&plt->ldr[idx];
74 : : }
75 : :
76 : : #define cmp_3way(a,b) ((a) < (b) ? -1 : (a) > (b))
77 : :
78 : 216807852 : static int cmp_rel(const void *a, const void *b)
79 : : {
80 : : const Elf32_Rel *x = a, *y = b;
81 : : int i;
82 : :
83 : : /* sort by type and symbol index */
84 [ + + + + ]: 222477098 : i = cmp_3way(ELF32_R_TYPE(x->r_info), ELF32_R_TYPE(y->r_info));
85 [ + + + + ]: 222477098 : if (i == 0)
86 [ + + + + ]: 184155326 : i = cmp_3way(ELF32_R_SYM(x->r_info), ELF32_R_SYM(y->r_info));
87 : 216807852 : return i;
88 : : }
89 : :
90 : 10600550 : static bool is_zero_addend_relocation(Elf32_Addr base, const Elf32_Rel *rel)
91 : : {
92 : 10600550 : u32 *tval = (u32 *)(base + rel->r_offset);
93 : :
94 : : /*
95 : : * Do a bitwise compare on the raw addend rather than fully decoding
96 : : * the offset and doing an arithmetic comparison.
97 : : * Note that a zero-addend jump/call relocation is encoded taking the
98 : : * PC bias into account, i.e., -8 for ARM and -4 for Thumb2.
99 : : */
100 [ - + - ]: 10600550 : switch (ELF32_R_TYPE(rel->r_info)) {
101 : : u16 upper, lower;
102 : :
103 : : case R_ARM_THM_CALL:
104 : : case R_ARM_THM_JUMP24:
105 : 0 : upper = __mem_to_opcode_thumb16(((u16 *)tval)[0]);
106 : 0 : lower = __mem_to_opcode_thumb16(((u16 *)tval)[1]);
107 : :
108 [ # # # # ]: 0 : return (upper & 0x7ff) == 0x7ff && (lower & 0x2fff) == 0x2ffe;
109 : :
110 : : case R_ARM_CALL:
111 : : case R_ARM_PC24:
112 : : case R_ARM_JUMP24:
113 : 10600550 : return (__mem_to_opcode_arm(*tval) & 0xffffff) == 0xfffffe;
114 : : }
115 : 0 : BUG();
116 : : }
117 : :
118 : 5678380 : static bool duplicate_rel(Elf32_Addr base, const Elf32_Rel *rel, int num)
119 : : {
120 : : const Elf32_Rel *prev;
121 : :
122 : : /*
123 : : * Entries are sorted by type and symbol index. That means that,
124 : : * if a duplicate entry exists, it must be in the preceding
125 : : * slot.
126 : : */
127 [ + + ]: 5678380 : if (!num)
128 : : return false;
129 : :
130 : 5669246 : prev = rel + num - 1;
131 [ + + - + ]: 16260896 : return cmp_rel(rel + num, prev) == 0 &&
132 : 4922084 : is_zero_addend_relocation(base, prev);
133 : : }
134 : :
135 : : /* Count how many PLT entries we may need */
136 : 45302 : static unsigned int count_plts(const Elf32_Sym *syms, Elf32_Addr base,
137 : : const Elf32_Rel *rel, int num, Elf32_Word dstidx)
138 : : {
139 : : unsigned int ret = 0;
140 : : const Elf32_Sym *s;
141 : : int i;
142 : :
143 [ + + ]: 15657912 : for (i = 0; i < num; i++) {
144 [ + + ]: 15612822 : switch (ELF32_R_TYPE(rel[i].r_info)) {
145 : : case R_ARM_CALL:
146 : : case R_ARM_PC24:
147 : : case R_ARM_JUMP24:
148 : : case R_ARM_THM_CALL:
149 : : case R_ARM_THM_JUMP24:
150 : : /*
151 : : * We only have to consider branch targets that resolve
152 : : * to symbols that are defined in a different section.
153 : : * This is not simply a heuristic, it is a fundamental
154 : : * limitation, since there is no guaranteed way to emit
155 : : * PLT entries sufficiently close to the branch if the
156 : : * section size exceeds the range of a branch
157 : : * instruction. So ignore relocations against defined
158 : : * symbols if they live in the same section as the
159 : : * relocation target.
160 : : */
161 : 6253808 : s = syms + ELF32_R_SYM(rel[i].r_info);
162 [ + + ]: 6253808 : if (s->st_shndx == dstidx)
163 : : break;
164 : :
165 : : /*
166 : : * Jump relocations with non-zero addends against
167 : : * undefined symbols are supported by the ELF spec, but
168 : : * do not occur in practice (e.g., 'jump n bytes past
169 : : * the entry point of undefined function symbol f').
170 : : * So we need to support them, but there is no need to
171 : : * take them into consideration when trying to optimize
172 : : * this code. So let's only check for duplicates when
173 : : * the addend is zero. (Note that calls into the core
174 : : * module via init PLT entries could involve section
175 : : * relative symbol references with non-zero addends, for
176 : : * which we may end up emitting duplicates, but the init
177 : : * PLT is released along with the rest of the .init
178 : : * region as soon as module loading completes.)
179 : : */
180 [ + + + + ]: 11355994 : if (!is_zero_addend_relocation(base, rel + i) ||
181 : 5678366 : !duplicate_rel(base, rel, i))
182 : 756698 : ret++;
183 : : }
184 : : }
185 : 45090 : return ret;
186 : : }
187 : :
188 : 11014 : int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
189 : : char *secstrings, struct module *mod)
190 : : {
191 : : unsigned long core_plts = 0;
192 : : unsigned long init_plts = 0;
193 : 11014 : Elf32_Shdr *s, *sechdrs_end = sechdrs + ehdr->e_shnum;
194 : : Elf32_Sym *syms = NULL;
195 : :
196 : : /*
197 : : * To store the PLTs, we expand the .text section for core module code
198 : : * and for initialization code.
199 : : */
200 [ + + ]: 468912 : for (s = sechdrs; s < sechdrs_end; ++s) {
201 [ + + ]: 457898 : if (strcmp(".plt", secstrings + s->sh_name) == 0)
202 : 11070 : mod->arch.core.plt = s;
203 [ + + ]: 446828 : else if (strcmp(".init.plt", secstrings + s->sh_name) == 0)
204 : 11090 : mod->arch.init.plt = s;
205 [ + + ]: 435738 : else if (s->sh_type == SHT_SYMTAB)
206 : 11088 : syms = (Elf32_Sym *)s->sh_addr;
207 : : }
208 : :
209 [ + - + + ]: 11014 : if (!mod->arch.core.plt || !mod->arch.init.plt) {
210 : 162 : pr_err("%s: module PLT section(s) missing\n", mod->name);
211 : 0 : return -ENOEXEC;
212 : : }
213 [ - + ]: 10940 : if (!syms) {
214 : 0 : pr_err("%s: module symtab section missing\n", mod->name);
215 : 0 : return -ENOEXEC;
216 : : }
217 : :
218 [ + + ]: 457204 : for (s = sechdrs + 1; s < sechdrs_end; ++s) {
219 : 446120 : Elf32_Rel *rels = (void *)ehdr + s->sh_offset;
220 : 446120 : int numrels = s->sh_size / sizeof(Elf32_Rel);
221 : 446120 : Elf32_Shdr *dstsec = sechdrs + s->sh_info;
222 : :
223 [ + + ]: 446120 : if (s->sh_type != SHT_REL)
224 : 309314 : continue;
225 : :
226 : : /* ignore relocations that operate on non-exec sections */
227 [ + + ]: 136806 : if (!(dstsec->sh_flags & SHF_EXECINSTR))
228 : 91862 : continue;
229 : :
230 : : /* sort by type and symbol index */
231 : 44944 : sort(rels, numrels, sizeof(Elf32_Rel), cmp_rel, NULL);
232 : :
233 [ + + ]: 45084 : if (strncmp(secstrings + dstsec->sh_name, ".init", 5) != 0)
234 : 35208 : core_plts += count_plts(syms, dstsec->sh_addr, rels,
235 : : numrels, s->sh_info);
236 : : else
237 : 9876 : init_plts += count_plts(syms, dstsec->sh_addr, rels,
238 : : numrels, s->sh_info);
239 : : }
240 : :
241 : 11084 : mod->arch.core.plt->sh_type = SHT_NOBITS;
242 : 11084 : mod->arch.core.plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
243 : 11084 : mod->arch.core.plt->sh_addralign = L1_CACHE_BYTES;
244 : 11084 : mod->arch.core.plt->sh_size = round_up(core_plts * PLT_ENT_SIZE,
245 : : sizeof(struct plt_entries));
246 : 11084 : mod->arch.core.plt_count = 0;
247 : :
248 : 11084 : mod->arch.init.plt->sh_type = SHT_NOBITS;
249 : 11084 : mod->arch.init.plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
250 : 11084 : mod->arch.init.plt->sh_addralign = L1_CACHE_BYTES;
251 : 11084 : mod->arch.init.plt->sh_size = round_up(init_plts * PLT_ENT_SIZE,
252 : : sizeof(struct plt_entries));
253 : 11084 : mod->arch.init.plt_count = 0;
254 : :
255 : : pr_debug("%s: plt=%x, init.plt=%x\n", __func__,
256 : : mod->arch.core.plt->sh_size, mod->arch.init.plt->sh_size);
257 : 11084 : return 0;
258 : : }
|