예제 #1
0
static void
i386_pe_mark_dllimport (tree decl)
{
  const char *oldname;
  char  *newname;
  tree idp;
  rtx rtlname, newrtl;
  rtx symref;

  rtlname = XEXP (DECL_RTL (decl), 0);
  if (GET_CODE (rtlname) == SYMBOL_REF)
    oldname = XSTR (rtlname, 0);
  else if (GET_CODE (rtlname) == MEM
	   && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
    oldname = XSTR (XEXP (rtlname, 0), 0);
  else
    abort ();
  if (i386_pe_dllexport_name_p (oldname))
    {
      error ("%qs declared as both exported to and imported from a DLL",
             IDENTIFIER_POINTER (DECL_NAME (decl)));
      return;
    }
  else if (i386_pe_dllimport_name_p (oldname))
    {
      /* Already done, but do a sanity check to prevent assembler errors.  */
 /* APPLE LOCAL begin mainline 2005-10-12 */
      if (!DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl)
          || !DECL_DLLIMPORT_P (decl))
        {
          error ("%Jfailure in redeclaration of '%D': dllimport'd "
                 "symbol lacks external linkage.", decl, decl);
          abort();
        }
 /* APPLE LOCAL end mainline 2005-10-12 */
      return;
    }

  newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
  sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);

  /* We pass newname through get_identifier to ensure it has a unique
     address.  RTL processing can sometimes peek inside the symbol ref
     and compare the string's addresses to see if two symbols are
     identical.  */
  idp = get_identifier (newname);

  symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
  SYMBOL_REF_DECL (symref) = decl;
  newrtl = gen_rtx_MEM (Pmode,symref);
  XEXP (DECL_RTL (decl), 0) = newrtl;

 /* APPLE LOCAL begin mainline 2005-10-12 */
  DECL_DLLIMPORT_P (decl) = 1;
 /* APPLE LOCAL end mainline 2005-10-12 */
}
예제 #2
0
static void
i386_pe_mark_dllimport (tree decl)
{
    const char *oldname;
    char  *newname;
    tree idp;
    rtx rtlname, newrtl;
    rtx symref;

    rtlname = XEXP (DECL_RTL (decl), 0);
    if (GET_CODE (rtlname) == MEM)
        rtlname = XEXP (rtlname, 0);
    gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
    oldname = XSTR (rtlname, 0);
    if (i386_pe_dllexport_name_p (oldname))
    {
        error ("%qs declared as both exported to and imported from a DLL",
               IDENTIFIER_POINTER (DECL_NAME (decl)));
        return;
    }
    else if (i386_pe_dllimport_name_p (oldname))
    {
        /* Already done, but do a sanity check to prevent assembler
        errors.  */
        gcc_assert (DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)
                    && DECL_DLLIMPORT_P (decl));
        return;
    }

    newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
    sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);

    /* We pass newname through get_identifier to ensure it has a unique
       address.  RTL processing can sometimes peek inside the symbol ref
       and compare the string's addresses to see if two symbols are
       identical.  */
    idp = get_identifier (newname);

    symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
    SET_SYMBOL_REF_DECL (symref, decl);
    newrtl = gen_rtx_MEM (Pmode,symref);
    XEXP (DECL_RTL (decl), 0) = newrtl;

    DECL_DLLIMPORT_P (decl) = 1;
}
예제 #3
0
static void
i386_pe_mark_dllexport (tree decl)
{
  const char *oldname;
  char  *newname;
  rtx rtlname;
  rtx symref;
  tree idp;

  rtlname = XEXP (DECL_RTL (decl), 0);
  if (GET_CODE (rtlname) == SYMBOL_REF)
    oldname = XSTR (rtlname, 0);
  else if (GET_CODE (rtlname) == MEM
	   && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
    oldname = XSTR (XEXP (rtlname, 0), 0);
  else
    abort ();
  if (i386_pe_dllimport_name_p (oldname))
    {
      warning ("%Jinconsistent dll linkage for '%D', dllexport assumed.",
	       decl, decl);
     /* Remove DLL_IMPORT_PREFIX.  */
      oldname += strlen (DLL_IMPORT_PREFIX);
      DECL_NON_ADDR_CONST_P (decl) = 0;
    }
  else if (i386_pe_dllexport_name_p (oldname))
    return;  /*  already done  */

  newname = alloca (strlen (DLL_EXPORT_PREFIX) + strlen (oldname) + 1);
  sprintf (newname, "%s%s", DLL_EXPORT_PREFIX, oldname);

  /* We pass newname through get_identifier to ensure it has a unique
     address.  RTL processing can sometimes peek inside the symbol ref
     and compare the string's addresses to see if two symbols are
     identical.  */
  idp = get_identifier (newname);

  symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
  SYMBOL_REF_DECL (symref) = decl;
  XEXP (DECL_RTL (decl), 0) = symref;
}
예제 #4
0
void
i386_pe_encode_section_info (tree decl, rtx rtl, int first)
{
    default_encode_section_info (decl, rtl, first);

    if (first && TREE_CODE (decl) == FUNCTION_DECL)
    {
        tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
        tree newid = NULL_TREE;

        if (lookup_attribute ("stdcall", type_attributes))
            newid = gen_stdcall_or_fastcall_suffix (decl, false);
        else if (lookup_attribute ("fastcall", type_attributes))
            newid = gen_stdcall_or_fastcall_suffix (decl, true);
        if (newid != NULL_TREE)
        {
            rtx rtlname = XEXP (rtl, 0);
            if (GET_CODE (rtlname) == MEM)
                rtlname = XEXP (rtlname, 0);
            XSTR (rtlname, 0) = IDENTIFIER_POINTER (newid);
            /* These attributes must be present on first declaration,
               change_decl_assembler_name will warn if they are added
               later and the decl has been referenced, but duplicate_decls
               should catch the mismatch before this is called.  */
            change_decl_assembler_name (decl, newid);
        }
    }

    else if (TREE_CODE (decl) == VAR_DECL
             && lookup_attribute ("selectany", DECL_ATTRIBUTES (decl)))
    {
        if (DECL_INITIAL (decl)
                /* If an object is initialized with a ctor, the static
                   initialization and destruction code for it is present in
                   each unit defining the object.  The code that calls the
                   ctor is protected by a link-once guard variable, so that
                   the object still has link-once semantics,  */
                || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
            make_decl_one_only (decl);
        else
            error ("%q+D:'selectany' attribute applies only to initialized objects",
                   decl);
    }

    /* Mark the decl so we can tell from the rtl whether the object is
       dllexport'd or dllimport'd.  tree.c: merge_dllimport_decl_attributes
       handles dllexport/dllimport override semantics.  */

    if (i386_pe_dllexport_p (decl))
        i386_pe_mark_dllexport (decl);
    else if (i386_pe_dllimport_p (decl))
        i386_pe_mark_dllimport (decl);
    /* It might be that DECL has been declared as dllimport, but a
       subsequent definition nullified that.  Assert that
       tree.c: merge_dllimport_decl_attributes has removed the attribute
       before the RTL name was marked with the DLL_IMPORT_PREFIX.  */
    else
        gcc_assert (!((TREE_CODE (decl) == FUNCTION_DECL
                       || TREE_CODE (decl) == VAR_DECL)
                      && rtl != NULL_RTX
                      && GET_CODE (rtl) == MEM
                      && GET_CODE (XEXP (rtl, 0)) == MEM
                      && GET_CODE (XEXP (XEXP (rtl, 0), 0)) == SYMBOL_REF
                      && i386_pe_dllimport_name_p (XSTR (XEXP (XEXP (rtl, 0), 0), 0))));
}
예제 #5
0
void
i386_pe_encode_section_info (tree decl, rtx rtl, int first)
{
  default_encode_section_info (decl, rtl, first);

  if (first && TREE_CODE (decl) == FUNCTION_DECL)
    {
      tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
      tree newid = NULL_TREE;

      if (lookup_attribute ("stdcall", type_attributes))
	newid = gen_stdcall_or_fastcall_suffix (decl, false);
      else if (lookup_attribute ("fastcall", type_attributes))
	newid = gen_stdcall_or_fastcall_suffix (decl, true);
      if (newid != NULL_TREE) 	
	{
	  rtx rtlname = XEXP (rtl, 0);
	  if (GET_CODE (rtlname) == MEM)
	    rtlname = XEXP (rtlname, 0);
	  XSTR (rtlname, 0) = IDENTIFIER_POINTER (newid);
	  /* These attributes must be present on first declaration,
	     change_decl_assembler_name will warn if they are added
	     later and the decl has been referenced, but duplicate_decls
	     should catch the mismatch before this is called.  */ 
	  change_decl_assembler_name (decl, newid);
	}
    }

  /* Mark the decl so we can tell from the rtl whether the object is
     dllexport'd or dllimport'd.  This also handles dllexport/dllimport
     override semantics.  */

  if (i386_pe_dllexport_p (decl))
    i386_pe_mark_dllexport (decl);
  else if (i386_pe_dllimport_p (decl))
    i386_pe_mark_dllimport (decl);
  /* It might be that DECL has already been marked as dllimport, but a
     subsequent definition nullified that.  The attribute is gone but
     DECL_RTL still has (DLL_IMPORT_PREFIX) prefixed. We need to remove
     that. Ditto for the DECL_NON_ADDR_CONST_P flag.  */
  else if ((TREE_CODE (decl) == FUNCTION_DECL
	    || TREE_CODE (decl) == VAR_DECL)
	   && DECL_RTL (decl) != NULL_RTX
	   && GET_CODE (DECL_RTL (decl)) == MEM
	   && GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
	   && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == SYMBOL_REF
	   && i386_pe_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
    {
      const char *oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0);

      /* Remove DLL_IMPORT_PREFIX.  */
      tree idp = get_identifier (oldname + strlen (DLL_IMPORT_PREFIX));
      rtx symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
      SYMBOL_REF_DECL (symref) = decl;
      XEXP (DECL_RTL (decl), 0) = symref;
      DECL_NON_ADDR_CONST_P (decl) = 0;

      /* We previously set TREE_PUBLIC and DECL_EXTERNAL.
	 We leave these alone for now.  */

      if (DECL_INITIAL (decl) || !DECL_EXTERNAL (decl))
	warning ("%J'%D' defined locally after being "
		 "referenced with dllimport linkage", decl, decl);
      else
	warning ("%J'%D' redeclared without dllimport attribute "
		 "after being referenced with dllimport linkage", decl, decl);
    }
}