Commit 82c0e1a0 by Kai Tietz Committed by Kai Tietz

re PR target/52790 (Problems using x86_64-w64-mingw-w32-gfortran with mcmodel=large and medium)

	PR target/52790
	* config/i386/cygming.h (SUB_TARGET_RECORD_STUB): New sub-target macro.
	* config/i386/i386-protos.h (i386_pe_record_stub): Add new prototype.
	* config/i386/i386.c (legitimize_pe_coff_extern_decl): New static
	function.
	(legitimize_pe_coff_symbol): Likewise.
	(is_imported_p): New helper-function.
	(ix86_option_override_internal): Make MEDIUM_PIC the default code-model
	for Windows x64 targets.
	(ix86_expand_prologue): Optimize for pe-coff targets.
	(ix86_expand_split_stack_prologue): Adjust for pe-coff targets.
	(legitimate_pic_address_disp_p): Adjust for x64 pe-coff to support
	medium/large code-model.
	(legitimize_pic_address): Likewise.
	(legitimize_tls_address): Likewise.
	(ix86_expand_call): Likewise.
	(x86_output_mi_thunk): Likewise.
	(get_dllimport_decl): Add new beimport argument.
	(construct_plt_address): Don't assert for x64 pe-coff targets.
	* config/i386/i386.h (PIC_OFFSET_TABLE_REGNUM): Adjust for x64 pe-coff
	targets.
	(SYMBOL_FLAG_STUBVAR): New macro.
	(SYMBOL_REF_STUBVAR_P): Likewise.
	* config/i386/winnt.c (stub_list): New structure.
	(stub_head): New local variable.
	(i386_pe_record_stub): New function.
	(i386_pe_file_end): Emit refptr-stubs.

