[PING] [PATCH,i386][4.3][RFC] PIC Generation on windows/cygwin

Murali Vemulapati murali.vemulapati@gmail.com
Fri Feb 9 17:59:00 GMT 2007


Here is the patch as an attached text file.

Thanks
Murali

===================================================================
2007-02-01  Murali Vemulapati  <murali.vemulapati@gmail.com>

       * config/i386/i386.h : define TARGET_CYGMING to 0.
       * config/i386/cygming.h : define TARGET_CYGMING to 1.
       Do not ignore -fpic.
       Declare i386_pe_generate_imported_symbol_ref().
       * config/i386/winnt.c : define function
       i386_pe_generate_imported_symbol_ref.
       * config/i386/i386.c : declare pic_base_label.
       (output_set_got): generate a base label and save it in pic_base_label.
       (legitimate_pic_address_disp_p) : UNSPEC_GOTOFF is generated for
       imported symbols too.
       (legitimize_pic_address) : generate UNSPEC_GOTOFF for dllimported
       and global symbols.
       (output_pic_addr_const) : On target cygming, interpret UNSPEC_GOTOFF
       as offset from base label.
       (imported_symbolic_operand): New function which returns true
       if operand is a symbol rtx and is dllimported.
       (ix86_output_addr_diff_elt) : output an element of address diff
       vector as a relative offset from base label.
       (ix86_expand_call) : On target cygming, convert the address of a
       non-static, direct function to a PIC reference by calling
       legitimize_pic_address.

===============================================================

On 2/8/07, Danny Smith <dannysmith@clear.net.nz> wrote:
> > From Murali Vemulapati
> > Sent: Friday, 9 February 2007 7:36 a.m.
> > Can somebody please review and/or approve this patch for i386/cygwin?
> >
> > Thanks
> > Murali
> >
> http://gcc.gnu.org/ml/gcc-patches/2007-02/msg00117.html
>
>
> The patch does not apply cleanly.  Most (all?) of the  empty lines have
> been converted to two empty lines.  Could you check that and perhaps
> resend as attachment rather than inline text.
>
> Thanks
> Danny
>
>
-------------- next part --------------
Index: gcc/config/i386/i386.h
===================================================================
*** gcc/config/i386/i386.h	(revision 121377)
--- gcc/config/i386/i386.h	(working copy)
*************** extern int x86_prefetch_sse, x86_cmpxchg
*** 294,299 ****
--- 294,302 ----
     redefines this to 1.  */
  #define TARGET_MACHO 0
  
+ /* Default value for TARGET_CYGMING. cygming.h redefines this to 1. */
+ #define TARGET_CYGMING 0
+ 
  /* Subtargets may reset this to 1 in order to enable 96-bit long double
     with the rounding mode forced to 53 bits.  */
  #define TARGET_96_ROUND_53_LONG_DOUBLE 0
Index: gcc/config/i386/cygming.h
===================================================================
*** gcc/config/i386/cygming.h	(revision 121377)
--- gcc/config/i386/cygming.h	(working copy)
*************** Boston, MA 02110-1301, USA.  */
*** 49,54 ****
--- 49,58 ----
  
  #define TARGET_EXECUTABLE_SUFFIX ".exe"
  
+ /* support for position independent code on cygming */
+ #undef TARGET_CYGMING
+ #define TARGET_CYGMING 1
+ 
  #include <stdio.h>
  
  #define MAYBE_UWIN_CPP_BUILTINS() /* Nothing.  */
*************** union tree_node;
*** 117,136 ****
     Explicitly set data flag with 'd'.  */  
  #define READONLY_DATA_SECTION_ASM_OP "\t.section .rdata,\"dr\""
  
- /* Don't allow flag_pic to propagate since gas may produce invalid code
-    otherwise.  */
- 
- #undef  SUBTARGET_OVERRIDE_OPTIONS
- #define SUBTARGET_OVERRIDE_OPTIONS					\
- do {									\
-   if (flag_pic)								\
-     {									\
-       warning (0, "-f%s ignored for target (all code is position independent)",\
- 	       (flag_pic > 1) ? "PIC" : "pic");				\
-       flag_pic = 0;							\
-     }									\
- } while (0)								\
- 
  /* Define this macro if references to a symbol must be treated
     differently depending on something about the variable or
     function named by the symbol (such as what section it is in).
--- 121,126 ----
*************** extern void i386_pe_record_exported_symb
*** 297,302 ****
--- 287,293 ----
  extern void i386_pe_file_end (void);
  extern int i386_pe_dllexport_name_p (const char *);
  extern int i386_pe_dllimport_name_p (const char *);
+ extern rtx i386_pe_generate_imported_symbol_ref (rtx addr);
  
  /* For Win32 ABI compatibility */
  #undef DEFAULT_PCC_STRUCT_RETURN
