On Thu, 10 Jul 2025, Radek Barton via Cygwin-patches wrote:

> Hello.
>
> This patch implements `import_address` function by decoding `adr` AArch64 
> instructions to get
> target address.

Out of curiosity, can you elaborate on when `adr` is used rather than
`adrp`/`add` pair?  I know adr has much less range, but it seems like the
compiler can't know how far away many symbols will be (perhaps it can for
things like local labels).  When I was looking at ntdll in the fastcwd
stuff (and ucrt in ruby) adrp/add (or adrp/ldr) were used, never saw adr.

> Radek
>
> ---
> From 8bfc01898261e341bbc8abb437e159b6b33a9312 Mon Sep 17 00:00:00 2001
> From: Evgeny Karpov <evgeny.kar...@microsoft.com>
> Date: Fri, 4 Jul 2025 20:20:37 +0200
> Subject: [PATCH] Cygwin: malloc_wrapper: port to AArch64
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
>
> Implements import_address function by decoding adr AArch64 instructions to get
> target address.
>
> Signed-off-by: Evgeny Karpov <evgeny.kar...@microsoft.com>
> ---
>  winsup/cygwin/mm/malloc_wrapper.cc | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
>
> diff --git a/winsup/cygwin/mm/malloc_wrapper.cc 
> b/winsup/cygwin/mm/malloc_wrapper.cc
> index de3cf7ddc..863d3089c 100644
> --- a/winsup/cygwin/mm/malloc_wrapper.cc
> +++ b/winsup/cygwin/mm/malloc_wrapper.cc
> @@ -50,6 +50,19 @@ import_address (void *imp)
>  {
>    __try
>      {
> +#if defined(__aarch64__)
> +      // If opcode is an adr instruction.
> +      uint32_t opcode = *(uint32_t *) imp;
> +      if ((opcode & 0x9f000000) == 0x10000000)
> +     {
> +       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;
> +     }
> +#else
>        if (*((uint16_t *) imp) == 0x25ff)
>       {
>         const char *ptr = (const char *) imp;
> @@ -57,6 +70,7 @@ import_address (void *imp)
>                            (ptr + 6 + *(int32_t *)(ptr + 2));
>         return (void *) *jmpto;
>       }
> +#endif
>      }
>    __except (NO_ERROR) {}
>    __endtry
> --
> 2.50.1.vfs.0.0
>
>

-- 
Croll's Query:
        If tin whistles are made of tin, what are foghorns made of?

Reply via email to