OSDN Git Service

Mon Dec 7 09:58:26 1998 Catherine Moore <clm@cygnus.com>
[pf3gnuchains/gcc-fork.git] / gcc / config / arm / elf.h
1 /* Definitions of target machine for GNU compiler,
2    for ARM with ELF obj format.
3    Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
4    Contributed by Philip Blundell <philb@gnu.org> and
5    Catherine Moore <clm@cygnus.com>
6    
7 This file is part of GNU CC.
8
9 GNU CC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13
14 GNU CC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GNU CC; see the file COPYING.  If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA.  */
23
24
25 #define OBJECT_FORMAT_ELF
26
27 #ifndef LOCAL_LABEL_PREFIX
28 #define LOCAL_LABEL_PREFIX "."
29 #endif
30
31 #ifndef USER_LABEL_PREFIX
32 #define USER_LABEL_PREFIX ""
33 #endif
34
35 #ifndef CPP_PREDEFINES
36 #define CPP_PREDEFINES "-Darm -Darm_elf -Acpu(arm) -Amachine(arm) -D__ELF__"
37 #endif
38
39 /* The following macro defines the format used to output the second
40    operand of the .type assembler directive.  Different svr4 assemblers
41    expect various different forms for this operand.  The one given here
42    is just a default.  You may need to override it in your machine-
43    specific tm.h file (depending upon the particulars of your assembler).  */
44 #define TYPE_OPERAND_FMT        "%s"
45
46 /* Write the extra assembler code needed to declare a function's result.
47    Most svr4 assemblers don't require any special declaration of the
48    result value, but there are exceptions.  */
49 #ifndef ASM_DECLARE_RESULT
50 #define ASM_DECLARE_RESULT(FILE, RESULT)
51 #endif
52
53 /* These macros generate the special .type and .size directives which
54    are used to set the corresponding fields of the linker symbol table
55    entries in an ELF object file under SVR4.  These macros also output
56    the starting labels for the relevant functions/objects.  */
57 #define TYPE_ASM_OP     ".type"
58 #define SIZE_ASM_OP     ".size"
59
60 /* Write the extra assembler code needed to declare a function properly.
61    Some svr4 assemblers need to also have something extra said about the
62    function's return value.  We allow for that here.  */
63 #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)                     \
64   do {                                                                  \
65     fprintf (FILE, "\t%s\t ", TYPE_ASM_OP);                             \
66     assemble_name (FILE, NAME);                                         \
67     putc (',', FILE);                                                   \
68     fprintf (FILE, TYPE_OPERAND_FMT, "function");                       \
69     putc ('\n', FILE);                                                  \
70     ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL));                      \
71     ASM_OUTPUT_LABEL(FILE, NAME);                                       \
72   } while (0)
73
74 /* Write the extra assembler code needed to declare an object properly.  */
75 #define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL)                       \
76   do {                                                                  \
77     fprintf (FILE, "\t%s\t ", TYPE_ASM_OP);                             \
78     assemble_name (FILE, NAME);                                         \
79     putc (',', FILE);                                                   \
80     fprintf (FILE, TYPE_OPERAND_FMT, "object");                         \
81     putc ('\n', FILE);                                                  \
82     size_directive_output = 0;                                          \
83     if (!flag_inhibit_size_directive && DECL_SIZE (DECL))               \
84       {                                                                 \
85         size_directive_output = 1;                                      \
86         fprintf (FILE, "\t%s\t ", SIZE_ASM_OP);                         \
87         assemble_name (FILE, NAME);                                     \
88         putc (',', FILE);                                               \
89         fprintf (FILE, HOST_WIDE_INT_PRINT_DEC,                         \
90                  int_size_in_bytes (TREE_TYPE (DECL)));                 \
91         fputc ('\n', FILE);                                             \
92       }                                                                 \
93     ASM_OUTPUT_LABEL(FILE, NAME);                                       \
94   } while (0)
95
96 /* Output the size directive for a decl in rest_of_decl_compilation
97    in the case where we did not do so before the initializer.
98    Once we find the error_mark_node, we know that the value of
99    size_directive_output was set
100    by ASM_DECLARE_OBJECT_NAME when it was run for the same decl.  */
101 #define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END)         \
102 do {                                                                     \
103      char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0);                   \
104      if (!flag_inhibit_size_directive && DECL_SIZE (DECL)                \
105          && ! AT_END && TOP_LEVEL                                        \
106          && DECL_INITIAL (DECL) == error_mark_node                       \
107          && !size_directive_output)                                      \
108        {                                                                 \
109          size_directive_output = 1;                                      \
110          fprintf (FILE, "\t%s\t ", SIZE_ASM_OP);                         \
111          assemble_name (FILE, name);                                     \
112          putc (',', FILE);                                               \
113          fprintf (FILE, HOST_WIDE_INT_PRINT_DEC,                         \
114                   int_size_in_bytes (TREE_TYPE (DECL)));                 \
115         fputc ('\n', FILE);                                              \
116        }                                                                 \
117    } while (0)
118
119 /* This is how to declare the size of a function.  */
120 #define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)                    \
121   do {                                                                  \
122     if (!flag_inhibit_size_directive)                                   \
123       {                                                                 \
124         char label[256];                                                \
125         static int labelno;                                             \
126         labelno ++;                                                     \
127         ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno);            \
128         ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno);               \
129         fprintf (FILE, "\t%s\t ", SIZE_ASM_OP);                         \
130         assemble_name (FILE, (FNAME));                                  \
131         fprintf (FILE, ",");                                            \
132         assemble_name (FILE, label);                                    \
133         fprintf (FILE, "-");                                            \
134         assemble_name (FILE, (FNAME));                                  \
135         putc ('\n', FILE);                                              \
136       }                                                                 \
137   } while (0)
138
139 /* Define this macro if jump tables (for `tablejump' insns) should be
140    output in the text section, along with the assembler instructions.
141    Otherwise, the readonly data section is used.  */
142 #define JUMP_TABLES_IN_TEXT_SECTION 1
143
144 #ifndef ASM_SPEC
145 #define ASM_SPEC "%{mbig-endian:-EB} %{mcpu=*:-m%*} %{march=*:-m%*} \
146  %{mapcs-*:-mapcs-%*} %{mthumb-interwork:-mthumb-interwork}"
147 #endif
148
149 #ifndef LINK_SPEC
150 #define LINK_SPEC "%{mbig-endian:-EB} -X"
151 #endif
152   
153 /* Run-time Target Specification.  */
154 #ifndef TARGET_VERSION
155 #define TARGET_VERSION fputs (" (ARM/elf)", stderr)
156 #endif
157
158 #ifndef TARGET_DEFAULT
159 #define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32)
160 #endif
161
162 #ifndef MULTILIB_DEFAULTS
163 #define MULTILIB_DEFAULTS { "mlittle-endian", "msoft-float", "mapcs-32", "mno-thumb-interwork" }
164 #endif
165
166 /* Setting this to 32 produces more efficient code, but the value set in previous
167    versions of this toolchain was 8, which produces more compact structures. The
168    command line option -mstructure_size_boundary=<n> can be used to change this
169    value.  */
170 #undef  STRUCTURE_SIZE_BOUNDARY
171 #define STRUCTURE_SIZE_BOUNDARY arm_structure_size_boundary
172
173 extern int arm_structure_size_boundary;
174
175 /* A C expression whose value is nonzero if IDENTIFIER with arguments ARGS
176    is a valid machine specific attribute for DECL.
177    The attributes in ATTRIBUTES have previously been assigned to DECL.  */
178 extern int arm_valid_machine_decl_attribute ();
179 #define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
180 arm_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
181 \f
182
183 /* A C statement to output assembler commands which will identify the
184    object file as having been compiled with GNU CC (or another GNU
185    compiler).  */
186 /* Define this to NULL so we don't get anything.
187    We have ASM_IDENTIFY_LANGUAGE.
188    Also, when using stabs, gcc2_compiled must be a stabs entry, not an
189    ordinary symbol, or gdb won't see it.  The stabs entry must be
190    before the N_SO in order for gdb to find it.  */
191 #ifndef ASM_IDENTIFY_GCC
192 #define ASM_IDENTIFY_GCC(STREAM)                                \
193      fprintf (STREAM, "%sgcc2_compiled.:\n", LOCAL_LABEL_PREFIX )
194 #endif
195
196 /* This outputs a lot of .req's to define alias for various registers.
197    Let's try to avoid this.  */
198 #ifndef ASM_FILE_START
199 #define ASM_FILE_START(STREAM) \
200 do {                                                            \
201   extern char *version_string;                                  \
202   fprintf (STREAM, "%s Generated by gcc %s for ARM/elf\n",      \
203            ASM_COMMENT_START, version_string);                  \
204 } while (0)
205 #endif
206      
207 /* Output an internal label definition.  */
208 #ifndef ASM_OUTPUT_INTERNAL_LABEL
209 #define ASM_OUTPUT_INTERNAL_LABEL(STREAM, PREFIX, NUM)          \
210   do                                                            \
211     {                                                           \
212       char *s = (char *) alloca (40 + strlen (PREFIX));         \
213       extern int arm_target_label, arm_ccfsm_state;             \
214       extern rtx arm_target_insn;                               \
215                                                                 \
216       if (arm_ccfsm_state == 3 && arm_target_label == (NUM)     \
217         && !strcmp (PREFIX, "L"))                               \
218         {                                                       \
219           arm_ccfsm_state = 0;                                  \
220           arm_target_insn = NULL;                               \
221         }                                                       \
222         ASM_GENERATE_INTERNAL_LABEL (s, (PREFIX), (NUM));       \
223         ASM_OUTPUT_LABEL (STREAM, s);                           \
224     } while (0)
225 #endif
226 \f
227 /* Support the ctors/dtors and other sections.  */
228
229 /* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
230
231    Note that we want to give these sections the SHF_WRITE attribute
232    because these sections will actually contain data (i.e. tables of
233    addresses of functions in the current root executable or shared library
234    file) and, in the case of a shared library, the relocatable addresses
235    will have to be properly resolved/relocated (and then written into) by
236    the dynamic linker when it actually attaches the given shared library
237    to the executing process.  (Note that on SVR4, you may wish to use the
238    `-z text' option to the ELF linker, when building a shared library, as
239    an additional check that you are doing everything right.  But if you do
240    use the `-z text' option when building a shared library, you will get
241    errors unless the .ctors and .dtors sections are marked as writable
242    via the SHF_WRITE attribute.)  */
243 #ifndef CTORS_SECTION_ASM_OP
244 #define CTORS_SECTION_ASM_OP    "\t.section\t.ctors,\"aw\""
245 #endif
246      
247 #ifndef DTORS_SECTION_ASM_OP
248 #define DTORS_SECTION_ASM_OP    "\t.section\t.dtors,\"aw\""
249 #endif
250
251 /* A list of other sections which the compiler might be "in" at any
252    given time.  */
253 #ifndef SUBTARGET_EXTRA_SECTIONS
254 #define SUBTARGET_EXTRA_SECTIONS
255 #endif
256
257 #ifndef EXTRA_SECTIONS
258 #define EXTRA_SECTIONS SUBTARGET_EXTRA_SECTIONS in_ctors, in_dtors
259 #endif
260
261 /* A list of extra section function definitions.  */
262 #ifndef SUBTARGET_EXTRA_SECTION_FUNCTIONS
263 #define SUBTARGET_EXTRA_SECTION_FUNCTIONS
264 #endif
265
266 #ifndef EXTRA_SECTION_FUNCTIONS
267 #define EXTRA_SECTION_FUNCTIONS                 \
268   SUBTARGET_EXTRA_SECTION_FUNCTIONS             \
269   CTORS_SECTION_FUNCTION                        \
270   DTORS_SECTION_FUNCTION                        
271 #endif
272
273 #ifndef CTORS_SECTION_FUNCTION
274 #define CTORS_SECTION_FUNCTION                                          \
275 void                                                                    \
276 ctors_section ()                                                        \
277 {                                                                       \
278   if (in_section != in_ctors)                                           \
279     {                                                                   \
280       fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP);             \
281       in_section = in_ctors;                                            \
282     }                                                                   \
283 }
284 #endif
285
286 #ifndef DTORS_SECTION_FUNCTION
287 #define DTORS_SECTION_FUNCTION                                          \
288 void                                                                    \
289 dtors_section ()                                                        \
290 {                                                                       \
291   if (in_section != in_dtors)                                           \
292     {                                                                   \
293       fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP);             \
294       in_section = in_dtors;                                            \
295     }                                                                   \
296 }
297 #endif
298 \f
299 /* Support the ctors/dtors sections for g++.  */
300 #ifndef INT_ASM_OP
301 #define INT_ASM_OP      ".word"
302 #endif
303
304 /* A C statement (sans semicolon) to output an element in the table of
305    global constructors.  */
306 #ifndef ASM_OUTPUT_CONSTRUCTOR
307 #define ASM_OUTPUT_CONSTRUCTOR(STREAM,NAME) \
308 do {                                            \
309   ctors_section ();                             \
310   fprintf (STREAM, "\t%s\t ", INT_ASM_OP);      \
311   assemble_name (STREAM, NAME);                 \
312   fprintf (STREAM, "\n");                       \
313 } while (0)
314 #endif
315      
316 /* A C statement (sans semicolon) to output an element in the table of
317    global destructors.  */
318 #ifndef ASM_OUTPUT_DESTRUCTOR
319 #define ASM_OUTPUT_DESTRUCTOR(STREAM,NAME) \
320 do {                                            \
321   dtors_section ();                             \
322   fprintf (STREAM, "\t%s\t ", INT_ASM_OP);      \
323   assemble_name (STREAM, NAME);                 \
324   fprintf (STREAM, "\n");                       \
325 } while (0)
326 #endif
327
328 /* This is how we tell the assembler that a symbol is weak.  */
329
330 #define ASM_WEAKEN_LABEL(FILE,NAME) \
331   do { fputs ("\t.weak\t", FILE); assemble_name (FILE, NAME); \
332        fputc ('\n', FILE); } while (0)
333
334 #include "arm/aout.h"
335
336
337