diff mbox series

[v2,2/6] Extract ix86 dllimport implementation to mingw

Message ID DBBPR83MB06139B8CDEA1CC95D80F9E65F8FB2@DBBPR83MB0613.EURPRD83.prod.outlook.com
State New
Headers show
Series Add DLL import/export implementation to AArch64 | expand

Commit Message

Evgeny Karpov June 7, 2024, 9:48 a.m. UTC
This patch extracts the ix86 implementation for expanding a SYMBOL
into its corresponding dllimport, far-address, or refptr symbol.
It will be reused in the aarch64-w64-mingw32 target.
The implementation is copied as is from i386/i386.cc with
minor changes to follow to the code style.

Also this patch replaces the original DLL import/export
implementation in ix86 with mingw.

gcc/ChangeLog:

	* config.gcc: Add winnt-dll.o, which contains the DLL
	import/export implementation.
	* config/i386/cygming.h (SUB_TARGET_RECORD_STUB): Remove the
	old implementation. Rename the required function to MinGW.
	Use MinGW implementation for COFF and nothing otherwise.
	(GOT_ALIAS_SET): Likewise.
	* config/i386/i386-expand.cc (ix86_expand_move): Likewise.
	* config/i386/i386-expand.h (ix86_GOT_alias_set): Likewise.
	(legitimize_pe_coff_symbol): Likewise.
	* config/i386/i386-protos.h (i386_pe_record_stub): Likewise.
	* config/i386/i386.cc (is_imported_p): Likewise.
	(legitimate_pic_address_disp_p): Likewise.
	(ix86_GOT_alias_set): Likewise.
	(legitimize_pic_address): Likewise.
	(legitimize_tls_address): Likewise.
	(struct dllimport_hasher): Likewise.
	(GTY): Likewise.
	(get_dllimport_decl): Likewise.
	(legitimize_pe_coff_extern_decl): Likewise.
	(legitimize_dllimport_symbol): Likewise.
	(legitimize_pe_coff_symbol): Likewise.
	(ix86_legitimize_address): Likewise.
	* config/i386/i386.h (GOT_ALIAS_SET): Likewise.
	* config/mingw/winnt.cc (i386_pe_record_stub): Likewise.
	(mingw_pe_record_stub): Likewise.
	* config/mingw/winnt.h (mingw_pe_record_stub): Likewise.
	* config/mingw/t-cygming: Add the winnt-dll.o compilation.
	* config/mingw/winnt-dll.cc: New file.
	* config/mingw/winnt-dll.h: New file.
---
 gcc/config.gcc                 |  12 +-
 gcc/config/i386/cygming.h      |   5 +-
 gcc/config/i386/i386-expand.cc |   4 +-
 gcc/config/i386/i386-expand.h  |   2 -
 gcc/config/i386/i386-protos.h  |   1 -
 gcc/config/i386/i386.cc        | 205 ++---------------------------
 gcc/config/i386/i386.h         |   2 +
 gcc/config/mingw/t-cygming     |   6 +
 gcc/config/mingw/winnt-dll.cc  | 231 +++++++++++++++++++++++++++++++++
 gcc/config/mingw/winnt-dll.h   |  30 +++++
 gcc/config/mingw/winnt.cc      |   2 +-
 gcc/config/mingw/winnt.h       |   1 +
 12 files changed, 298 insertions(+), 203 deletions(-)
 create mode 100644 gcc/config/mingw/winnt-dll.cc
 create mode 100644 gcc/config/mingw/winnt-dll.h

Comments

Uros Bizjak June 7, 2024, 11:11 a.m. UTC | #1
On Fri, Jun 7, 2024 at 11:48 AM Evgeny Karpov
<Evgeny.Karpov@microsoft.com> wrote:
>
> This patch extracts the ix86 implementation for expanding a SYMBOL
> into its corresponding dllimport, far-address, or refptr symbol.
> It will be reused in the aarch64-w64-mingw32 target.
> The implementation is copied as is from i386/i386.cc with
> minor changes to follow to the code style.
>
> Also this patch replaces the original DLL import/export
> implementation in ix86 with mingw.
>
> gcc/ChangeLog:
>
>         * config.gcc: Add winnt-dll.o, which contains the DLL
>         import/export implementation.
>         * config/i386/cygming.h (SUB_TARGET_RECORD_STUB): Remove the
>         old implementation. Rename the required function to MinGW.
>         Use MinGW implementation for COFF and nothing otherwise.
>         (GOT_ALIAS_SET): Likewise.
>         * config/i386/i386-expand.cc (ix86_expand_move): Likewise.
>         * config/i386/i386-expand.h (ix86_GOT_alias_set): Likewise.
>         (legitimize_pe_coff_symbol): Likewise.
>         * config/i386/i386-protos.h (i386_pe_record_stub): Likewise.
>         * config/i386/i386.cc (is_imported_p): Likewise.
>         (legitimate_pic_address_disp_p): Likewise.
>         (ix86_GOT_alias_set): Likewise.
>         (legitimize_pic_address): Likewise.
>         (legitimize_tls_address): Likewise.
>         (struct dllimport_hasher): Likewise.
>         (GTY): Likewise.
>         (get_dllimport_decl): Likewise.
>         (legitimize_pe_coff_extern_decl): Likewise.
>         (legitimize_dllimport_symbol): Likewise.
>         (legitimize_pe_coff_symbol): Likewise.
>         (ix86_legitimize_address): Likewise.
>         * config/i386/i386.h (GOT_ALIAS_SET): Likewise.
>         * config/mingw/winnt.cc (i386_pe_record_stub): Likewise.
>         (mingw_pe_record_stub): Likewise.
>         * config/mingw/winnt.h (mingw_pe_record_stub): Likewise.
>         * config/mingw/t-cygming: Add the winnt-dll.o compilation.
>         * config/mingw/winnt-dll.cc: New file.
>         * config/mingw/winnt-dll.h: New file.

LGTM for generic x86 changes.

Thanks,
Uros.

> ---
>  gcc/config.gcc                 |  12 +-
>  gcc/config/i386/cygming.h      |   5 +-
>  gcc/config/i386/i386-expand.cc |   4 +-
>  gcc/config/i386/i386-expand.h  |   2 -
>  gcc/config/i386/i386-protos.h  |   1 -
>  gcc/config/i386/i386.cc        | 205 ++---------------------------
>  gcc/config/i386/i386.h         |   2 +
>  gcc/config/mingw/t-cygming     |   6 +
>  gcc/config/mingw/winnt-dll.cc  | 231 +++++++++++++++++++++++++++++++++
>  gcc/config/mingw/winnt-dll.h   |  30 +++++
>  gcc/config/mingw/winnt.cc      |   2 +-
>  gcc/config/mingw/winnt.h       |   1 +
>  12 files changed, 298 insertions(+), 203 deletions(-)
>  create mode 100644 gcc/config/mingw/winnt-dll.cc
>  create mode 100644 gcc/config/mingw/winnt-dll.h
>
> diff --git a/gcc/config.gcc b/gcc/config.gcc
> index 553a310f4bd..d053b98efa8 100644
> --- a/gcc/config.gcc
> +++ b/gcc/config.gcc
> @@ -2177,11 +2177,13 @@ i[4567]86-wrs-vxworks*|x86_64-wrs-vxworks7*)
>  i[34567]86-*-cygwin*)
>         tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/cygming.h i386/cygwin.h i386/cygwin-stdint.h"
>         tm_file="${tm_file} mingw/winnt.h"
> +       tm_file="${tm_file} mingw/winnt-dll.h"
>         xm_file=i386/xm-cygwin.h
>         tmake_file="${tmake_file} mingw/t-cygming t-slibgcc"
>         target_gtfiles="$target_gtfiles \$(srcdir)/config/mingw/winnt.cc"
> +       target_gtfiles="$target_gtfiles \$(srcdir)/config/mingw/winnt-dll.cc"
>         extra_options="${extra_options} mingw/cygming.opt i386/cygwin.opt"
> -       extra_objs="${extra_objs} winnt.o winnt-stubs.o"
> +       extra_objs="${extra_objs} winnt.o winnt-stubs.o winnt-dll.o"
>         c_target_objs="${c_target_objs} msformat-c.o"
>         cxx_target_objs="${cxx_target_objs} winnt-cxx.o msformat-c.o"
>         d_target_objs="${d_target_objs} cygwin-d.o"
> @@ -2196,11 +2198,13 @@ x86_64-*-cygwin*)
>         need_64bit_isa=yes
>         tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/cygming.h i386/cygwin.h i386/cygwin-w64.h i386/cygwin-stdint.h"
>         tm_file="${tm_file} mingw/winnt.h"
> +       tm_file="${tm_file} mingw/winnt-dll.h"
>         xm_file=i386/xm-cygwin.h
>         tmake_file="${tmake_file} mingw/t-cygming t-slibgcc"
>         target_gtfiles="$target_gtfiles \$(srcdir)/config/mingw/winnt.cc"
> +       target_gtfiles="$target_gtfiles \$(srcdir)/config/mingw/winnt-dll.cc"
>         extra_options="${extra_options} mingw/cygming.opt i386/cygwin.opt"
> -       extra_objs="${extra_objs} winnt.o winnt-stubs.o"
> +       extra_objs="${extra_objs} winnt.o winnt-stubs.o winnt-dll.o"
>         c_target_objs="${c_target_objs} msformat-c.o"
>         cxx_target_objs="${cxx_target_objs} winnt-cxx.o msformat-c.o"
>         d_target_objs="${d_target_objs} cygwin-d.o"
> @@ -2266,6 +2270,7 @@ i[34567]86-*-mingw* | x86_64-*-mingw*)
>         esac
>         tm_file="${tm_file} mingw/mingw-stdint.h"
>         tm_file="${tm_file} mingw/winnt.h"
> +       tm_file="${tm_file} mingw/winnt-dll.h"
>         tmake_file="${tmake_file} t-winnt mingw/t-cygming t-slibgcc"
>          case ${target} in
>                 x86_64-w64-*)
> @@ -2277,6 +2282,7 @@ i[34567]86-*-mingw* | x86_64-*-mingw*)
>         esac
>          native_system_header_dir=/mingw/include
>         target_gtfiles="$target_gtfiles \$(srcdir)/config/mingw/winnt.cc"
> +       target_gtfiles="$target_gtfiles \$(srcdir)/config/mingw/winnt-dll.cc"
>         extra_options="${extra_options} mingw/cygming.opt mingw/mingw.opt"
>         case ${target} in
>                 *-w64-*)
> @@ -2285,7 +2291,7 @@ i[34567]86-*-mingw* | x86_64-*-mingw*)
>                 *)
>                         ;;
>         esac
> -       extra_objs="${extra_objs} winnt.o winnt-stubs.o"
> +       extra_objs="${extra_objs} winnt.o winnt-stubs.o winnt-dll.o"
>         c_target_objs="${c_target_objs} msformat-c.o"
>         cxx_target_objs="${cxx_target_objs} winnt-cxx.o msformat-c.o"
>         gas=yes
> diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
> index 98b375538e7..56945f00c11 100644
> --- a/gcc/config/i386/cygming.h
> +++ b/gcc/config/i386/cygming.h
> @@ -461,7 +461,7 @@ do {                                                \
>  #define TARGET_ASM_ASSEMBLE_VISIBILITY i386_pe_assemble_visibility
>
>  #undef SUB_TARGET_RECORD_STUB
> -#define SUB_TARGET_RECORD_STUB i386_pe_record_stub
> +#define SUB_TARGET_RECORD_STUB mingw_pe_record_stub
>
>  /* Static stack checking is supported by means of probes.  */
>  #define STACK_CHECK_STATIC_BUILTIN 1
> @@ -469,3 +469,6 @@ do {                                                \
>  #ifndef HAVE_GAS_ALIGNED_COMM
>  # define HAVE_GAS_ALIGNED_COMM 0
>  #endif
> +
> +#undef GOT_ALIAS_SET
> +#define GOT_ALIAS_SET mingw_GOT_alias_set ()
> diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
> index d1d396a8713..e09c97f1520 100644
> --- a/gcc/config/i386/i386-expand.cc
> +++ b/gcc/config/i386/i386-expand.cc
> @@ -408,10 +408,11 @@ ix86_expand_move (machine_mode mode, rtx operands[])
>                                  : UNSPEC_GOT));
>           op1 = gen_rtx_CONST (Pmode, op1);
>           op1 = gen_const_mem (Pmode, op1);
> -         set_mem_alias_set (op1, ix86_GOT_alias_set ());
> +         set_mem_alias_set (op1, GOT_ALIAS_SET);
>         }
>        else
>         {
> +#if TARGET_PECOFF
>           tmp = legitimize_pe_coff_symbol (op1, addend != NULL_RTX);
>           if (tmp)
>             {
> @@ -424,6 +425,7 @@ ix86_expand_move (machine_mode mode, rtx operands[])
>               op1 = operands[1];
>               break;
>             }
> +#endif
>         }
>
>        if (addend)
> diff --git a/gcc/config/i386/i386-expand.h b/gcc/config/i386/i386-expand.h
> index 65cb49c921c..5e02df1706d 100644
> --- a/gcc/config/i386/i386-expand.h
> +++ b/gcc/config/i386/i386-expand.h
> @@ -34,9 +34,7 @@ struct expand_vec_perm_d
>  };
>
>  rtx legitimize_tls_address (rtx x, enum tls_model model, bool for_mov);
> -alias_set_type ix86_GOT_alias_set (void);
>  rtx legitimize_pic_address (rtx orig, rtx reg);
> -rtx legitimize_pe_coff_symbol (rtx addr, bool inreg);
>
>  bool insn_defines_reg (unsigned int regno1, unsigned int regno2,
>                        rtx_insn *insn);
> diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
> index 65ef3d77c3a..b2e9b9e0d3d 100644
> --- a/gcc/config/i386/i386-protos.h
> +++ b/gcc/config/i386/i386-protos.h
> @@ -318,7 +318,6 @@ extern void i386_pe_end_cold_function (FILE *, const char *, tree);
>  extern void i386_pe_assemble_visibility (tree, int);
>  extern tree i386_pe_mangle_decl_assembler_name (tree, tree);
>  extern tree i386_pe_mangle_assembler_name (const char *);
> -extern void i386_pe_record_stub (const char *);
>
>  extern void i386_pe_seh_init (FILE *);
>  extern void i386_pe_seh_end_prologue (FILE *);
> diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
> index 4126ab24a79..cf998252340 100644
> --- a/gcc/config/i386/i386.cc
> +++ b/gcc/config/i386/i386.cc
> @@ -11244,20 +11244,6 @@ ix86_cannot_force_const_mem (machine_mode mode, rtx x)
>    return !ix86_legitimate_constant_p (mode, x);
>  }
>
> -/*  Nonzero if the symbol is marked as dllimport, or as stub-variable,
> -    otherwise zero.  */
> -
> -static bool
> -is_imported_p (rtx x)
> -{
> -  if (!TARGET_DLLIMPORT_DECL_ATTRIBUTES
> -      || GET_CODE (x) != SYMBOL_REF)
> -    return false;
> -
> -  return SYMBOL_REF_DLLIMPORT_P (x) || SYMBOL_REF_STUBVAR_P (x);
> -}
> -
> -
>  /* Nonzero if the constant value X is a legitimate general operand
>     when generating PIC code.  It is given that flag_pic is on and
>     that X satisfies CONSTANT_P.  */
> @@ -11359,8 +11345,10 @@ legitimate_pic_address_disp_p (rtx disp)
>
>           if (TARGET_PECOFF)
>             {
> +#if TARGET_PECOFF
>               if (is_imported_p (op0))
>                 return true;
> +#endif
>
>               if (SYMBOL_REF_FAR_ADDR_P (op0) || !SYMBOL_REF_LOCAL_P (op0))
>                 break;
> @@ -11836,16 +11824,6 @@ constant_address_p (rtx x)
>    return CONSTANT_P (x) && ix86_legitimate_address_p (Pmode, x, 1);
>  }
>
>
> -/* Return a unique alias set for the GOT.  */
> -
> -alias_set_type
> -ix86_GOT_alias_set (void)
> -{
> -  static alias_set_type set = -1;
> -  if (set == -1)
> -    set = new_alias_set ();
> -  return set;
> -}
>
>  /* Return a legitimate reference for ORIG (an address) using the
>     register REG.  If REG is 0, a new pseudo is generated.
> @@ -11883,9 +11861,11 @@ legitimize_pic_address (rtx orig, rtx reg)
>
>    if (TARGET_64BIT && TARGET_DLLIMPORT_DECL_ATTRIBUTES)
>      {
> +#if TARGET_PECOFF
>        rtx tmp = legitimize_pe_coff_symbol (addr, true);
>        if (tmp)
>          return tmp;
> +#endif
>      }
>
>    if (TARGET_64BIT && legitimate_pic_address_disp_p (addr))
> @@ -11928,9 +11908,11 @@ legitimize_pic_address (rtx orig, rtx reg)
>               on VxWorks, see gotoff_operand.  */
>            || (TARGET_VXWORKS_RTP && GET_CODE (addr) == LABEL_REF))
>      {
> +#if TARGET_PECOFF
>        rtx tmp = legitimize_pe_coff_symbol (addr, true);
>        if (tmp)
>          return tmp;
> +#endif
>
>        /* For x64 PE-COFF there is no GOT table,
>          so we use address directly.  */
> @@ -11945,7 +11927,7 @@ legitimize_pic_address (rtx orig, rtx reg)
>                                     UNSPEC_GOTPCREL);
>           new_rtx = gen_rtx_CONST (Pmode, new_rtx);
>           new_rtx = gen_const_mem (Pmode, new_rtx);
> -         set_mem_alias_set (new_rtx, ix86_GOT_alias_set ());
> +         set_mem_alias_set (new_rtx, GOT_ALIAS_SET);
>         }
>        else
>         {
> @@ -11967,7 +11949,7 @@ legitimize_pic_address (rtx orig, rtx reg)
>             new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
>
>           new_rtx = gen_const_mem (Pmode, new_rtx);
> -         set_mem_alias_set (new_rtx, ix86_GOT_alias_set ());
> +         set_mem_alias_set (new_rtx, GOT_ALIAS_SET);
>         }
>
>        new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
> @@ -12344,7 +12326,7 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
>        if (pic)
>         off = gen_rtx_PLUS (tp_mode, pic, off);
>        off = gen_const_mem (tp_mode, off);
> -      set_mem_alias_set (off, ix86_GOT_alias_set ());
> +      set_mem_alias_set (off, GOT_ALIAS_SET);
>
>        if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
>         {
> @@ -12503,173 +12485,6 @@ ix86_rewrite_tls_address (rtx pattern)
>    return pattern;
>  }
>
> -/* Create or return the unique __imp_DECL dllimport symbol corresponding
> -   to symbol DECL if BEIMPORT is true.  Otherwise create or return the
> -   unique refptr-DECL symbol corresponding to symbol DECL.  */
> -
> -struct dllimport_hasher : ggc_cache_ptr_hash<tree_map>
> -{
> -  static inline hashval_t hash (tree_map *m) { return m->hash; }
> -  static inline bool
> -  equal (tree_map *a, tree_map *b)
> -  {
> -    return a->base.from == b->base.from;
> -  }
> -
> -  static int
> -  keep_cache_entry (tree_map *&m)
> -  {
> -    return ggc_marked_p (m->base.from);
> -  }
> -};
> -
> -static GTY((cache)) hash_table<dllimport_hasher> *dllimport_map;
> -
> -static tree
> -get_dllimport_decl (tree decl, bool beimport)
> -{
> -  struct tree_map *h, in;
> -  const char *name;
> -  const char *prefix;
> -  size_t namelen, prefixlen;
> -  char *imp_name;
> -  tree to;
> -  rtx rtl;
> -
> -  if (!dllimport_map)
> -    dllimport_map = hash_table<dllimport_hasher>::create_ggc (512);
> -
> -  in.hash = htab_hash_pointer (decl);
> -  in.base.from = decl;
> -  tree_map **loc = dllimport_map->find_slot_with_hash (&in, in.hash, INSERT);
> -  h = *loc;
> -  if (h)
> -    return h->to;
> -
> -  *loc = h = ggc_alloc<tree_map> ();
> -  h->hash = in.hash;
> -  h->base.from = decl;
> -  h->to = to = build_decl (DECL_SOURCE_LOCATION (decl),
> -                          VAR_DECL, NULL, ptr_type_node);
> -  DECL_ARTIFICIAL (to) = 1;
> -  DECL_IGNORED_P (to) = 1;
> -  DECL_EXTERNAL (to) = 1;
> -  TREE_READONLY (to) = 1;
> -
> -  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
> -  name = targetm.strip_name_encoding (name);
> -  if (beimport)
> -    prefix = name[0] == FASTCALL_PREFIX || user_label_prefix[0] == 0
> -      ? "*__imp_" : "*__imp__";
> -  else
> -    prefix = user_label_prefix[0] == 0 ? "*.refptr." : "*refptr.";
> -  namelen = strlen (name);
> -  prefixlen = strlen (prefix);
> -  imp_name = (char *) alloca (namelen + prefixlen + 1);
> -  memcpy (imp_name, prefix, prefixlen);
> -  memcpy (imp_name + prefixlen, name, namelen + 1);
> -
> -  name = ggc_alloc_string (imp_name, namelen + prefixlen);
> -  rtl = gen_rtx_SYMBOL_REF (Pmode, name);
> -  SET_SYMBOL_REF_DECL (rtl, to);
> -  SYMBOL_REF_FLAGS (rtl) = SYMBOL_FLAG_LOCAL | SYMBOL_FLAG_STUBVAR;
> -  if (!beimport)
> -    {
> -      SYMBOL_REF_FLAGS (rtl) |= SYMBOL_FLAG_EXTERNAL;
> -#ifdef SUB_TARGET_RECORD_STUB
> -      SUB_TARGET_RECORD_STUB (name);
> -#endif
> -    }
> -
> -  rtl = gen_const_mem (Pmode, rtl);
> -  set_mem_alias_set (rtl, ix86_GOT_alias_set ());
> -
> -  SET_DECL_RTL (to, rtl);
> -  SET_DECL_ASSEMBLER_NAME (to, get_identifier (name));
> -
> -  return to;
> -}
> -
> -/* Expand SYMBOL into its corresponding far-address symbol.
> -   WANT_REG is true if we require the result be a register.  */
> -
> -static rtx
> -legitimize_pe_coff_extern_decl (rtx symbol, bool want_reg)
> -{
> -  tree imp_decl;
> -  rtx x;
> -
> -  gcc_assert (SYMBOL_REF_DECL (symbol));
> -  imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol), false);
> -
> -  x = DECL_RTL (imp_decl);
> -  if (want_reg)
> -    x = force_reg (Pmode, x);
> -  return x;
> -}
> -
> -/* Expand SYMBOL into its corresponding dllimport symbol.  WANT_REG is
> -   true if we require the result be a register.  */
> -
> -static rtx
> -legitimize_dllimport_symbol (rtx symbol, bool want_reg)
> -{
> -  tree imp_decl;
> -  rtx x;
> -
> -  gcc_assert (SYMBOL_REF_DECL (symbol));
> -  imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol), true);
> -
> -  x = DECL_RTL (imp_decl);
> -  if (want_reg)
> -    x = force_reg (Pmode, x);
> -  return x;
> -}
> -
> -/* Expand SYMBOL into its corresponding dllimport or refptr symbol.  WANT_REG
> -   is true if we require the result be a register.  */
> -
> -rtx
> -legitimize_pe_coff_symbol (rtx addr, bool inreg)
> -{
> -  if (!TARGET_PECOFF)
> -    return NULL_RTX;
> -
> -  if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
> -    {
> -      if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_DLLIMPORT_P (addr))
> -       return legitimize_dllimport_symbol (addr, inreg);
> -      if (GET_CODE (addr) == CONST
> -         && GET_CODE (XEXP (addr, 0)) == PLUS
> -         && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF
> -         && SYMBOL_REF_DLLIMPORT_P (XEXP (XEXP (addr, 0), 0)))
> -       {
> -         rtx t = legitimize_dllimport_symbol (XEXP (XEXP (addr, 0), 0), inreg);
> -         return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1));
> -       }
> -    }
> -
> -  if (ix86_cmodel != CM_LARGE_PIC && ix86_cmodel != CM_MEDIUM_PIC)
> -    return NULL_RTX;
> -  if (GET_CODE (addr) == SYMBOL_REF
> -      && !is_imported_p (addr)
> -      && SYMBOL_REF_EXTERNAL_P (addr)
> -      && SYMBOL_REF_DECL (addr))
> -    return legitimize_pe_coff_extern_decl (addr, inreg);
> -
> -  if (GET_CODE (addr) == CONST
> -      && GET_CODE (XEXP (addr, 0)) == PLUS
> -      && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF
> -      && !is_imported_p (XEXP (XEXP (addr, 0), 0))
> -      && SYMBOL_REF_EXTERNAL_P (XEXP (XEXP (addr, 0), 0))
> -      && SYMBOL_REF_DECL (XEXP (XEXP (addr, 0), 0)))
> -    {
> -      rtx t = legitimize_pe_coff_extern_decl (XEXP (XEXP (addr, 0), 0), inreg);
> -      return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1));
> -    }
> -  return NULL_RTX;
> -}
> -
>  /* Try machine-dependent ways of modifying an illegitimate address
>     to be legitimate.  If we find one, return the new, valid address.
>     This macro is used in only one place: `memory_address' in explow.cc.
> @@ -12709,9 +12524,11 @@ ix86_legitimize_address (rtx x, rtx, machine_mode mode)
>
>    if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
>      {
> +#if TARGET_PECOFF
>        rtx tmp = legitimize_pe_coff_symbol (x, true);
>        if (tmp)
>          return tmp;
> +#endif
>      }
>
>    if (flag_pic && SYMBOLIC_CONST (x))
> diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
> index 7051c6c13e4..d9f02f66518 100644
> --- a/gcc/config/i386/i386.h
> +++ b/gcc/config/i386/i386.h
> @@ -2262,6 +2262,8 @@ extern int const svr4_debugger_register_map[FIRST_PSEUDO_REGISTER];
>  /* Which processor to tune code generation for.  These must be in sync
>     with processor_cost_table in i386-options.cc.  */
>
> +#define GOT_ALIAS_SET -1
> +
>  enum processor_type
>  {
>    PROCESSOR_GENERIC = 0,
> diff --git a/gcc/config/mingw/t-cygming b/gcc/config/mingw/t-cygming
> index f5de941c8e5..3dd9116d92b 100644
> --- a/gcc/config/mingw/t-cygming
> +++ b/gcc/config/mingw/t-cygming
> @@ -33,6 +33,12 @@ winnt-cxx.o: $(srcdir)/config/mingw/winnt-cxx.cc $(CONFIG_H) $(SYSTEM_H) \
>         $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
>         $(srcdir)/config/mingw/winnt-cxx.cc
>
> +winnt-dll.o: $(srcdir)/config/mingw/winnt-dll.cc $(CONFIG_H) $(SYSTEM_H) \
> +  coretypes.h \
> +  $(TM_H) $(TREE_H) flags.h \
> +  $(TM_P_H) $(HASH_TABLE_H) $(GGC_H)
> +       $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
> +       $(srcdir)/config/mingw/winnt-dll.cc
>
>  winnt-stubs.o: $(srcdir)/config/mingw/winnt-stubs.cc $(CONFIG_H) $(SYSTEM_H) \
>    coretypes.h \
> diff --git a/gcc/config/mingw/winnt-dll.cc b/gcc/config/mingw/winnt-dll.cc
> new file mode 100644
> index 00000000000..1354402a959
> --- /dev/null
> +++ b/gcc/config/mingw/winnt-dll.cc
> @@ -0,0 +1,231 @@
> +/* Expand a SYMBOL into its corresponding dllimport, far-address,
> +or refptr symbol.
> +Copyright (C) 1988-2024 Free Software Foundation, Inc.
> +
> +GCC is free software; you can redistribute it and/or modify it under
> +the terms of the GNU General Public License as published by the Free
> +Software Foundation; either version 3, or (at your option) any later
> +version.
> +
> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING3.  If not see
> +http://www.gnu.org/licenses/.  */
> +
> +#include "config.h"
> +#include "system.h"
> +#include "coretypes.h"
> +#include "backend.h"
> +#include "target.h"
> +#include "rtl.h"
> +#include "tree.h"
> +#include "memmodel.h"
> +#include "stringpool.h"
> +#include "emit-rtl.h"
> +#include "alias.h"
> +#include "varasm.h"
> +#include "output.h"
> +#include "explow.h"
> +#include "winnt.h"
> +
> +/* Create or return the unique __imp_DECL dllimport symbol corresponding
> +   to symbol DECL if BEIMPORT is true.  Otherwise create or return the
> +   unique refptr-DECL symbol corresponding to symbol DECL.  */
> +
> +struct dllimport_hasher : ggc_cache_ptr_hash<tree_map>
> +{
> +  static inline hashval_t hash (tree_map *m)
> +  {
> +    return m->hash;
> +  }
> +
> +  static inline bool
> +  equal (tree_map *a, tree_map *b)
> +  {
> +    return a->base.from == b->base.from;
> +  }
> +
> +  static int
> +  keep_cache_entry (tree_map *&m)
> +  {
> +    return ggc_marked_p (m->base.from);
> +  }
> +};
> +
> +static GTY ((cache)) hash_table<dllimport_hasher> *dllimport_map;
> +
> +/*  Nonzero if the symbol is marked as dllimport, or as stub-variable,
> +    otherwise zero.  */
> +
> +bool
> +is_imported_p (rtx x)
> +{
> +  if (!TARGET_DLLIMPORT_DECL_ATTRIBUTES
> +      || GET_CODE (x) != SYMBOL_REF)
> +    return false;
> +
> +  return SYMBOL_REF_DLLIMPORT_P (x) || SYMBOL_REF_STUBVAR_P (x);
> +}
> +
> +/* Return a unique alias set for the GOT.  */
> +
> +alias_set_type
> +mingw_GOT_alias_set (void)
> +{
> +  static alias_set_type set = -1;
> +  if (set == -1)
> +    set = new_alias_set ();
> +  return set;
> +}
> +
> +static tree
> +get_dllimport_decl (tree decl, bool beimport)
> +{
> +  struct tree_map *h, in;
> +  const char *name;
> +  const char *prefix;
> +  size_t namelen, prefixlen;
> +  char *imp_name;
> +  tree to;
> +  rtx rtl;
> +
> +  if (!dllimport_map)
> +    dllimport_map = hash_table<dllimport_hasher>::create_ggc (512);
> +
> +  in.hash = htab_hash_pointer (decl);
> +  in.base.from = decl;
> +  tree_map **loc = dllimport_map->find_slot_with_hash (&in, in.hash, INSERT);
> +  h = *loc;
> +  if (h)
> +    return h->to;
> +
> +  *loc = h = ggc_alloc<tree_map> ();
> +  h->hash = in.hash;
> +  h->base.from = decl;
> +  h->to = to = build_decl (DECL_SOURCE_LOCATION (decl),
> +                          VAR_DECL, NULL, ptr_type_node);
> +  DECL_ARTIFICIAL (to) = 1;
> +  DECL_IGNORED_P (to) = 1;
> +  DECL_EXTERNAL (to) = 1;
> +  TREE_READONLY (to) = 1;
> +
> +  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
> +  name = targetm.strip_name_encoding (name);
> +  if (beimport)
> +    prefix = name[0] == FASTCALL_PREFIX || user_label_prefix[0] == 0
> +      ? "*__imp_" : "*__imp__";
> +  else
> +    prefix = user_label_prefix[0] == 0 ? "*.refptr." : "*refptr.";
> +  namelen = strlen (name);
> +  prefixlen = strlen (prefix);
> +  imp_name = (char *) alloca (namelen + prefixlen + 1);
> +  memcpy (imp_name, prefix, prefixlen);
> +  memcpy (imp_name + prefixlen, name, namelen + 1);
> +
> +  name = ggc_alloc_string (imp_name, namelen + prefixlen);
> +  rtl = gen_rtx_SYMBOL_REF (Pmode, name);
> +  SET_SYMBOL_REF_DECL (rtl, to);
> +  SYMBOL_REF_FLAGS (rtl) = SYMBOL_FLAG_LOCAL | SYMBOL_FLAG_STUBVAR;
> +  if (!beimport)
> +    {
> +      SYMBOL_REF_FLAGS (rtl) |= SYMBOL_FLAG_EXTERNAL;
> +#ifdef SUB_TARGET_RECORD_STUB
> +      SUB_TARGET_RECORD_STUB (name);
> +#endif
> +    }
> +
> +  rtl = gen_const_mem (Pmode, rtl);
> +  set_mem_alias_set (rtl, mingw_GOT_alias_set ());
> +
> +  SET_DECL_RTL (to, rtl);
> +  SET_DECL_ASSEMBLER_NAME (to, get_identifier (name));
> +
> +  return to;
> +}
> +
> +/* Expand SYMBOL into its corresponding far-address symbol.
> +   WANT_REG is true if we require the result be a register.  */
> +
> +static rtx
> +legitimize_pe_coff_extern_decl (rtx symbol, bool want_reg)
> +{
> +  tree imp_decl;
> +  rtx x;
> +
> +  gcc_assert (SYMBOL_REF_DECL (symbol));
> +  imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol), false);
> +
> +  x = DECL_RTL (imp_decl);
> +  if (want_reg)
> +    x = force_reg (Pmode, x);
> +  return x;
> +}
> +
> +/* Expand SYMBOL into its corresponding dllimport symbol.  WANT_REG is
> +   true if we require the result be a register.  */
> +
> +static rtx
> +legitimize_dllimport_symbol (rtx symbol, bool want_reg)
> +{
> +  tree imp_decl;
> +  rtx x;
> +
> +  gcc_assert (SYMBOL_REF_DECL (symbol));
> +  imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol), true);
> +
> +  x = DECL_RTL (imp_decl);
> +  if (want_reg)
> +    x = force_reg (Pmode, x);
> +  return x;
> +}
> +
> +/* Expand SYMBOL into its corresponding dllimport or refptr symbol.  WANT_REG
> +   is true if we require the result be a register.  */
> +
> +rtx
> +legitimize_pe_coff_symbol (rtx addr, bool inreg)
> +{
> +  if (!TARGET_PECOFF)
> +    return NULL_RTX;
> +
> +  if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
> +    {
> +      if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_DLLIMPORT_P (addr))
> +       return legitimize_dllimport_symbol (addr, inreg);
> +      if (GET_CODE (addr) == CONST
> +         && GET_CODE (XEXP (addr, 0)) == PLUS
> +         && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF
> +         && SYMBOL_REF_DLLIMPORT_P (XEXP (XEXP (addr, 0), 0)))
> +       {
> +         rtx t = legitimize_dllimport_symbol (XEXP (XEXP (addr, 0), 0), inreg);
> +         return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1));
> +       }
> +    }
> +
> +  if (ix86_cmodel != CM_LARGE_PIC && ix86_cmodel != CM_MEDIUM_PIC)
> +    return NULL_RTX;
> +
> +  if (GET_CODE (addr) == SYMBOL_REF
> +      && !is_imported_p (addr)
> +      && SYMBOL_REF_EXTERNAL_P (addr)
> +      && SYMBOL_REF_DECL (addr))
> +    return legitimize_pe_coff_extern_decl (addr, inreg);
> +
> +  if (GET_CODE (addr) == CONST
> +      && GET_CODE (XEXP (addr, 0)) == PLUS
> +      && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF
> +      && !is_imported_p (XEXP (XEXP (addr, 0), 0))
> +      && SYMBOL_REF_EXTERNAL_P (XEXP (XEXP (addr, 0), 0))
> +      && SYMBOL_REF_DECL (XEXP (XEXP (addr, 0), 0)))
> +    {
> +      rtx t = legitimize_pe_coff_extern_decl (XEXP (XEXP (addr, 0), 0), inreg);
> +      return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1));
> +    }
> +  return NULL_RTX;
> +}
> +
> +#include "gt-winnt-dll.h"
> \ No newline at end of file
> diff --git a/gcc/config/mingw/winnt-dll.h b/gcc/config/mingw/winnt-dll.h
> new file mode 100644
> index 00000000000..14ca743b69f
> --- /dev/null
> +++ b/gcc/config/mingw/winnt-dll.h
> @@ -0,0 +1,30 @@
> +/* Expand a SYMBOL into its corresponding dllimport, far-address,
> +or refptr symbol.
> +Copyright (C) 2024 Free Software Foundation, Inc.
> +
> +GCC is free software; you can redistribute it and/or modify it under
> +the terms of the GNU General Public License as published by the Free
> +Software Foundation; either version 3, or (at your option) any later
> +version.
> +
> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING3.  If not see
> +http://www.gnu.org/licenses/.  */
> +
> +#ifndef GCC_MINGW_WINNT_DLL_H
> +#define GCC_MINGW_WINNT_DLL_H
> +
> +#ifndef USED_FOR_TARGET
> +
> +extern bool is_imported_p (rtx x);
> +extern alias_set_type mingw_GOT_alias_set (void);
> +extern rtx legitimize_pe_coff_symbol (rtx addr, bool inreg);
> +
> +#endif /* not USED_FOR_TARGET.  */
> +
> +#endif /* GCC_MINGW_WINNT_DLL_H.  */
> diff --git a/gcc/config/mingw/winnt.cc b/gcc/config/mingw/winnt.cc
> index 2a4fc03fc56..9901576ade0 100644
> --- a/gcc/config/mingw/winnt.cc
> +++ b/gcc/config/mingw/winnt.cc
> @@ -672,7 +672,7 @@ mingw_pe_maybe_record_exported_symbol (tree decl, const char *name, int is_data)
>  }
>
>  void
> -i386_pe_record_stub (const char *name)
> +mingw_pe_record_stub (const char *name)
>  {
>    struct stub_list *p;
>
> diff --git a/gcc/config/mingw/winnt.h b/gcc/config/mingw/winnt.h
> index d6202816e8f..74e454a13c8 100644
> --- a/gcc/config/mingw/winnt.h
> +++ b/gcc/config/mingw/winnt.h
> @@ -25,6 +25,7 @@ extern void mingw_pe_declare_function_type (FILE *file, const char *name,
>         int pub);
>  extern void mingw_pe_encode_section_info (tree, rtx, int);
>  extern void mingw_pe_maybe_record_exported_symbol (tree, const char *, int);
> +extern void mingw_pe_record_stub (const char *name);
>  extern unsigned int mingw_pe_section_type_flags (tree, const char *, int);
>  extern void mingw_pe_unique_section (tree, int);
>
> --
> 2.25.1
>
Evgeny Karpov June 8, 2024, 12:37 p.m. UTC | #2
This patch makes changes to the i386.cc file, which contains the ASCII 0x0C character. However, this character was replaced by the mail client, and the patchwork could not validate the series. I am resubmitting the patch as an attachment.
Tobias Burnus June 25, 2024, 10:02 a.m. UTC | #3
Hi Evgeny,

I am not sure whether I have chosen the right email in the thread but:
a x86-64 GNU Linux build currently fails as follows.

At a glance, it seems to be sufficient to remove the prototype 
declaration in i386.cc.

Namely:

gcc/config/i386/i386.cc:107:12: error: 'rtx_def* 
legitimize_dllimport_symbol(rtx, bool)' declared 'static' but never 
defined [-Werror=unused-function]
   107 | static rtx legitimize_dllimport_symbol (rtx, bool);
       |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~

gcc/gcc/config/i386/i386.cc:108:12: error: 'rtx_def* 
legitimize_pe_coff_extern_decl(rtx, bool)' declared 'static' but never 
defined [-Werror=unused-function]
   108 | static rtx legitimize_pe_coff_extern_decl (rtx, bool);
       |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^Cmake[3]: *** [Makefile:2556: i386.o] Interrupt

There is:

config/i386/i386.cc:static rtx legitimize_dllimport_symbol (rtx, bool);
config/mingw/winnt-dll.cc:legitimize_dllimport_symbol (rtx symbol, bool 
want_reg)
config/mingw/winnt-dll.cc:      return legitimize_dllimport_symbol 
(addr, inreg);
config/mingw/winnt-dll.cc:        rtx t = legitimize_dllimport_symbol 
(XEXP (XEXP (addr, 0), 0), inreg);


And:

config/i386/i386.cc:static rtx legitimize_pe_coff_extern_decl (rtx, bool);
config/mingw/winnt-dll.cc:legitimize_pe_coff_extern_decl (rtx symbol, 
bool want_reg)
config/mingw/winnt-dll.cc:    return legitimize_pe_coff_extern_decl 
(addr, inreg);
config/mingw/winnt-dll.cc:      rtx t = legitimize_pe_coff_extern_decl 
(XEXP (XEXP (addr, 0), 0), inreg);

Tobias
Evgeny Karpov June 25, 2024, 10:49 a.m. UTC | #4
Tuesday, June 25, 2024 12:03 PM
Tobias Burnus <tburnus@baylibre.com> wrote:
> 
> Hi Evgeny,
> 
> I am not sure whether I have chosen the right email in the thread but:
> a x86-64 GNU Linux build currently fails as follows.
> 
> At a glance, it seems to be sufficient to remove the prototype
> declaration in i386.cc.
> 
> Namely:
> 
> gcc/config/i386/i386.cc:107:12: error: 'rtx_def*
> legitimize_dllimport_symbol(rtx, bool)' declared 'static' but never
> defined [-Werror=unused-function]
>    107 | static rtx legitimize_dllimport_symbol (rtx, bool);
>        |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> gcc/gcc/config/i386/i386.cc:108:12: error: 'rtx_def*
> legitimize_pe_coff_extern_decl(rtx, bool)' declared 'static' but never
> defined [-Werror=unused-function]
>    108 | static rtx legitimize_pe_coff_extern_decl (rtx, bool);
>        |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ^Cmake[3]: *** [Makefile:2556: i386.o] Interrupt
> 
> There is:
> 
> config/i386/i386.cc:static rtx legitimize_dllimport_symbol (rtx, bool);
> config/mingw/winnt-dll.cc:legitimize_dllimport_symbol (rtx symbol, bool
> want_reg)
> config/mingw/winnt-dll.cc:      return legitimize_dllimport_symbol
> (addr, inreg);
> config/mingw/winnt-dll.cc:        rtx t = legitimize_dllimport_symbol
> (XEXP (XEXP (addr, 0), 0), inreg);
> 
> 
> And:
> 
> config/i386/i386.cc:static rtx legitimize_pe_coff_extern_decl (rtx, bool);
> config/mingw/winnt-dll.cc:legitimize_pe_coff_extern_decl (rtx symbol,
> bool want_reg)
> config/mingw/winnt-dll.cc:    return legitimize_pe_coff_extern_decl
> (addr, inreg);
> config/mingw/winnt-dll.cc:      rtx t = legitimize_pe_coff_extern_decl
> (XEXP (XEXP (addr, 0), 0), inreg);
> 
> Tobias

Thank you, Tobias, for reporting the problem.

x86_64-gnu-linux build has been built however it looks like it is missing a check for unused functions.
The fix will be prepared, tested and submitted to the mailing list today.

Regards,
Evgeny
diff mbox series

Patch

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 553a310f4bd..d053b98efa8 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2177,11 +2177,13 @@  i[4567]86-wrs-vxworks*|x86_64-wrs-vxworks7*)
 i[34567]86-*-cygwin*)
 	tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/cygming.h i386/cygwin.h i386/cygwin-stdint.h"
 	tm_file="${tm_file} mingw/winnt.h"
+	tm_file="${tm_file} mingw/winnt-dll.h"
 	xm_file=i386/xm-cygwin.h
 	tmake_file="${tmake_file} mingw/t-cygming t-slibgcc"
 	target_gtfiles="$target_gtfiles \$(srcdir)/config/mingw/winnt.cc"
+	target_gtfiles="$target_gtfiles \$(srcdir)/config/mingw/winnt-dll.cc"
 	extra_options="${extra_options} mingw/cygming.opt i386/cygwin.opt"
-	extra_objs="${extra_objs} winnt.o winnt-stubs.o"
+	extra_objs="${extra_objs} winnt.o winnt-stubs.o winnt-dll.o"
 	c_target_objs="${c_target_objs} msformat-c.o"
 	cxx_target_objs="${cxx_target_objs} winnt-cxx.o msformat-c.o"
 	d_target_objs="${d_target_objs} cygwin-d.o"
@@ -2196,11 +2198,13 @@  x86_64-*-cygwin*)
 	need_64bit_isa=yes
 	tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/cygming.h i386/cygwin.h i386/cygwin-w64.h i386/cygwin-stdint.h"
 	tm_file="${tm_file} mingw/winnt.h"
+	tm_file="${tm_file} mingw/winnt-dll.h"
 	xm_file=i386/xm-cygwin.h
 	tmake_file="${tmake_file} mingw/t-cygming t-slibgcc"
 	target_gtfiles="$target_gtfiles \$(srcdir)/config/mingw/winnt.cc"
