From 686652a12e6d5042a11b5b2a2bf6a15fae361e80 Mon Sep 17 00:00:00 2001 From: Piotr Kubaj Date: Fri, 6 Nov 2026 08:18:39 +0100 Subject: [PATCH] ld: read the FreeBSD ELF hints file in either byte order FreeBSD's ldconfig writes the hints file in little-endian byte order on all architectures unless it is run with -B, so the header is not necessarily in host byte order. This causes an issue when trying to link some software on powerpc64 (big-endian POWER). Signed-off-by: Piotr Kubaj --- ld/ldelf.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/ld/ldelf.c b/ld/ldelf.c index 00923bd81e6..d3c24543d61 100644 --- a/ld/ldelf.c +++ b/ld/ldelf.c @@ -780,18 +780,29 @@ ldelf_check_ld_elf_hints (const struct bfd_link_needed_list *l, int force, if (f != NULL) { struct elfhints_hdr hdr; + bfd_vma (*get32) (const void *) = NULL; - if (fread (&hdr, 1, sizeof (hdr), f) == sizeof (hdr) - && hdr.magic == ELFHINTS_MAGIC - && hdr.version == 1) + /* FreeBSD's ldconfig writes the hints file in little-endian + byte order on all architectures unless it is run with -B, + so the header is not necessarily in host byte order. */ + if (fread (&hdr, 1, sizeof (hdr), f) == sizeof (hdr)) { - if (fseek (f, hdr.strtab + hdr.dirlist, SEEK_SET) != -1) + if (bfd_getl32 (&hdr.magic) == ELFHINTS_MAGIC) + get32 = bfd_getl32; + else if (bfd_getb32 (&hdr.magic) == ELFHINTS_MAGIC) + get32 = bfd_getb32; + } + + if (get32 != NULL && get32 (&hdr.version) == 1) + { + if (fseek (f, get32 (&hdr.strtab) + get32 (&hdr.dirlist), + SEEK_SET) != -1) { + unsigned long dirlistlen = get32 (&hdr.dirlistlen); char *b; - b = xmalloc (hdr.dirlistlen + 1); - if (fread (b, 1, hdr.dirlistlen + 1, f) == - hdr.dirlistlen + 1) + b = xmalloc (dirlistlen + 1); + if (fread (b, 1, dirlistlen + 1, f) == dirlistlen + 1) ld_elf_hints = ldelf_add_sysroot (b); free (b); -- 2.43.7