]> gcc.gnu.org Git - gcc.git/blame - gcc/config/arm/pe.c
arm.c, [...]: Replace "gen_rtx (FOO, " with "gen_rtx_FOO (".
[gcc.git] / gcc / config / arm / pe.c
CommitLineData
cb805c2d 1/* Routines for GCC for ARM/pe.
ae46c4e0 2 Copyright (C) 1995, 1996, 2000, 2001, 2002 Free Software Foundation, Inc.
cb805c2d
NC
3 Contributed by Doug Evans (dje@cygnus.com).
4
4f448245 5 This file is part of GCC.
cb805c2d 6
4f448245
NC
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 2, or (at your
10 option) any later version.
cb805c2d 11
4f448245
NC
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
cb805c2d 16
4f448245
NC
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
cb805c2d 21
cb805c2d 22#include "config.h"
c27ba912 23#include "system.h"
4977bab6
ZW
24#include "coretypes.h"
25#include "tm.h"
cb805c2d
NC
26#include "rtl.h"
27#include "output.h"
28#include "flags.h"
29#include "tree.h"
30#include "expr.h"
b020fd92 31#include "toplev.h"
d5b7b3ae 32#include "tm_p.h"
cb805c2d
NC
33
34extern int current_function_anonymous_args;
35
cb805c2d 36\f
825dda42 37/* Return nonzero if DECL is a dllexport'd object. */
cb805c2d
NC
38
39tree current_class_type; /* FIXME */
40
41int
42arm_dllexport_p (decl)
43 tree decl;
44{
45 tree exp;
46
47 if (TREE_CODE (decl) != VAR_DECL
48 && TREE_CODE (decl) != FUNCTION_DECL)
49 return 0;
91d231cb 50 exp = lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl));
cb805c2d
NC
51 if (exp)
52 return 1;
53
cb805c2d
NC
54 return 0;
55}
56
825dda42 57/* Return nonzero if DECL is a dllimport'd object. */
cb805c2d
NC
58
59int
60arm_dllimport_p (decl)
61 tree decl;
62{
63 tree imp;
64
65 if (TREE_CODE (decl) == FUNCTION_DECL
66 && TARGET_NOP_FUN_DLLIMPORT)
67 return 0;
68
69 if (TREE_CODE (decl) != VAR_DECL
70 && TREE_CODE (decl) != FUNCTION_DECL)
71 return 0;
91d231cb 72 imp = lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl));
cb805c2d
NC
73 if (imp)
74 return 1;
75
cb805c2d
NC
76 return 0;
77}
78
825dda42 79/* Return nonzero if SYMBOL is marked as being dllexport'd. */
cb805c2d
NC
80
81int
82arm_dllexport_name_p (symbol)
3cce094d 83 const char * symbol;
cb805c2d 84{
c27ba912 85 return symbol[0] == ARM_PE_FLAG_CHAR && symbol[1] == 'e' && symbol[2] == '.';
cb805c2d
NC
86}
87
825dda42 88/* Return nonzero if SYMBOL is marked as being dllimport'd. */
cb805c2d
NC
89
90int
91arm_dllimport_name_p (symbol)
3cce094d 92 const char * symbol;
cb805c2d 93{
c27ba912 94 return symbol[0] == ARM_PE_FLAG_CHAR && symbol[1] == 'i' && symbol[2] == '.';
cb805c2d
NC
95}
96
97/* Mark a DECL as being dllexport'd.
98 Note that we override the previous setting (eg: dllimport). */
99
100void
101arm_mark_dllexport (decl)
102 tree decl;
103{
3cce094d 104 const char * oldname;
cb805c2d
NC
105 char * newname;
106 rtx rtlname;
107 tree idp;
108
109 rtlname = XEXP (DECL_RTL (decl), 0);
110 if (GET_CODE (rtlname) == SYMBOL_REF)
111 oldname = XSTR (rtlname, 0);
112 else if (GET_CODE (rtlname) == MEM
113 && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
114 oldname = XSTR (XEXP (rtlname, 0), 0);
115 else
116 abort ();
117 if (arm_dllimport_name_p (oldname))
118 oldname += 9;
119 else if (arm_dllexport_name_p (oldname))
120 return; /* already done */
121
122 newname = alloca (strlen (oldname) + 4);
c27ba912 123 sprintf (newname, "%ce.%s", ARM_PE_FLAG_CHAR, oldname);
cb805c2d
NC
124
125 /* We pass newname through get_identifier to ensure it has a unique
126 address. RTL processing can sometimes peek inside the symbol ref
127 and compare the string's addresses to see if two symbols are
128 identical. */
129 /* ??? At least I think that's why we do this. */
130 idp = get_identifier (newname);
131
132 XEXP (DECL_RTL (decl), 0) =
f1c25d3b 133 gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
cb805c2d
NC
134}
135
136/* Mark a DECL as being dllimport'd. */
137
138void
139arm_mark_dllimport (decl)
140 tree decl;
141{
3cce094d 142 const char * oldname;
cb805c2d
NC
143 char * newname;
144 tree idp;
145 rtx rtlname, newrtl;
146
147 rtlname = XEXP (DECL_RTL (decl), 0);
148
149 if (GET_CODE (rtlname) == SYMBOL_REF)
150 oldname = XSTR (rtlname, 0);
151 else if (GET_CODE (rtlname) == MEM
152 && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
153 oldname = XSTR (XEXP (rtlname, 0), 0);
154 else
155 abort ();
156
157 if (arm_dllexport_name_p (oldname))
158 abort (); /* this shouldn't happen */
159 else if (arm_dllimport_name_p (oldname))
160 return; /* already done */
161
162 /* ??? One can well ask why we're making these checks here,
163 and that would be a good question. */
164
165 /* Imported variables can't be initialized. */
166 if (TREE_CODE (decl) == VAR_DECL
167 && !DECL_VIRTUAL_P (decl)
168 && DECL_INITIAL (decl))
169 {
ddd2d57e 170 error ("%Jinitialized variable '%D' is marked dllimport", decl, decl);
cb805c2d
NC
171 return;
172 }
173 /* Nor can they be static. */
174 if (TREE_CODE (decl) == VAR_DECL
175 /* ??? Is this test for vtables needed? */
176 && !DECL_VIRTUAL_P (decl)
177 && 0 /*???*/)
178 {
ddd2d57e 179 error ("%Jstatic variable '%D' is marked dllimport", decl, decl);
cb805c2d
NC
180 return;
181 }
182
183 /* `extern' needn't be specified with dllimport.
184 Specify `extern' now and hope for the best. Sigh. */
185 if (TREE_CODE (decl) == VAR_DECL
186 /* ??? Is this test for vtables needed? */
187 && !DECL_VIRTUAL_P (decl))
188 {
189 DECL_EXTERNAL (decl) = 1;
190 TREE_PUBLIC (decl) = 1;
191 }
192
193 newname = alloca (strlen (oldname) + 11);
c27ba912 194 sprintf (newname, "%ci.__imp_%s", ARM_PE_FLAG_CHAR, oldname);
cb805c2d
NC
195
196 /* We pass newname through get_identifier to ensure it has a unique
197 address. RTL processing can sometimes peek inside the symbol ref
198 and compare the string's addresses to see if two symbols are
199 identical. */
200 /* ??? At least I think that's why we do this. */
201 idp = get_identifier (newname);
202
f1c25d3b
KH
203 newrtl = gen_rtx_MEM (Pmode,
204 gen_rtx_SYMBOL_REF (Pmode,
205 IDENTIFIER_POINTER (idp)));
cb805c2d
NC
206 XEXP (DECL_RTL (decl), 0) = newrtl;
207}
208
cb805c2d 209void
c6a2438a 210arm_pe_encode_section_info (decl, rtl, first)
cb805c2d 211 tree decl;
c6a2438a 212 rtx rtl;
b2003250 213 int first ATTRIBUTE_UNUSED;
cb805c2d 214{
fb49053f 215 /* This bit is copied from arm_encode_section_info. */
cb805c2d
NC
216 if (optimize > 0 && TREE_CONSTANT (decl)
217 && (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))
c6a2438a 218 SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
cb805c2d
NC
219
220 /* Mark the decl so we can tell from the rtl whether the object is
221 dllexport'd or dllimport'd. */
222 if (arm_dllexport_p (decl))
223 arm_mark_dllexport (decl);
224 else if (arm_dllimport_p (decl))
225 arm_mark_dllimport (decl);
226 /* It might be that DECL has already been marked as dllimport, but a
227 subsequent definition nullified that. The attribute is gone but
228 DECL_RTL still has @i.__imp_foo. We need to remove that. */
229 else if ((TREE_CODE (decl) == FUNCTION_DECL
230 || TREE_CODE (decl) == VAR_DECL)
231 && DECL_RTL (decl) != NULL_RTX
232 && GET_CODE (DECL_RTL (decl)) == MEM
233 && GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
234 && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == SYMBOL_REF
235 && arm_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
236 {
3cce094d 237 const char *oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0);
cb805c2d 238 tree idp = get_identifier (oldname + 9);
f1c25d3b 239 rtx newrtl = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
cb805c2d
NC
240
241 XEXP (DECL_RTL (decl), 0) = newrtl;
242
243 /* We previously set TREE_PUBLIC and DECL_EXTERNAL.
244 ??? We leave these alone for now. */
245 }
246}
247
cb805c2d
NC
248void
249arm_pe_unique_section (decl, reloc)
250 tree decl;
251 int reloc;
252{
253 int len;
ec940faa 254 const char * name;
cb805c2d 255 char * string;
adf97f58 256 const char * prefix;
cb805c2d
NC
257
258 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
772c5265 259 name = arm_strip_name_encoding (name);
cb805c2d
NC
260
261 /* The object is put in, for example, section .text$foo.
262 The linker will then ultimately place them in .text
263 (everything from the $ on is stripped). */
264 if (TREE_CODE (decl) == FUNCTION_DECL)
265 prefix = ".text$";
4e4d733e 266 else if (decl_readonly_section (decl, reloc))
cb805c2d
NC
267 prefix = ".rdata$";
268 else
269 prefix = ".data$";
270 len = strlen (name) + strlen (prefix);
271 string = alloca (len + 1);
272 sprintf (string, "%s%s", prefix, name);
273
274 DECL_SECTION_NAME (decl) = build_string (len, string);
275}
This page took 1.016442 seconds and 5 git commands to generate.