Index: gcc/config/i386/winnt.c
===================================================================
*** gcc/config/i386/winnt.c	(revision 121377)
--- gcc/config/i386/winnt.c	(working copy)
*************** i386_pe_file_end (void)
*** 733,736 ****
--- 733,761 ----
      }
  }
  
+ /* Given an RTX of type symbol_ref, generate and return an RTX
+    of type symbol_ref whose name is prefixed with DLL_IMPORT_PREFIX.
+ */
+ 
+ rtx i386_pe_generate_imported_symbol_ref (rtx addr)
+ {
+   const char *oldname;
+   char  *newname;
+   tree idp;
+   rtx symref;
+ 
+   gcc_assert (GET_CODE (addr) == SYMBOL_REF);
+   oldname = XSTR (addr, 0);
+   gcc_assert(! i386_pe_dllimport_name_p (oldname));
+   /* strip dllexport prefix, if any. */
+   oldname = i386_pe_strip_name_encoding(oldname);
+   newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
+   sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);
+ 
+   idp = get_identifier (newname);
+ 
+   symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
+   return symref;
+ }
+ 
  #include "gt-winnt.h"
Index: gcc/config/i386/i386.c
===================================================================
*** gcc/config/i386/i386.c	(revision 121377)
--- gcc/config/i386/i386.c	(working copy)
*************** static void ix86_dwarf_handle_frame_unsp
*** 1365,1370 ****
--- 1365,1372 ----
  static void i386_solaris_elf_named_section (const char *, unsigned int, tree)
    ATTRIBUTE_UNUSED;
  
+ static bool imported_symbolic_operand (rtx);
+ 
  /* Register class used for passing given 64bit part of the argument.
     These represent classes as documented by the PS ABI, with the exception
     of SSESF, SSEDF classes, that are basically SSE class, just gcc will
*************** static void x86_64_elf_unique_section (t
*** 1404,1409 ****
--- 1406,1422 ----
  static section *x86_64_elf_select_section (tree decl, int reloc,
  					   unsigned HOST_WIDE_INT align)
  					     ATTRIBUTE_UNUSED;
+ 
+ /* Support for position independent code on target cygming. 
+    In position independent mode, references to static and global
+    symbols are generated as offsets relative to a base label. The same
+    base label is used for computing relative offsets of labels
+    in the address diff vector for a switch statement. There is 
+    one base label in each function. */
+ 
+ /* The base label used for all relative offsets in pic mode. */
+ static GTY(()) rtx pic_base_label;
+ 
  

  /* Initialize the GCC target structure.  */
  #undef TARGET_ATTRIBUTE_TABLE
*************** output_set_got (rtx dest, rtx label ATTR
*** 5091,5100 ****
    rtx xops[3];
  
    xops[0] = dest;
    xops[1] = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);
  
!   if (! TARGET_DEEP_BRANCH_PREDICTION || !flag_pic)
      {
        xops[2] = gen_rtx_LABEL_REF (Pmode, label ? label : gen_label_rtx ());
  
        if (!flag_pic)
--- 5104,5118 ----
    rtx xops[3];
  
    xops[0] = dest;
+ #if (!TARGET_CYGMING)
    xops[1] = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);
+ #endif
  
!   if (TARGET_CYGMING || ! TARGET_DEEP_BRANCH_PREDICTION || !flag_pic)
      {
+       /* On target CYGMING, references to static and global symbols and
+ 	 entries in address diff vector for a switch statement are 
+ 	 generated as displacements from the following base label. */
        xops[2] = gen_rtx_LABEL_REF (Pmode, label ? label : gen_label_rtx ());
  
        if (!flag_pic)
*************** output_set_got (rtx dest, rtx label ATTR
*** 5138,5147 ****
--- 5156,5169 ----
    if (TARGET_MACHO)
      return "";
  
+ #if (!TARGET_CYGMING)
    if (!flag_pic || TARGET_DEEP_BRANCH_PREDICTION)
      output_asm_insn ("add{l}\t{%1, %0|%0, %1}", xops);
    else
      output_asm_insn ("add{l}\t{%1+[.-%a2], %0|%0, %1+(.-%a2)}", xops);
+ #else
+   pic_base_label = xops[2];
+ #endif
  
    return "";
  }
*************** legitimate_pic_address_disp_p (rtx disp)
*** 6463,6472 ****
        /* Refuse GOTOFF in 64bit mode since it is always 64bit when used.
  	 While ABI specify also 32bit relocation but we don't produce it in
  	 small PIC model at all.  */
        if ((GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF
  	   || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF)
  	  && !TARGET_64BIT)
!         return local_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
        return false;
      case UNSPEC_GOTTPOFF:
      case UNSPEC_GOTNTPOFF:
--- 6485,6499 ----
        /* Refuse GOTOFF in 64bit mode since it is always 64bit when used.
  	 While ABI specify also 32bit relocation but we don't produce it in
  	 small PIC model at all.  */
+       /* On target CYGMING, a reference to the slot in Import Address 
+ 	 Table corresponding to a dllimport'ed symbol is 
+ 	 generated as a displacement from the PIC base label (@GOTOFF)
+ 	 just like a local symbolic operand. */
        if ((GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF
  	   || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF)
  	  && !TARGET_64BIT)
!         return (local_symbolic_operand (XVECEXP (disp, 0, 0), Pmode)
! 		|| imported_symbolic_operand (XVECEXP (disp, 0, 0)));
        return false;
      case UNSPEC_GOTTPOFF:
      case UNSPEC_GOTNTPOFF:
*************** legitimize_pic_address (rtx orig, rtx re
*** 6819,6829 ****
  	}
        else new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmpreg);
      }
!   else if (!TARGET_64BIT && local_symbolic_operand (addr, Pmode))
      {
        /* This symbol may be referenced via a displacement from the PIC
  	 base address (@GOTOFF).  */
! 
        if (reload_in_progress)
  	regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
        if (GET_CODE (addr) == CONST)
--- 6846,6863 ----
  	}
        else new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmpreg);
      }
