0001
0002
0003
0004
0005
0006 #include <linux/elf.h>
0007 #include <linux/ftrace.h>
0008 #include <linux/kernel.h>
0009 #include <linux/module.h>
0010 #include <linux/sort.h>
0011 #include <linux/moduleloader.h>
0012
0013 #include <asm/cache.h>
0014 #include <asm/opcodes.h>
0015
0016 #ifdef CONFIG_THUMB2_KERNEL
0017 #define PLT_ENT_LDR __opcode_to_mem_thumb32(0xf8dff000 | \
0018 (PLT_ENT_STRIDE - 4))
0019 #else
0020 #define PLT_ENT_LDR __opcode_to_mem_arm(0xe59ff000 | \
0021 (PLT_ENT_STRIDE - 8))
0022 #endif
0023
0024 static const u32 fixed_plts[] = {
0025 #ifdef CONFIG_DYNAMIC_FTRACE
0026 FTRACE_ADDR,
0027 MCOUNT_ADDR,
0028 #endif
0029 };
0030
0031 static bool in_init(const struct module *mod, unsigned long loc)
0032 {
0033 return loc - (u32)mod->init_layout.base < mod->init_layout.size;
0034 }
0035
0036 static void prealloc_fixed(struct mod_plt_sec *pltsec, struct plt_entries *plt)
0037 {
0038 int i;
0039
0040 if (!ARRAY_SIZE(fixed_plts) || pltsec->plt_count)
0041 return;
0042 pltsec->plt_count = ARRAY_SIZE(fixed_plts);
0043
0044 for (i = 0; i < ARRAY_SIZE(plt->ldr); ++i)
0045 plt->ldr[i] = PLT_ENT_LDR;
0046
0047 BUILD_BUG_ON(sizeof(fixed_plts) > sizeof(plt->lit));
0048 memcpy(plt->lit, fixed_plts, sizeof(fixed_plts));
0049 }
0050
0051 u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val)
0052 {
0053 struct mod_plt_sec *pltsec = !in_init(mod, loc) ? &mod->arch.core :
0054 &mod->arch.init;
0055 struct plt_entries *plt;
0056 int idx;
0057
0058
0059 if (!pltsec->plt_ent)
0060 pltsec->plt_ent = (struct plt_entries *)pltsec->plt->sh_addr;
0061 plt = pltsec->plt_ent;
0062
0063 prealloc_fixed(pltsec, plt);
0064
0065 for (idx = 0; idx < ARRAY_SIZE(fixed_plts); ++idx)
0066 if (plt->lit[idx] == val)
0067 return (u32)&plt->ldr[idx];
0068
0069 idx = 0;
0070
0071
0072
0073
0074
0075 if (pltsec->plt_count > 0) {
0076 plt += (pltsec->plt_count - 1) / PLT_ENT_COUNT;
0077 idx = (pltsec->plt_count - 1) % PLT_ENT_COUNT;
0078
0079 if (plt->lit[idx] == val)
0080 return (u32)&plt->ldr[idx];
0081
0082 idx = (idx + 1) % PLT_ENT_COUNT;
0083 if (!idx)
0084 plt++;
0085 }
0086
0087 pltsec->plt_count++;
0088 BUG_ON(pltsec->plt_count * PLT_ENT_SIZE > pltsec->plt->sh_size);
0089
0090 if (!idx)
0091
0092 *plt = (struct plt_entries){
0093 { [0 ... PLT_ENT_COUNT - 1] = PLT_ENT_LDR, },
0094 { val, }
0095 };
0096 else
0097 plt->lit[idx] = val;
0098
0099 return (u32)&plt->ldr[idx];
0100 }
0101
0102 #define cmp_3way(a,b) ((a) < (b) ? -1 : (a) > (b))
0103
0104 static int cmp_rel(const void *a, const void *b)
0105 {
0106 const Elf32_Rel *x = a, *y = b;
0107 int i;
0108
0109
0110 i = cmp_3way(ELF32_R_TYPE(x->r_info), ELF32_R_TYPE(y->r_info));
0111 if (i == 0)
0112 i = cmp_3way(ELF32_R_SYM(x->r_info), ELF32_R_SYM(y->r_info));
0113 return i;
0114 }
0115
0116 static bool is_zero_addend_relocation(Elf32_Addr base, const Elf32_Rel *rel)
0117 {
0118 u32 *tval = (u32 *)(base + rel->r_offset);
0119
0120
0121
0122
0123
0124
0125
0126 switch (ELF32_R_TYPE(rel->r_info)) {
0127 u16 upper, lower;
0128
0129 case R_ARM_THM_CALL:
0130 case R_ARM_THM_JUMP24:
0131 upper = __mem_to_opcode_thumb16(((u16 *)tval)[0]);
0132 lower = __mem_to_opcode_thumb16(((u16 *)tval)[1]);
0133
0134 return (upper & 0x7ff) == 0x7ff && (lower & 0x2fff) == 0x2ffe;
0135
0136 case R_ARM_CALL:
0137 case R_ARM_PC24:
0138 case R_ARM_JUMP24:
0139 return (__mem_to_opcode_arm(*tval) & 0xffffff) == 0xfffffe;
0140 }
0141 BUG();
0142 }
0143
0144 static bool duplicate_rel(Elf32_Addr base, const Elf32_Rel *rel, int num)
0145 {
0146 const Elf32_Rel *prev;
0147
0148
0149
0150
0151
0152
0153 if (!num)
0154 return false;
0155
0156 prev = rel + num - 1;
0157 return cmp_rel(rel + num, prev) == 0 &&
0158 is_zero_addend_relocation(base, prev);
0159 }
0160
0161
0162 static unsigned int count_plts(const Elf32_Sym *syms, Elf32_Addr base,
0163 const Elf32_Rel *rel, int num, Elf32_Word dstidx)
0164 {
0165 unsigned int ret = 0;
0166 const Elf32_Sym *s;
0167 int i;
0168
0169 for (i = 0; i < num; i++) {
0170 switch (ELF32_R_TYPE(rel[i].r_info)) {
0171 case R_ARM_CALL:
0172 case R_ARM_PC24:
0173 case R_ARM_JUMP24:
0174 case R_ARM_THM_CALL:
0175 case R_ARM_THM_JUMP24:
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187 s = syms + ELF32_R_SYM(rel[i].r_info);
0188 if (s->st_shndx == dstidx)
0189 break;
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206 if (!is_zero_addend_relocation(base, rel + i) ||
0207 !duplicate_rel(base, rel, i))
0208 ret++;
0209 }
0210 }
0211 return ret;
0212 }
0213
0214 int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
0215 char *secstrings, struct module *mod)
0216 {
0217 unsigned long core_plts = ARRAY_SIZE(fixed_plts);
0218 unsigned long init_plts = ARRAY_SIZE(fixed_plts);
0219 Elf32_Shdr *s, *sechdrs_end = sechdrs + ehdr->e_shnum;
0220 Elf32_Sym *syms = NULL;
0221
0222
0223
0224
0225
0226 for (s = sechdrs; s < sechdrs_end; ++s) {
0227 if (strcmp(".plt", secstrings + s->sh_name) == 0)
0228 mod->arch.core.plt = s;
0229 else if (strcmp(".init.plt", secstrings + s->sh_name) == 0)
0230 mod->arch.init.plt = s;
0231 else if (s->sh_type == SHT_SYMTAB)
0232 syms = (Elf32_Sym *)s->sh_addr;
0233 }
0234
0235 if (!mod->arch.core.plt || !mod->arch.init.plt) {
0236 pr_err("%s: module PLT section(s) missing\n", mod->name);
0237 return -ENOEXEC;
0238 }
0239 if (!syms) {
0240 pr_err("%s: module symtab section missing\n", mod->name);
0241 return -ENOEXEC;
0242 }
0243
0244 for (s = sechdrs + 1; s < sechdrs_end; ++s) {
0245 Elf32_Rel *rels = (void *)ehdr + s->sh_offset;
0246 int numrels = s->sh_size / sizeof(Elf32_Rel);
0247 Elf32_Shdr *dstsec = sechdrs + s->sh_info;
0248
0249 if (s->sh_type != SHT_REL)
0250 continue;
0251
0252
0253 if (!(dstsec->sh_flags & SHF_EXECINSTR))
0254 continue;
0255
0256
0257 sort(rels, numrels, sizeof(Elf32_Rel), cmp_rel, NULL);
0258
0259 if (strncmp(secstrings + dstsec->sh_name, ".init", 5) != 0)
0260 core_plts += count_plts(syms, dstsec->sh_addr, rels,
0261 numrels, s->sh_info);
0262 else
0263 init_plts += count_plts(syms, dstsec->sh_addr, rels,
0264 numrels, s->sh_info);
0265 }
0266
0267 mod->arch.core.plt->sh_type = SHT_NOBITS;
0268 mod->arch.core.plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
0269 mod->arch.core.plt->sh_addralign = L1_CACHE_BYTES;
0270 mod->arch.core.plt->sh_size = round_up(core_plts * PLT_ENT_SIZE,
0271 sizeof(struct plt_entries));
0272 mod->arch.core.plt_count = 0;
0273 mod->arch.core.plt_ent = NULL;
0274
0275 mod->arch.init.plt->sh_type = SHT_NOBITS;
0276 mod->arch.init.plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
0277 mod->arch.init.plt->sh_addralign = L1_CACHE_BYTES;
0278 mod->arch.init.plt->sh_size = round_up(init_plts * PLT_ENT_SIZE,
0279 sizeof(struct plt_entries));
0280 mod->arch.init.plt_count = 0;
0281 mod->arch.init.plt_ent = NULL;
0282
0283 pr_debug("%s: plt=%x, init.plt=%x\n", __func__,
0284 mod->arch.core.plt->sh_size, mod->arch.init.plt->sh_size);
0285 return 0;
0286 }