From-SVN: r197373
parent 09bb4c99
2013-04-02 Kai Tietz <ktietz@redhat.com>
PR target/52790
* config/i386/cygming.h (SUB_TARGET_RECORD_STUB): New sub-target macro.
* config/i386/i386-protos.h (i386_pe_record_stub): Add new prototype.
* config/i386/i386.c (legitimize_pe_coff_extern_decl): New static function.
(legitimize_pe_coff_symbol): Likewise.
(is_imported_p): New helper-function.
(ix86_option_override_internal): Make MEDIUM_PIC the default code-model
for Windows x64 targets.
(ix86_expand_prologue): Optimize for pe-coff targets.
(ix86_expand_split_stack_prologue): Adjust for pe-coff targets.
(legitimate_pic_address_disp_p): Adjust for x64 pe-coff to support
medium/large code-model.
(legitimize_pic_address): Likewise.
(legitimize_tls_address): Likewise.
(ix86_expand_call): Likewise.
(x86_output_mi_thunk): Likewise.
(get_dllimport_decl): Add new beimport argument.
(construct_plt_address): Don't assert for x64 pe-coff targets.
* config/i386/i386.h (PIC_OFFSET_TABLE_REGNUM): Adjust for x64 pe-coff
targets.
(SYMBOL_FLAG_STUBVAR): New macro.
(SYMBOL_REF_STUBVAR_P): Likewise.
* config/i386/winnt.c (stub_list): New structure.
(stub_head): New local variable.
(i386_pe_record_stub): New function.
(i386_pe_file_end): Emit refptr-stubs.
2013-04-02 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/56745
......
......@@ -474,5 +474,8 @@ do { \
#undef TARGET_ASM_ASSEMBLE_VISIBILITY
#define TARGET_ASM_ASSEMBLE_VISIBILITY i386_pe_assemble_visibility
#undef SUB_TARGET_RECORD_STUB
#define SUB_TARGET_RECORD_STUB i386_pe_record_stub
/* Static stack checking is supported by means of probes. */
#define STACK_CHECK_STATIC_BUILTIN 1
......@@ -260,6 +260,7 @@ extern void i386_pe_end_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 *);
......
......@@ -64,6 +64,8 @@ along with GCC; see the file COPYING3. If not see
#include "tree-flow.h"
static rtx legitimize_dllimport_symbol (rtx, bool);
static rtx legitimize_pe_coff_extern_decl (rtx, bool);
static rtx legitimize_pe_coff_symbol (rtx, bool);
#ifndef CHECK_STACK_LIMIT
#define CHECK_STACK_LIMIT (-1)
......@@ -3233,9 +3235,7 @@ ix86_option_override_internal (bool main_args_p)
use of rip-relative addressing. This eliminates fixups that
would otherwise be needed if this object is to be placed in a
DLL, and is essentially just as efficient as direct addressing. */
if (TARGET_64BIT && DEFAULT_ABI == MS_ABI)
ix86_cmodel = CM_SMALL_PIC, flag_pic = 1;
else if (TARGET_64BIT && TARGET_RDOS)
if (TARGET_64BIT && (TARGET_RDOS || DEFAULT_ABI == MS_ABI))
ix86_cmodel = CM_MEDIUM_PIC, flag_pic = 1;
else if (TARGET_64BIT)
ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL;
......@@ -10575,7 +10575,9 @@ ix86_expand_prologue (void)
ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
pic_reg_used = false;
/* We don't use pic-register for pe-coff target. */
if (pic_offset_table_rtx
&& DEFAULT_ABI != MS_ABI
&& (df_regs_ever_live_p (REAL_PIC_OFFSET_TABLE_REGNUM)
|| crtl->profile))
{
......@@ -11380,7 +11382,8 @@ ix86_expand_split_stack_prologue (void)
use_reg (&call_fusage, rax);
}
if (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
if ((ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
&& DEFAULT_ABI != MS_ABI)
{
HOST_WIDE_INT argval;
......@@ -11998,6 +12001,19 @@ ix86_cannot_force_const_mem (enum 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
......@@ -12086,10 +12102,38 @@ legitimate_pic_address_disp_p (rtx disp)
/* FALLTHRU */
case SYMBOL_REF:
/* TLS references should always be enclosed in UNSPEC. */
if (SYMBOL_REF_TLS_MODEL (op0))
/* TLS references should always be enclosed in UNSPEC.
The dllimported symbol needs always to be resolved. */
if (SYMBOL_REF_TLS_MODEL (op0)
|| (TARGET_DLLIMPORT_DECL_ATTRIBUTES && SYMBOL_REF_DLLIMPORT_P (op0)))
return false;
if (!SYMBOL_REF_FAR_ADDR_P (op0) && SYMBOL_REF_LOCAL_P (op0)
if (DEFAULT_ABI == MS_ABI)
{
if (is_imported_p (op0))
return true;
if (SYMBOL_REF_FAR_ADDR_P (op0)
|| !SYMBOL_REF_LOCAL_P (op0))
break;
/* Function-symbols need to be resolved only for
large-model.
For the small-model we don't need to resolve anything
here. */
if ((ix86_cmodel != CM_LARGE_PIC
&& SYMBOL_REF_FUNCTION_P (op0))
|| ix86_cmodel == CM_SMALL_PIC)
return true;
/* Non-external symbols don't need to be resolved for
large, and medium-model. */
if ((ix86_cmodel == CM_LARGE_PIC
|| ix86_cmodel == CM_MEDIUM_PIC)
&& !SYMBOL_REF_EXTERNAL_P (op0))
return true;
}
else if (!SYMBOL_REF_FAR_ADDR_P (op0)
&& SYMBOL_REF_LOCAL_P (op0)
&& ix86_cmodel != CM_LARGE_PIC)
return true;
break;
......@@ -12151,7 +12195,7 @@ legitimate_pic_address_disp_p (rtx disp)
if ((GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF
|| GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF)
&& !TARGET_64BIT)
return gotoff_operand (XVECEXP (disp, 0, 0), Pmode);
return DEFAULT_ABI != MS_ABI && gotoff_operand (XVECEXP (disp, 0, 0), Pmode);
return false;
case UNSPEC_GOTTPOFF:
case UNSPEC_GOTNTPOFF:
......@@ -12486,11 +12530,17 @@ legitimize_pic_address (rtx orig, rtx reg)
}
#endif
if (TARGET_64BIT && TARGET_DLLIMPORT_DECL_ATTRIBUTES)
{
rtx tmp = legitimize_pe_coff_symbol (addr, true);
if (tmp)
return tmp;
}
if (TARGET_64BIT && legitimate_pic_address_disp_p (addr))
new_rtx = addr;
else if (TARGET_64BIT
&& ix86_cmodel != CM_SMALL_PIC
&& gotoff_operand (addr, Pmode))
else if (TARGET_64BIT && DEFAULT_ABI != MS_ABI
&& ix86_cmodel != CM_SMALL_PIC && gotoff_operand (addr, Pmode))
{
rtx tmpreg;
/* This symbol may be referenced via a displacement from the PIC
......@@ -12521,9 +12571,10 @@ legitimize_pic_address (rtx orig, rtx reg)
tmpreg, 1, OPTAB_DIRECT);
new_rtx = reg;
}
else new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmpreg);
else
new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmpreg);
}
else if (!TARGET_64BIT && gotoff_operand (addr, Pmode))
else if (!TARGET_64BIT && DEFAULT_ABI != MS_ABI && gotoff_operand (addr, Pmode))
{
/* This symbol may be referenced via a displacement from the PIC
base address (@GOTOFF). */
......@@ -12554,18 +12605,9 @@ legitimize_pic_address (rtx orig, rtx reg)
see gotoff_operand. */
|| (TARGET_VXWORKS_RTP && GET_CODE (addr) == LABEL_REF))
{
if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
{
if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_DLLIMPORT_P (addr))
return legitimize_dllimport_symbol (addr, true);
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), true);
return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1));
}
}
rtx tmp = legitimize_pe_coff_symbol (addr, true);
if (tmp)
return tmp;
/* For x64 PE-COFF there is no GOT table. So we use address
directly. */
......@@ -12647,7 +12689,7 @@ legitimize_pic_address (rtx orig, rtx reg)
/* Check first to see if this is a constant offset from a @GOTOFF
symbol reference. */
if (gotoff_operand (op0, Pmode)
if (DEFAULT_ABI != MS_ABI && gotoff_operand (op0, Pmode)
&& CONST_INT_P (op1))
{
if (!TARGET_64BIT)
......@@ -12791,7 +12833,7 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
if (!TARGET_64BIT)
{
if (flag_pic)
if (flag_pic && DEFAULT_ABI != MS_ABI)
pic = pic_offset_table_rtx;
else
{
......@@ -13000,13 +13042,14 @@ legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
}
/* Create or return the unique __imp_DECL dllimport symbol corresponding
to symbol DECL. */
to symbol DECL if BEIMPORT is true. Otherwise create or return the
unique refptr-DECL symbol corresponding to symbol DECL. */
static GTY((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
htab_t dllimport_map;
static tree
get_dllimport_decl (tree decl)
get_dllimport_decl (tree decl, bool beimport)
{
struct tree_map *h, in;
void **loc;
......@@ -13039,8 +13082,11 @@ get_dllimport_decl (tree decl)
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);
......@@ -13050,7 +13096,14 @@ get_dllimport_decl (tree decl)
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_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 ());
......@@ -13061,6 +13114,24 @@ get_dllimport_decl (tree decl)
return to;
}
/* Expand SYMBOL into its corresponding far-addresse 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. */
......@@ -13071,7 +13142,7 @@ legitimize_dllimport_symbol (rtx symbol, bool want_reg)
rtx x;
gcc_assert (SYMBOL_REF_DECL (symbol));
imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol));
imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol), true);
x = DECL_RTL (imp_decl);
if (want_reg)
......@@ -13079,6 +13150,50 @@ legitimize_dllimport_symbol (rtx symbol, bool want_reg)
return x;
}
/* Expand SYMBOL into its corresponding dllimport or refptr symbol. WANT_REG
is true if we require the result be a register. */
static rtx
legitimize_pe_coff_symbol (rtx addr, bool inreg)
{
if (DEFAULT_ABI != MS_ABI)
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.c.
......@@ -13119,16 +13234,9 @@ ix86_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
{
if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_DLLIMPORT_P (x))
return legitimize_dllimport_symbol (x, true);
if (GET_CODE (x) == CONST
&& GET_CODE (XEXP (x, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
&& SYMBOL_REF_DLLIMPORT_P (XEXP (XEXP (x, 0), 0)))
{
rtx t = legitimize_dllimport_symbol (XEXP (XEXP (x, 0), 0), true);
return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (x, 0), 1));
}
rtx tmp = legitimize_pe_coff_symbol (x, true);
if (tmp)
return tmp;
}
if (flag_pic && SYMBOLIC_CONST (x))
......@@ -15944,6 +16052,8 @@ ix86_expand_move (enum machine_mode mode, rtx operands[])
if (GET_CODE (op1) == SYMBOL_REF)
{
rtx tmp;
model = SYMBOL_REF_TLS_MODEL (op1);
if (model)
{
......@@ -15953,9 +16063,8 @@ ix86_expand_move (enum machine_mode mode, rtx operands[])
return;
op1 = convert_to_mode (mode, op1, 1);
}
else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
&& SYMBOL_REF_DLLIMPORT_P (op1))
op1 = legitimize_dllimport_symbol (op1, false);
else if ((tmp = legitimize_pe_coff_symbol (op1, false)) != NULL_RTX)
op1 = tmp;
}
else if (GET_CODE (op1) == CONST
&& GET_CODE (XEXP (op1, 0)) == PLUS
......@@ -15963,14 +16072,13 @@ ix86_expand_move (enum machine_mode mode, rtx operands[])
{
rtx addend = XEXP (XEXP (op1, 0), 1);
rtx symbol = XEXP (XEXP (op1, 0), 0);
rtx tmp = NULL;
rtx tmp;
model = SYMBOL_REF_TLS_MODEL (symbol);
if (model)
tmp = legitimize_tls_address (symbol, model, true);
else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
&& SYMBOL_REF_DLLIMPORT_P (symbol))
tmp = legitimize_dllimport_symbol (symbol, true);
else
tmp = legitimize_pe_coff_symbol (symbol, true);
if (tmp)
{
......@@ -23576,7 +23684,7 @@ construct_plt_address (rtx symbol)
rtx tmp, unspec;
gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
gcc_assert (ix86_cmodel == CM_LARGE_PIC);
gcc_assert (ix86_cmodel == CM_LARGE_PIC && DEFAULT_ABI != MS_ABI);
gcc_assert (Pmode == DImode);
tmp = gen_reg_rtx (Pmode);
......@@ -23618,7 +23726,8 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
else
{
/* Static functions and indirect calls don't need the pic register. */
if (flag_pic && (!TARGET_64BIT || ix86_cmodel == CM_LARGE_PIC)
if (flag_pic && (!TARGET_64BIT
|| (ix86_cmodel == CM_LARGE_PIC && DEFAULT_ABI != MS_ABI))
&& GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
&& ! SYMBOL_REF_LOCAL_P (XEXP (fnaddr, 0)))
use_reg (&use, pic_offset_table_rtx);
......@@ -23632,6 +23741,7 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
}
if (ix86_cmodel == CM_LARGE_PIC
&& DEFAULT_ABI != MS_ABI
&& MEM_P (fnaddr)
&& GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
&& !local_symbolic_operand (XEXP (fnaddr, 0), VOIDmode))
......@@ -34970,7 +35080,7 @@ x86_output_mi_thunk (FILE *file,
if (TARGET_64BIT)
{
if (!flag_pic || targetm.binds_local_p (function)
|| cfun->machine->call_abi == MS_ABI)
|| DEFAULT_ABI == MS_ABI)
;
else
{
......@@ -1179,7 +1179,8 @@ enum target_cpu_default
#define REAL_PIC_OFFSET_TABLE_REGNUM BX_REG
#define PIC_OFFSET_TABLE_REGNUM \
((TARGET_64BIT && ix86_cmodel == CM_SMALL_PIC) \
((TARGET_64BIT && (ix86_cmodel == CM_SMALL_PIC \
|| DEFAULT_ABI == MS_ABI)) \
|| !flag_pic ? INVALID_REGNUM \
: reload_completed ? REGNO (pic_offset_table_rtx) \
: REAL_PIC_OFFSET_TABLE_REGNUM)
......@@ -2379,6 +2380,10 @@ struct GTY(()) machine_function {
#define SYMBOL_REF_DLLEXPORT_P(X) \
((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_DLLEXPORT) != 0)
#define SYMBOL_FLAG_STUBVAR (SYMBOL_FLAG_MACH_DEP << 4)
#define SYMBOL_REF_STUBVAR_P(X) \
((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_STUBVAR) != 0)
extern void debug_ready_dispatch (void);
extern void debug_dispatch_window (int);
......
......@@ -646,8 +646,18 @@ struct GTY(()) export_list
int is_data; /* used to type tag exported symbols. */
};
/* Keep a list of stub symbols. */
struct GTY(()) stub_list
{
struct stub_list *next;
const char *name;
};
static GTY(()) struct export_list *export_head;
static GTY(()) struct stub_list *stub_head;
/* Assemble an export symbol entry. We need to keep a list of
these, so that we can output the export list at the end of the
assembly. We used to output these export symbols in each function,
......@@ -678,6 +688,30 @@ i386_pe_maybe_record_exported_symbol (tree decl, const char *name, int is_data)
export_head = p;
}
void
i386_pe_record_stub (const char *name)
{
struct stub_list *p;
if (!name || *name == 0)
return;
p = stub_head;
while (p != NULL)
{
if (p->name[0] == *name
&& !strcmp (p->name, name))
return;
p = p->next;
}
p = ggc_alloc_stub_list ();
p->next = stub_head;
p->name = name;
stub_head = p;
}
#ifdef CXX_WRAP_SPEC_LIST
/* Hash table equality helper function. */
......@@ -781,6 +815,30 @@ i386_pe_file_end (void)
(q->is_data ? ",data" : ""));
}
}
if (stub_head)
{
struct stub_list *q;
for (q = stub_head; q != NULL; q = q->next)
{
const char *name = q->name;
const char *oname;
if (name[0] == '*')
++name;
oname = name;
if (name[0] == '.')
++name;
if (strncmp (name, "refptr.", 7) != 0)
continue;
name += 7;
fprintf (asm_out_file, "\t.section\t.rdata$%s, \"dr\"\n"
"\t.globl\t%s\n"
"\t.linkonce\tdiscard\n", oname, oname);
fprintf (asm_out_file, "%s:\n\t.quad\t%s\n", oname, name);
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment