[PATCH v2 1/1] aarch64: mingw: Auto-import implementation
Jan Beulich
jbeulich@suse.com
Fri Aug 14 13:53:14 GMT 2026
On 31.07.2026 16:46, Evgeny Karpov wrote:
> --- a/ld/emultempl/pep.em
> +++ b/ld/emultempl/pep.em
> @@ -1160,10 +1160,22 @@ pep_fixup_stdcalls (void)
> static bfd_vma
> read_addend (arelent *rel, asection *s)
> {
> - char buf[8];
> bfd_vma addend = 0;
> bool ok = false;
>
> +#if defined (COFF_WITH_peAArch64)
> + switch (rel->howto->bitsize)
> + {
> + case 12:
> + case 21:
> + case 26:
> + ok = true;
> + break;
> + }
> +
> +#else
> + char buf[8];
> +
> switch (rel->howto->bitsize)
> {
> case 8:
> @@ -1186,7 +1198,6 @@ read_addend (arelent *rel, asection *s)
> addend = bfd_get_16 (s->owner, buf);
> }
> break;
> - case 26:
How come this can go away here?
Apart from this question only a few mechanical comments; the bulk of this
wants looking at by Arm64 folks.
> --- a/ld/pe-dll.c
> +++ b/ld/pe-dll.c
> @@ -2842,10 +2842,181 @@ pe_create_runtime_relocator_reference (bfd *parent)
> return abfd;
> }
>
> +static void
> +aarch64_make_jump_stub(const char* symbol_name, bfd* parent)
> +{
> + static struct bfd_hash_table *stub_hash = NULL;
> + if (!stub_hash)
> + {
> + stub_hash = (struct bfd_hash_table *) xmalloc
> + (sizeof (struct bfd_hash_table));
> + bfd_hash_table_init (stub_hash, bfd_hash_newfunc,
> + sizeof (struct bfd_hash_entry));
> + }
> +
> + if (pe_dll_extra_pe_debug)
> + printf ("validate jump stub for %s\n", symbol_name);
> +
> + if (bfd_hash_lookup(stub_hash, symbol_name, false, false))
> + return;
> +
> + if (pe_dll_extra_pe_debug)
> + printf ("creating jump stub for %s\n", symbol_name);
> + bfd_hash_lookup(stub_hash, symbol_name, true, true);
> +
> + static unsigned tmp_stub_seq = 0;
> + char *oname = xasprintf ("jump_stub_d%06d.o", tmp_stub_seq);
> + ++tmp_stub_seq;
> +
> + bfd *abfd = bfd_create (oname, parent);
> + free (oname);
> + bfd_make_writable (abfd);
> +
> + bfd_set_format (abfd, bfd_object);
> + bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
> +
> + symptr = 0;
> + symtab = xmalloc (12 * sizeof (asymbol *));
> +
> + asection *tx = quick_section (abfd, ".text", SEC_CODE | SEC_HAS_CONTENTS
> + | SEC_READONLY, 2);
> + quick_symbol (abfd, "", symbol_name, "", tx, BSF_GLOBAL, 0);
> + quick_symbol (abfd, "__imp_", symbol_name, "", bfd_und_section_ptr,
> + BSF_GLOBAL, 0);
> +
> + const unsigned jmp_byte_count = sizeof (jmp_aarch64_bytes);
> + bfd_set_section_size (tx, jmp_byte_count);
> + unsigned char *td = xmalloc (jmp_byte_count);
> + tx->contents = td;
> + memcpy (td, jmp_aarch64_bytes, jmp_byte_count);
> +
> + quick_reloc (abfd, 0, BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL, 2);
> + quick_reloc (abfd, 4, BFD_RELOC_AARCH64_ADD_LO12, 2);
> + save_relocs (tx);
> +
> + bfd_set_symtab (abfd, symtab, symptr);
> +
> + bfd_set_section_contents (abfd, tx, td, 0, jmp_byte_count);
> + bfd_make_readable (abfd);
> + add_bfd_to_link (abfd, bfd_get_filename (abfd), &link_info);
> +}
> +
> +static void
> +aarch64_make_imp_offset(const char* imp_symbol_name,
> + const char* imp_offset_name, const int offset,
> + unsigned rd, const char* caller_label, bfd* parent)
> +{
> + if (pe_dll_extra_pe_debug)
> + printf("symbol: %s imp_offset_name: %s offset: %u rs: %u caller: %s\n",
> + imp_symbol_name, imp_offset_name, offset, rd, caller_label);
> +
> + static const unsigned char imp_offset_bytes[] =
> + {
> + 0x00, 0x00, 0x00, 0x90, /* adrp x0, <imp_symbol_name> */
> + 0x00, 0x00, 0x40, 0xf9, /* ldr x0, [x0, :lo12:<imp_symbol_name>] */
> + 0x00, 0x00, 0x40, 0x91, /* add x0, x0, 0, lsl 12 */
> + 0x01, 0x00, 0x00, 0x14 /* b <caller_label> + 4 */
> + };
> +
> + static unsigned tmp_stub_seq = 0;
> + char *oname = xasprintf ("imp_offset_stub_d%06d.o", tmp_stub_seq);
> + ++tmp_stub_seq;
> +
> + bfd *abfd = bfd_create (oname, parent);
> + free (oname);
> + bfd_make_writable (abfd);
> +
> + bfd_set_format (abfd, bfd_object);
> + bfd_set_arch_mach (abfd, pe_details->bfd_arch, 0);
> +
> + symptr = 0;
> + symtab = xmalloc (12 * sizeof (asymbol *));
> +
> + asection *tx = quick_section (abfd, ".text", SEC_CODE | SEC_HAS_CONTENTS
> + | SEC_READONLY, 2);
> + quick_symbol (abfd, "", imp_offset_name, "", tx, BSF_GLOBAL, 0);
> + quick_symbol (abfd, "", imp_symbol_name, "", UNDSEC, BSF_GLOBAL, 0);
> + quick_symbol (abfd, "", caller_label, "", UNDSEC, BSF_GLOBAL, 0);
> +
> + const unsigned imp_offset_byte_count = sizeof (imp_offset_bytes);
> + bfd_set_section_size (tx, imp_offset_byte_count);
> + uint32_t *td = xmalloc (imp_offset_byte_count);
> + tx->contents = (bfd_byte*) td;
> + memcpy (td, imp_offset_bytes, imp_offset_byte_count);
> +
> + rd &= (1 << 5) - 1;
> + td[0] |= rd;
> + td[1] |= (rd << 5) | rd;
> +
> + unsigned imm = 0;
> + if (offset >= 0)
> + imm = offset;
> + else
> + {
> + imm = -offset + 4096;
> +/* Change "add x0, x0, 0, lsl 12" to "sub x0, x0, 0, lsl 12". */
The comment wants indenting.
> + td[2] |= 1 << 30;
> + }
> + imm >>= 12;
> + imm &= ((1 << 12) - 1);
> + td[2] |= (rd << 5) | rd;
> + td[2] |= imm << 10;
> +
> + quick_reloc (abfd, 0, BFD_RELOC_AARCH64_ADR_HI21_PCREL, 2);
> + quick_reloc (abfd, 4, BFD_RELOC_AARCH64_LDST64_LO12, 2);
> + quick_reloc (abfd, 12, BFD_RELOC_AARCH64_CALL26, 3);
> + save_relocs (tx);
> +
> + bfd_set_symtab (abfd, symtab, symptr);
> +
> + bfd_set_section_contents (abfd, tx, td, 0, imp_offset_byte_count);
> + bfd_make_readable (abfd);
> + add_bfd_to_link (abfd, bfd_get_filename (abfd), &link_info);
> +}
> +
> void
> pe_create_import_fixup (arelent *rel, asection *s, bfd_vma addend, char *name,
> const char *symname)
> {
> + if (pe_details->pe_arch == PE_ARCH_aarch64)
> + {
There looks to be an indentation issue on these two lines.
> + if (rel->howto->bitsize == 12)
> + return;
> + else if (rel->howto->bitsize == 26)
> + {
> +/* On AArch64, a single opcode is not sufficient for relocation
> + in dynamic linking. The linker generates a jump stub instead. */
Missing indentation again.
Jan
More information about the Binutils
mailing list