!   else if (!TARGET_64BIT && (local_symbolic_operand (addr, Pmode)
! 			     || imported_symbolic_operand (addr)))
      {
        /* This symbol may be referenced via a displacement from the PIC
  	 base address (@GOTOFF).  */
!       /* On target CYGMING, dllimport'ed symbols are referenced via a load
! 	 from the Import Address Table (IAT). For each dllimport'ed symbol
! 	 <sym>, there is a slot in IAT which is referenced by the symbol
! 	 __imp_<sym>. The symbol __imp_<sym> will be at a 
! 	 known (at link time) fixed displacement from the PIC base label.
! 	 Hence, the symbol __imp_<sym> may be referenced via a 
! 	 displacement from the PIC base label (@GOTOFF). */
        if (reload_in_progress)
  	regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
        if (GET_CODE (addr) == CONST)
*************** legitimize_pic_address (rtx orig, rtx re
*** 6865,6874 ****
  	{
  	  /* This symbol must be referenced via a load from the
  	     Global Offset Table (@GOT).  */
! 
  	  if (reload_in_progress)
  	    regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
  	  new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
  	  new = gen_rtx_CONST (Pmode, new);
  	  new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
  	  new = gen_const_mem (Pmode, new);
--- 6899,6926 ----
  	{
  	  /* This symbol must be referenced via a load from the
  	     Global Offset Table (@GOT).  */
! 	  /* On CYGMING, we do not know at compile time whether
! 	     a global symbol which is not explicitly imported
! 	     (through __declspec(dllimport) will be resolved
! 	     within the same DLL or will be imported from another
! 	     DLL. This will be known only at link time. We
! 	     assume that such a symbol <sym> is dllimport'ed and
! 	     reference it via a load from IAT. That means, a symbol
! 	     <sym> is referenced as *__imp_<sym> where __imp_<sym>
! 	     itself is accessed via a displacement from the PIC
! 	     base label (@GOTOFF). At link time, if it turns out
! 	     that the symbol is defined within the same DLL, 
! 	     the linker will provide a symbol definition for 
! 	     __imp_<sym> in the .data segment and load it with
! 	     the symbol address for <sym>. */
  	  if (reload_in_progress)
  	    regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
+ #if (TARGET_CYGMING)
+ 	  addr = i386_pe_generate_imported_symbol_ref(addr);
+ 	  new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
+ #else
  	  new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
+ #endif
  	  new = gen_rtx_CONST (Pmode, new);
  	  new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
  	  new = gen_const_mem (Pmode, new);
*************** legitimize_pic_address (rtx orig, rtx re
*** 6912,6918 ****
  
  	  /* Check first to see if this is a constant offset from a @GOTOFF
  	     symbol reference.  */
! 	  if (local_symbolic_operand (op0, Pmode)
  	      && CONST_INT_P (op1))
  	    {
  	      if (!TARGET_64BIT)
--- 6964,6973 ----
  
  	  /* Check first to see if this is a constant offset from a @GOTOFF
  	     symbol reference.  */
! 	  /* On target CYGMING, a reference to a IAT slot can be generated
! 	     as a fixed displacement from the PIC base label (@GOTOFF).*/
! 	  if ((local_symbolic_operand (op0, Pmode) ||
! 	      imported_symbolic_operand (op0))
  	      && CONST_INT_P (op1))
  	    {
  	      if (!TARGET_64BIT)
*************** output_pic_addr_const (FILE *file, rtx x
*** 7355,7361 ****
  
      case SYMBOL_REF:
        output_addr_const (file, x);
!       if (!TARGET_MACHO && code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
  	fputs ("@PLT", file);
        break;
  
--- 7410,7421 ----
  
      case SYMBOL_REF:
        output_addr_const (file, x);
!       /* On target CYGMING, there is no PLT.
! 	 In ix86_expand_call(), we call legitimize_pic_address() 
! 	 to convert the address of a direct, non-local function
! 	 to a PIC reference. */
!       if (!TARGET_MACHO && code == 'P' && 
! 	  ! (TARGET_CYGMING || SYMBOL_REF_LOCAL_P (x)))
  	fputs ("@PLT", file);
        break;
  
*************** output_pic_addr_const (FILE *file, rtx x
*** 7430,7436 ****
--- 7490,7503 ----
  	  fputs ("@GOT", file);
  	  break;
  	case UNSPEC_GOTOFF:
+ #if (!TARGET_CYGMING)
  	  fputs ("@GOTOFF", file);
+ #else
+ 	  /* On target CYGMING, we interpret GOTOFF of a symbol
+ 	     as the offset of the symbol from the PIC base label. */
+ 	  putc ('-', file);
+ 	  output_pic_addr_const (file, pic_base_label, code);
+ #endif
  	  break;
  	case UNSPEC_GOTPCREL:
  	  fputs ("@GOTPCREL(%rip)", file);
*************** output_pic_addr_const (FILE *file, rtx x
*** 7471,7476 ****
--- 7538,7560 ----
      }
  }
  
+ /* Return true if the operand is a imported symbolic operand
+    (using the dllimport storage-class attribute). */
+ 
+ static bool
+ imported_symbolic_operand (rtx op)
+ {
+   if (GET_CODE (op) == SYMBOL_REF)
+     {
+ #if (TARGET_CYGMING)
+       if (i386_pe_dllimport_name_p(XSTR (op, 0)))
+ 	return true;
+ #endif
+       return false;
+     }
+   return false;
+ }
+ 
  /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
     We need to emit DTP-relative relocations.  */
  
*************** ix86_output_addr_diff_elt (FILE *file, i
*** 9049,9054 ****
--- 9133,9146 ----
    if (TARGET_64BIT)
      fprintf (file, "%s%s%d-%s%d\n",
  	     ASM_LONG, LPREFIX, value, LPREFIX, rel);
+   /* On cygming, GOTOFF of a label is the offset of the label
+      from the PIC base label. */
+   else if (TARGET_CYGMING)
+     {
+       fprintf (file, "%s%s%d-%s%d\n",
+ 	       ASM_LONG, LPREFIX, value, LPREFIX,
+ 	       CODE_LABEL_NUMBER(XEXP(pic_base_label,0)));
+     }
    else if (HAVE_AS_GOTOFF_IN_DATA)
      fprintf (file, "%s%s%d@GOTOFF\n", ASM_LONG, LPREFIX, value);
  #if TARGET_MACHO
*************** ix86_expand_call (rtx retval, rtx fnaddr
*** 14391,14397 ****
        if (! TARGET_64BIT && flag_pic
  	  && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
  	  && ! SYMBOL_REF_LOCAL_P (XEXP (fnaddr, 0)))
! 	use_reg (&use, pic_offset_table_rtx);
      }
  
    if (TARGET_64BIT && INTVAL (callarg2) >= 0)
--- 14483,14500 ----
        if (! TARGET_64BIT && flag_pic
  	  && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
  	  && ! SYMBOL_REF_LOCAL_P (XEXP (fnaddr, 0)))
! 	{
! 	  use_reg (&use, pic_offset_table_rtx);
! #if (TARGET_CYGMING)
! 	  {
! 	    /* On target CYGMING, there is no PLT. Convert
! 	       the function address to a PIC reference. */
! 	    rtx reg;
! 	    reg = legitimize_pic_address (XEXP (fnaddr, 0), 0);
! 	    XEXP (fnaddr, 0) = reg;
! 	  }
! #endif
! 	}
      }
  
    if (TARGET_64BIT && INTVAL (callarg2) >= 0)


More information about the Gcc-patches mailing list