powerpc/64: Add UADDR64 relocation support
authorAlexey Kardashevskiy <aik@ozlabs.ru>
Wed, 9 Mar 2022 06:18:22 +0000 (17:18 +1100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 May 2022 07:16:33 +0000 (09:16 +0200)
commit42af65b705a516f98773dacee076d1ac167919af
tree2801986d2e14a3e3a34cef208668eec37bfa1894
parentd17f64c295124e198a707f0e1e40ee298d919271
powerpc/64: Add UADDR64 relocation support

commit d799769188529abc6cbf035a10087a51f7832b6b upstream.

When ld detects unaligned relocations, it emits R_PPC64_UADDR64
relocations instead of R_PPC64_RELATIVE. Currently R_PPC64_UADDR64 are
detected by arch/powerpc/tools/relocs_check.sh and expected not to work.
Below is a simple chunk to trigger this behaviour (this disables
optimization for the demonstration purposes only, this also happens with
-O1/-O2 when CONFIG_PRINTK_INDEX=y, for example):

  \#pragma GCC push_options
  \#pragma GCC optimize ("O0")
  struct entry {
          const char *file;
          int line;
  } __attribute__((packed));
  static const struct entry e1 = { .file = __FILE__, .line = __LINE__ };
  static const struct entry e2 = { .file = __FILE__, .line = __LINE__ };
  ...
  prom_printf("e1=%s %lx %lx\n", e1.file, (unsigned long) e1.file, mfmsr());
  prom_printf("e2=%s %lx\n", e2.file, (unsigned long) e2.file);
  \#pragma GCC pop_options

This adds support for UADDR64 for 64bit. This reuses __dynamic_symtab
from the 32bit code which supports more relocation types already.

Because RELACOUNT includes only R_PPC64_RELATIVE, this replaces it with
RELASZ which is the size of all relocation records.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nathan Chancellor <nathan@kernel.org>
Link: https://lore.kernel.org/r/20220309061822.168173-1-aik@ozlabs.ru
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/powerpc/kernel/reloc_64.S
arch/powerpc/kernel/vmlinux.lds.S
arch/powerpc/tools/relocs_check.sh