1

When bisecting the Linux kernel to find a bug (in my case between v4.4 and v4.9), I'm encountering the following build error:

RELOCS  arch/x86/boot/compressed/vmlinux.relocs
Unsupported relocation type: R_X86_64_PLT32 (4)

What can be done against that?

I have found various other places where people report this issue:

2 Answers 2

1

There seems to be an incompatibility with newer versions of binutils.

I found that GNU binutils 2.31.1 results in this bug, but using version 2.30 instead fixes the problem.


Source:

I eventually found the answer in this chat log where user deviosity says:

and keep runnning into the dreaded: Unsupported relocation type: R_X86_64_PLT32 (4) error, which usually is resolved by downgrading binutils to 2.30 versus 2.31

and this comment also confirms it (Ubuntu 16.04 also uses an older binutils version, 2.26.1).

1
  • 1
    Thanks for this! I am now building these kernel versions using a chroot of Ubuntu 16.04. I disabled "Enable loadable module support -> Module signature verification" (CONFIG_MODULE_SIG) in my Fedora kernel config, to avoid an error when I make modules_install on the main system, due to a cryptography library version mismatch.
    – sourcejedi
    Jul 3, 2019 at 13:47
1

I found the following patch on https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b21ebf2fb4cde1618915a97cc773e287ff49173e

I had to patch module.c manually, as that patch failed.

diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index 1f790cf9d38f..3b7427aa7d85 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -542,6 +542,7 @@ int arch_kexec_apply_relocations_add(const Elf64_Ehdr *ehdr,
                goto overflow;
            break;
        case R_X86_64_PC32:
+       case R_X86_64_PLT32:
            value -= (u64)address;
            *(u32 *)location = value;
            break;
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
index da0c160e5589..f58336af095c 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -191,6 +191,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
                goto overflow;
            break;
        case R_X86_64_PC32:
+       case R_X86_64_PLT32:
            if (*(u32 *)loc != 0)
                goto invalid_relocation;
            val -= (u64)loc;
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
index 5d73c443e778..220e97841e49 100644
--- a/arch/x86/tools/relocs.c
+++ b/arch/x86/tools/relocs.c
@@ -770,9 +770,12 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
        break;

    case R_X86_64_PC32:
+   case R_X86_64_PLT32:
        /*
         * PC relative relocations don't need to be adjusted unless
         * referencing a percpu symbol.
+        *
+        * NB: R_X86_64_PLT32 can be treated as R_X86_64_PC32.
         */
        if (is_percpu_sym(sym, symname))
            add_reloc(&relocs32neg, offset);

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .