1 // SPDX-License-Identifier: GPL-2.0-only !! 1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 2 /* 3 * linux/arch/arm/kernel/module.c << 4 * 3 * 5 * Copyright (C) 2002 Russell King. !! 4 * Copyright (C) 2001 Rusty Russell. 6 * Modified for nommu by Hyok S. Choi !! 5 * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org) 7 * !! 6 * Copyright (C) 2005 Thiemo Seufer 8 * Module allocation method suggested by Andi << 9 */ 7 */ 10 #include <linux/module.h> !! 8 >> 9 #undef DEBUG >> 10 >> 11 #include <linux/extable.h> 11 #include <linux/moduleloader.h> 12 #include <linux/moduleloader.h> 12 #include <linux/kernel.h> << 13 #include <linux/mm.h> << 14 #include <linux/elf.h> 13 #include <linux/elf.h> >> 14 #include <linux/mm.h> >> 15 #include <linux/numa.h> >> 16 #include <linux/vmalloc.h> >> 17 #include <linux/slab.h> 15 #include <linux/fs.h> 18 #include <linux/fs.h> 16 #include <linux/string.h> 19 #include <linux/string.h> >> 20 #include <linux/kernel.h> >> 21 #include <linux/spinlock.h> >> 22 #include <linux/jump_label.h> >> 23 >> 24 extern void jump_label_apply_nops(struct module *mod); 17 25 18 #include <asm/sections.h> !! 26 struct mips_hi16 { 19 #include <asm/smp_plat.h> !! 27 struct mips_hi16 *next; 20 #include <asm/unwind.h> !! 28 Elf_Addr *addr; 21 #include <asm/opcodes.h> !! 29 Elf_Addr value; >> 30 }; 22 31 23 bool module_init_section(const char *name) !! 32 static LIST_HEAD(dbe_list); >> 33 static DEFINE_SPINLOCK(dbe_lock); >> 34 >> 35 #ifdef MODULE_START >> 36 void *module_alloc(unsigned long size) 24 { 37 { 25 return strstarts(name, ".init") || !! 38 return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END, 26 strstarts(name, ".ARM.extab.in !! 39 GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE, 27 strstarts(name, ".ARM.exidx.in !! 40 __builtin_return_address(0)); 28 } 41 } >> 42 #endif 29 43 30 bool module_exit_section(const char *name) !! 44 static void apply_r_mips_32(u32 *location, u32 base, Elf_Addr v) 31 { 45 { 32 return strstarts(name, ".exit") || !! 46 *location = base + v; 33 strstarts(name, ".ARM.extab.ex << 34 strstarts(name, ".ARM.exidx.ex << 35 } 47 } 36 48 37 #ifdef CONFIG_ARM_HAS_GROUP_RELOCS !! 49 static int apply_r_mips_26(struct module *me, u32 *location, u32 base, 38 /* !! 50 Elf_Addr v) 39 * This implements the partitioning algorithm << 40 * documented in the ARM AArch32 ELF psABI (IH << 41 * << 42 * A single PC-relative symbol reference is di << 43 * operations, where the final one could be in << 44 * instruction with immediate offset. E.g., << 45 * << 46 * ADD Rd, PC, #... or << 47 * ADD Rd, Rd, #... << 48 * LDR Rd, [Rd, #...] << 49 * << 50 * The latter has a guaranteed range of only 1 << 51 * of limited use in the kernel. However, the << 52 * -/+ 256 MiB, (2x8 + 12 == 28 bits), which m << 53 * any in-kernel symbol reference (unless modu << 54 * << 55 * The main advantage of this approach over th << 56 * load is that literal loads may miss in the << 57 * lower cache efficiency for variables that a << 58 * different places in the code. << 59 */ << 60 static u32 get_group_rem(u32 group, u32 *offse << 61 { 51 { 62 u32 val = *offset; !! 52 if (v % 4) { 63 u32 shift; !! 53 pr_err("module %s: dangerous R_MIPS_26 relocation\n", 64 do { !! 54 me->name); 65 shift = val ? (31 - __fls(val) !! 55 return -ENOEXEC; 66 *offset = val; !! 56 } 67 if (!val) !! 57 68 break; !! 58 if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { 69 val &= 0xffffff >> shift; !! 59 pr_err("module %s: relocation overflow\n", 70 } while (group--); !! 60 me->name); 71 return shift; !! 61 return -ENOEXEC; >> 62 } >> 63 >> 64 *location = (*location & ~0x03ffffff) | >> 65 ((base + (v >> 2)) & 0x03ffffff); >> 66 >> 67 return 0; 72 } 68 } 73 #endif << 74 69 75 int !! 70 static int apply_r_mips_hi16(struct module *me, u32 *location, Elf_Addr v, 76 apply_relocate(Elf32_Shdr *sechdrs, const char !! 71 bool rela) 77 unsigned int relindex, struct m !! 72 { 78 { !! 73 struct mips_hi16 *n; 79 Elf32_Shdr *symsec = sechdrs + syminde << 80 Elf32_Shdr *relsec = sechdrs + relinde << 81 Elf32_Shdr *dstsec = sechdrs + relsec- << 82 Elf32_Rel *rel = (void *)relsec->sh_ad << 83 unsigned int i; << 84 << 85 for (i = 0; i < relsec->sh_size / size << 86 unsigned long loc; << 87 Elf32_Sym *sym; << 88 const char *symname; << 89 #ifdef CONFIG_ARM_HAS_GROUP_RELOCS << 90 u32 shift, group = 1; << 91 #endif << 92 s32 offset; << 93 u32 tmp; << 94 #ifdef CONFIG_THUMB2_KERNEL << 95 u32 upper, lower, sign, j1, j2 << 96 #endif << 97 74 98 offset = ELF32_R_SYM(rel->r_in !! 75 if (rela) { 99 if (offset < 0 || offset > (sy !! 76 *location = (*location & 0xffff0000) | 100 pr_err("%s: section %u !! 77 ((((long long) v + 0x8000LL) >> 16) & 0xffff); 101 module->name, !! 78 return 0; 102 return -ENOEXEC; !! 79 } 103 } << 104 80 105 sym = ((Elf32_Sym *)symsec->sh !! 81 /* 106 symname = strtab + sym->st_nam !! 82 * We cannot relocate this one now because we don't know the value of >> 83 * the carry we need to add. Save the information, and let LO16 do the >> 84 * actual relocation. >> 85 */ >> 86 n = kmalloc(sizeof *n, GFP_KERNEL); >> 87 if (!n) >> 88 return -ENOMEM; >> 89 >> 90 n->addr = (Elf_Addr *)location; >> 91 n->value = v; >> 92 n->next = me->arch.r_mips_hi16_list; >> 93 me->arch.r_mips_hi16_list = n; 107 94 108 if (rel->r_offset < 0 || rel-> !! 95 return 0; 109 pr_err("%s: section %u !! 96 } 110 module->name, r << 111 rel->r_offset, << 112 return -ENOEXEC; << 113 } << 114 97 115 loc = dstsec->sh_addr + rel->r !! 98 static void free_relocation_chain(struct mips_hi16 *l) >> 99 { >> 100 struct mips_hi16 *next; 116 101 117 switch (ELF32_R_TYPE(rel->r_in !! 102 while (l) { 118 case R_ARM_NONE: !! 103 next = l->next; 119 /* ignore */ !! 104 kfree(l); 120 break; !! 105 l = next; >> 106 } >> 107 } 121 108 122 case R_ARM_ABS32: !! 109 static int apply_r_mips_lo16(struct module *me, u32 *location, 123 case R_ARM_TARGET1: !! 110 u32 base, Elf_Addr v, bool rela) 124 *(u32 *)loc += sym->st !! 111 { 125 break; !! 112 unsigned long insnlo = base; >> 113 struct mips_hi16 *l; >> 114 Elf_Addr val, vallo; >> 115 >> 116 if (rela) { >> 117 *location = (*location & 0xffff0000) | (v & 0xffff); >> 118 return 0; >> 119 } 126 120 127 case R_ARM_PC24: !! 121 /* Sign extend the addend we extract from the lo insn. */ 128 case R_ARM_CALL: !! 122 vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000; 129 case R_ARM_JUMP24: << 130 if (sym->st_value & 3) << 131 pr_err("%s: se << 132 module- << 133 return -ENOEXE << 134 } << 135 << 136 offset = __mem_to_opco << 137 offset = (offset & 0x0 << 138 offset = sign_extend32 << 139 123 140 offset += sym->st_valu !! 124 if (me->arch.r_mips_hi16_list != NULL) { >> 125 l = me->arch.r_mips_hi16_list; >> 126 while (l != NULL) { >> 127 struct mips_hi16 *next; >> 128 unsigned long insn; 141 129 142 /* 130 /* 143 * Route through a PLT !! 131 * The value for the HI16 had best be the same. 144 * supported range. No << 145 * contains the absolu << 146 * @sym + addend, corr << 147 */ 132 */ 148 if (IS_ENABLED(CONFIG_ !! 133 if (v != l->value) 149 (offset <= (s32)0x !! 134 goto out_danger; 150 offset >= (s32)0x << 151 offset = get_m << 152 << 153 - loc << 154 << 155 if (offset <= (s32)0xf << 156 offset >= (s32)0x0 << 157 pr_err("%s: se << 158 module- << 159 ELF32_R << 160 sym->st << 161 return -ENOEXE << 162 } << 163 135 164 offset >>= 2; !! 136 /* 165 offset &= 0x00ffffff; !! 137 * Do the HI16 relocation. Note that we actually don't >> 138 * need to know anything about the LO16 itself, except >> 139 * where to find the low 16 bits of the addend needed >> 140 * by the LO16. >> 141 */ >> 142 insn = *l->addr; >> 143 val = ((insn & 0xffff) << 16) + vallo; >> 144 val += v; 166 145 167 *(u32 *)loc &= __opcod !! 146 /* 168 *(u32 *)loc |= __opcod !! 147 * Account for the sign extension that will happen in 169 break; !! 148 * the low bits. >> 149 */ >> 150 val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff; 170 151 171 case R_ARM_V4BX: !! 152 insn = (insn & ~0xffff) | val; 172 /* Preserve Rm and the !! 153 *l->addr = insn; 173 * other bits to re-cod << 174 * MOV PC,Rm. << 175 */ << 176 *(u32 *)loc &= __opcode << 177 *(u32 *)loc |= __opcode << 178 break; << 179 << 180 case R_ARM_PREL31: << 181 offset = (*(s32 *)loc << 182 offset += sym->st_valu << 183 if (offset >= 0x400000 << 184 pr_err("%s: se << 185 module- << 186 ELF32_R << 187 sym->st << 188 return -ENOEXE << 189 } << 190 *(u32 *)loc &= 0x80000 << 191 *(u32 *)loc |= offset << 192 break; << 193 154 194 case R_ARM_REL32: !! 155 next = l->next; 195 *(u32 *)loc += sym->st !! 156 kfree(l); 196 break; !! 157 l = next; >> 158 } 197 159 198 case R_ARM_MOVW_ABS_NC: !! 160 me->arch.r_mips_hi16_list = NULL; 199 case R_ARM_MOVT_ABS: !! 161 } 200 case R_ARM_MOVW_PREL_NC: << 201 case R_ARM_MOVT_PREL: << 202 offset = tmp = __mem_t << 203 offset = ((offset & 0x << 204 offset = sign_extend32 << 205 << 206 offset += sym->st_valu << 207 if (ELF32_R_TYPE(rel-> << 208 ELF32_R_TYPE(rel-> << 209 offset -= loc; << 210 if (ELF32_R_TYPE(rel-> << 211 ELF32_R_TYPE(rel-> << 212 offset >>= 16; << 213 << 214 tmp &= 0xfff0f000; << 215 tmp |= ((offset & 0xf0 << 216 (offset & 0x0f << 217 162 218 *(u32 *)loc = __opcode !! 163 /* 219 break; !! 164 * Ok, we're done with the HI16 relocs. Now deal with the LO16. >> 165 */ >> 166 val = v + vallo; >> 167 insnlo = (insnlo & ~0xffff) | (val & 0xffff); >> 168 *location = insnlo; 220 169 221 #ifdef CONFIG_ARM_HAS_GROUP_RELOCS !! 170 return 0; 222 case R_ARM_ALU_PC_G0_NC: << 223 group = 0; << 224 fallthrough; << 225 case R_ARM_ALU_PC_G1_NC: << 226 tmp = __mem_to_opcode_ << 227 offset = ror32(tmp & 0 << 228 if (tmp & BIT(22)) << 229 offset = -offs << 230 offset += sym->st_valu << 231 if (offset < 0) { << 232 offset = -offs << 233 tmp = (tmp & ~ << 234 } else { << 235 tmp = (tmp & ~ << 236 } << 237 << 238 shift = get_group_rem( << 239 if (shift < 24) { << 240 offset >>= 24 << 241 offset |= (shi << 242 } << 243 *(u32 *)loc = __opcode << 244 break; << 245 171 246 case R_ARM_LDR_PC_G2: !! 172 out_danger: 247 tmp = __mem_to_opcode_ !! 173 free_relocation_chain(l); 248 offset = tmp & 0xfff; !! 174 me->arch.r_mips_hi16_list = NULL; 249 if (~tmp & BIT(23)) << 250 offset = -offs << 251 offset += sym->st_valu << 252 if (offset < 0) { << 253 offset = -offs << 254 tmp &= ~BIT(23 << 255 } else { << 256 tmp |= BIT(23) << 257 } << 258 get_group_rem(2, &offs << 259 << 260 if (offset > 0xfff) { << 261 pr_err("%s: se << 262 module- << 263 ELF32_R << 264 sym->st << 265 return -ENOEXE << 266 } << 267 *(u32 *)loc = __opcode << 268 break; << 269 #endif << 270 #ifdef CONFIG_THUMB2_KERNEL << 271 case R_ARM_THM_CALL: << 272 case R_ARM_THM_JUMP24: << 273 /* << 274 * For function symbol << 275 * allowed (no interwo << 276 * << 277 * For non-function sy << 278 * has no specific ARM << 279 * the branch is resol << 280 * that interworking i << 281 */ << 282 if (ELF32_ST_TYPE(sym- << 283 !(sym->st_value & << 284 pr_err("%s: se << 285 module- << 286 return -ENOEXE << 287 } << 288 175 289 upper = __mem_to_opcod !! 176 pr_err("module %s: dangerous R_MIPS_LO16 relocation\n", me->name); 290 lower = __mem_to_opcod << 291 177 292 /* !! 178 return -ENOEXEC; 293 * 25 bit signed addre !! 179 } 294 * instructions): << 295 * S:I1:I2:imm10:imm << 296 * where: << 297 * S = upper[10] << 298 * I1 = ~(J1 ^ S) << 299 * I2 = ~(J2 ^ S) << 300 * imm10 = upper[9:0 << 301 * imm11 = lower[10: << 302 * J1 = lower[13] << 303 * J2 = lower[11] << 304 */ << 305 sign = (upper >> 10) & << 306 j1 = (lower >> 13) & 1 << 307 j2 = (lower >> 11) & 1 << 308 offset = (sign << 24) << 309 ((~(j2 ^ sign) << 310 ((upper & 0x03 << 311 ((lower & 0x07 << 312 offset = sign_extend32 << 313 offset += sym->st_valu << 314 180 315 /* !! 181 static int apply_r_mips_pc(struct module *me, u32 *location, u32 base, 316 * Route through a PLT !! 182 Elf_Addr v, unsigned int bits) 317 * supported range. !! 183 { 318 */ !! 184 unsigned long mask = GENMASK(bits - 1, 0); 319 if (IS_ENABLED(CONFIG_ !! 185 unsigned long se_bits; 320 (offset <= (s32)0x !! 186 long offset; 321 offset >= (s32)0x !! 187 322 offset = get_m !! 188 if (v % 4) { 323 !! 189 pr_err("module %s: dangerous R_MIPS_PC%u relocation\n", 324 - loc !! 190 me->name, bits); 325 !! 191 return -ENOEXEC; 326 if (offset <= (s32)0xf !! 192 } 327 offset >= (s32)0x0 << 328 pr_err("%s: se << 329 module- << 330 ELF32_R << 331 sym->st << 332 return -ENOEXE << 333 } << 334 << 335 sign = (offset >> 24) << 336 j1 = sign ^ (~(offset << 337 j2 = sign ^ (~(offset << 338 upper = (u16)((upper & << 339 (( << 340 lower = (u16)((lower & << 341 (j1 << 1 << 342 ((offset << 343 193 344 *(u16 *)loc = __opcode !! 194 /* retrieve & sign extend implicit addend if any */ 345 *(u16 *)(loc + 2) = __ !! 195 offset = base & mask; 346 break; !! 196 offset |= (offset & BIT(bits - 1)) ? ~mask : 0; >> 197 >> 198 offset += ((long)v - (long)location) >> 2; >> 199 >> 200 /* check the sign bit onwards are identical - ie. we didn't overflow */ >> 201 se_bits = (offset & BIT(bits - 1)) ? ~0ul : 0; >> 202 if ((offset & ~mask) != (se_bits & ~mask)) { >> 203 pr_err("module %s: relocation overflow\n", me->name); >> 204 return -ENOEXEC; >> 205 } 347 206 348 case R_ARM_THM_MOVW_ABS_NC: !! 207 *location = (*location & ~mask) | (offset & mask); 349 case R_ARM_THM_MOVT_ABS: << 350 case R_ARM_THM_MOVW_PREL_NC: << 351 case R_ARM_THM_MOVT_PREL: << 352 upper = __mem_to_opcod << 353 lower = __mem_to_opcod << 354 208 355 /* !! 209 return 0; 356 * MOVT/MOVW instructi !! 210 } 357 * !! 211 358 * i = upper[10] !! 212 static int apply_r_mips_pc16(struct module *me, u32 *location, u32 base, 359 * imm4 = upper[3:0] !! 213 Elf_Addr v) 360 * imm3 = lower[14:12] !! 214 { 361 * imm8 = lower[7:0] !! 215 return apply_r_mips_pc(me, location, base, v, 16); 362 * !! 216 } 363 * imm16 = imm4:i:imm3 !! 217 364 */ !! 218 static int apply_r_mips_pc21(struct module *me, u32 *location, u32 base, 365 offset = ((upper & 0x0 !! 219 Elf_Addr v) 366 ((upper & 0x04 !! 220 { 367 ((lower & 0x70 !! 221 return apply_r_mips_pc(me, location, base, v, 21); 368 offset = sign_extend32 !! 222 } 369 offset += sym->st_valu !! 223 370 !! 224 static int apply_r_mips_pc26(struct module *me, u32 *location, u32 base, 371 if (ELF32_R_TYPE(rel-> !! 225 Elf_Addr v) 372 ELF32_R_TYPE(rel-> !! 226 { 373 offset -= loc; !! 227 return apply_r_mips_pc(me, location, base, v, 26); 374 if (ELF32_R_TYPE(rel-> !! 228 } 375 ELF32_R_TYPE(rel-> !! 229 376 offset >>= 16; !! 230 static int apply_r_mips_64(u32 *location, Elf_Addr v, bool rela) 377 !! 231 { 378 upper = (u16)((upper & !! 232 if (WARN_ON(!rela)) 379 ((offset !! 233 return -EINVAL; 380 ((offset !! 234 381 lower = (u16)((lower & !! 235 *(Elf_Addr *)location = v; 382 ((offset << 383 (offset << 384 *(u16 *)loc = __opcode << 385 *(u16 *)(loc + 2) = __ << 386 break; << 387 #endif << 388 236 389 default: << 390 pr_err("%s: unknown re << 391 module->name, E << 392 return -ENOEXEC; << 393 } << 394 } << 395 return 0; 237 return 0; 396 } 238 } 397 239 398 static const Elf_Shdr *find_mod_section(const !! 240 static int apply_r_mips_higher(u32 *location, Elf_Addr v, bool rela) 399 const Elf_Shdr *sechdrs, const char *n << 400 { 241 { 401 const Elf_Shdr *s, *se; !! 242 if (WARN_ON(!rela)) 402 const char *secstrs = (void *)hdr + se !! 243 return -EINVAL; 403 244 404 for (s = sechdrs, se = sechdrs + hdr-> !! 245 *location = (*location & 0xffff0000) | 405 if (strcmp(name, secstrs + s-> !! 246 ((((long long)v + 0x80008000LL) >> 32) & 0xffff); 406 return s; << 407 247 408 return NULL; !! 248 return 0; 409 } 249 } 410 250 411 extern void fixup_pv_table(const void *, unsig !! 251 static int apply_r_mips_highest(u32 *location, Elf_Addr v, bool rela) 412 extern void fixup_smp(const void *, unsigned l !! 252 { >> 253 if (WARN_ON(!rela)) >> 254 return -EINVAL; >> 255 >> 256 *location = (*location & 0xffff0000) | >> 257 ((((long long)v + 0x800080008000LL) >> 48) & 0xffff); >> 258 >> 259 return 0; >> 260 } 413 261 414 int module_finalize(const Elf32_Ehdr *hdr, con !! 262 /** 415 struct module *mod) !! 263 * reloc_handler() - Apply a particular relocation to a module >> 264 * @type: type of the relocation to apply >> 265 * @me: the module to apply the reloc to >> 266 * @location: the address at which the reloc is to be applied >> 267 * @base: the existing value at location for REL-style; 0 for RELA-style >> 268 * @v: the value of the reloc, with addend for RELA-style >> 269 * @rela: indication of is this a RELA (true) or REL (false) relocation >> 270 * >> 271 * Each implemented relocation function applies a particular type of >> 272 * relocation to the module @me. Relocs that may be found in either REL or RELA >> 273 * variants can be handled by making use of the @base & @v parameters which are >> 274 * set to values which abstract the difference away from the particular reloc >> 275 * implementations. >> 276 * >> 277 * Return: 0 upon success, else -ERRNO >> 278 */ >> 279 static int reloc_handler(u32 type, struct module *me, u32 *location, u32 base, >> 280 Elf_Addr v, bool rela) 416 { 281 { 417 const Elf_Shdr *s = NULL; !! 282 switch (type) { 418 #ifdef CONFIG_ARM_UNWIND !! 283 case R_MIPS_NONE: 419 const char *secstrs = (void *)hdr + se !! 284 break; 420 const Elf_Shdr *sechdrs_end = sechdrs !! 285 case R_MIPS_32: 421 struct list_head *unwind_list = &mod-> !! 286 apply_r_mips_32(location, base, v); >> 287 break; >> 288 case R_MIPS_26: >> 289 return apply_r_mips_26(me, location, base, v); >> 290 case R_MIPS_HI16: >> 291 return apply_r_mips_hi16(me, location, v, rela); >> 292 case R_MIPS_LO16: >> 293 return apply_r_mips_lo16(me, location, base, v, rela); >> 294 case R_MIPS_PC16: >> 295 return apply_r_mips_pc16(me, location, base, v); >> 296 case R_MIPS_PC21_S2: >> 297 return apply_r_mips_pc21(me, location, base, v); >> 298 case R_MIPS_PC26_S2: >> 299 return apply_r_mips_pc26(me, location, base, v); >> 300 case R_MIPS_64: >> 301 return apply_r_mips_64(location, v, rela); >> 302 case R_MIPS_HIGHER: >> 303 return apply_r_mips_higher(location, v, rela); >> 304 case R_MIPS_HIGHEST: >> 305 return apply_r_mips_highest(location, v, rela); >> 306 default: >> 307 pr_err("%s: Unknown relocation type %u\n", me->name, type); >> 308 return -EINVAL; >> 309 } 422 310 423 INIT_LIST_HEAD(unwind_list); !! 311 return 0; 424 mod->arch.init_table = NULL; !! 312 } 425 313 426 for (s = sechdrs; s < sechdrs_end; s++ !! 314 static int __apply_relocate(Elf_Shdr *sechdrs, const char *strtab, 427 const char *secname = secstrs !! 315 unsigned int symindex, unsigned int relsec, 428 const char *txtname; !! 316 struct module *me, bool rela) 429 const Elf_Shdr *txt_sec; !! 317 { >> 318 union { >> 319 Elf_Mips_Rel *rel; >> 320 Elf_Mips_Rela *rela; >> 321 } r; >> 322 Elf_Sym *sym; >> 323 u32 *location, base; >> 324 unsigned int i, type; >> 325 Elf_Addr v; >> 326 int err = 0; >> 327 size_t reloc_sz; >> 328 >> 329 pr_debug("Applying relocate section %u to %u\n", relsec, >> 330 sechdrs[relsec].sh_info); >> 331 >> 332 r.rel = (void *)sechdrs[relsec].sh_addr; >> 333 reloc_sz = rela ? sizeof(*r.rela) : sizeof(*r.rel); >> 334 me->arch.r_mips_hi16_list = NULL; >> 335 for (i = 0; i < sechdrs[relsec].sh_size / reloc_sz; i++) { >> 336 /* This is where to make the change */ >> 337 location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr >> 338 + r.rel->r_offset; >> 339 /* This is the symbol it is referring to */ >> 340 sym = (Elf_Sym *)sechdrs[symindex].sh_addr >> 341 + ELF_MIPS_R_SYM(*r.rel); >> 342 if (sym->st_value >= -MAX_ERRNO) { >> 343 /* Ignore unresolved weak symbol */ >> 344 if (ELF_ST_BIND(sym->st_info) == STB_WEAK) >> 345 continue; >> 346 pr_warn("%s: Unknown symbol %s\n", >> 347 me->name, strtab + sym->st_name); >> 348 err = -ENOENT; >> 349 goto out; >> 350 } 430 351 431 if (!(s->sh_flags & SHF_ALLOC) !! 352 type = ELF_MIPS_R_TYPE(*r.rel); 432 s->sh_type != ELF_SECTION_ << 433 continue; << 434 353 435 if (!strcmp(".ARM.exidx", secn !! 354 if (rela) { 436 txtname = ".text"; !! 355 v = sym->st_value + r.rela->r_addend; 437 else !! 356 base = 0; 438 txtname = secname + st !! 357 r.rela = &r.rela[1]; 439 txt_sec = find_mod_section(hdr !! 358 } else { 440 !! 359 v = sym->st_value; 441 if (txt_sec) { !! 360 base = *location; 442 struct unwind_table *t !! 361 r.rel = &r.rel[1]; 443 unwind_table_a << 444 << 445 << 446 << 447 << 448 list_add(&table->mod_l << 449 << 450 /* save init table for << 451 if (strcmp(".ARM.exidx << 452 mod->arch.init << 453 } 362 } >> 363 >> 364 err = reloc_handler(type, me, location, base, v, rela); >> 365 if (err) >> 366 goto out; 454 } 367 } 455 #endif !! 368 456 #ifdef CONFIG_ARM_PATCH_PHYS_VIRT !! 369 out: 457 s = find_mod_section(hdr, sechdrs, ".p !! 370 /* 458 if (s) !! 371 * Normally the hi16 list should be deallocated at this point. A 459 fixup_pv_table((void *)s->sh_a !! 372 * malformed binary however could contain a series of R_MIPS_HI16 460 #endif !! 373 * relocations not followed by a R_MIPS_LO16 relocation, or if we hit 461 s = find_mod_section(hdr, sechdrs, ".a !! 374 * an error processing a reloc we might have gotten here before 462 if (s && !is_smp()) !! 375 * reaching the R_MIPS_LO16. In either case, free up the list and 463 #ifdef CONFIG_SMP_ON_UP !! 376 * return an error. 464 fixup_smp((void *)s->sh_addr, !! 377 */ 465 #else !! 378 if (me->arch.r_mips_hi16_list) { 466 return -EINVAL; !! 379 free_relocation_chain(me->arch.r_mips_hi16_list); 467 #endif !! 380 me->arch.r_mips_hi16_list = NULL; 468 return 0; !! 381 err = err ?: -ENOEXEC; >> 382 } >> 383 >> 384 return err; 469 } 385 } 470 386 471 void !! 387 int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, 472 module_arch_cleanup(struct module *mod) !! 388 unsigned int symindex, unsigned int relsec, >> 389 struct module *me) 473 { 390 { 474 #ifdef CONFIG_ARM_UNWIND !! 391 return __apply_relocate(sechdrs, strtab, symindex, relsec, me, false); 475 struct unwind_table *tmp; !! 392 } 476 struct unwind_table *n; !! 393 477 !! 394 #ifdef CONFIG_MODULES_USE_ELF_RELA 478 list_for_each_entry_safe(tmp, n, !! 395 int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, 479 &mod->arch.unwind_list !! 396 unsigned int symindex, unsigned int relsec, 480 list_del(&tmp->mod_list); !! 397 struct module *me) 481 unwind_table_del(tmp); !! 398 { >> 399 return __apply_relocate(sechdrs, strtab, symindex, relsec, me, true); >> 400 } >> 401 #endif /* CONFIG_MODULES_USE_ELF_RELA */ >> 402 >> 403 /* Given an address, look for it in the module exception tables. */ >> 404 const struct exception_table_entry *search_module_dbetables(unsigned long addr) >> 405 { >> 406 unsigned long flags; >> 407 const struct exception_table_entry *e = NULL; >> 408 struct mod_arch_specific *dbe; >> 409 >> 410 spin_lock_irqsave(&dbe_lock, flags); >> 411 list_for_each_entry(dbe, &dbe_list, dbe_list) { >> 412 e = search_extable(dbe->dbe_start, >> 413 dbe->dbe_end - dbe->dbe_start, addr); >> 414 if (e) >> 415 break; 482 } 416 } 483 mod->arch.init_table = NULL; !! 417 spin_unlock_irqrestore(&dbe_lock, flags); 484 #endif !! 418 >> 419 /* Now, if we found one, we are running inside it now, hence >> 420 we cannot unload the module, hence no refcnt needed. */ >> 421 return e; 485 } 422 } 486 423 487 void __weak module_arch_freeing_init(struct mo !! 424 /* Put in dbe list if necessary. */ >> 425 int module_finalize(const Elf_Ehdr *hdr, >> 426 const Elf_Shdr *sechdrs, >> 427 struct module *me) 488 { 428 { 489 #ifdef CONFIG_ARM_UNWIND !! 429 const Elf_Shdr *s; 490 struct unwind_table *init = mod->arch. !! 430 char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; >> 431 >> 432 if (IS_ENABLED(CONFIG_JUMP_LABEL)) >> 433 jump_label_apply_nops(me); 491 434 492 if (init) { !! 435 INIT_LIST_HEAD(&me->arch.dbe_list); 493 mod->arch.init_table = NULL; !! 436 for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { 494 list_del(&init->mod_list); !! 437 if (strcmp("__dbe_table", secstrings + s->sh_name) != 0) 495 unwind_table_del(init); !! 438 continue; >> 439 me->arch.dbe_start = (void *)s->sh_addr; >> 440 me->arch.dbe_end = (void *)s->sh_addr + s->sh_size; >> 441 spin_lock_irq(&dbe_lock); >> 442 list_add(&me->arch.dbe_list, &dbe_list); >> 443 spin_unlock_irq(&dbe_lock); 496 } 444 } 497 #endif !! 445 return 0; >> 446 } >> 447 >> 448 void module_arch_cleanup(struct module *mod) >> 449 { >> 450 spin_lock_irq(&dbe_lock); >> 451 list_del(&mod->arch.dbe_list); >> 452 spin_unlock_irq(&dbe_lock); 498 } 453 } 499 454
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.