DEBUGP("Applying relocate section %u to %u\n",
relsec, sechdrs[relsec].sh_info); for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { /* This is where to make the change */
location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ rel[i].r_offset; /* This is the symbol it is referring to. Note that all
undefined symbols have been resolved. */
sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+ ELF32_R_SYM(rel[i].r_info);
switch (ELF32_R_TYPE(rel[i].r_info)) { case R_386_32: /* We add the value into the location given */
*location += sym->st_value; break; case R_386_PC32: case R_386_PLT32: /* Add the value, subtract its position */
*location += sym->st_value - (uint32_t)location; break; default:
pr_err("%s: Unknown relocation: %u\n",
me->name, ELF32_R_TYPE(rel[i].r_info)); return -ENOEXEC;
}
} return 0;
} #else/*X86_64*/ staticint __write_relocate_add(Elf64_Shdr *sechdrs, constchar *strtab, unsignedint symindex, unsignedint relsec, struct module *me, void *(*write)(void *dest, constvoid *src, size_t len), bool apply)
{ unsignedint i;
Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
Elf64_Sym *sym; void *loc;
u64 val;
u64 zero = 0ULL;
DEBUGP("%s relocate section %u to %u\n",
apply ? "Applying" : "Clearing",
relsec, sechdrs[relsec].sh_info); for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
size_t size;
/* This is where to make the change */
loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ rel[i].r_offset;
/* This is the symbol it is referring to. Note that all
undefined symbols have been resolved. */
sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
+ ELF64_R_SYM(rel[i].r_info);
val = (u64)&addr + rel[i].r_addend;
fallthrough;
} #endif case R_X86_64_PC32: case R_X86_64_PLT32:
val -= (u64)loc;
size = 4; break; case R_X86_64_PC64:
val -= (u64)loc;
size = 8; break; default:
pr_err("%s: Unknown rela relocation: %llu\n",
me->name, ELF64_R_TYPE(rel[i].r_info)); return -ENOEXEC;
}
if (apply) { if (memcmp(loc, &zero, size)) {
pr_err("x86/modules: Invalid relocation target, existing value is nonzero for type %d, loc %p, val %Lx\n",
(int)ELF64_R_TYPE(rel[i].r_info), loc, val); return -ENOEXEC;
}
write(loc, &val, size);
} else { if (memcmp(loc, &val, size)) {
pr_warn("x86/modules: Invalid relocation target, existing value does not match expected value for type %d, loc %p, val %Lx\n",
(int)ELF64_R_TYPE(rel[i].r_info), loc, val); return -ENOEXEC;
}
write(loc, &zero, size);
}
} return 0;
overflow:
pr_err("overflow in relocation type %d val %Lx\n",
(int)ELF64_R_TYPE(rel[i].r_info), val);
pr_err("`%s' likely not compiled with -mcmodel=kernel\n",
me->name); return -ENOEXEC;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.