+	target_gtfiles="$target_gtfiles \$(srcdir)/config/mingw/winnt-dll.cc"
 	extra_options="${extra_options} mingw/cygming.opt i386/cygwin.opt"
-	extra_objs="${extra_objs} winnt.o winnt-stubs.o"
+	extra_objs="${extra_objs} winnt.o winnt-stubs.o winnt-dll.o"
 	c_target_objs="${c_target_objs} msformat-c.o"
 	cxx_target_objs="${cxx_target_objs} winnt-cxx.o msformat-c.o"
 	d_target_objs="${d_target_objs} cygwin-d.o"
@@ -2266,6 +2270,7 @@  i[34567]86-*-mingw* | x86_64-*-mingw*)
 	esac
 	tm_file="${tm_file} mingw/mingw-stdint.h"
 	tm_file="${tm_file} mingw/winnt.h"
+	tm_file="${tm_file} mingw/winnt-dll.h"
 	tmake_file="${tmake_file} t-winnt mingw/t-cygming t-slibgcc"
         case ${target} in
                x86_64-w64-*)
@@ -2277,6 +2282,7 @@  i[34567]86-*-mingw* | x86_64-*-mingw*)
 	esac
         native_system_header_dir=/mingw/include
 	target_gtfiles="$target_gtfiles \$(srcdir)/config/mingw/winnt.cc"
+	target_gtfiles="$target_gtfiles \$(srcdir)/config/mingw/winnt-dll.cc"
 	extra_options="${extra_options} mingw/cygming.opt mingw/mingw.opt"
 	case ${target} in
 		*-w64-*)
@@ -2285,7 +2291,7 @@  i[34567]86-*-mingw* | x86_64-*-mingw*)
 		*)
 			;;
 	esac
-	extra_objs="${extra_objs} winnt.o winnt-stubs.o"
+	extra_objs="${extra_objs} winnt.o winnt-stubs.o winnt-dll.o"
 	c_target_objs="${c_target_objs} msformat-c.o"
 	cxx_target_objs="${cxx_target_objs} winnt-cxx.o msformat-c.o"
 	gas=yes
diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
index 98b375538e7..56945f00c11 100644
--- a/gcc/config/i386/cygming.h
+++ b/gcc/config/i386/cygming.h
@@ -461,7 +461,7 @@  do {						\
 #define TARGET_ASM_ASSEMBLE_VISIBILITY i386_pe_assemble_visibility
 
 #undef SUB_TARGET_RECORD_STUB
-#define SUB_TARGET_RECORD_STUB i386_pe_record_stub
+#define SUB_TARGET_RECORD_STUB mingw_pe_record_stub
 
 /* Static stack checking is supported by means of probes.  */
 #define STACK_CHECK_STATIC_BUILTIN 1
@@ -469,3 +469,6 @@  do {						\
 #ifndef HAVE_GAS_ALIGNED_COMM
 # define HAVE_GAS_ALIGNED_COMM 0
 #endif
+
+#undef GOT_ALIAS_SET
+#define GOT_ALIAS_SET mingw_GOT_alias_set ()
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index d1d396a8713..e09c97f1520 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -408,10 +408,11 @@  ix86_expand_move (machine_mode mode, rtx operands[])
 				 : UNSPEC_GOT));
 	  op1 = gen_rtx_CONST (Pmode, op1);
 	  op1 = gen_const_mem (Pmode, op1);
-	  set_mem_alias_set (op1, ix86_GOT_alias_set ());
+	  set_mem_alias_set (op1, GOT_ALIAS_SET);
 	}
       else
 	{
+#if TARGET_PECOFF
 	  tmp = legitimize_pe_coff_symbol (op1, addend != NULL_RTX);
 	  if (tmp)
 	    {
@@ -424,6 +425,7 @@  ix86_expand_move (machine_mode mode, rtx operands[])
 	      op1 = operands[1];
 	      break;
 	    }
+#endif
 	}
 
       if (addend)
diff --git a/gcc/config/i386/i386-expand.h b/gcc/config/i386/i386-expand.h
index 65cb49c921c..5e02df1706d 100644
--- a/gcc/config/i386/i386-expand.h
+++ b/gcc/config/i386/i386-expand.h
@@ -34,9 +34,7 @@  struct expand_vec_perm_d
 };
 
 rtx legitimize_tls_address (rtx x, enum tls_model model, bool for_mov);
-alias_set_type ix86_GOT_alias_set (void);
 rtx legitimize_pic_address (rtx orig, rtx reg);
-rtx legitimize_pe_coff_symbol (rtx addr, bool inreg);
 
 bool insn_defines_reg (unsigned int regno1, unsigned int regno2,
 		       rtx_insn *insn);
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 65ef3d77c3a..b2e9b9e0d3d 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -318,7 +318,6 @@  extern void i386_pe_end_cold_function (FILE *, const char *, tree);
 extern void i386_pe_assemble_visibility (tree, int);
 extern tree i386_pe_mangle_decl_assembler_name (tree, tree);
 extern tree i386_pe_mangle_assembler_name (const char *);
-extern void i386_pe_record_stub (const char *);
 
 extern void i386_pe_seh_init (FILE *);
 extern void i386_pe_seh_end_prologue (FILE *);
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 4126ab24a79..cf998252340 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -11244,20 +11244,6 @@  ix86_cannot_force_const_mem (machine_mode mode, rtx x)
   return !ix86_legitimate_constant_p (mode, x);
 }
 
-/*  Nonzero if the symbol is marked as dllimport, or as stub-variable,
-    otherwise zero.  */
-
-static bool
-is_imported_p (rtx x)
-{
-  if (!TARGET_DLLIMPORT_DECL_ATTRIBUTES
-      || GET_CODE (x) != SYMBOL_REF)
-    return false;
-
-  return SYMBOL_REF_DLLIMPORT_P (x) || SYMBOL_REF_STUBVAR_P (x);
-}
-
-
 /* Nonzero if the constant value X is a legitimate general operand
    when generating PIC code.  It is given that flag_pic is on and
    that X satisfies CONSTANT_P.  */
@@ -11359,8 +11345,10 @@  legitimate_pic_address_disp_p (rtx disp)
 
 	  if (TARGET_PECOFF)
 	    {
+#if TARGET_PECOFF
 	      if (is_imported_p (op0))
 		return true;
+#endif
 
 	      if (SYMBOL_REF_FAR_ADDR_P (op0) || !SYMBOL_REF_LOCAL_P (op0))
 		break;
@@ -11836,16 +11824,6 @@  constant_address_p (rtx x)
   return CONSTANT_P (x) && ix86_legitimate_address_p (Pmode, x, 1);
 }
 

-/* Return a unique alias set for the GOT.  */
-
-alias_set_type
-ix86_GOT_alias_set (void)
-{
-  static alias_set_type set = -1;
-  if (set == -1)
-    set = new_alias_set ();
-  return set;
-}
 
 /* Return a legitimate reference for ORIG (an address) using the
    register REG.  If REG is 0, a new pseudo is generated.
@@ -11883,9 +11861,11 @@  legitimize_pic_address (rtx orig, rtx reg)
 
   if (TARGET_64BIT && TARGET_DLLIMPORT_DECL_ATTRIBUTES)
     {
+#if TARGET_PECOFF
       rtx tmp = legitimize_pe_coff_symbol (addr, true);
       if (tmp)
         return tmp;
+#endif
     }
 
   if (TARGET_64BIT && legitimate_pic_address_disp_p (addr))
@@ -11928,9 +11908,11 @@  legitimize_pic_address (rtx orig, rtx reg)
 	      on VxWorks, see gotoff_operand.  */
 	   || (TARGET_VXWORKS_RTP && GET_CODE (addr) == LABEL_REF))
     {
+#if TARGET_PECOFF
       rtx tmp = legitimize_pe_coff_symbol (addr, true);
       if (tmp)
         return tmp;
+#endif
 
       /* For x64 PE-COFF there is no GOT table,
 	 so we use address directly.  */
@@ -11945,7 +11927,7 @@  legitimize_pic_address (rtx orig, rtx reg)
 				    UNSPEC_GOTPCREL);
 	  new_rtx = gen_rtx_CONST (Pmode, new_rtx);
 	  new_rtx = gen_const_mem (Pmode, new_rtx);
-	  set_mem_alias_set (new_rtx, ix86_GOT_alias_set ());
+	  set_mem_alias_set (new_rtx, GOT_ALIAS_SET);
 	}
       else
 	{
@@ -11967,7 +11949,7 @@  legitimize_pic_address (rtx orig, rtx reg)
 	    new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
 
 	  new_rtx = gen_const_mem (Pmode, new_rtx);
-	  set_mem_alias_set (new_rtx, ix86_GOT_alias_set ());
+	  set_mem_alias_set (new_rtx, GOT_ALIAS_SET);
 	}
 
       new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
@@ -12344,7 +12326,7 @@  legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
       if (pic)
 	off = gen_rtx_PLUS (tp_mode, pic, off);
       off = gen_const_mem (tp_mode, off);
-      set_mem_alias_set (off, ix86_GOT_alias_set ());
+      set_mem_alias_set (off, GOT_ALIAS_SET);
 
       if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
 	{
@@ -12503,173 +12485,6 @@  ix86_rewrite_tls_address (rtx pattern)
   return pattern;
 }
 
-/* Create or return the unique __imp_DECL dllimport symbol corresponding
-   to symbol DECL if BEIMPORT is true.  Otherwise create or return the
-   unique refptr-DECL symbol corresponding to symbol DECL.  */
-
-struct dllimport_hasher : ggc_cache_ptr_hash<tree_map>
-{
-  static inline hashval_t hash (tree_map *m) { return m->hash; }
-  static inline bool
-  equal (tree_map *a, tree_map *b)
-  {
-    return a->base.from == b->base.from;
-  }
-
-  static int
-  keep_cache_entry (tree_map *&m)
-  {
-    return ggc_marked_p (m->base.from);
-  }
-};
-
-static GTY((cache)) hash_table<dllimport_hasher> *dllimport_map;
-
-static tree
-get_dllimport_decl (tree decl, bool beimport)
-{
-  struct tree_map *h, in;
-  const char *name;
-  const char *prefix;
-  size_t namelen, prefixlen;
-  char *imp_name;
-  tree to;
-  rtx rtl;
-
-  if (!dllimport_map)
-    dllimport_map = hash_table<dllimport_hasher>::create_ggc (512);
-
-  in.hash = htab_hash_pointer (decl);
-  in.base.from = decl;
-  tree_map **loc = dllimport_map->find_slot_with_hash (&in, in.hash, INSERT);
-  h = *loc;
-  if (h)
-    return h->to;
-
-  *loc = h = ggc_alloc<tree_map> ();
-  h->hash = in.hash;
-  h->base.from = decl;
-  h->to = to = build_decl (DECL_SOURCE_LOCATION (decl),
-			   VAR_DECL, NULL, ptr_type_node);
-  DECL_ARTIFICIAL (to) = 1;
-  DECL_IGNORED_P (to) = 1;
-  DECL_EXTERNAL (to) = 1;
-  TREE_READONLY (to) = 1;
-
-  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-  name = targetm.strip_name_encoding (name);
-  if (beimport)
-    prefix = name[0] == FASTCALL_PREFIX || user_label_prefix[0] == 0
-      ? "*__imp_" : "*__imp__";
-  else
-    prefix = user_label_prefix[0] == 0 ? "*.refptr." : "*refptr.";
-  namelen = strlen (name);
-  prefixlen = strlen (prefix);
-  imp_name = (char *) alloca (namelen + prefixlen + 1);
-  memcpy (imp_name, prefix, prefixlen);
-  memcpy (imp_name + prefixlen, name, namelen + 1);
-
-  name = ggc_alloc_string (imp_name, namelen + prefixlen);
-  rtl = gen_rtx_SYMBOL_REF (Pmode, name);
-  SET_SYMBOL_REF_DECL (rtl, to);
-  SYMBOL_REF_FLAGS (rtl) = SYMBOL_FLAG_LOCAL | SYMBOL_FLAG_STUBVAR;
-  if (!beimport)
-    {
-      SYMBOL_REF_FLAGS (rtl) |= SYMBOL_FLAG_EXTERNAL;
-#ifdef SUB_TARGET_RECORD_STUB
-      SUB_TARGET_RECORD_STUB (name);
-#endif
-    }      
-
-  rtl = gen_const_mem (Pmode, rtl);
-  set_mem_alias_set (rtl, ix86_GOT_alias_set ());
-
-  SET_DECL_RTL (to, rtl);
-  SET_DECL_ASSEMBLER_NAME (to, get_identifier (name));
-
-  return to;
-}
-
-/* Expand SYMBOL into its corresponding far-address symbol.
-   WANT_REG is true if we require the result be a register.  */
-
-static rtx
-legitimize_pe_coff_extern_decl (rtx symbol, bool want_reg)
-{
-  tree imp_decl;
-  rtx x;
-
-  gcc_assert (SYMBOL_REF_DECL (symbol));
-  imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol), false);
-
-  x = DECL_RTL (imp_decl);
-  if (want_reg)
-    x = force_reg (Pmode, x);
-  return x;
-}
-
-/* Expand SYMBOL into its corresponding dllimport symbol.  WANT_REG is
-   true if we require the result be a register.  */
-
-static rtx
-legitimize_dllimport_symbol (rtx symbol, bool want_reg)
-{
-  tree imp_decl;
-  rtx x;
-
-  gcc_assert (SYMBOL_REF_DECL (symbol));
-  imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol), true);
-
-  x = DECL_RTL (imp_decl);
-  if (want_reg)
-    x = force_reg (Pmode, x);
-  return x;
-}
-
-/* Expand SYMBOL into its corresponding dllimport or refptr symbol.  WANT_REG 
-   is true if we require the result be a register.  */
-
-rtx
-legitimize_pe_coff_symbol (rtx addr, bool inreg)
-{
-  if (!TARGET_PECOFF)
-    return NULL_RTX;
-
-  if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
-    {
-      if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_DLLIMPORT_P (addr))
-	return legitimize_dllimport_symbol (addr, inreg);
-      if (GET_CODE (addr) == CONST
-	  && GET_CODE (XEXP (addr, 0)) == PLUS
-	  && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF
-	  && SYMBOL_REF_DLLIMPORT_P (XEXP (XEXP (addr, 0), 0)))
-	{
-	  rtx t = legitimize_dllimport_symbol (XEXP (XEXP (addr, 0), 0), inreg);
-	  return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1));
-	}
-    }
-
-  if (ix86_cmodel != CM_LARGE_PIC && ix86_cmodel != CM_MEDIUM_PIC)
-    return NULL_RTX;
-  if (GET_CODE (addr) == SYMBOL_REF
-      && !is_imported_p (addr)
-      && SYMBOL_REF_EXTERNAL_P (addr)
-      && SYMBOL_REF_DECL (addr))
-    return legitimize_pe_coff_extern_decl (addr, inreg);
-
-  if (GET_CODE (addr) == CONST
-      && GET_CODE (XEXP (addr, 0)) == PLUS
-      && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF
-      && !is_imported_p (XEXP (XEXP (addr, 0), 0))
-      && SYMBOL_REF_EXTERNAL_P (XEXP (XEXP (addr, 0), 0))
-      && SYMBOL_REF_DECL (XEXP (XEXP (addr, 0), 0)))
-    {
-      rtx t = legitimize_pe_coff_extern_decl (XEXP (XEXP (addr, 0), 0), inreg);
-      return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1));
-    }
-  return NULL_RTX;
-}
-
 /* Try machine-dependent ways of modifying an illegitimate address
    to be legitimate.  If we find one, return the new, valid address.
    This macro is used in only one place: `memory_address' in explow.cc.
@@ -12709,9 +12524,11 @@  ix86_legitimize_address (rtx x, rtx, machine_mode mode)
 
   if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
     {
+#if TARGET_PECOFF
       rtx tmp = legitimize_pe_coff_symbol (x, true);
       if (tmp)
         return tmp;
+#endif
     }
 
   if (flag_pic && SYMBOLIC_CONST (x))
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 7051c6c13e4..d9f02f66518 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -2262,6 +2262,8 @@  extern int const svr4_debugger_register_map[FIRST_PSEUDO_REGISTER];
 /* Which processor to tune code generation for.  These must be in sync
    with processor_cost_table in i386-options.cc.  */
 
+#define GOT_ALIAS_SET -1
+
 enum processor_type
 {
   PROCESSOR_GENERIC = 0,
diff --git a/gcc/config/mingw/t-cygming b/gcc/config/mingw/t-cygming
index f5de941c8e5..3dd9116d92b 100644
--- a/gcc/config/mingw/t-cygming
+++ b/gcc/config/mingw/t-cygming
@@ -33,6 +33,12 @@  winnt-cxx.o: $(srcdir)/config/mingw/winnt-cxx.cc $(CONFIG_H) $(SYSTEM_H) \
 	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
 	$(srcdir)/config/mingw/winnt-cxx.cc
 
+winnt-dll.o: $(srcdir)/config/mingw/winnt-dll.cc $(CONFIG_H) $(SYSTEM_H) \
+  coretypes.h \
+  $(TM_H) $(TREE_H) flags.h \
+  $(TM_P_H) $(HASH_TABLE_H) $(GGC_H)
+	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+	$(srcdir)/config/mingw/winnt-dll.cc
 
 winnt-stubs.o: $(srcdir)/config/mingw/winnt-stubs.cc $(CONFIG_H) $(SYSTEM_H) \
   coretypes.h \
diff --git a/gcc/config/mingw/winnt-dll.cc b/gcc/config/mingw/winnt-dll.cc
new file mode 100644
index 00000000000..1354402a959
--- /dev/null
+++ b/gcc/config/mingw/winnt-dll.cc
@@ -0,0 +1,231 @@ 
+/* Expand a SYMBOL into its corresponding dllimport, far-address,
+or refptr symbol.
+Copyright (C) 1988-2024 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+http://www.gnu.org/licenses/.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "target.h"
+#include "rtl.h"
+#include "tree.h"
+#include "memmodel.h"
+#include "stringpool.h"
+#include "emit-rtl.h"
+#include "alias.h"
+#include "varasm.h"
+#include "output.h"
+#include "explow.h"
+#include "winnt.h"
+
+/* Create or return the unique __imp_DECL dllimport symbol corresponding
+   to symbol DECL if BEIMPORT is true.  Otherwise create or return the
+   unique refptr-DECL symbol corresponding to symbol DECL.  */
+
+struct dllimport_hasher : ggc_cache_ptr_hash<tree_map>
+{
+  static inline hashval_t hash (tree_map *m)
+  {
+    return m->hash;
+  }
+
+  static inline bool
+  equal (tree_map *a, tree_map *b)
+  {
+    return a->base.from == b->base.from;
+  }
+
+  static int
+  keep_cache_entry (tree_map *&m)
+  {
+    return ggc_marked_p (m->base.from);
+  }
+};
+
+static GTY ((cache)) hash_table<dllimport_hasher> *dllimport_map;
+
+/*  Nonzero if the symbol is marked as dllimport, or as stub-variable,
+    otherwise zero.  */
+
+bool
+is_imported_p (rtx x)
+{
+  if (!TARGET_DLLIMPORT_DECL_ATTRIBUTES
+      || GET_CODE (x) != SYMBOL_REF)
+    return false;
+
+  return SYMBOL_REF_DLLIMPORT_P (x) || SYMBOL_REF_STUBVAR_P (x);
+}
+
+/* Return a unique alias set for the GOT.  */
+
+alias_set_type
+mingw_GOT_alias_set (void)
+{
+  static alias_set_type set = -1;
+  if (set == -1)
+    set = new_alias_set ();
+  return set;
+}
+
+static tree
+get_dllimport_decl (tree decl, bool beimport)
+{
+  struct tree_map *h, in;
+  const char *name;
+  const char *prefix;
+  size_t namelen, prefixlen;
+  char *imp_name;
+  tree to;
+  rtx rtl;
+
+  if (!dllimport_map)
+    dllimport_map = hash_table<dllimport_hasher>::create_ggc (512);
+
+  in.hash = htab_hash_pointer (decl);
+  in.base.from = decl;
+  tree_map **loc = dllimport_map->find_slot_with_hash (&in, in.hash, INSERT);
+  h = *loc;
+  if (h)
+    return h->to;
+
+  *loc = h = ggc_alloc<tree_map> ();
+  h->hash = in.hash;
+  h->base.from = decl;
+  h->to = to = build_decl (DECL_SOURCE_LOCATION (decl),
+			   VAR_DECL, NULL, ptr_type_node);
+  DECL_ARTIFICIAL (to) = 1;
+  DECL_IGNORED_P (to) = 1;
+  DECL_EXTERNAL (to) = 1;
+  TREE_READONLY (to) = 1;
+
+  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+  name = targetm.strip_name_encoding (name);
+  if (beimport)
+    prefix = name[0] == FASTCALL_PREFIX || user_label_prefix[0] == 0
+      ? "*__imp_" : "*__imp__";
+  else
+    prefix = user_label_prefix[0] == 0 ? "*.refptr." : "*refptr.";
+  namelen = strlen (name);
+  prefixlen = strlen (prefix);
+  imp_name = (char *) alloca (namelen + prefixlen + 1);
+  memcpy (imp_name, prefix, prefixlen);
+  memcpy (imp_name + prefixlen, name, namelen + 1);
+
+  name = ggc_alloc_string (imp_name, namelen + prefixlen);
+  rtl = gen_rtx_SYMBOL_REF (Pmode, name);
+  SET_SYMBOL_REF_DECL (rtl, to);
+  SYMBOL_REF_FLAGS (rtl) = SYMBOL_FLAG_LOCAL | SYMBOL_FLAG_STUBVAR;
+  if (!beimport)
+    {
+      SYMBOL_REF_FLAGS (rtl) |= SYMBOL_FLAG_EXTERNAL;
+#ifdef SUB_TARGET_RECORD_STUB
+      SUB_TARGET_RECORD_STUB (name);
+#endif
+    }
+
+  rtl = gen_const_mem (Pmode, rtl);
+  set_mem_alias_set (rtl, mingw_GOT_alias_set ());
+
+  SET_DECL_RTL (to, rtl);
+  SET_DECL_ASSEMBLER_NAME (to, get_identifier (name));
+
+  return to;
+}
+
+/* Expand SYMBOL into its corresponding far-address symbol.
+   WANT_REG is true if we require the result be a register.  */
+
+static rtx
+legitimize_pe_coff_extern_decl (rtx symbol, bool want_reg)
+{
+  tree imp_decl;
+  rtx x;
+
+  gcc_assert (SYMBOL_REF_DECL (symbol));
+  imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol), false);
+
+  x = DECL_RTL (imp_decl);
+  if (want_reg)
+    x = force_reg (Pmode, x);
+  return x;
+}
+
+/* Expand SYMBOL into its corresponding dllimport symbol.  WANT_REG is
+   true if we require the result be a register.  */
+
+static rtx
+legitimize_dllimport_symbol (rtx symbol, bool want_reg)
+{
+  tree imp_decl;
+  rtx x;
+
+  gcc_assert (SYMBOL_REF_DECL (symbol));
+  imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol), true);
+
+  x = DECL_RTL (imp_decl);
+  if (want_reg)
+    x = force_reg (Pmode, x);
+  return x;
+}
+
+/* Expand SYMBOL into its corresponding dllimport or refptr symbol.  WANT_REG
+   is true if we require the result be a register.  */
+
+rtx
+legitimize_pe_coff_symbol (rtx addr, bool inreg)
+{
+  if (!TARGET_PECOFF)
+    return NULL_RTX;
+
+  if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
+    {
+      if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_DLLIMPORT_P (addr))
+	return legitimize_dllimport_symbol (addr, inreg);
+      if (GET_CODE (addr) == CONST
+	  && GET_CODE (XEXP (addr, 0)) == PLUS
+	  && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF
+	  && SYMBOL_REF_DLLIMPORT_P (XEXP (XEXP (addr, 0), 0)))
+	{
+	  rtx t = legitimize_dllimport_symbol (XEXP (XEXP (addr, 0), 0), inreg);
+	  return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1));
+	}
+    }
+
+  if (ix86_cmodel != CM_LARGE_PIC && ix86_cmodel != CM_MEDIUM_PIC)
+    return NULL_RTX;
+
+  if (GET_CODE (addr) == SYMBOL_REF
+      && !is_imported_p (addr)
+      && SYMBOL_REF_EXTERNAL_P (addr)
+      && SYMBOL_REF_DECL (addr))
+    return legitimize_pe_coff_extern_decl (addr, inreg);
+
+  if (GET_CODE (addr) == CONST
+      && GET_CODE (XEXP (addr, 0)) == PLUS
+      && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF
+      && !is_imported_p (XEXP (XEXP (addr, 0), 0))
+      && SYMBOL_REF_EXTERNAL_P (XEXP (XEXP (addr, 0), 0))
+      && SYMBOL_REF_DECL (XEXP (XEXP (addr, 0), 0)))
+    {
+      rtx t = legitimize_pe_coff_extern_decl (XEXP (XEXP (addr, 0), 0), inreg);
+      return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1));
+    }
+  return NULL_RTX;
+}
+
+#include "gt-winnt-dll.h"
\ No newline at end of file
diff --git a/gcc/config/mingw/winnt-dll.h b/gcc/config/mingw/winnt-dll.h
new file mode 100644
index 00000000000..14ca743b69f
--- /dev/null
+++ b/gcc/config/mingw/winnt-dll.h
@@ -0,0 +1,30 @@ 
+/* Expand a SYMBOL into its corresponding dllimport, far-address,
+or refptr symbol.
+Copyright (C) 2024 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+http://www.gnu.org/licenses/.  */
+
+#ifndef GCC_MINGW_WINNT_DLL_H
+#define GCC_MINGW_WINNT_DLL_H
+
+#ifndef USED_FOR_TARGET
+
+extern bool is_imported_p (rtx x);
+extern alias_set_type mingw_GOT_alias_set (void);
+extern rtx legitimize_pe_coff_symbol (rtx addr, bool inreg);
+
+#endif /* not USED_FOR_TARGET.  */
+
+#endif /* GCC_MINGW_WINNT_DLL_H.  */
diff --git a/gcc/config/mingw/winnt.cc b/gcc/config/mingw/winnt.cc
index 2a4fc03fc56..9901576ade0 100644
--- a/gcc/config/mingw/winnt.cc
+++ b/gcc/config/mingw/winnt.cc
@@ -672,7 +672,7 @@  mingw_pe_maybe_record_exported_symbol (tree decl, const char *name, int is_data)
 }
 
 void
-i386_pe_record_stub (const char *name)
+mingw_pe_record_stub (const char *name)
 {
   struct stub_list *p;
 
diff --git a/gcc/config/mingw/winnt.h b/gcc/config/mingw/winnt.h
index d6202816e8f..74e454a13c8 100644
--- a/gcc/config/mingw/winnt.h
+++ b/gcc/config/mingw/winnt.h
@@ -25,6 +25,7 @@  extern void mingw_pe_declare_function_type (FILE *file, const char *name,
 	int pub);
 extern void mingw_pe_encode_section_info (tree, rtx, int);
 extern void mingw_pe_maybe_record_exported_symbol (tree, const char *, int);
+extern void mingw_pe_record_stub (const char *name);
 extern unsigned int mingw_pe_section_type_flags (tree, const char *, int);
 extern void mingw_pe_unique_section (tree, int);