19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22 #include <linux/elf.h>
25 #include <linux/string.h>
26 #include <linux/kernel.h>
33 #include <asm/pgtable.h>
36 #define DEBUGP(fmt, ...) \
37 printk(KERN_DEBUG fmt, ##__VA_ARGS__)
39 #define DEBUGP(fmt, ...) \
42 printk(KERN_DEBUG fmt, ##__VA_ARGS__); \
52 -1, __builtin_return_address(0));
58 unsigned int symindex,
63 Elf32_Rel *rel = (
void *)sechdrs[relsec].sh_addr;
67 DEBUGP(
"Applying relocate section %u to %u\n",
68 relsec, sechdrs[relsec].sh_info);
69 for (i = 0; i < sechdrs[relsec].
sh_size /
sizeof(*rel); i++) {
71 location = (
void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
75 sym = (
Elf32_Sym *)sechdrs[symindex].sh_addr
88 pr_err(
"%s: Unknown relocation: %u\n",
98 unsigned int symindex,
103 Elf64_Rela *rel = (
void *)sechdrs[relsec].sh_addr;
108 DEBUGP(
"Applying relocate section %u to %u\n",
109 relsec, sechdrs[relsec].sh_info);
110 for (i = 0; i < sechdrs[relsec].
sh_size /
sizeof(*rel); i++) {
112 loc = (
void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
117 sym = (
Elf64_Sym *)sechdrs[symindex].sh_addr
120 DEBUGP(
"type %d st_value %Lx r_addend %Lx loc %Lx\n",
139 if ((
s64)val != *(
s32 *)loc)
146 if ((
s64)val != *(
s32 *)loc)
151 pr_err(
"%s: Unknown rela relocation: %llu\n",
159 pr_err(
"overflow in relocation type %d val %Lx\n",
161 pr_err(
"`%s' likely not compiled with -mcmodel=kernel\n",
173 char *secstrings = (
void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
175 for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
176 if (!
strcmp(
".text", secstrings + s->sh_name))
178 if (!
strcmp(
".altinstructions", secstrings + s->sh_name))
180 if (!
strcmp(
".smp_locks", secstrings + s->sh_name))
182 if (!
strcmp(
".parainstructions", secstrings + s->sh_name))
188 void *aseg = (
void *)alt->sh_addr;
192 void *lseg = (
void *)locks->sh_addr;
193 void *tseg = (
void *)text->sh_addr;
194 alternatives_smp_module_add(me, me->
name,
195 lseg, lseg + locks->sh_size,
196 tseg, tseg + text->sh_size);
200 void *pseg = (
void *)para->sh_addr;
201 apply_paravirt(pseg, pseg + para->sh_size);
205 jump_label_apply_nops(me);
212 alternatives_smp_module_del(mod);