Commit 27da1b4d by Mumit Khan Committed by Jeff Law

Support for dllimport and dllexport attributes for i386-pe.

	* tree.h (DECL_NON_ADDR_CONST_P): New accessor macro.
	(struct tree_decl): Add non_addr_const_p field.
	* tree.c (staticp): Use.
	* i386/cygwin32.h (CPP_PREDEFINES): Map __declspec(x) to GCC
	attributes.
	(SUBTARGET_SWITCHES): Switches to turn on/off dllimport|export
	attributes. Also accept -mwindows option.
	(VALID_MACHINE_DECL_ATTRIBUTE): New macro.
	(MERGE_MACHINE_DECL_ATTRIBUTE): New macro.
	(REDO_SECTION_INFO_P): New macro.
	(DRECTVE_SECTION_FUNCTION): New macro.
	(drectve_section): Cover function to implement above.
	(SWITCH_TO_SECTION_FUNCTION): New macro.
	(switch_to_section): Covert function to implement above.
	(EXTRA_SECTIONS): Add in_drectve.
	(EXTRA_SECTION_FUNCTIONS): Add in_drectve and switch_to_section.
	(ENCODE_SECTION_INFO): Delete old macro and redefine as a function.
	(STRIP_NAME_ENCODING): Handle new attributes.
	(ASM_OUTPUT_LABELREF): New macro.
	(ASM_OUTPUT_FUNCTION_NAME): New macro.
	(ASM_OUTPUT_COMMON): New macro.
	(ASM_OUTPUT_DECLARE_OBJECT_NAME): New macro.
	* i386/mingw32.h (CPP_PREDEFINES): Map __declspec(x) to GCC
	attributes.
	* i386/winnt.c (i386_pe_valid_decl_attribute_p): New function.
	(i386_pe_merge_decl_attributes): New function.
	(i386_pe_check_vtable_importexport): New function.
	(i386_pe_dllexport_p): New function.
	(i386_pe_dllimport_p): New function.
	(i386_pe_dllexport_name_p): New function.
	(i386_pe_dllimport_name_p): New function.
	(i386_pe_mark_dllexport): New function.
	(i386_pe_mark_dllimport): New function.
	(i386_pe_encode_section_info): New function.
	(i386_pe_unique_section): Strip encoding from name first.

