118334Speter/* Subroutines for insn-output.c for Windows NT. 218334Speter Contributed by Douglas Rupp (drupp@cs.washington.edu) 3169689Skan Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 4169689Skan 2005, 2006 Free Software Foundation, Inc. 518334Speter 6119256SkanThis file is part of GCC. 718334Speter 8119256SkanGCC is free software; you can redistribute it and/or modify it under 9119256Skanthe terms of the GNU General Public License as published by the Free 10119256SkanSoftware Foundation; either version 2, or (at your option) any later 11119256Skanversion. 1218334Speter 13119256SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY 14119256SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or 15119256SkanFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16119256Skanfor more details. 1718334Speter 1818334SpeterYou should have received a copy of the GNU General Public License 19119256Skanalong with GCC; see the file COPYING. If not, write to the Free 20169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 21169689Skan02110-1301, USA. */ 2218334Speter 2318334Speter#include "config.h" 2450397Sobrien#include "system.h" 25132718Skan#include "coretypes.h" 26132718Skan#include "tm.h" 2718334Speter#include "rtl.h" 2818334Speter#include "regs.h" 2918334Speter#include "hard-reg-set.h" 3018334Speter#include "output.h" 3118334Speter#include "tree.h" 3218334Speter#include "flags.h" 3390075Sobrien#include "tm_p.h" 3490075Sobrien#include "toplev.h" 3590075Sobrien#include "hashtab.h" 36117395Skan#include "ggc.h" 3718334Speter 3850397Sobrien/* i386/PE specific attribute support. 3950397Sobrien 4050397Sobrien i386/PE has two new attributes: 4150397Sobrien dllexport - for exporting a function/variable that will live in a dll 4250397Sobrien dllimport - for importing a function/variable from a dll 4350397Sobrien 4450397Sobrien Microsoft allows multiple declspecs in one __declspec, separating 4550397Sobrien them with spaces. We do NOT support this. Instead, use __declspec 4650397Sobrien multiple times. 4750397Sobrien*/ 4850397Sobrien 49132718Skanstatic tree associated_type (tree); 50169689Skanstatic tree gen_stdcall_or_fastcall_suffix (tree, bool); 51169689Skanstatic bool i386_pe_dllexport_p (tree); 52169689Skanstatic bool i386_pe_dllimport_p (tree); 53132718Skanstatic void i386_pe_mark_dllexport (tree); 54132718Skanstatic void i386_pe_mark_dllimport (tree); 5550397Sobrien 56132718Skan/* This is we how mark internal identifiers with dllimport or dllexport 57132718Skan attributes. */ 58132718Skan#ifndef DLL_IMPORT_PREFIX 59132718Skan#define DLL_IMPORT_PREFIX "#i." 60132718Skan#endif 61132718Skan#ifndef DLL_EXPORT_PREFIX 62132718Skan#define DLL_EXPORT_PREFIX "#e." 63132718Skan#endif 64132718Skan 65169689Skan/* Handle a "shared" attribute; 6690075Sobrien arguments as in struct attribute_spec.handler. */ 6790075Sobrientree 68169689Skanix86_handle_shared_attribute (tree *node, tree name, 69169689Skan tree args ATTRIBUTE_UNUSED, 70169689Skan int flags ATTRIBUTE_UNUSED, bool *no_add_attrs) 7150397Sobrien{ 72169689Skan if (TREE_CODE (*node) != VAR_DECL) 7350397Sobrien { 74169689Skan warning (OPT_Wattributes, "%qs attribute only applies to variables", 75169689Skan IDENTIFIER_POINTER (name)); 76119256Skan *no_add_attrs = true; 77119256Skan } 78119256Skan 7990075Sobrien return NULL_TREE; 8050397Sobrien} 8150397Sobrien 82169689Skan/* Handle a "selectany" attribute; 8390075Sobrien arguments as in struct attribute_spec.handler. */ 8450397Sobrientree 85169689Skanix86_handle_selectany_attribute (tree *node, tree name, 86169689Skan tree args ATTRIBUTE_UNUSED, 87169689Skan int flags ATTRIBUTE_UNUSED, 88169689Skan bool *no_add_attrs) 8950397Sobrien{ 90169689Skan /* The attribute applies only to objects that are initialized and have 91169689Skan external linkage. However, we may not know about initialization 92169689Skan until the language frontend has processed the decl. We'll check for 93169689Skan initialization later in encode_section_info. */ 94169689Skan if (TREE_CODE (*node) != VAR_DECL || !TREE_PUBLIC (*node)) 95169689Skan { 96169689Skan error ("%qs attribute applies only to initialized variables" 97169689Skan " with external linkage", IDENTIFIER_POINTER (name)); 9890075Sobrien *no_add_attrs = true; 9950397Sobrien } 10050397Sobrien 10190075Sobrien return NULL_TREE; 10250397Sobrien} 103169689Skan 10450397Sobrien 10550397Sobrien/* Return the type that we should use to determine if DECL is 10650397Sobrien imported or exported. */ 10750397Sobrien 10850397Sobrienstatic tree 109132718Skanassociated_type (tree decl) 11050397Sobrien{ 111169689Skan return (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl))) 112169689Skan ? DECL_CONTEXT (decl) : NULL_TREE; 113169689Skan} 11450397Sobrien 11550397Sobrien 116169689Skan/* Return true if DECL is a dllexport'd object. */ 11750397Sobrien 118169689Skanstatic bool 119132718Skani386_pe_dllexport_p (tree decl) 12050397Sobrien{ 12150397Sobrien if (TREE_CODE (decl) != VAR_DECL 122169689Skan && TREE_CODE (decl) != FUNCTION_DECL) 123169689Skan return false; 12450397Sobrien 125169689Skan if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))) 126169689Skan return true; 12750397Sobrien 128169689Skan /* Also mark class members of exported classes with dllexport. */ 129169689Skan if (associated_type (decl) 130169689Skan && lookup_attribute ("dllexport", 131169689Skan TYPE_ATTRIBUTES (associated_type (decl)))) 132169689Skan return i386_pe_type_dllexport_p (decl); 133169689Skan 134169689Skan return false; 13550397Sobrien} 13650397Sobrien 137169689Skanstatic bool 138132718Skani386_pe_dllimport_p (tree decl) 13950397Sobrien{ 14050397Sobrien if (TREE_CODE (decl) != VAR_DECL 141169689Skan && TREE_CODE (decl) != FUNCTION_DECL) 142169689Skan return false; 143119256Skan 144169689Skan /* Lookup the attribute in addition to checking the DECL_DLLIMPORT_P flag. 145169689Skan We may need to override an earlier decision. */ 146169689Skan if (DECL_DLLIMPORT_P (decl) 147169689Skan && lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl))) 14850397Sobrien { 149169689Skan /* Make a final check to see if this is a definition before we generate 150169689Skan RTL for an indirect reference. */ 151169689Skan if (!DECL_EXTERNAL (decl)) 152119256Skan { 153169689Skan error ("%q+D: definition is marked as dllimport", decl); 154169689Skan DECL_DLLIMPORT_P (decl) = 0; 155169689Skan return false; 156169689Skan } 157169689Skan return true; 158119256Skan } 159169689Skan /* The DECL_DLLIMPORT_P flag was set for decls in the class definition 160169689Skan by targetm.cxx.adjust_class_at_definition. Check again to emit 161169689Skan warnings if the class attribute has been overridden by an 162169689Skan out-of-class definition. */ 163169689Skan else if (associated_type (decl) 164169689Skan && lookup_attribute ("dllimport", 165169689Skan TYPE_ATTRIBUTES (associated_type (decl)))) 166169689Skan return i386_pe_type_dllimport_p (decl); 167119256Skan 168169689Skan return false; 16950397Sobrien} 17050397Sobrien 171169689Skan/* Handle the -mno-fun-dllimport target switch. */ 172169689Skanbool 173169689Skani386_pe_valid_dllimport_attribute_p (tree decl) 174169689Skan{ 175169689Skan if (TARGET_NOP_FUN_DLLIMPORT && TREE_CODE (decl) == FUNCTION_DECL) 176169689Skan return false; 177169689Skan return true; 178169689Skan} 179169689Skan 180117395Skan/* Return nonzero if SYMBOL is marked as being dllexport'd. */ 18150397Sobrien 18250397Sobrienint 183132718Skani386_pe_dllexport_name_p (const char *symbol) 18450397Sobrien{ 185132718Skan return (strncmp (DLL_EXPORT_PREFIX, symbol, 186132718Skan strlen (DLL_EXPORT_PREFIX)) == 0); 18750397Sobrien} 18850397Sobrien 189117395Skan/* Return nonzero if SYMBOL is marked as being dllimport'd. */ 19050397Sobrien 19150397Sobrienint 192132718Skani386_pe_dllimport_name_p (const char *symbol) 19350397Sobrien{ 194132718Skan return (strncmp (DLL_IMPORT_PREFIX, symbol, 195132718Skan strlen (DLL_IMPORT_PREFIX)) == 0); 19650397Sobrien} 19750397Sobrien 19850397Sobrien/* Mark a DECL as being dllexport'd. 199169689Skan Note that we override the previous setting (e.g.: dllimport). */ 20050397Sobrien 201132718Skanstatic void 202132718Skani386_pe_mark_dllexport (tree decl) 20350397Sobrien{ 20490075Sobrien const char *oldname; 20590075Sobrien char *newname; 20650397Sobrien rtx rtlname; 207169689Skan rtx symref; 20850397Sobrien tree idp; 20950397Sobrien 21050397Sobrien rtlname = XEXP (DECL_RTL (decl), 0); 211169689Skan if (GET_CODE (rtlname) == MEM) 212169689Skan rtlname = XEXP (rtlname, 0); 213169689Skan gcc_assert (GET_CODE (rtlname) == SYMBOL_REF); 214169689Skan oldname = XSTR (rtlname, 0); 21550397Sobrien if (i386_pe_dllimport_name_p (oldname)) 216119256Skan { 217169689Skan warning (0, "inconsistent dll linkage for %q+D, dllexport assumed", 218169689Skan decl); 219119256Skan /* Remove DLL_IMPORT_PREFIX. */ 220132718Skan oldname += strlen (DLL_IMPORT_PREFIX); 221119256Skan } 22250397Sobrien else if (i386_pe_dllexport_name_p (oldname)) 223132718Skan return; /* already done */ 22450397Sobrien 225132718Skan newname = alloca (strlen (DLL_EXPORT_PREFIX) + strlen (oldname) + 1); 226132718Skan sprintf (newname, "%s%s", DLL_EXPORT_PREFIX, oldname); 22750397Sobrien 22850397Sobrien /* We pass newname through get_identifier to ensure it has a unique 22950397Sobrien address. RTL processing can sometimes peek inside the symbol ref 23050397Sobrien and compare the string's addresses to see if two symbols are 23150397Sobrien identical. */ 23250397Sobrien idp = get_identifier (newname); 23350397Sobrien 234169689Skan symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp)); 235169689Skan SET_SYMBOL_REF_DECL (symref, decl); 236169689Skan XEXP (DECL_RTL (decl), 0) = symref; 23750397Sobrien} 23850397Sobrien 23950397Sobrien/* Mark a DECL as being dllimport'd. */ 24050397Sobrien 241132718Skanstatic void 242132718Skani386_pe_mark_dllimport (tree decl) 24350397Sobrien{ 24490075Sobrien const char *oldname; 24590075Sobrien char *newname; 24650397Sobrien tree idp; 24750397Sobrien rtx rtlname, newrtl; 248169689Skan rtx symref; 24950397Sobrien 25050397Sobrien rtlname = XEXP (DECL_RTL (decl), 0); 251169689Skan if (GET_CODE (rtlname) == MEM) 252169689Skan rtlname = XEXP (rtlname, 0); 253169689Skan gcc_assert (GET_CODE (rtlname) == SYMBOL_REF); 254169689Skan oldname = XSTR (rtlname, 0); 25550397Sobrien if (i386_pe_dllexport_name_p (oldname)) 25650397Sobrien { 257169689Skan error ("%qs declared as both exported to and imported from a DLL", 25850397Sobrien IDENTIFIER_POINTER (DECL_NAME (decl))); 25950397Sobrien return; 26050397Sobrien } 26150397Sobrien else if (i386_pe_dllimport_name_p (oldname)) 26250397Sobrien { 263169689Skan /* Already done, but do a sanity check to prevent assembler 264169689Skan errors. */ 265169689Skan gcc_assert (DECL_EXTERNAL (decl) && TREE_PUBLIC (decl) 266169689Skan && DECL_DLLIMPORT_P (decl)); 267132718Skan return; 26850397Sobrien } 26950397Sobrien 270132718Skan newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1); 271132718Skan sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname); 27250397Sobrien 27350397Sobrien /* We pass newname through get_identifier to ensure it has a unique 27450397Sobrien address. RTL processing can sometimes peek inside the symbol ref 27550397Sobrien and compare the string's addresses to see if two symbols are 27650397Sobrien identical. */ 27750397Sobrien idp = get_identifier (newname); 27850397Sobrien 279169689Skan symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp)); 280169689Skan SET_SYMBOL_REF_DECL (symref, decl); 281169689Skan newrtl = gen_rtx_MEM (Pmode,symref); 28250397Sobrien XEXP (DECL_RTL (decl), 0) = newrtl; 28350397Sobrien 284169689Skan DECL_DLLIMPORT_P (decl) = 1; 28550397Sobrien} 28650397Sobrien 287132718Skan/* Return string which is the former assembler name modified with a 288132718Skan suffix consisting of an atsign (@) followed by the number of bytes of 289169689Skan arguments. If FASTCALL is true, also add the FASTCALL_PREFIX. */ 29018334Speter 291169689Skanstatic tree 292169689Skangen_stdcall_or_fastcall_suffix (tree decl, bool fastcall) 29318334Speter{ 29418334Speter int total = 0; 29550397Sobrien /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead 29650397Sobrien of DECL_ASSEMBLER_NAME. */ 297169689Skan const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); 29818334Speter char *newsym; 299169689Skan char *p; 300169689Skan tree formal_type; 30118334Speter 302169689Skan /* Do not change the identifier if a verbatim asmspec or already done. */ 303169689Skan if (*asmname == '*' || strchr (asmname, '@')) 304169689Skan return DECL_ASSEMBLER_NAME (decl); 30518334Speter 306169689Skan formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl)); 307169689Skan if (formal_type != NULL_TREE) 308169689Skan { 309169689Skan /* These attributes are ignored for variadic functions in 310169689Skan i386.c:ix86_return_pops_args. For compatibility with MS 311169689Skan compiler do not add @0 suffix here. */ 312169689Skan if (TREE_VALUE (tree_last (formal_type)) != void_type_node) 313169689Skan return DECL_ASSEMBLER_NAME (decl); 314169689Skan 315169689Skan /* Quit if we hit an incomplete type. Error is reported 316169689Skan by convert_arguments in c-typeck.c or cp/typeck.c. */ 317169689Skan while (TREE_VALUE (formal_type) != void_type_node 318169689Skan && COMPLETE_TYPE_P (TREE_VALUE (formal_type))) 319169689Skan { 320169689Skan int parm_size 321169689Skan = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type))); 32250397Sobrien /* Must round up to include padding. This is done the same 32350397Sobrien way as in store_one_arg. */ 324169689Skan parm_size = ((parm_size + PARM_BOUNDARY - 1) 325169689Skan / PARM_BOUNDARY * PARM_BOUNDARY); 326169689Skan total += parm_size; 327169689Skan formal_type = TREE_CHAIN (formal_type);\ 328169689Skan } 329169689Skan } 33018334Speter 331132718Skan /* Assume max of 8 base 10 digits in the suffix. */ 332169689Skan newsym = alloca (1 + strlen (asmname) + 1 + 8 + 1); 333169689Skan p = newsym; 334169689Skan if (fastcall) 335169689Skan *p++ = FASTCALL_PREFIX; 336169689Skan sprintf (p, "%s@%d", asmname, total/BITS_PER_UNIT); 337169689Skan return get_identifier (newsym); 33818334Speter} 33918334Speter 34050397Sobrienvoid 341132718Skani386_pe_encode_section_info (tree decl, rtx rtl, int first) 34250397Sobrien{ 343132718Skan default_encode_section_info (decl, rtl, first); 344132718Skan 345169689Skan if (first && TREE_CODE (decl) == FUNCTION_DECL) 34650397Sobrien { 347169689Skan tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl)); 348169689Skan tree newid = NULL_TREE; 349169689Skan 350169689Skan if (lookup_attribute ("stdcall", type_attributes)) 351169689Skan newid = gen_stdcall_or_fastcall_suffix (decl, false); 352169689Skan else if (lookup_attribute ("fastcall", type_attributes)) 353169689Skan newid = gen_stdcall_or_fastcall_suffix (decl, true); 354169689Skan if (newid != NULL_TREE) 355169689Skan { 356169689Skan rtx rtlname = XEXP (rtl, 0); 357169689Skan if (GET_CODE (rtlname) == MEM) 358169689Skan rtlname = XEXP (rtlname, 0); 359169689Skan XSTR (rtlname, 0) = IDENTIFIER_POINTER (newid); 360169689Skan /* These attributes must be present on first declaration, 361169689Skan change_decl_assembler_name will warn if they are added 362169689Skan later and the decl has been referenced, but duplicate_decls 363169689Skan should catch the mismatch before this is called. */ 364169689Skan change_decl_assembler_name (decl, newid); 365169689Skan } 36650397Sobrien } 36750397Sobrien 368169689Skan else if (TREE_CODE (decl) == VAR_DECL 369169689Skan && lookup_attribute ("selectany", DECL_ATTRIBUTES (decl))) 370169689Skan { 371169689Skan if (DECL_INITIAL (decl) 372169689Skan /* If an object is initialized with a ctor, the static 373169689Skan initialization and destruction code for it is present in 374169689Skan each unit defining the object. The code that calls the 375169689Skan ctor is protected by a link-once guard variable, so that 376169689Skan the object still has link-once semantics, */ 377169689Skan || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) 378169689Skan make_decl_one_only (decl); 379169689Skan else 380169689Skan error ("%q+D:'selectany' attribute applies only to initialized objects", 381169689Skan decl); 382169689Skan } 383169689Skan 38450397Sobrien /* Mark the decl so we can tell from the rtl whether the object is 385169689Skan dllexport'd or dllimport'd. tree.c: merge_dllimport_decl_attributes 386169689Skan handles dllexport/dllimport override semantics. */ 38750397Sobrien 38850397Sobrien if (i386_pe_dllexport_p (decl)) 38950397Sobrien i386_pe_mark_dllexport (decl); 39050397Sobrien else if (i386_pe_dllimport_p (decl)) 39150397Sobrien i386_pe_mark_dllimport (decl); 392169689Skan /* It might be that DECL has been declared as dllimport, but a 393169689Skan subsequent definition nullified that. Assert that 394169689Skan tree.c: merge_dllimport_decl_attributes has removed the attribute 395169689Skan before the RTL name was marked with the DLL_IMPORT_PREFIX. */ 396169689Skan else 397169689Skan gcc_assert (!((TREE_CODE (decl) == FUNCTION_DECL 398169689Skan || TREE_CODE (decl) == VAR_DECL) 399169689Skan && rtl != NULL_RTX 400169689Skan && GET_CODE (rtl) == MEM 401169689Skan && GET_CODE (XEXP (rtl, 0)) == MEM 402169689Skan && GET_CODE (XEXP (XEXP (rtl, 0), 0)) == SYMBOL_REF 403169689Skan && i386_pe_dllimport_name_p (XSTR (XEXP (XEXP (rtl, 0), 0), 0)))); 40450397Sobrien} 40550397Sobrien 406132718Skan/* Strip only the leading encoding, leaving the stdcall suffix and fastcall 407132718Skan prefix if it exists. */ 40850397Sobrien 409117395Skanconst char * 410132718Skani386_pe_strip_name_encoding (const char *str) 411117395Skan{ 412132718Skan if (strncmp (str, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX)) 413132718Skan == 0) 414132718Skan str += strlen (DLL_IMPORT_PREFIX); 415132718Skan else if (strncmp (str, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX)) 416132718Skan == 0) 417132718Skan str += strlen (DLL_EXPORT_PREFIX); 418117395Skan if (*str == '*') 419117395Skan str += 1; 420117395Skan return str; 421117395Skan} 422117395Skan 423169689Skan/* Also strip the fastcall prefix and stdcall suffix. */ 424117395Skan 425117395Skanconst char * 426132718Skani386_pe_strip_name_encoding_full (const char *str) 427117395Skan{ 428117395Skan const char *p; 429117395Skan const char *name = i386_pe_strip_name_encoding (str); 430132718Skan 431169689Skan /* Strip leading '@' on fastcall symbols. */ 432169689Skan if (*name == '@') 433169689Skan name++; 434169689Skan 435169689Skan /* Strip trailing "@n". */ 436117395Skan p = strchr (name, '@'); 437117395Skan if (p) 438117395Skan return ggc_alloc_string (name, p - name); 439117395Skan 440117395Skan return name; 441117395Skan} 442117395Skan 443132718Skan/* Output a reference to a label. Fastcall symbols are prefixed with @, 444132718Skan whereas symbols for functions using other calling conventions don't 445132718Skan have a prefix (unless they are marked dllimport or dllexport). */ 446132718Skan 447132718Skanvoid i386_pe_output_labelref (FILE *stream, const char *name) 448132718Skan{ 449132718Skan if (strncmp (name, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX)) 450132718Skan == 0) 451132718Skan /* A dll import */ 452132718Skan { 453132718Skan if (name[strlen (DLL_IMPORT_PREFIX)] == FASTCALL_PREFIX) 454132718Skan /* A dllimport fastcall symbol. */ 455132718Skan { 456132718Skan fprintf (stream, "__imp_%s", 457132718Skan i386_pe_strip_name_encoding (name)); 458132718Skan } 459132718Skan else 460132718Skan /* A dllimport non-fastcall symbol. */ 461132718Skan { 462132718Skan fprintf (stream, "__imp__%s", 463132718Skan i386_pe_strip_name_encoding (name)); 464132718Skan } 465132718Skan } 466132718Skan else if ((name[0] == FASTCALL_PREFIX) 467169689Skan || (strncmp (name, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX)) 468132718Skan == 0 469169689Skan && name[strlen (DLL_EXPORT_PREFIX)] == FASTCALL_PREFIX)) 470132718Skan /* A fastcall symbol. */ 471132718Skan { 472132718Skan fprintf (stream, "%s", 473132718Skan i386_pe_strip_name_encoding (name)); 474132718Skan } 475132718Skan else 476132718Skan /* Everything else. */ 477132718Skan { 478132718Skan fprintf (stream, "%s%s", USER_LABEL_PREFIX, 479132718Skan i386_pe_strip_name_encoding (name)); 480132718Skan } 481132718Skan} 482132718Skan 48350397Sobrienvoid 484132718Skani386_pe_unique_section (tree decl, int reloc) 48550397Sobrien{ 48650397Sobrien int len; 48790075Sobrien const char *name, *prefix; 48890075Sobrien char *string; 48950397Sobrien 49050397Sobrien name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); 491117395Skan name = i386_pe_strip_name_encoding_full (name); 49250397Sobrien 49350397Sobrien /* The object is put in, for example, section .text$foo. 49450397Sobrien The linker will then ultimately place them in .text 49550397Sobrien (everything from the $ on is stripped). Don't put 496132718Skan read-only data in .rdata section to avoid a PE linker 49750397Sobrien bug when .rdata$* grouped sections are used in code 49850397Sobrien without a .rdata section. */ 49950397Sobrien if (TREE_CODE (decl) == FUNCTION_DECL) 50050397Sobrien prefix = ".text$"; 501117395Skan else if (decl_readonly_section (decl, reloc)) 50250397Sobrien prefix = ".rdata$"; 50350397Sobrien else 50450397Sobrien prefix = ".data$"; 50550397Sobrien len = strlen (name) + strlen (prefix); 50650397Sobrien string = alloca (len + 1); 50750397Sobrien sprintf (string, "%s%s", prefix, name); 50850397Sobrien 50950397Sobrien DECL_SECTION_NAME (decl) = build_string (len, string); 51050397Sobrien} 51190075Sobrien 51290075Sobrien/* Select a set of attributes for section NAME based on the properties 51390075Sobrien of DECL and whether or not RELOC indicates that DECL's initializer 51490075Sobrien might contain runtime relocations. 51590075Sobrien 51690075Sobrien We make the section read-only and executable for a function decl, 51790075Sobrien read-only for a const data decl, and writable for a non-const data decl. 51890075Sobrien 51990075Sobrien If the section has already been defined, to not allow it to have 52090075Sobrien different attributes, as (1) this is ambiguous since we're not seeing 52190075Sobrien all the declarations up front and (2) some assemblers (e.g. SVR4) 522132718Skan do not recognize section redefinitions. */ 52390075Sobrien/* ??? This differs from the "standard" PE implementation in that we 52490075Sobrien handle the SHARED variable attribute. Should this be done for all 52590075Sobrien PE targets? */ 52690075Sobrien 52790075Sobrien#define SECTION_PE_SHARED SECTION_MACH_DEP 52890075Sobrien 52990075Sobrienunsigned int 530132718Skani386_pe_section_type_flags (tree decl, const char *name, int reloc) 53190075Sobrien{ 53290075Sobrien static htab_t htab; 53390075Sobrien unsigned int flags; 53490075Sobrien unsigned int **slot; 53590075Sobrien 53690075Sobrien /* The names we put in the hashtable will always be the unique 537169689Skan versions given to us by the stringtable, so we can just use 53890075Sobrien their addresses as the keys. */ 53990075Sobrien if (!htab) 54090075Sobrien htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL); 54190075Sobrien 54290075Sobrien if (decl && TREE_CODE (decl) == FUNCTION_DECL) 54390075Sobrien flags = SECTION_CODE; 544117395Skan else if (decl && decl_readonly_section (decl, reloc)) 54590075Sobrien flags = 0; 54690075Sobrien else 54790075Sobrien { 54890075Sobrien flags = SECTION_WRITE; 54990075Sobrien 55090075Sobrien if (decl && TREE_CODE (decl) == VAR_DECL 55190075Sobrien && lookup_attribute ("shared", DECL_ATTRIBUTES (decl))) 55290075Sobrien flags |= SECTION_PE_SHARED; 55390075Sobrien } 55490075Sobrien 55590075Sobrien if (decl && DECL_ONE_ONLY (decl)) 55690075Sobrien flags |= SECTION_LINKONCE; 55790075Sobrien 55890075Sobrien /* See if we already have an entry for this section. */ 55990075Sobrien slot = (unsigned int **) htab_find_slot (htab, name, INSERT); 56090075Sobrien if (!*slot) 56190075Sobrien { 56290075Sobrien *slot = (unsigned int *) xmalloc (sizeof (unsigned int)); 56390075Sobrien **slot = flags; 56490075Sobrien } 56590075Sobrien else 56690075Sobrien { 56790075Sobrien if (decl && **slot != flags) 568169689Skan error ("%q+D causes a section type conflict", decl); 56990075Sobrien } 57090075Sobrien 57190075Sobrien return flags; 57290075Sobrien} 57390075Sobrien 57490075Sobrienvoid 575169689Skani386_pe_asm_named_section (const char *name, unsigned int flags, 576169689Skan tree decl) 57790075Sobrien{ 57890075Sobrien char flagchars[8], *f = flagchars; 57990075Sobrien 580132718Skan if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0) 581132718Skan /* readonly data */ 582132718Skan { 583132718Skan *f++ ='d'; /* This is necessary for older versions of gas. */ 584132718Skan *f++ ='r'; 585132718Skan } 586132718Skan else 587132718Skan { 588132718Skan if (flags & SECTION_CODE) 589132718Skan *f++ = 'x'; 590132718Skan if (flags & SECTION_WRITE) 591132718Skan *f++ = 'w'; 592132718Skan if (flags & SECTION_PE_SHARED) 593132718Skan *f++ = 's'; 594132718Skan } 595132718Skan 59690075Sobrien *f = '\0'; 59790075Sobrien 59890075Sobrien fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars); 59990075Sobrien 60090075Sobrien if (flags & SECTION_LINKONCE) 60190075Sobrien { 60290075Sobrien /* Functions may have been compiled at various levels of 603169689Skan optimization so we can't use `same_size' here. 604169689Skan Instead, have the linker pick one, without warning. 605169689Skan If 'selectany' attribute has been specified, MS compiler 606169689Skan sets 'discard' characteristic, rather than telling linker 607169689Skan to warn of size or content mismatch, so do the same. */ 608169689Skan bool discard = (flags & SECTION_CODE) 609169689Skan || lookup_attribute ("selectany", 610169689Skan DECL_ATTRIBUTES (decl)); 61190075Sobrien fprintf (asm_out_file, "\t.linkonce %s\n", 612169689Skan (discard ? "discard" : "same_size")); 61390075Sobrien } 61490075Sobrien} 61550397Sobrien 61650397Sobrien/* The Microsoft linker requires that every function be marked as 61752284Sobrien DT_FCN. When using gas on cygwin, we must emit appropriate .type 61850397Sobrien directives. */ 61950397Sobrien 62050397Sobrien#include "gsyms.h" 62150397Sobrien 62250397Sobrien/* Mark a function appropriately. This should only be called for 62350397Sobrien functions for which we are not emitting COFF debugging information. 62450397Sobrien FILE is the assembler output file, NAME is the name of the 625117395Skan function, and PUBLIC is nonzero if the function is globally 62650397Sobrien visible. */ 62750397Sobrien 62850397Sobrienvoid 629132718Skani386_pe_declare_function_type (FILE *file, const char *name, int public) 63050397Sobrien{ 63150397Sobrien fprintf (file, "\t.def\t"); 63250397Sobrien assemble_name (file, name); 63350397Sobrien fprintf (file, ";\t.scl\t%d;\t.type\t%d;\t.endef\n", 63450397Sobrien public ? (int) C_EXT : (int) C_STAT, 63550397Sobrien (int) DT_FCN << N_BTSHFT); 63650397Sobrien} 63750397Sobrien 63850397Sobrien/* Keep a list of external functions. */ 63950397Sobrien 640169689Skanstruct extern_list GTY(()) 64150397Sobrien{ 64250397Sobrien struct extern_list *next; 643169689Skan tree decl; 64490075Sobrien const char *name; 64550397Sobrien}; 64650397Sobrien 647169689Skanstatic GTY(()) struct extern_list *extern_head; 64850397Sobrien 64950397Sobrien/* Assemble an external function reference. We need to keep a list of 65050397Sobrien these, so that we can output the function types at the end of the 65150397Sobrien assembly. We can't output the types now, because we might see a 65250397Sobrien definition of the function later on and emit debugging information 65350397Sobrien for it then. */ 65450397Sobrien 65550397Sobrienvoid 656169689Skani386_pe_record_external_function (tree decl, const char *name) 65750397Sobrien{ 65850397Sobrien struct extern_list *p; 65950397Sobrien 660169689Skan p = (struct extern_list *) ggc_alloc (sizeof *p); 66150397Sobrien p->next = extern_head; 662169689Skan p->decl = decl; 66350397Sobrien p->name = name; 66450397Sobrien extern_head = p; 66550397Sobrien} 66650397Sobrien 66790075Sobrien/* Keep a list of exported symbols. */ 66852284Sobrien 669169689Skanstruct export_list GTY(()) 67090075Sobrien{ 67190075Sobrien struct export_list *next; 67290075Sobrien const char *name; 67390075Sobrien int is_data; /* used to type tag exported symbols. */ 67490075Sobrien}; 67590075Sobrien 676169689Skanstatic GTY(()) struct export_list *export_head; 67790075Sobrien 67852284Sobrien/* Assemble an export symbol entry. We need to keep a list of 67952284Sobrien these, so that we can output the export list at the end of the 68052284Sobrien assembly. We used to output these export symbols in each function, 681132718Skan but that causes problems with GNU ld when the sections are 68252284Sobrien linkonce. */ 68352284Sobrien 68452284Sobrienvoid 685132718Skani386_pe_record_exported_symbol (const char *name, int is_data) 68652284Sobrien{ 68790075Sobrien struct export_list *p; 68852284Sobrien 689169689Skan p = (struct export_list *) ggc_alloc (sizeof *p); 69090075Sobrien p->next = export_head; 69152284Sobrien p->name = name; 69290075Sobrien p->is_data = is_data; 69390075Sobrien export_head = p; 69452284Sobrien} 69552284Sobrien 69650397Sobrien/* This is called at the end of assembly. For each external function 69752284Sobrien which has not been defined, we output a declaration now. We also 69852284Sobrien output the .drectve section. */ 69950397Sobrien 70050397Sobrienvoid 701132718Skani386_pe_file_end (void) 70250397Sobrien{ 70350397Sobrien struct extern_list *p; 70450397Sobrien 705132718Skan ix86_file_end (); 70690075Sobrien 70750397Sobrien for (p = extern_head; p != NULL; p = p->next) 70850397Sobrien { 70950397Sobrien tree decl; 71050397Sobrien 711169689Skan decl = p->decl; 71250397Sobrien 71350397Sobrien /* Positively ensure only one declaration for any given symbol. */ 714169689Skan if (! TREE_ASM_WRITTEN (decl) 715169689Skan && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) 71650397Sobrien { 71750397Sobrien TREE_ASM_WRITTEN (decl) = 1; 718132718Skan i386_pe_declare_function_type (asm_out_file, p->name, 719132718Skan TREE_PUBLIC (decl)); 72050397Sobrien } 72150397Sobrien } 72252284Sobrien 72390075Sobrien if (export_head) 72452284Sobrien { 72590075Sobrien struct export_list *q; 72690075Sobrien drectve_section (); 72790075Sobrien for (q = export_head; q != NULL; q = q->next) 72890075Sobrien { 729132718Skan fprintf (asm_out_file, "\t.ascii \" -export:%s%s\"\n", 730117395Skan i386_pe_strip_name_encoding (q->name), 73190075Sobrien (q->is_data) ? ",data" : ""); 73290075Sobrien } 73352284Sobrien } 73450397Sobrien} 735169689Skan 736169689Skan#include "gt-winnt.h" 737