This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Declare function types correctly for cygwin32


The Microsoft Windows linker requires that the n_type field of each
symbol which represents a function be set to indicate that the symbol
is a function.  This includes undefined symbols used for external
called functions.  The Microsoft documentation indicates that type is
used to support incremental linking.

The appended patch modifies the cygwin32 toolchain to emit this
information.  This changes gcc to emit .type directives as needed for
cygwin32.  This is based on similar patches to the Irix 5 port to
declare all external function symbols.

Ian


Thu Jul  2 18:47:12 1998  Ian Lance Taylor  <ian@cygnus.com>

	* i386/cygwin32.h: Add some declaration of external functions.
 	(ASM_DECLARE_FUNCTION_NAME): Define.
	(ASM_OUTPUT_EXTERNAL, ASM_OUTPUT_EXTERNAL_LIBCALL): Define.
	(ASM_FILE_END): Define.
	* i386/winnt.c (i386_pe_declare_function_type): New function.
	(struct extern_list, extern_head): Define.
	(i386_pe_record_external_function): New function.
	(i386_pe_asm_file_end): New function.


Index: cygwin32.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/config/i386/cygwin32.h,v
retrieving revision 1.22
diff -p -r1.22 cygwin32.h
*** cygwin32.h	1998/05/08 20:36:53	1.22
--- cygwin32.h	1998/07/02 22:46:52
*************** do {								\
*** 224,229 ****
--- 224,259 ----
  	     ? "discard" : "same_size");			\
  } while (0)
  
+ /* Write the extra assembler code needed to declare a function
+    properly.  If we are generating SDB debugging information, this
+    will happen automatically, so we only need to handle other cases.  */
+ #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)			\
+   do									\
+     {									\
+       if (write_symbols != SDB_DEBUG)					\
+ 	i386_pe_declare_function_type (FILE, NAME, TREE_PUBLIC (DECL));	\
+       ASM_OUTPUT_LABEL (FILE, NAME);					\
+     }									\
+   while (0)
+ 
+ /* Add an external function to the list of functions to be declared at
+    the end of the file.  */
+ #define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME)				\
+   do									\
+     {									\
+       if (TREE_CODE (DECL) == FUNCTION_DECL)				\
+ 	i386_pe_record_external_function (NAME);			\
+     }									\
+   while (0)
+ 
+ /* Declare the type properly for any external libcall.  */
+ #define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
+   i386_pe_declare_function_type (FILE, XSTR (FUN, 0), 1)
+ 
+ /* Output function declarations at the end of the file.  */
+ #define ASM_FILE_END(FILE) \
+   i386_pe_asm_file_end (FILE)
+ 
  #undef ASM_COMMENT_START
  #define ASM_COMMENT_START " #"
  
*************** do {								\
*** 232,234 ****
--- 262,284 ----
  
  /* Don't assume anything about the header files. */
  #define NO_IMPLICIT_EXTERN_C
+ 
+ /* External function declarations.  */
+ 
+ #ifndef PROTO
+ #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
+ #define PROTO(ARGS) ARGS
+ #else
+ #define PROTO(ARGS) ()
+ #endif
+ #endif
+ 
+ #ifdef BUFSIZE		/* stdio.h has been included, ok to use FILE * */
+ #define STDIO_PROTO(ARGS) PROTO(ARGS)
+ #else
+ #define STDIO_PROTO(ARGS) ()
+ #endif
+ 
+ extern void i386_pe_record_external_function PROTO((char *));
+ extern void i386_pe_declare_function_type STDIO_PROTO((FILE *, char *, int));
+ extern void i386_pe_asm_file_end STDIO_PROTO((FILE *));
Index: winnt.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/config/i386/winnt.c,v
retrieving revision 1.11
diff -p -r1.11 winnt.c
*** winnt.c	1998/05/08 20:38:18	1.11
--- winnt.c	1998/07/02 22:46:52
*************** i386_pe_unique_section (decl, reloc)
*** 98,100 ****
--- 98,177 ----
  
    DECL_SECTION_NAME (decl) = build_string (len, string);
  }
+ 
+ /* The Microsoft linker requires that every function be marked as
+    DT_FCN.  When using gas on cygwin32, we must emit appropriate .type
+    directives.  */
+ 
+ #include "gsyms.h"
+ 
+ /* Mark a function appropriately.  This should only be called for
+    functions for which we are not emitting COFF debugging information.
+    FILE is the assembler output file, NAME is the name of the
+    function, and PUBLIC is non-zero if the function is globally
+    visible.  */
+ 
+ void
+ i386_pe_declare_function_type (file, name, public)
+      FILE *file;
+      char *name;
+      int public;
+ {
+   fprintf (file, "\t.def\t");
+   assemble_name (file, name);
+   fprintf (file, ";\t.scl\t%d;\t.type\t%d;\t.endef\n",
+ 	   public ? (int) C_EXT : (int) C_STAT,
+ 	   (int) DT_FCN << N_BTSHFT);
+ }
+ 
+ /* Keep a list of external functions.  */
+ 
+ struct extern_list
+ {
+   struct extern_list *next;
+   char *name;
+ };
+ 
+ static struct extern_list *extern_head;
+ 
+ /* Assemble an external function reference.  We need to keep a list of
+    these, so that we can output the function types at the end of the
+    assembly.  We can't output the types now, because we might see a
+    definition of the function later on and emit debugging information
+    for it then.  */
+ 
+ void
+ i386_pe_record_external_function (name)
+      char *name;
+ {
+   struct extern_list *p;
+ 
+   p = (struct extern_list *) permalloc (sizeof *p);
+   p->next = extern_head;
+   p->name = name;
+   extern_head = p;
+ }
+ 
+ /* This is called at the end of assembly.  For each external function
+    which has not been defined, we output a declaration now.  */
+ 
+ void
+ i386_pe_asm_file_end (file)
+      FILE *file;
+ {
+   struct extern_list *p;
+ 
+   for (p = extern_head; p != NULL; p = p->next)
+     {
+       tree decl;
+ 
+       decl = get_identifier (p->name);
+ 
+       /* Positively ensure only one declaration for any given symbol.  */
+       if (! TREE_ASM_WRITTEN (decl))
+ 	{
+ 	  TREE_ASM_WRITTEN (decl) = 1;
+ 	  i386_pe_declare_function_type (file, p->name, TREE_PUBLIC (decl));
+ 	}
+     }
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]