Add support for R_X86_64_PLT32

Starting with binutils 2.31, the Linux kernel may have R_X86_64_PLT32
relocations. Make sure we support them. This should be as simple as
treating R_X86_64_PLT32 exactly like R_X86_64_PC32 everywhere. For more
details see upstream commit torvalds/linux@b21ebf2.

This also fixes the following issue seen on Fedora 29:

```
$ kpatch-build/kpatch-build -t vmlinux ./test/integration/fedora-27/convert-global-local.patch
Using cache at /home/jpoimboe/.kpatch/src
Testing patch file(s)
Reading special section data
Building original source
Building patched source
Extracting new and modified ELF sections
ERROR: slub.o: 1 function(s) can not be patched
slub.o: function __kmalloc has no fentry/mcount call, unable to patch
/home/jpoimboe/git/kpatch/kpatch-build/create-diff-object: unreconcilable difference
ERROR: 1 error(s) encountered. Check /home/jpoimboe/.kpatch/build.log for more details.
```

Fixes #975.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
This commit is contained in:
Josh Poimboeuf 2019-07-05 11:45:50 -05:00
parent 2f343f1861
commit b5745d7ea6
3 changed files with 6 additions and 2 deletions

View File

@ -700,6 +700,7 @@ static int kpatch_write_relocations(struct kpatch_module *kpmod,
case R_X86_64_NONE:
continue;
case R_X86_64_PC32:
case R_X86_64_PLT32:
loc = dynrela->dest;
val = (u32)(dynrela->src + dynrela->addend -
dynrela->dest);

View File

@ -1288,7 +1288,8 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf)
#ifdef __powerpc64__
add_off = 0;
#else
if (rela->type == R_X86_64_PC32) {
if (rela->type == R_X86_64_PC32 ||
rela->type == R_X86_64_PLT32) {
struct insn insn;
rela_insn(sec, rela, &insn);
add_off = (long)insn.next_byte -

View File

@ -332,7 +332,9 @@ static void kpatch_find_func_profiling_calls(struct kpatch_elf *kelf)
#else
rela = list_first_entry(&sym->sec->rela->relas, struct rela,
list);
if ((rela->type != R_X86_64_NONE && rela->type != R_X86_64_PC32) ||
if ((rela->type != R_X86_64_NONE &&
rela->type != R_X86_64_PC32 &&
rela->type != R_X86_64_PLT32) ||
strcmp(rela->sym->name, "__fentry__"))
continue;