^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Kernel module help for x86.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) Copyright (C) 2001 Rusty Russell.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/moduleloader.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/elf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/kasan.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/jump_label.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/memory.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/text-patching.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/setup.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <asm/unwind.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define DEBUGP(fmt, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) printk(KERN_DEBUG fmt, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define DEBUGP(fmt, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) if (0) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) printk(KERN_DEBUG fmt, ##__VA_ARGS__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #ifdef CONFIG_RANDOMIZE_BASE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static unsigned long module_load_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* Mutex protects the module_load_offset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static DEFINE_MUTEX(module_kaslr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static unsigned long int get_module_load_offset(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (kaslr_enabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) mutex_lock(&module_kaslr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * Calculate the module_load_offset the first time this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * code is called. Once calculated it stays the same until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * reboot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (module_load_offset == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) module_load_offset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) (get_random_int() % 1024 + 1) * PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) mutex_unlock(&module_kaslr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return module_load_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static unsigned long int get_module_load_offset(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) void *module_alloc(unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (PAGE_ALIGN(size) > MODULES_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) p = __vmalloc_node_range(size, MODULE_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) MODULES_VADDR + get_module_load_offset(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) MODULES_END, GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) PAGE_KERNEL, 0, NUMA_NO_NODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) __builtin_return_address(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (p && (kasan_module_alloc(p, size) < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) vfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #ifdef CONFIG_X86_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) int apply_relocate(Elf32_Shdr *sechdrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) const char *strtab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) unsigned int symindex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) unsigned int relsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct module *me)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) Elf32_Sym *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) uint32_t *location;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) DEBUGP("Applying relocate section %u to %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) relsec, sechdrs[relsec].sh_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* This is where to make the change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) + rel[i].r_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* This is the symbol it is referring to. Note that all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) undefined symbols have been resolved. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) + ELF32_R_SYM(rel[i].r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) switch (ELF32_R_TYPE(rel[i].r_info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) case R_386_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* We add the value into the location given */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) *location += sym->st_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) case R_386_PC32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) case R_386_PLT32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* Add the value, subtract its position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) *location += sym->st_value - (uint32_t)location;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) pr_err("%s: Unknown relocation: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) me->name, ELF32_R_TYPE(rel[i].r_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return -ENOEXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #else /*X86_64*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static int __apply_relocate_add(Elf64_Shdr *sechdrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) const char *strtab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) unsigned int symindex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) unsigned int relsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct module *me,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) void *(*write)(void *dest, const void *src, size_t len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) Elf64_Sym *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) void *loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) u64 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) DEBUGP("Applying relocate section %u to %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) relsec, sechdrs[relsec].sh_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* This is where to make the change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) + rel[i].r_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* This is the symbol it is referring to. Note that all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) undefined symbols have been resolved. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) + ELF64_R_SYM(rel[i].r_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) DEBUGP("type %d st_value %Lx r_addend %Lx loc %Lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) (int)ELF64_R_TYPE(rel[i].r_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) sym->st_value, rel[i].r_addend, (u64)loc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) val = sym->st_value + rel[i].r_addend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) switch (ELF64_R_TYPE(rel[i].r_info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) case R_X86_64_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) case R_X86_64_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (*(u64 *)loc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) goto invalid_relocation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) write(loc, &val, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) case R_X86_64_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (*(u32 *)loc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) goto invalid_relocation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) write(loc, &val, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (val != *(u32 *)loc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) goto overflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) case R_X86_64_32S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (*(s32 *)loc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) goto invalid_relocation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) write(loc, &val, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if ((s64)val != *(s32 *)loc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) goto overflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) case R_X86_64_PC32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) case R_X86_64_PLT32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (*(u32 *)loc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) goto invalid_relocation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) val -= (u64)loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) write(loc, &val, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if ((s64)val != *(s32 *)loc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) goto overflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) case R_X86_64_PC64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (*(u64 *)loc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) goto invalid_relocation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) val -= (u64)loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) write(loc, &val, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) case R_X86_64_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (!strncmp(strtab + sym->st_name, "__typeid__", 10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* fallthrough */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) pr_err("%s: Unknown rela relocation: %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) me->name, ELF64_R_TYPE(rel[i].r_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return -ENOEXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) invalid_relocation:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) pr_err("x86/modules: Skipping invalid relocation target, existing value is nonzero for type %d, loc %p, val %Lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) (int)ELF64_R_TYPE(rel[i].r_info), loc, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return -ENOEXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) overflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) pr_err("overflow in relocation type %d val %Lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) (int)ELF64_R_TYPE(rel[i].r_info), val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) pr_err("`%s' likely not compiled with -mcmodel=kernel\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) me->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return -ENOEXEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) int apply_relocate_add(Elf64_Shdr *sechdrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) const char *strtab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) unsigned int symindex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) unsigned int relsec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct module *me)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) bool early = me->state == MODULE_STATE_UNFORMED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) void *(*write)(void *, const void *, size_t) = memcpy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (!early) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) write = text_poke;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) mutex_lock(&text_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) ret = __apply_relocate_add(sechdrs, strtab, symindex, relsec, me,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (!early) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) text_poke_sync();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) mutex_unlock(&text_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) int module_finalize(const Elf_Ehdr *hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) const Elf_Shdr *sechdrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct module *me)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) *para = NULL, *orc = NULL, *orc_ip = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (!strcmp(".text", secstrings + s->sh_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) text = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (!strcmp(".altinstructions", secstrings + s->sh_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) alt = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (!strcmp(".smp_locks", secstrings + s->sh_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) locks = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (!strcmp(".parainstructions", secstrings + s->sh_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) para = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (!strcmp(".orc_unwind", secstrings + s->sh_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) orc = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (!strcmp(".orc_unwind_ip", secstrings + s->sh_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) orc_ip = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (alt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /* patch .altinstructions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) void *aseg = (void *)alt->sh_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) apply_alternatives(aseg, aseg + alt->sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (locks && text) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) void *lseg = (void *)locks->sh_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) void *tseg = (void *)text->sh_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) alternatives_smp_module_add(me, me->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) lseg, lseg + locks->sh_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) tseg, tseg + text->sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (para) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) void *pseg = (void *)para->sh_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) apply_paravirt(pseg, pseg + para->sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /* make jump label nops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) jump_label_apply_nops(me);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (orc && orc_ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) unwind_module_init(me, (void *)orc_ip->sh_addr, orc_ip->sh_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) (void *)orc->sh_addr, orc->sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) void module_arch_cleanup(struct module *mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) alternatives_smp_module_del(mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }