On Fri, Jun 7, 2024 at 11:48 AM Evgeny Karpov <evgeny.kar...@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 >