From-SVN: r20983
parent bceb30e7
Tue Jul 7 01:03:03 1998 Mumit Khan <khan@xraylith.wisc.edu>
Support for dllimport and dllexport attributes for i386-pe.
* tree.h (DECL_NON_ADDR_CONST_P): New accessor macro.
(struct tree_decl): Add non_addr_const_p field.
* tree.c (staticp): Use.
* i386/cygwin32.h (CPP_PREDEFINES): Map __declspec(x) to GCC
attributes.
(SUBTARGET_SWITCHES): Switches to turn on/off dllimport|export
attributes. Also accept -mwindows option.
(VALID_MACHINE_DECL_ATTRIBUTE): New macro.
(MERGE_MACHINE_DECL_ATTRIBUTE): New macro.
(REDO_SECTION_INFO_P): New macro.
(DRECTVE_SECTION_FUNCTION): New macro.
(drectve_section): Cover function to implement above.
(SWITCH_TO_SECTION_FUNCTION): New macro.
(switch_to_section): Covert function to implement above.
(EXTRA_SECTIONS): Add in_drectve.
(EXTRA_SECTION_FUNCTIONS): Add in_drectve and switch_to_section.
(ENCODE_SECTION_INFO): Delete old macro and redefine as a function.
(STRIP_NAME_ENCODING): Handle new attributes.
(ASM_OUTPUT_LABELREF): New macro.
(ASM_OUTPUT_FUNCTION_NAME): New macro.
(ASM_OUTPUT_COMMON): New macro.
(ASM_OUTPUT_DECLARE_OBJECT_NAME): New macro.
* i386/mingw32.h (CPP_PREDEFINES): Map __declspec(x) to GCC
attributes.
* i386/winnt.c (i386_pe_valid_decl_attribute_p): New function.
(i386_pe_merge_decl_attributes): New function.
(i386_pe_check_vtable_importexport): New function.
(i386_pe_dllexport_p): New function.
(i386_pe_dllimport_p): New function.
(i386_pe_dllexport_name_p): New function.
(i386_pe_dllimport_name_p): New function.
(i386_pe_mark_dllexport): New function.
(i386_pe_mark_dllimport): New function.
(i386_pe_encode_section_info): New function.
(i386_pe_unique_section): Strip encoding from name first.
Tue Jul 7 00:50:17 1998 Manfred Hollstein (manfred@s-direktnet.de)
* libgcc2.c (L_exit): Provide a fake for atexit on systems which
......
......@@ -30,6 +30,14 @@ Boston, MA 02111-1307, USA. */
#include "i386/gas.h"
#include "dbxcoff.h"
/* Support the __declspec keyword by turning them into attributes.
We currently only support: dllimport and dllexport.
Note that the current way we do this may result in a collision with
predefined attributes later on. This can be solved by using one attribute,
say __declspec__, and passing args to it. The problem with that approach
is that args are not accumulated: each new appearance would clobber any
existing args. */
#ifdef CPP_PREDEFINES
#undef CPP_PREDEFINES
#endif
......@@ -38,6 +46,7 @@ Boston, MA 02111-1307, USA. */
-D__CYGWIN32__ -DWINNT -D_X86_=1 -D__STDC__=1\
-D__stdcall=__attribute__((__stdcall__)) \
-D__cdecl=__attribute__((__cdecl__)) \
-D__declspec(x)=__attribute__((x)) \
-Asystem(winnt) -Acpu(i386) -Amachine(i386)"
#undef CPP_SPEC
......@@ -69,13 +78,51 @@ Boston, MA 02111-1307, USA. */
#define WCHAR_TYPE "short unsigned int"
#define HAVE_ATEXIT 1
/* Ignore dllimport for functions. */
#define TARGET_NOP_FUN_DLLIMPORT (target_flags & 0x20000)
#undef SUBTARGET_SWITCHES
#define SUBTARGET_SWITCHES \
{ "nop-fun-dllimport", 0x20000 }, \
{ "no-nop-fun-dllimport", -0x20000 }, \
{ "windows", 0x0 },
/* A C expression whose value is nonzero if IDENTIFIER with arguments ARGS
is a valid machine specific attribute for DECL.
The attributes in ATTRIBUTES have previously been assigned to DECL. */
extern int i386_pe_valid_decl_attribute_p ();
#undef VALID_MACHINE_DECL_ATTRIBUTE
#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
i386_pe_valid_decl_attribute_p (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
extern union tree_node *i386_pe_merge_decl_attributes ();
#define MERGE_MACHINE_DECL_ATTRIBUTES(OLD, NEW) \
i386_pe_merge_decl_attributes ((OLD), (NEW))
/* Used to implement dllexport overriding dllimport semantics. It's also used
to handle vtables - the first pass won't do anything because
DECL_CONTEXT (DECL) will be 0 so i386_pe_dll{ex,im}port_p will return 0.
It's also used to handle dllimport override semantics. */
#if 0
#define REDO_SECTION_INFO_P(DECL) \
((DECL_MACHINE_ATTRIBUTES (DECL) != NULL_TREE) \
|| (TREE_CODE (DECL) == VAR_DECL && DECL_VIRTUAL_P (DECL)))
#else
#define REDO_SECTION_INFO_P(DECL) 1
#endif
#undef EXTRA_SECTIONS
#define EXTRA_SECTIONS in_ctor, in_dtor
#define EXTRA_SECTIONS in_ctor, in_dtor, in_drectve
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
CTOR_SECTION_FUNCTION \
DTOR_SECTION_FUNCTION
DTOR_SECTION_FUNCTION \
DRECTVE_SECTION_FUNCTION \
SWITCH_TO_SECTION_FUNCTION
#define CTOR_SECTION_FUNCTION \
void \
......@@ -99,6 +146,41 @@ dtor_section () \
} \
}
#define DRECTVE_SECTION_FUNCTION \
void \
drectve_section () \
{ \
if (in_section != in_drectve) \
{ \
fprintf (asm_out_file, "%s\n", "\t.section .drectve\n"); \
in_section = in_drectve; \
} \
}
/* Switch to SECTION (an `enum in_section').
??? This facility should be provided by GCC proper.
The problem is that we want to temporarily switch sections in
ASM_DECLARE_OBJECT_NAME and then switch back to the original section
afterwards. */
#define SWITCH_TO_SECTION_FUNCTION \
void \
switch_to_section (section, decl) \
enum in_section section; \
tree decl; \
{ \
switch (section) \
{ \
case in_text: text_section (); break; \
case in_data: data_section (); break; \
case in_named: named_section (decl, NULL, 0); break; \
case in_ctor: ctor_section (); break; \
case in_dtor: dtor_section (); break; \
case in_drectve: drectve_section (); break; \
default: abort (); break; \
} \
}
#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
do { \
ctor_section (); \
......@@ -119,44 +201,38 @@ dtor_section () \
differently depending on something about the variable or
function named by the symbol (such as what section it is in).
On i386, if using PIC, mark a SYMBOL_REF for a non-global symbol
so that we may access it directly in the GOT.
On i386 running Windows NT, modify the assembler name with a suffix
consisting of an atsign (@) followed by string of digits that represents
the number of bytes of arguments passed to the function, if it has the
attribute STDCALL. */
attribute STDCALL.
In addition, we must mark dll symbols specially. Definitions of
dllexport'd objects install some info in the .drectve section.
References to dllimport'd objects are fetched indirectly via
_imp__. If both are declared, dllexport overrides. This is also
needed to implement one-only vtables: they go into their own
section and we need to set DECL_SECTION_NAME so we do that here.
Note that we can be called twice on the same decl. */
extern void i386_pe_encode_section_info ();
#ifdef ENCODE_SECTION_INFO
#undef ENCODE_SECTION_INFO
#define ENCODE_SECTION_INFO(DECL) \
do \
{ \
if (flag_pic) \
{ \
rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \
? TREE_CST_RTL (DECL) : DECL_RTL (DECL)); \
SYMBOL_REF_FLAG (XEXP (rtl, 0)) \
= (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \
|| ! TREE_PUBLIC (DECL)); \
} \
if (TREE_CODE (DECL) == FUNCTION_DECL) \
if (lookup_attribute ("stdcall", \
TYPE_ATTRIBUTES (TREE_TYPE (DECL)))) \
XEXP (DECL_RTL (DECL), 0) = \
gen_rtx (SYMBOL_REF, Pmode, gen_stdcall_suffix (DECL)); \
} \
while (0)
#endif
#define ENCODE_SECTION_INFO(DECL) i386_pe_encode_section_info (DECL)
/* This macro gets just the user-specified name out of the string in a
SYMBOL_REF. Discard trailing @[NUM] encoded by ENCODE_SECTION_INFO. */
/* Utility used only in this file. */
#define I386_PE_STRIP_ENCODING(SYM_NAME) \
((SYM_NAME) + ((SYM_NAME)[0] == '@' ? 3 : 0))
/* This macro gets just the user-specified name
out of the string in a SYMBOL_REF. Discard
trailing @[NUM] encoded by ENCODE_SECTION_INFO. */
#undef STRIP_NAME_ENCODING
#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \
do { \
char *_p; \
char *_name = ((SYMBOL_NAME) + ((SYMBOL_NAME)[0] == '*')); \
char *_name = I386_PE_STRIP_ENCODING (SYMBOL_NAME); \
for (_p = _name; *_p && *_p != '@'; ++_p) \
; \
if (*_p == '@') \
......@@ -170,6 +246,62 @@ do { \
(VAR) = _name; \
} while (0)
/* Output a reference to a label. */
#undef ASM_OUTPUT_LABELREF
#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
fprintf (STREAM, "%s%s", USER_LABEL_PREFIX, \
I386_PE_STRIP_ENCODING (NAME)) \
/* Output a function definition label. */
#undef ASM_DECLARE_FUNCTION_NAME
#define ASM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \
do { \
if (i386_pe_dllexport_name_p (NAME)) \
{ \
drectve_section (); \
fprintf ((STREAM), "\t.ascii \" -export:%s\"\n", \
I386_PE_STRIP_ENCODING (NAME)); \
function_section (DECL); \
} \
ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
} while (0)
/* Output a common block. */
#undef ASM_OUTPUT_COMMON
#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
do { \
if (i386_pe_dllexport_name_p (NAME)) \
{ \
drectve_section (); \
fprintf ((STREAM), "\t.ascii \" -export:%s\"\n", \
I386_PE_STRIP_ENCODING (NAME)); \
} \
if (! i386_pe_dllimport_name_p (NAME)) \
{ \
fprintf ((STREAM), "\t.comm\t"); \
assemble_name ((STREAM), (NAME)); \
fprintf ((STREAM), ", %d\t%s %d\n", \
(ROUNDED), ASM_COMMENT_START, (SIZE)); \
} \
} while (0)
/* Output the label for an initialized variable. */
#undef ASM_DECLARE_OBJECT_NAME
#define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \
do { \
if (i386_pe_dllexport_name_p (NAME)) \
{ \
enum in_section save_section = in_section; \
drectve_section (); \
fprintf ((STREAM), "\t.ascii \" -export:%s\"\n", \
I386_PE_STRIP_ENCODING (NAME)); \
switch_to_section (save_section, (DECL)); \
} \
ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
} while (0)
/* Emit code to check the stack when allocating more that 4000
bytes in one go. */
......
......@@ -31,6 +31,7 @@ Boston, MA 02111-1307, USA. */
-D__MINGW32__ -DWINNT -D_X86_=1 -D__STDC__=1\
-D__stdcall=__attribute__((__stdcall__)) \
-D__cdecl=__attribute__((__cdecl__)) \
-D__declspec(x)=__attribute__((x)) \
-Asystem(winnt) -Acpu(i386) -Amachine(i386)"
/* Specific a different directory for the standard include files. */
......
......@@ -2265,9 +2265,12 @@ staticp (arg)
case FUNCTION_DECL:
/* Nested functions aren't static, since taking their address
involves a trampoline. */
return decl_function_context (arg) == 0 || DECL_NO_STATIC_CHAIN (arg);
return (decl_function_context (arg) == 0 || DECL_NO_STATIC_CHAIN (arg))
&& ! DECL_NON_ADDR_CONST_P (arg);
case VAR_DECL:
return TREE_STATIC (arg) || DECL_EXTERNAL (arg);
return (TREE_STATIC (arg) || DECL_EXTERNAL (arg))
&& ! DECL_NON_ADDR_CONST_P (arg);
case CONSTRUCTOR:
return TREE_STATIC (arg);
......
......@@ -1201,6 +1201,10 @@ struct tree_type
#define DECL_LANG_FLAG_6(NODE) (DECL_CHECK (NODE)->decl.lang_flag_6)
#define DECL_LANG_FLAG_7(NODE) (DECL_CHECK (NODE)->decl.lang_flag_7)
/* Used to indicate that the pointer to this DECL cannot be treated as
an address constant. */
#define DECL_NON_ADDR_CONST_P(NODE) (DECL_CHECK (NODE)->decl.non_addr_const_p)
struct tree_decl
{
char common[sizeof (struct tree_common)];
......@@ -1242,6 +1246,8 @@ struct tree_decl
unsigned lang_flag_6 : 1;
unsigned lang_flag_7 : 1;
unsigned non_addr_const_p : 1;
/* For a FUNCTION_DECL, if inline, this is the size of frame needed.
If built-in, this is the code for which built-in function.
For other kinds of decls, this is DECL_ALIGN. */
......
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