00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "rtl.h"
00025 #include "output.h"
00026 #include "flags.h"
00027 #include "tree.h"
00028 #include "expr.h"
00029 #include "toplev.h"
00030 #include "tm_p.h"
00031
00032 extern int current_function_anonymous_args;
00033
00034
00035
00036
00037 tree current_class_type;
00038
00039 int
00040 arm_dllexport_p (decl)
00041 tree decl;
00042 {
00043 tree exp;
00044
00045 if (TREE_CODE (decl) != VAR_DECL
00046 && TREE_CODE (decl) != FUNCTION_DECL)
00047 return 0;
00048 exp = lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl));
00049 if (exp)
00050 return 1;
00051
00052 return 0;
00053 }
00054
00055
00056
00057 int
00058 arm_dllimport_p (decl)
00059 tree decl;
00060 {
00061 tree imp;
00062
00063 if (TREE_CODE (decl) == FUNCTION_DECL
00064 && TARGET_NOP_FUN_DLLIMPORT)
00065 return 0;
00066
00067 if (TREE_CODE (decl) != VAR_DECL
00068 && TREE_CODE (decl) != FUNCTION_DECL)
00069 return 0;
00070 imp = lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl));
00071 if (imp)
00072 return 1;
00073
00074 return 0;
00075 }
00076
00077
00078
00079 int
00080 arm_dllexport_name_p (symbol)
00081 const char * symbol;
00082 {
00083 return symbol[0] == ARM_PE_FLAG_CHAR && symbol[1] == 'e' && symbol[2] == '.';
00084 }
00085
00086
00087
00088 int
00089 arm_dllimport_name_p (symbol)
00090 const char * symbol;
00091 {
00092 return symbol[0] == ARM_PE_FLAG_CHAR && symbol[1] == 'i' && symbol[2] == '.';
00093 }
00094
00095
00096
00097
00098 void
00099 arm_mark_dllexport (decl)
00100 tree decl;
00101 {
00102 const char * oldname;
00103 char * newname;
00104 rtx rtlname;
00105 tree idp;
00106
00107 rtlname = XEXP (DECL_RTL (decl), 0);
00108 if (GET_CODE (rtlname) == SYMBOL_REF)
00109 oldname = XSTR (rtlname, 0);
00110 else if (GET_CODE (rtlname) == MEM
00111 && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
00112 oldname = XSTR (XEXP (rtlname, 0), 0);
00113 else
00114 abort ();
00115 if (arm_dllimport_name_p (oldname))
00116 oldname += 9;
00117 else if (arm_dllexport_name_p (oldname))
00118 return;
00119
00120 newname = alloca (strlen (oldname) + 4);
00121 sprintf (newname, "%ce.%s", ARM_PE_FLAG_CHAR, oldname);
00122
00123
00124
00125
00126
00127
00128 idp = get_identifier (newname);
00129
00130 XEXP (DECL_RTL (decl), 0) =
00131 gen_rtx (SYMBOL_REF, Pmode, IDENTIFIER_POINTER (idp));
00132 }
00133
00134
00135
00136 void
00137 arm_mark_dllimport (decl)
00138 tree decl;
00139 {
00140 const char * oldname;
00141 char * newname;
00142 tree idp;
00143 rtx rtlname, newrtl;
00144
00145 rtlname = XEXP (DECL_RTL (decl), 0);
00146
00147 if (GET_CODE (rtlname) == SYMBOL_REF)
00148 oldname = XSTR (rtlname, 0);
00149 else if (GET_CODE (rtlname) == MEM
00150 && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
00151 oldname = XSTR (XEXP (rtlname, 0), 0);
00152 else
00153 abort ();
00154
00155 if (arm_dllexport_name_p (oldname))
00156 abort ();
00157 else if (arm_dllimport_name_p (oldname))
00158 return;
00159
00160
00161
00162
00163
00164 if (TREE_CODE (decl) == VAR_DECL
00165 && !DECL_VIRTUAL_P (decl)
00166 && DECL_INITIAL (decl))
00167 {
00168 error_with_decl (decl, "initialized variable `%s' is marked dllimport");
00169 return;
00170 }
00171
00172 if (TREE_CODE (decl) == VAR_DECL
00173
00174 && !DECL_VIRTUAL_P (decl)
00175 && 0 )
00176 {
00177 error_with_decl (decl, "static variable `%s' is marked dllimport");
00178 return;
00179 }
00180
00181
00182
00183 if (TREE_CODE (decl) == VAR_DECL
00184
00185 && !DECL_VIRTUAL_P (decl))
00186 {
00187 DECL_EXTERNAL (decl) = 1;
00188 TREE_PUBLIC (decl) = 1;
00189 }
00190
00191 newname = alloca (strlen (oldname) + 11);
00192 sprintf (newname, "%ci.__imp_%s", ARM_PE_FLAG_CHAR, oldname);
00193
00194
00195
00196
00197
00198
00199 idp = get_identifier (newname);
00200
00201 newrtl = gen_rtx (MEM, Pmode,
00202 gen_rtx (SYMBOL_REF, Pmode,
00203 IDENTIFIER_POINTER (idp)));
00204 XEXP (DECL_RTL (decl), 0) = newrtl;
00205 }
00206
00207
00208
00209 void
00210 arm_pe_encode_section_info (decl)
00211 tree decl;
00212 {
00213
00214 if (optimize > 0 && TREE_CONSTANT (decl)
00215 && (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))
00216 {
00217 rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
00218 ? TREE_CST_RTL (decl) : DECL_RTL (decl));
00219 SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
00220 }
00221
00222
00223
00224 if (arm_dllexport_p (decl))
00225 arm_mark_dllexport (decl);
00226 else if (arm_dllimport_p (decl))
00227 arm_mark_dllimport (decl);
00228
00229
00230
00231 else if ((TREE_CODE (decl) == FUNCTION_DECL
00232 || TREE_CODE (decl) == VAR_DECL)
00233 && DECL_RTL (decl) != NULL_RTX
00234 && GET_CODE (DECL_RTL (decl)) == MEM
00235 && GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
00236 && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == SYMBOL_REF
00237 && arm_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
00238 {
00239 const char *oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0);
00240 tree idp = get_identifier (oldname + 9);
00241 rtx newrtl = gen_rtx (SYMBOL_REF, Pmode, IDENTIFIER_POINTER (idp));
00242
00243 XEXP (DECL_RTL (decl), 0) = newrtl;
00244
00245
00246
00247 }
00248 }
00249
00250
00251
00252 void
00253 arm_pe_unique_section (decl, reloc)
00254 tree decl;
00255 int reloc;
00256 {
00257 int len;
00258 const char * name;
00259 char * string;
00260 const char * prefix;
00261
00262 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
00263
00264 STRIP_NAME_ENCODING (name, name);
00265
00266
00267
00268
00269 if (TREE_CODE (decl) == FUNCTION_DECL)
00270 prefix = ".text$";
00271 else if (DECL_READONLY_SECTION (decl, reloc))
00272 prefix = ".rdata$";
00273 else
00274 prefix = ".data$";
00275 len = strlen (name) + strlen (prefix);
00276 string = alloca (len + 1);
00277 sprintf (string, "%s%s", prefix, name);
00278
00279 DECL_SECTION_NAME (decl) = build_string (len, string);
00280 }