From 08869deb7efbda6e979886cb67e3d5843f92c2e8 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Sun, 30 Jun 2019 07:39:20 -0500 Subject: add support for powerpc/powerpc64 unaligned relocations R_PPC_UADDR32 (R_PPC64_UADDR64) has the same meaning as R_PPC_ADDR32 (R_PPC64_ADDR64), except that its address need not be aligned. For powerpc64, BFD ld(1) will automatically convert between ADDR<->UADDR relocations when the address is/isn't at its native alignment. This will happen if, for example, there is a pointer in a packed struct. gold and lld do not currently generate R_PPC64_UADDR64, but pass through misaligned R_PPC64_ADDR64 relocations from object files, possibly relaxing them to misaligned R_PPC64_RELATIVE. In both cases (relaxed or not) this violates the PSABI, which defines the relevant field type as "a 64-bit field occupying 8 bytes, the alignment of which is 8 bytes unless otherwise specified." All three linkers violate the PSABI on 32-bit powerpc, where the only difference is that the field is 32 bits wide, aligned to 4 bytes. Currently musl fails to load executables linked by BFD ld containing R_PPC64_UADDR64, with the error "unsupported relocation type 43". This change provides compatibility with BFD ld on powerpc64, and any static linker on either architecture that starts following the PSABI more closely. --- ldso/dynlink.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'ldso/dynlink.c') diff --git a/ldso/dynlink.c b/ldso/dynlink.c index 531811cc..edd91acd 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -407,6 +407,9 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri case REL_PLT: *reloc_addr = sym_val + addend; break; + case REL_USYMBOLIC: + memcpy(reloc_addr, &(size_t){sym_val + addend}, sizeof(size_t)); + break; case REL_RELATIVE: *reloc_addr = (size_t)base + addend; break; -- cgit v1.2.1