On Mon, 21 Jul 2025, Corinna Vinschen wrote: > Jeremy? > > On Jul 21 07:56, Radek Barton via Cygwin-patches wrote: > > Hello. > > > > Sending a patch with AArch64 +/-4GB relocations in mkimport as promised at > > https://sourceware.org/pipermail/cygwin-patches/2025q3/014155.html > > > > Radek > > > > --- > > >From 3ec4e2136942ade5856310ee1f4d9d89359c3c79 Mon Sep 17 00:00:00 2001 > > From: =?UTF-8?q?Radek=20Barto=C5=88?= <radek.bar...@microsoft.com> > > Date: Sat, 19 Jul 2025 19:17:12 +0200 > > Subject: [PATCH] Cygwin: mkimport: implement AArch64 +/-4GB relocations > > MIME-Version: 1.0 > > Content-Type: text/plain; charset=UTF-8 > > Content-Transfer-Encoding: 8bit > > > > Based on https://sourceware.org/pipermail/cygwin-patches/2025q3/014154.html > > suggestion, this patch implements +/-4GB relocations for AArch64 in the > > mkimport > > script by using adrp and ldr instructions. This change required update > > in winsup\cygwin\mm\malloc_wrapper.cc where those instructions are > > decoded to get target import address.
How is malloc_wrapper used? Is it expected to only look at the imports generated by mkimport, or does it need to work in the face of arbitrary binaries? MSVC and LLD seem to both use the adrp/ldr-with-offset form which mkimport generates with this patch, but looking at the source of binutils it looks like it does adrp/add/ldr-0-offset so if it is expected to deal with an import stub from an import library generated by dlltool this code would probably have to also account for getting the lower 12 bits from an add instruction as well as from an ldr offset. I went through a lot of this in aarch64/fastcwd I don't know if there's some sane way to refactor to share that (or if it's even worth it for these 3 instructions). > > > > Signed-off-by: Radek Bartoň <radek.bar...@microsoft.com> > > --- > > winsup/cygwin/mm/malloc_wrapper.cc | 23 ++++++++++++++--------- > > winsup/cygwin/scripts/mkimport | 4 ++-- > > 2 files changed, 16 insertions(+), 11 deletions(-) > > > > diff --git a/winsup/cygwin/mm/malloc_wrapper.cc > > b/winsup/cygwin/mm/malloc_wrapper.cc > > index 863d3089c..5ca4da587 100644 > > --- a/winsup/cygwin/mm/malloc_wrapper.cc > > +++ b/winsup/cygwin/mm/malloc_wrapper.cc > > @@ -51,16 +51,21 @@ import_address (void *imp) > > __try > > { > > #if defined(__aarch64__) > > - // If opcode is an adr instruction. > > - uint32_t opcode = *(uint32_t *) imp; > > - if ((opcode & 0x9f000000) == 0x10000000) > > + // If opcode1 is an adrp and opcode2 is ldr instruction: > > + // - https://www.scs.stanford.edu/~zyedidia/arm64/adrp.html > > + // - https://www.scs.stanford.edu/~zyedidia/arm64/ldr_imm_gen.html > > + uint32_t opcode1 = *((uint32_t *) imp); > > + uint32_t opcode2 = *(((uint32_t *) imp) + 1); > > + if (((opcode1 & 0x9f000000) == 0x90000000) && ((opcode2 & > > 0xbfc00000) == 0xb9400000)) > > { > > - uint32_t immhi = (opcode >> 5) & 0x7ffff; > > - uint32_t immlo = (opcode >> 29) & 0x3; > > - int64_t sign_extend = (0l - (immhi >> 18)) << 21; > > - int64_t imm = sign_extend | (immhi << 2) | immlo; > > - uintptr_t jmpto = *(uintptr_t *) ((uint8_t *) imp + imm); > > - return (void *) jmpto; > > + uint32_t immhi = (opcode1 >> 5) & 0x7ffff; > > + uint32_t immlo = (opcode1 >> 29) & 0x3; > > + uint32_t imm12 = ((opcode2 >> 10) & 0xfff) * 8; // 64 bit scale > > + int64_t sign_extend = (0l - ((int64_t) immhi >> 32)) << 33; // sign > > extend from 33 to 64 bits > > + int64_t imm = sign_extend | (((immhi << 2) | immlo) << 12); > > + int64_t base = (int64_t) imp & ~0xfff; > > + uintptr_t* jmpto = (uintptr_t *) (base + imm + imm12); > > + return (void *) *jmpto; > > } > > #else > > if (*((uint16_t *) imp) == 0x25ff) > > diff --git a/winsup/cygwin/scripts/mkimport b/winsup/cygwin/scripts/mkimport > > index 0c1bcafbf..80594296a 100755 > > --- a/winsup/cygwin/scripts/mkimport > > +++ b/winsup/cygwin/scripts/mkimport > > @@ -73,8 +73,8 @@ EOF > > .extern $imp_sym > > .global $glob_sym > > $glob_sym: > > - adr x16, $imp_sym > > - ldr x16, [x16] > > + adrp x16, $imp_sym > > + ldr x16, [x16, #:lo12:$imp_sym] > > br x16 > > EOF > > } else { > > -- > > 2.50.1.vfs.0.0 > > > >