OSDN Git Service

* doc/tm.texi (SDB and DWARF): Add extra parameter to
[pf3gnuchains/gcc-fork.git] / gcc / config / darwin.c
1 /* Functions for generic Darwin as target machine for GNU C compiler.
2    Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002, 2003, 2004,
3    2005
4    Free Software Foundation, Inc.
5    Contributed by Apple Computer Inc.
6
7 This file is part of GCC.
8
9 GCC 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 GCC 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 GCC; see the file COPYING.  If not, write to
21 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA.  */
23
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "rtl.h"
29 #include "regs.h"
30 #include "hard-reg-set.h"
31 #include "real.h"
32 #include "insn-config.h"
33 #include "conditions.h"
34 #include "insn-flags.h"
35 #include "output.h"
36 #include "insn-attr.h"
37 #include "flags.h"
38 #include "tree.h"
39 #include "expr.h"
40 #include "reload.h"
41 #include "function.h"
42 #include "ggc.h"
43 #include "langhooks.h"
44 #include "target.h"
45 #include "tm_p.h"
46 #include "toplev.h"
47 #include "hashtab.h"
48
49 /* Darwin supports a feature called fix-and-continue, which is used
50    for rapid turn around debugging.  When code is compiled with the
51    -mfix-and-continue flag, two changes are made to the generated code
52    that allow the system to do things that it would normally not be
53    able to do easily.  These changes allow gdb to load in
54    recompilation of a translation unit that has been changed into a
55    running program and replace existing functions and methods of that
56    translation unit with versions of those functions and methods
57    from the newly compiled translation unit.  The new functions access
58    the existing static symbols from the old translation unit, if the
59    symbol existed in the unit to be replaced, and from the new
60    translation unit, otherwise.
61
62    The changes are to insert 5 nops at the beginning of all functions
63    and to use indirection to get at static symbols.  The 5 nops
64    are required by consumers of the generated code.  Currently, gdb
65    uses this to patch in a jump to the overriding function, this
66    allows all uses of the old name to forward to the replacement,
67    including existing function pointers and virtual methods.  See
68    rs6000_emit_prologue for the code that handles the nop insertions.
69
70    The added indirection allows gdb to redirect accesses to static
71    symbols from the newly loaded translation unit to the existing
72    symbol, if any.  @code{static} symbols are special and are handled by
73    setting the second word in the .non_lazy_symbol_pointer data
74    structure to symbol.  See indirect_data for the code that handles
75    the extra indirection, and machopic_output_indirection and its use
76    of MACHO_SYMBOL_STATIC for the code that handles @code{static}
77    symbol indirection.  */
78
79 /* Section names.  */
80 section * darwin_sections[NUM_DARWIN_SECTIONS];
81
82 /* A get_unnamed_section callback used to switch to an ObjC section.
83    DIRECTIVE is as for output_section_asm_op.  */
84
85 static void
86 output_objc_section_asm_op (const void *directive)
87 {
88   static bool been_here = false;
89
90   if (! been_here)
91     {
92       static const enum darwin_section_enum tomark[] =
93         {
94           /* written, cold -> hot */
95           objc_cat_cls_meth_section,
96           objc_cat_inst_meth_section,
97           objc_string_object_section,
98           objc_constant_string_object_section,
99           objc_selector_refs_section,
100           objc_selector_fixup_section,
101           objc_cls_refs_section,
102           objc_class_section,
103           objc_meta_class_section,
104           /* shared, hot -> cold */
105           objc_cls_meth_section,
106           objc_inst_meth_section,
107           objc_protocol_section,
108           objc_class_names_section,
109           objc_meth_var_types_section,
110           objc_meth_var_names_section,
111           objc_category_section,
112           objc_class_vars_section,
113           objc_instance_vars_section,
114           objc_module_info_section,
115           objc_symbols_section
116         };
117       size_t i;
118
119       been_here = true;
120       for (i = 0; i < ARRAY_SIZE (tomark); i++)
121         switch_to_section (darwin_sections[tomark[i]]);
122     }
123   output_section_asm_op (directive);
124 }
125
126 /* Implement TARGET_ASM_INIT_SECTIONS.  */
127
128 void
129 darwin_init_sections (void)
130 {
131 #define DEF_SECTION(NAME, FLAGS, DIRECTIVE, OBJC)               \
132   darwin_sections[NAME] =                                       \
133     get_unnamed_section (FLAGS, (OBJC                           \
134                                  ? output_objc_section_asm_op   \
135                                  : output_section_asm_op),      \
136                          "\t" DIRECTIVE);
137 #include "config/darwin-sections.def"
138 #undef DEF_SECTION
139
140   readonly_data_section = darwin_sections[const_section];
141   exception_section = darwin_sections[darwin_exception_section];
142   eh_frame_section = darwin_sections[darwin_eh_frame_section];
143 }
144
145 int
146 name_needs_quotes (const char *name)
147 {
148   int c;
149   while ((c = *name++) != '\0')
150     if (! ISIDNUM (c) && c != '.' && c != '$')
151       return 1;
152   return 0;
153 }
154
155 /* Return true if SYM_REF can be used without an indirection.  */
156 static int
157 machopic_symbol_defined_p (rtx sym_ref)
158 {
159   if (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_DEFINED)
160     return true;
161
162   /* If a symbol references local and is not an extern to this
163      file, then the symbol might be able to declared as defined.  */
164   if (SYMBOL_REF_LOCAL_P (sym_ref) && ! SYMBOL_REF_EXTERNAL_P (sym_ref))
165     {
166       /* If the symbol references a variable and the variable is a
167          common symbol, then this symbol is not defined.  */
168       if (SYMBOL_REF_FLAGS (sym_ref) & MACHO_SYMBOL_FLAG_VARIABLE)
169         {
170           tree decl = SYMBOL_REF_DECL (sym_ref);
171           if (!decl)
172             return true;
173           if (DECL_COMMON (decl))
174             return false;
175         }
176       return true;
177     }
178   return false;
179 }
180
181 /* This module assumes that (const (symbol_ref "foo")) is a legal pic
182    reference, which will not be changed.  */
183
184 enum machopic_addr_class
185 machopic_classify_symbol (rtx sym_ref)
186 {
187   int flags;
188   bool function_p;
189
190   flags = SYMBOL_REF_FLAGS (sym_ref);
191   function_p = SYMBOL_REF_FUNCTION_P (sym_ref);
192   if (machopic_symbol_defined_p (sym_ref))
193     return (function_p
194             ? MACHOPIC_DEFINED_FUNCTION : MACHOPIC_DEFINED_DATA);
195   else
196     return (function_p
197             ? MACHOPIC_UNDEFINED_FUNCTION : MACHOPIC_UNDEFINED_DATA);
198 }
199
200 #ifndef TARGET_FIX_AND_CONTINUE
201 #define TARGET_FIX_AND_CONTINUE 0
202 #endif
203
204 /* Indicate when fix-and-continue style code generation is being used
205    and when a reference to data should be indirected so that it can be
206    rebound in a new translation unit to reference the original instance
207    of that data.  Symbol names that are for code generation local to
208    the translation unit are bound to the new translation unit;
209    currently this means symbols that begin with L or _OBJC_;
210    otherwise, we indicate that an indirect reference should be made to
211    permit the runtime to rebind new instances of the translation unit
212    to the original instance of the data.  */
213
214 static int
215 indirect_data (rtx sym_ref)
216 {
217   int lprefix;
218   const char *name;
219
220   /* If we aren't generating fix-and-continue code, don't do anything special.  */
221   if (TARGET_FIX_AND_CONTINUE == 0)
222     return 0;
223
224   /* Otherwise, all symbol except symbols that begin with L or _OBJC_
225      are indirected.  Symbols that begin with L and _OBJC_ are always
226      bound to the current translation unit as they are used for
227      generated local data of the translation unit.  */
228
229   name = XSTR (sym_ref, 0);
230
231   lprefix = (((name[0] == '*' || name[0] == '&')
232               && (name[1] == 'L' || (name[1] == '"' && name[2] == 'L')))
233              || (strncmp (name, "_OBJC_", 6) == 0));
234
235   return ! lprefix;
236 }
237
238
239 static int
240 machopic_data_defined_p (rtx sym_ref)
241 {
242   if (indirect_data (sym_ref))
243     return 0;
244
245   switch (machopic_classify_symbol (sym_ref))
246     {
247     case MACHOPIC_DEFINED_DATA:
248     case MACHOPIC_DEFINED_FUNCTION:
249       return 1;
250     default:
251       return 0;
252     }
253 }
254
255 void
256 machopic_define_symbol (rtx mem)
257 {
258   rtx sym_ref;
259
260   gcc_assert (GET_CODE (mem) == MEM);
261   sym_ref = XEXP (mem, 0);
262   SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
263 }
264
265 static GTY(()) char * function_base;
266
267 const char *
268 machopic_function_base_name (void)
269 {
270   /* if dynamic-no-pic is on, we should not get here */
271   gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
272
273   if (function_base == NULL)
274     function_base =
275       (char *) ggc_alloc_string ("<pic base>", sizeof ("<pic base>"));
276
277   current_function_uses_pic_offset_table = 1;
278
279   return function_base;
280 }
281
282 /* Return a SYMBOL_REF for the PIC function base.  */
283
284 rtx
285 machopic_function_base_sym (void)
286 {
287   rtx sym_ref;
288
289   sym_ref = gen_rtx_SYMBOL_REF (Pmode, machopic_function_base_name ());
290   SYMBOL_REF_FLAGS (sym_ref)
291     |= (MACHO_SYMBOL_FLAG_VARIABLE | MACHO_SYMBOL_FLAG_DEFINED);
292   return sym_ref;
293 }
294
295 /* Return either ORIG or (const:P (minus:P ORIG PIC_BASE)), depending
296    on whether pic_base is NULL or not.  */
297 static inline rtx
298 gen_pic_offset (rtx orig, rtx pic_base)
299 {
300   if (!pic_base)
301     return orig;
302   else
303     return gen_rtx_CONST (Pmode, gen_rtx_MINUS (Pmode, orig, pic_base));
304 }
305
306 static GTY(()) const char * function_base_func_name;
307 static GTY(()) int current_pic_label_num;
308
309 void
310 machopic_output_function_base_name (FILE *file)
311 {
312   const char *current_name;
313
314   /* If dynamic-no-pic is on, we should not get here.  */
315   gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
316   current_name =
317     IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
318   if (function_base_func_name != current_name)
319     {
320       ++current_pic_label_num;
321       function_base_func_name = current_name;
322     }
323   fprintf (file, "\"L%011d$pb\"", current_pic_label_num);
324 }
325
326 /* The suffix attached to non-lazy pointer symbols.  */
327 #define NON_LAZY_POINTER_SUFFIX "$non_lazy_ptr"
328 /* The suffix attached to stub symbols.  */
329 #define STUB_SUFFIX "$stub"
330
331 typedef struct machopic_indirection GTY (())
332 {
333   /* The SYMBOL_REF for the entity referenced.  */
334   rtx symbol;
335   /* The name of the stub or non-lazy pointer.  */
336   const char * ptr_name;
337   /* True iff this entry is for a stub (as opposed to a non-lazy
338      pointer).  */
339   bool stub_p;
340   /* True iff this stub or pointer pointer has been referenced.  */
341   bool used;
342 } machopic_indirection;
343
344 /* A table mapping stub names and non-lazy pointer names to
345    SYMBOL_REFs for the stubbed-to and pointed-to entities.  */
346
347 static GTY ((param_is (struct machopic_indirection))) htab_t
348   machopic_indirections;
349
350 /* Return a hash value for a SLOT in the indirections hash table.  */
351
352 static hashval_t
353 machopic_indirection_hash (const void *slot)
354 {
355   const machopic_indirection *p = (const machopic_indirection *) slot;
356   return htab_hash_string (p->ptr_name);
357 }
358
359 /* Returns true if the KEY is the same as that associated with
360    SLOT.  */
361
362 static int
363 machopic_indirection_eq (const void *slot, const void *key)
364 {
365   return strcmp (((const machopic_indirection *) slot)->ptr_name, key) == 0;
366 }
367
368 /* Return the name of the non-lazy pointer (if STUB_P is false) or
369    stub (if STUB_B is true) corresponding to the given name.  */
370
371 const char *
372 machopic_indirection_name (rtx sym_ref, bool stub_p)
373 {
374   char *buffer;
375   const char *name = XSTR (sym_ref, 0);
376   size_t namelen = strlen (name);
377   machopic_indirection *p;
378   void ** slot;
379   bool saw_star = false;
380   bool needs_quotes;
381   const char *suffix;
382   const char *prefix = user_label_prefix;
383   const char *quote = "";
384   tree id;
385
386   id = maybe_get_identifier (name);
387   if (id)
388     {
389       tree id_orig = id;
390
391       while (IDENTIFIER_TRANSPARENT_ALIAS (id))
392         id = TREE_CHAIN (id);
393       if (id != id_orig)
394         {
395           name = IDENTIFIER_POINTER (id);
396           namelen = strlen (name);
397         }
398     }
399
400   if (name[0] == '*')
401     {
402       saw_star = true;
403       prefix = "";
404       ++name;
405       --namelen;
406     }
407
408   needs_quotes = name_needs_quotes (name);
409   if (needs_quotes)
410     {
411       quote = "\"";
412     }
413
414   if (stub_p)
415     suffix = STUB_SUFFIX;
416   else
417     suffix = NON_LAZY_POINTER_SUFFIX;
418
419   buffer = alloca (strlen ("&L")
420                    + strlen (prefix)
421                    + namelen
422                    + strlen (suffix)
423                    + 2 * strlen (quote)
424                    + 1 /* '\0' */);
425
426   /* Construct the name of the non-lazy pointer or stub.  */
427   sprintf (buffer, "&%sL%s%s%s%s", quote, prefix, name, suffix, quote);
428
429   if (!machopic_indirections)
430     machopic_indirections = htab_create_ggc (37,
431                                              machopic_indirection_hash,
432                                              machopic_indirection_eq,
433                                              /*htab_del=*/NULL);
434
435   slot = htab_find_slot_with_hash (machopic_indirections, buffer,
436                                    htab_hash_string (buffer), INSERT);
437   if (*slot)
438     {
439       p = (machopic_indirection *) *slot;
440     }
441   else
442     {
443       p = (machopic_indirection *) ggc_alloc (sizeof (machopic_indirection));
444       p->symbol = sym_ref;
445       p->ptr_name = xstrdup (buffer);
446       p->stub_p = stub_p;
447       p->used = false;
448       *slot = p;
449     }
450
451   return p->ptr_name;
452 }
453
454 /* Return the name of the stub for the mcount function.  */
455
456 const char*
457 machopic_mcount_stub_name (void)
458 {
459   rtx symbol = gen_rtx_SYMBOL_REF (Pmode, "*mcount");
460   return machopic_indirection_name (symbol, /*stub_p=*/true);
461 }
462
463 /* If NAME is the name of a stub or a non-lazy pointer , mark the stub
464    or non-lazy pointer as used -- and mark the object to which the
465    pointer/stub refers as used as well, since the pointer/stub will
466    emit a reference to it.  */
467
468 void
469 machopic_validate_stub_or_non_lazy_ptr (const char *name)
470 {
471   machopic_indirection *p;
472
473   p = ((machopic_indirection *)
474        (htab_find_with_hash (machopic_indirections, name,
475                              htab_hash_string (name))));
476   if (p && ! p->used)
477     {
478       const char *real_name;
479       tree id;
480
481       p->used = true;
482
483       /* Do what output_addr_const will do when we actually call it.  */
484       if (SYMBOL_REF_DECL (p->symbol))
485         mark_decl_referenced (SYMBOL_REF_DECL (p->symbol));
486
487       real_name = targetm.strip_name_encoding (XSTR (p->symbol, 0));
488
489       id = maybe_get_identifier (real_name);
490       if (id)
491         mark_referenced (id);
492     }
493 }
494
495 /* Transform ORIG, which may be any data source, to the corresponding
496    source using indirections.  */
497
498 rtx
499 machopic_indirect_data_reference (rtx orig, rtx reg)
500 {
501   rtx ptr_ref = orig;
502
503   if (! MACHOPIC_INDIRECT)
504     return orig;
505
506   if (GET_CODE (orig) == SYMBOL_REF)
507     {
508       int defined = machopic_data_defined_p (orig);
509
510       if (defined && MACHO_DYNAMIC_NO_PIC_P)
511         {
512 #if defined (TARGET_TOC)
513           /* Create a new register for CSE opportunities.  */
514           rtx hi_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
515           emit_insn (gen_macho_high (hi_reg, orig));
516           emit_insn (gen_macho_low (reg, hi_reg, orig));
517 #else
518            /* some other cpu -- writeme!  */
519            gcc_unreachable ();
520 #endif
521            return reg;
522         }
523       else if (defined)
524         {
525 #if defined (TARGET_TOC) || defined (HAVE_lo_sum)
526           rtx pic_base = machopic_function_base_sym ();
527           rtx offset = gen_pic_offset (orig, pic_base);
528 #endif
529
530 #if defined (TARGET_TOC) /* i.e., PowerPC */
531           rtx hi_sum_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
532
533           gcc_assert (reg);
534
535           emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
536                               gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
537                                        gen_rtx_HIGH (Pmode, offset))));
538           emit_insn (gen_rtx_SET (Pmode, reg,
539                                   gen_rtx_LO_SUM (Pmode, hi_sum_reg, offset)));
540
541           orig = reg;
542 #else
543 #if defined (HAVE_lo_sum)
544           gcc_assert (reg);
545
546           emit_insn (gen_rtx_SET (VOIDmode, reg,
547                                   gen_rtx_HIGH (Pmode, offset)));
548           emit_insn (gen_rtx_SET (VOIDmode, reg,
549                                   gen_rtx_LO_SUM (Pmode, reg, offset)));
550           emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
551
552           orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
553 #endif
554 #endif
555           return orig;
556         }
557
558       ptr_ref = (gen_rtx_SYMBOL_REF
559                  (Pmode,
560                   machopic_indirection_name (orig, /*stub_p=*/false)));
561
562       SYMBOL_REF_DATA (ptr_ref) = SYMBOL_REF_DATA (orig);
563
564       ptr_ref = gen_const_mem (Pmode, ptr_ref);
565       machopic_define_symbol (ptr_ref);
566
567       return ptr_ref;
568     }
569   else if (GET_CODE (orig) == CONST)
570     {
571       rtx base, result;
572
573       /* legitimize both operands of the PLUS */
574       if (GET_CODE (XEXP (orig, 0)) == PLUS)
575         {
576           base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0),
577                                                    reg);
578           orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
579                                                    (base == reg ? 0 : reg));
580         }
581       else
582         return orig;
583
584       if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
585         result = plus_constant (base, INTVAL (orig));
586       else
587         result = gen_rtx_PLUS (Pmode, base, orig);
588
589       if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
590         {
591           if (reg)
592             {
593               emit_move_insn (reg, result);
594               result = reg;
595             }
596           else
597             {
598               result = force_reg (GET_MODE (result), result);
599             }
600         }
601
602       return result;
603
604     }
605   else if (GET_CODE (orig) == MEM)
606     XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
607   /* When the target is i386, this code prevents crashes due to the
608      compiler's ignorance on how to move the PIC base register to
609      other registers.  (The reload phase sometimes introduces such
610      insns.)  */
611   else if (GET_CODE (orig) == PLUS
612            && GET_CODE (XEXP (orig, 0)) == REG
613            && REGNO (XEXP (orig, 0)) == PIC_OFFSET_TABLE_REGNUM
614 #ifdef I386
615            /* Prevent the same register from being erroneously used
616               as both the base and index registers.  */
617            && GET_CODE (XEXP (orig, 1)) == CONST
618 #endif
619            && reg)
620     {
621       emit_move_insn (reg, XEXP (orig, 0));
622       XEXP (ptr_ref, 0) = reg;
623     }
624   return ptr_ref;
625 }
626
627 /* Transform TARGET (a MEM), which is a function call target, to the
628    corresponding symbol_stub if necessary.  Return a new MEM.  */
629
630 rtx
631 machopic_indirect_call_target (rtx target)
632 {
633   if (GET_CODE (target) != MEM)
634     return target;
635
636   if (MACHOPIC_INDIRECT
637       && GET_CODE (XEXP (target, 0)) == SYMBOL_REF
638       && !(SYMBOL_REF_FLAGS (XEXP (target, 0))
639            & MACHO_SYMBOL_FLAG_DEFINED))
640     {
641       rtx sym_ref = XEXP (target, 0);
642       const char *stub_name = machopic_indirection_name (sym_ref,
643                                                          /*stub_p=*/true);
644       enum machine_mode mode = GET_MODE (sym_ref);
645
646       XEXP (target, 0) = gen_rtx_SYMBOL_REF (mode, stub_name);
647       SYMBOL_REF_DATA (XEXP (target, 0)) = SYMBOL_REF_DATA (sym_ref);
648       MEM_READONLY_P (target) = 1;
649       MEM_NOTRAP_P (target) = 1;
650     }
651
652   return target;
653 }
654
655 rtx
656 machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
657 {
658   rtx pic_ref = orig;
659
660   if (! MACHOPIC_INDIRECT)
661     return orig;
662
663   /* First handle a simple SYMBOL_REF or LABEL_REF */
664   if (GET_CODE (orig) == LABEL_REF
665       || (GET_CODE (orig) == SYMBOL_REF
666           ))
667     {
668       /* addr(foo) = &func+(foo-func) */
669       rtx pic_base;
670
671       orig = machopic_indirect_data_reference (orig, reg);
672
673       if (GET_CODE (orig) == PLUS
674           && GET_CODE (XEXP (orig, 0)) == REG)
675         {
676           if (reg == 0)
677             return force_reg (mode, orig);
678
679           emit_move_insn (reg, orig);
680           return reg;
681         }
682
683       /* if dynamic-no-pic we don't have a pic base  */
684       if (MACHO_DYNAMIC_NO_PIC_P)
685         pic_base = NULL;
686       else
687         pic_base = machopic_function_base_sym ();
688
689       if (GET_CODE (orig) == MEM)
690         {
691           if (reg == 0)
692             {
693               gcc_assert (!reload_in_progress);
694               reg = gen_reg_rtx (Pmode);
695             }
696
697 #ifdef HAVE_lo_sum
698           if (MACHO_DYNAMIC_NO_PIC_P
699               && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
700                   || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
701             {
702 #if defined (TARGET_TOC)        /* ppc  */
703               rtx temp_reg = (no_new_pseudos) ? reg : gen_reg_rtx (Pmode);
704               rtx asym = XEXP (orig, 0);
705               rtx mem;
706
707               emit_insn (gen_macho_high (temp_reg, asym));
708               mem = gen_const_mem (GET_MODE (orig),
709                                    gen_rtx_LO_SUM (Pmode, temp_reg, asym));
710               emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
711 #else
712               /* Some other CPU -- WriteMe! but right now there are no other platform that can use dynamic-no-pic  */
713               gcc_unreachable ();
714 #endif
715               pic_ref = reg;
716             }
717           else
718           if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
719               || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
720             {
721               rtx offset = gen_pic_offset (XEXP (orig, 0), pic_base);
722 #if defined (TARGET_TOC) /* i.e., PowerPC */
723               /* Generating a new reg may expose opportunities for
724                  common subexpression elimination.  */
725               rtx hi_sum_reg = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
726               rtx mem;
727               rtx insn;
728               rtx sum;
729
730               sum = gen_rtx_HIGH (Pmode, offset);
731               if (! MACHO_DYNAMIC_NO_PIC_P)
732                 sum = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, sum);
733
734               emit_insn (gen_rtx_SET (Pmode, hi_sum_reg, sum));
735
736               mem = gen_const_mem (GET_MODE (orig),
737                                   gen_rtx_LO_SUM (Pmode,
738                                                   hi_sum_reg, offset));
739               insn = emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
740               REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, pic_ref,
741                                                     REG_NOTES (insn));
742
743               pic_ref = reg;
744 #else
745               emit_insn (gen_rtx_USE (VOIDmode,
746                                       gen_rtx_REG (Pmode,
747                                                    PIC_OFFSET_TABLE_REGNUM)));
748
749               emit_insn (gen_rtx_SET (VOIDmode, reg,
750                                       gen_rtx_HIGH (Pmode,
751                                                     gen_rtx_CONST (Pmode,
752                                                                    offset))));
753               emit_insn (gen_rtx_SET (VOIDmode, reg,
754                                   gen_rtx_LO_SUM (Pmode, reg,
755                                            gen_rtx_CONST (Pmode, offset))));
756               pic_ref = gen_rtx_PLUS (Pmode,
757                                       pic_offset_table_rtx, reg);
758 #endif
759             }
760           else
761 #endif  /* HAVE_lo_sum */
762             {
763               rtx pic = pic_offset_table_rtx;
764               if (GET_CODE (pic) != REG)
765                 {
766                   emit_move_insn (reg, pic);
767                   pic = reg;
768                 }
769 #if 0
770               emit_insn (gen_rtx_USE (VOIDmode,
771                                       gen_rtx_REG (Pmode,
772                                                    PIC_OFFSET_TABLE_REGNUM)));
773 #endif
774
775               if (reload_in_progress)
776                 regs_ever_live[REGNO (pic)] = 1;
777               pic_ref = gen_rtx_PLUS (Pmode, pic,
778                                       gen_pic_offset (XEXP (orig, 0),
779                                                       pic_base));
780             }
781
782 #if !defined (TARGET_TOC)
783           emit_move_insn (reg, pic_ref);
784           pic_ref = gen_const_mem (GET_MODE (orig), reg);
785 #endif
786         }
787       else
788         {
789
790 #ifdef HAVE_lo_sum
791           if (GET_CODE (orig) == SYMBOL_REF
792               || GET_CODE (orig) == LABEL_REF)
793             {
794               rtx offset = gen_pic_offset (orig, pic_base);
795 #if defined (TARGET_TOC) /* i.e., PowerPC */
796               rtx hi_sum_reg;
797
798               if (reg == 0)
799                 {
800                   gcc_assert (!reload_in_progress);
801                   reg = gen_reg_rtx (Pmode);
802                 }
803
804               hi_sum_reg = reg;
805
806               emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
807                                       (MACHO_DYNAMIC_NO_PIC_P)
808                                       ? gen_rtx_HIGH (Pmode, offset)
809                                       : gen_rtx_PLUS (Pmode,
810                                                       pic_offset_table_rtx,
811                                                       gen_rtx_HIGH (Pmode,
812                                                                     offset))));
813               emit_insn (gen_rtx_SET (VOIDmode, reg,
814                                       gen_rtx_LO_SUM (Pmode,
815                                                       hi_sum_reg, offset)));
816               pic_ref = reg;
817 #else
818               emit_insn (gen_rtx_SET (VOIDmode, reg,
819                                       gen_rtx_HIGH (Pmode, offset)));
820               emit_insn (gen_rtx_SET (VOIDmode, reg,
821                                       gen_rtx_LO_SUM (Pmode, reg, offset)));
822               pic_ref = gen_rtx_PLUS (Pmode,
823                                       pic_offset_table_rtx, reg);
824 #endif
825             }
826           else
827 #endif  /*  HAVE_lo_sum  */
828             {
829               if (REG_P (orig)
830                   || GET_CODE (orig) == SUBREG)
831                 {
832                   return orig;
833                 }
834               else
835                 {
836                   rtx pic = pic_offset_table_rtx;
837                   if (GET_CODE (pic) != REG)
838                     {
839                       emit_move_insn (reg, pic);
840                       pic = reg;
841                     }
842 #if 0
843                   emit_insn (gen_rtx_USE (VOIDmode,
844                                           pic_offset_table_rtx));
845 #endif
846                   if (reload_in_progress)
847                     regs_ever_live[REGNO (pic)] = 1;
848                   pic_ref = gen_rtx_PLUS (Pmode,
849                                           pic,
850                                           gen_pic_offset (orig, pic_base));
851                 }
852             }
853         }
854
855       if (GET_CODE (pic_ref) != REG)
856         {
857           if (reg != 0)
858             {
859               emit_move_insn (reg, pic_ref);
860               return reg;
861             }
862           else
863             {
864               return force_reg (mode, pic_ref);
865             }
866         }
867       else
868         {
869           return pic_ref;
870         }
871     }
872
873   else if (GET_CODE (orig) == SYMBOL_REF)
874     return orig;
875
876   else if (GET_CODE (orig) == PLUS
877            && (GET_CODE (XEXP (orig, 0)) == MEM
878                || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
879                || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
880            && XEXP (orig, 0) != pic_offset_table_rtx
881            && GET_CODE (XEXP (orig, 1)) != REG)
882
883     {
884       rtx base;
885       int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
886
887       base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
888       orig = machopic_legitimize_pic_address (XEXP (orig, 1),
889                                               Pmode, (base == reg ? 0 : reg));
890       if (GET_CODE (orig) == CONST_INT)
891         {
892           pic_ref = plus_constant (base, INTVAL (orig));
893           is_complex = 1;
894         }
895       else
896         pic_ref = gen_rtx_PLUS (Pmode, base, orig);
897
898       if (reg && is_complex)
899         {
900           emit_move_insn (reg, pic_ref);
901           pic_ref = reg;
902         }
903       /* Likewise, should we set special REG_NOTEs here?  */
904     }
905
906   else if (GET_CODE (orig) == CONST)
907     {
908       return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
909     }
910
911   else if (GET_CODE (orig) == MEM
912            && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
913     {
914       rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
915       addr = replace_equiv_address (orig, addr);
916       emit_move_insn (reg, addr);
917       pic_ref = reg;
918     }
919
920   return pic_ref;
921 }
922
923 /* Output the stub or non-lazy pointer in *SLOT, if it has been used.
924    DATA is the FILE* for assembly output.  Called from
925    htab_traverse.  */
926
927 static int
928 machopic_output_indirection (void **slot, void *data)
929 {
930   machopic_indirection *p = *((machopic_indirection **) slot);
931   FILE *asm_out_file = (FILE *) data;
932   rtx symbol;
933   const char *sym_name;
934   const char *ptr_name;
935
936   if (!p->used)
937     return 1;
938
939   symbol = p->symbol;
940   sym_name = XSTR (symbol, 0);
941   ptr_name = p->ptr_name;
942
943   if (p->stub_p)
944     {
945       char *sym;
946       char *stub;
947       tree id;
948
949       id = maybe_get_identifier (sym_name);
950       if (id)
951         {
952           tree id_orig = id;
953
954           while (IDENTIFIER_TRANSPARENT_ALIAS (id))
955             id = TREE_CHAIN (id);
956           if (id != id_orig)
957             sym_name = IDENTIFIER_POINTER (id);
958         }
959
960       sym = alloca (strlen (sym_name) + 2);
961       if (sym_name[0] == '*' || sym_name[0] == '&')
962         strcpy (sym, sym_name + 1);
963       else if (sym_name[0] == '-' || sym_name[0] == '+')
964         strcpy (sym, sym_name);
965       else
966         sprintf (sym, "%s%s", user_label_prefix, sym_name);
967
968       stub = alloca (strlen (ptr_name) + 2);
969       if (ptr_name[0] == '*' || ptr_name[0] == '&')
970         strcpy (stub, ptr_name + 1);
971       else
972         sprintf (stub, "%s%s", user_label_prefix, ptr_name);
973
974       machopic_output_stub (asm_out_file, sym, stub);
975     }
976   else if (! indirect_data (symbol)
977            && (machopic_symbol_defined_p (symbol)
978                || SYMBOL_REF_LOCAL_P (symbol)))
979     {
980       switch_to_section (data_section);
981       assemble_align (GET_MODE_ALIGNMENT (Pmode));
982       assemble_label (ptr_name);
983       assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
984                         GET_MODE_SIZE (Pmode),
985                         GET_MODE_ALIGNMENT (Pmode), 1);
986     }
987   else
988     {
989       rtx init = const0_rtx;
990
991       switch_to_section (darwin_sections[machopic_nl_symbol_ptr_section]);
992       assemble_name (asm_out_file, ptr_name);
993       fprintf (asm_out_file, ":\n");
994
995       fprintf (asm_out_file, "\t.indirect_symbol ");
996       assemble_name (asm_out_file, sym_name);
997       fprintf (asm_out_file, "\n");
998
999       /* Variables that are marked with MACHO_SYMBOL_STATIC need to
1000          have their symbol name instead of 0 in the second entry of
1001          the non-lazy symbol pointer data structure when they are
1002          defined.  This allows the runtime to rebind newer instances
1003          of the translation unit with the original instance of the
1004          symbol.  */
1005
1006       if ((SYMBOL_REF_FLAGS (symbol) & MACHO_SYMBOL_STATIC)
1007           && machopic_symbol_defined_p (symbol))
1008         init = gen_rtx_SYMBOL_REF (Pmode, sym_name);
1009
1010       assemble_integer (init, GET_MODE_SIZE (Pmode),
1011                         GET_MODE_ALIGNMENT (Pmode), 1);
1012     }
1013
1014   return 1;
1015 }
1016
1017 void
1018 machopic_finish (FILE *asm_out_file)
1019 {
1020   if (machopic_indirections)
1021     htab_traverse_noresize (machopic_indirections,
1022                             machopic_output_indirection,
1023                             asm_out_file);
1024 }
1025
1026 int
1027 machopic_operand_p (rtx op)
1028 {
1029   if (MACHOPIC_JUST_INDIRECT)
1030     {
1031       while (GET_CODE (op) == CONST)
1032         op = XEXP (op, 0);
1033
1034       if (GET_CODE (op) == SYMBOL_REF)
1035         return machopic_symbol_defined_p (op);
1036       else
1037         return 0;
1038     }
1039
1040   while (GET_CODE (op) == CONST)
1041     op = XEXP (op, 0);
1042
1043   if (GET_CODE (op) == MINUS
1044       && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
1045       && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
1046       && machopic_symbol_defined_p (XEXP (op, 0))
1047       && machopic_symbol_defined_p (XEXP (op, 1)))
1048       return 1;
1049
1050   return 0;
1051 }
1052
1053 /* This function records whether a given name corresponds to a defined
1054    or undefined function or variable, for machopic_classify_ident to
1055    use later.  */
1056
1057 void
1058 darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
1059 {
1060   rtx sym_ref;
1061
1062   /* Do the standard encoding things first.  */
1063   default_encode_section_info (decl, rtl, first);
1064
1065   if (TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
1066     return;
1067
1068   sym_ref = XEXP (rtl, 0);
1069   if (TREE_CODE (decl) == VAR_DECL)
1070     SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_VARIABLE;
1071
1072   if (!DECL_EXTERNAL (decl)
1073       && (!TREE_PUBLIC (decl) || !DECL_WEAK (decl))
1074       && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
1075       && ((TREE_STATIC (decl)
1076            && (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
1077           || (!DECL_COMMON (decl) && DECL_INITIAL (decl)
1078               && DECL_INITIAL (decl) != error_mark_node)))
1079     SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
1080
1081   if (! TREE_PUBLIC (decl))
1082     SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_STATIC;
1083 }
1084
1085 void
1086 darwin_mark_decl_preserved (const char *name)
1087 {
1088   fprintf (asm_out_file, ".no_dead_strip ");
1089   assemble_name (asm_out_file, name);
1090   fputc ('\n', asm_out_file);
1091 }
1092
1093 section *
1094 machopic_select_section (tree exp, int reloc,
1095                          unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1096 {
1097   section *base_section;
1098   bool weak_p = (DECL_P (exp) && DECL_WEAK (exp)
1099                  && (lookup_attribute ("weak", DECL_ATTRIBUTES (exp))
1100                      || ! lookup_attribute ("weak_import",
1101                                             DECL_ATTRIBUTES (exp))));
1102
1103   if (TREE_CODE (exp) == FUNCTION_DECL)
1104     {
1105       if (reloc == 1)
1106         base_section = (weak_p
1107                         ? darwin_sections[text_unlikely_coal_section]
1108                         : unlikely_text_section ());
1109       else
1110         base_section = weak_p ? darwin_sections[text_coal_section] : text_section;
1111     }
1112   else if (decl_readonly_section_1 (exp, reloc, MACHOPIC_INDIRECT))
1113     base_section = weak_p ? darwin_sections[const_coal_section] : darwin_sections[const_section];
1114   else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
1115     base_section = weak_p ? darwin_sections[const_data_coal_section] : darwin_sections[const_data_section];
1116   else
1117     base_section = weak_p ? darwin_sections[data_coal_section] : data_section;
1118
1119   if (TREE_CODE (exp) == STRING_CST
1120       && ((size_t) TREE_STRING_LENGTH (exp)
1121           == strlen (TREE_STRING_POINTER (exp)) + 1))
1122     return darwin_sections[cstring_section];
1123   else if ((TREE_CODE (exp) == INTEGER_CST || TREE_CODE (exp) == REAL_CST)
1124            && flag_merge_constants)
1125     {
1126       tree size = TYPE_SIZE_UNIT (TREE_TYPE (exp));
1127
1128       if (TREE_CODE (size) == INTEGER_CST &&
1129           TREE_INT_CST_LOW (size) == 4 &&
1130           TREE_INT_CST_HIGH (size) == 0)
1131         return darwin_sections[literal4_section];
1132       else if (TREE_CODE (size) == INTEGER_CST &&
1133                TREE_INT_CST_LOW (size) == 8 &&
1134                TREE_INT_CST_HIGH (size) == 0)
1135         return darwin_sections[literal8_section];
1136       else
1137         return base_section;
1138     }
1139   else if (TREE_CODE (exp) == CONSTRUCTOR
1140            && TREE_TYPE (exp)
1141            && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
1142            && TYPE_NAME (TREE_TYPE (exp)))
1143     {
1144       tree name = TYPE_NAME (TREE_TYPE (exp));
1145       if (TREE_CODE (name) == TYPE_DECL)
1146         name = DECL_NAME (name);
1147
1148       if (!strcmp (IDENTIFIER_POINTER (name), "__builtin_ObjCString"))
1149         {
1150           if (flag_next_runtime)
1151             return darwin_sections[objc_constant_string_object_section];
1152           else
1153             return darwin_sections[objc_string_object_section];
1154         }
1155       else
1156         return base_section;
1157     }
1158   else if (TREE_CODE (exp) == VAR_DECL &&
1159            DECL_NAME (exp) &&
1160            TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
1161            IDENTIFIER_POINTER (DECL_NAME (exp)) &&
1162            !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
1163     {
1164       const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
1165
1166       if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
1167         return darwin_sections[objc_cls_meth_section];
1168       else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
1169         return darwin_sections[objc_inst_meth_section];
1170       else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
1171         return darwin_sections[objc_cat_cls_meth_section];
1172       else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
1173         return darwin_sections[objc_cat_inst_meth_section];
1174       else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
1175         return darwin_sections[objc_class_vars_section];
1176       else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
1177         return darwin_sections[objc_instance_vars_section];
1178       else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
1179         return darwin_sections[objc_cat_cls_meth_section];
1180       else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
1181         return darwin_sections[objc_class_names_section];
1182       else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
1183         return darwin_sections[objc_meth_var_names_section];
1184       else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
1185         return darwin_sections[objc_meth_var_types_section];
1186       else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
1187         return darwin_sections[objc_cls_refs_section];
1188       else if (!strncmp (name, "_OBJC_CLASS_", 12))
1189         return darwin_sections[objc_class_section];
1190       else if (!strncmp (name, "_OBJC_METACLASS_", 16))
1191         return darwin_sections[objc_meta_class_section];
1192       else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
1193         return darwin_sections[objc_category_section];
1194       else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
1195         return darwin_sections[objc_selector_refs_section];
1196       else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
1197         return darwin_sections[objc_selector_fixup_section];
1198       else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
1199         return darwin_sections[objc_symbols_section];
1200       else if (!strncmp (name, "_OBJC_MODULES", 13))
1201         return darwin_sections[objc_module_info_section];
1202       else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
1203         return darwin_sections[objc_image_info_section];
1204       else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
1205         return darwin_sections[objc_cat_inst_meth_section];
1206       else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
1207         return darwin_sections[objc_cat_cls_meth_section];
1208       else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
1209         return darwin_sections[objc_cat_cls_meth_section];
1210       else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
1211         return darwin_sections[objc_protocol_section];
1212       else
1213         return base_section;
1214     }
1215   else
1216     return base_section;
1217 }
1218
1219 /* This can be called with address expressions as "rtx".
1220    They must go in "const".  */
1221
1222 section *
1223 machopic_select_rtx_section (enum machine_mode mode, rtx x,
1224                              unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
1225 {
1226   if (GET_MODE_SIZE (mode) == 8
1227       && (GET_CODE (x) == CONST_INT
1228           || GET_CODE (x) == CONST_DOUBLE))
1229     return darwin_sections[literal8_section];
1230   else if (GET_MODE_SIZE (mode) == 4
1231            && (GET_CODE (x) == CONST_INT
1232                || GET_CODE (x) == CONST_DOUBLE))
1233     return darwin_sections[literal4_section];
1234   else if (MACHOPIC_INDIRECT
1235            && (GET_CODE (x) == SYMBOL_REF
1236                || GET_CODE (x) == CONST
1237                || GET_CODE (x) == LABEL_REF))
1238     return darwin_sections[const_data_section];
1239   else
1240     return darwin_sections[const_section];
1241 }
1242
1243 void
1244 machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1245 {
1246   if (MACHOPIC_INDIRECT)
1247     switch_to_section (darwin_sections[mod_init_section]);
1248   else
1249     switch_to_section (darwin_sections[constructor_section]);
1250   assemble_align (POINTER_SIZE);
1251   assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1252
1253   if (! MACHOPIC_INDIRECT)
1254     fprintf (asm_out_file, ".reference .constructors_used\n");
1255 }
1256
1257 void
1258 machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
1259 {
1260   if (MACHOPIC_INDIRECT)
1261     switch_to_section (darwin_sections[mod_term_section]);
1262   else
1263     switch_to_section (darwin_sections[destructor_section]);
1264   assemble_align (POINTER_SIZE);
1265   assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1266
1267   if (! MACHOPIC_INDIRECT)
1268     fprintf (asm_out_file, ".reference .destructors_used\n");
1269 }
1270
1271 void
1272 darwin_globalize_label (FILE *stream, const char *name)
1273 {
1274   if (!!strncmp (name, "_OBJC_", 6))
1275     default_globalize_label (stream, name);
1276 }
1277
1278 void
1279 darwin_asm_named_section (const char *name,
1280                           unsigned int flags ATTRIBUTE_UNUSED,
1281                           tree decl ATTRIBUTE_UNUSED)
1282 {
1283   fprintf (asm_out_file, "\t.section %s\n", name);
1284 }
1285
1286 void
1287 darwin_unique_section (tree decl ATTRIBUTE_UNUSED, int reloc ATTRIBUTE_UNUSED)
1288 {
1289   /* Darwin does not use unique sections.  */
1290 }
1291
1292 /* Handle a "weak_import" attribute; arguments as in
1293    struct attribute_spec.handler.  */
1294
1295 tree
1296 darwin_handle_weak_import_attribute (tree *node, tree name,
1297                                      tree ARG_UNUSED (args),
1298                                      int ARG_UNUSED (flags),
1299                                      bool * no_add_attrs)
1300 {
1301   if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
1302     {
1303       warning (OPT_Wattributes, "%qs attribute ignored",
1304                IDENTIFIER_POINTER (name));
1305       *no_add_attrs = true;
1306     }
1307   else
1308     declare_weak (*node);
1309
1310   return NULL_TREE;
1311 }
1312
1313 static void
1314 no_dead_strip (FILE *file, const char *lab)
1315 {
1316   fprintf (file, ".no_dead_strip %s\n", lab);
1317 }
1318
1319 /* Emit a label for an FDE, making it global and/or weak if appropriate.
1320    The third parameter is nonzero if this is for exception handling.
1321    The fourth parameter is nonzero if this is just a placeholder for an
1322    FDE that we are omitting. */
1323
1324 void
1325 darwin_emit_unwind_label (FILE *file, tree decl, int for_eh, int empty)
1326 {
1327   tree id = DECL_ASSEMBLER_NAME (decl)
1328     ? DECL_ASSEMBLER_NAME (decl)
1329     : DECL_NAME (decl);
1330
1331   const char *base = IDENTIFIER_POINTER (id);
1332
1333   bool need_quotes = name_needs_quotes (base);
1334   char *lab;
1335
1336   if (! for_eh)
1337     return;
1338
1339   lab = concat (need_quotes ? "\"" : "", user_label_prefix, base, ".eh",
1340                 need_quotes ? "\"" : "", NULL);
1341
1342   if (TREE_PUBLIC (decl))
1343     fprintf (file, "\t%s %s\n",
1344              (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
1345               ? ".globl"
1346               : ".private_extern"),
1347              lab);
1348
1349   if (DECL_WEAK (decl))
1350     fprintf (file, "\t.weak_definition %s\n", lab);
1351
1352   if (empty)
1353     {
1354       fprintf (file, "%s = 0\n", lab);
1355
1356       /* Mark the absolute .eh and .eh1 style labels as needed to
1357          ensure that we don't dead code strip them and keep such
1358          labels from another instantiation point until we can fix this
1359          properly with group comdat support.  */
1360       no_dead_strip (file, lab);
1361     }
1362   else
1363     fprintf (file, "%s:\n", lab);
1364
1365   free (lab);
1366 }
1367
1368 static GTY(()) unsigned long except_table_label_num;
1369
1370 void
1371 darwin_emit_except_table_label (FILE *file)
1372 {
1373   char section_start_label[30];
1374
1375   ASM_GENERATE_INTERNAL_LABEL (section_start_label, "GCC_except_table",
1376                                except_table_label_num++);
1377   ASM_OUTPUT_LABEL (file, section_start_label);
1378 }
1379 /* Generate a PC-relative reference to a Mach-O non-lazy-symbol.  */
1380
1381 void
1382 darwin_non_lazy_pcrel (FILE *file, rtx addr)
1383 {
1384   const char *nlp_name;
1385
1386   gcc_assert (GET_CODE (addr) == SYMBOL_REF);
1387
1388   nlp_name = machopic_indirection_name (addr, /*stub_p=*/false);
1389   fputs ("\t.long\t", file);
1390   ASM_OUTPUT_LABELREF (file, nlp_name);
1391   fputs ("-.", file);
1392 }
1393
1394 /* Emit an assembler directive to set visibility for a symbol.  The
1395    only supported visibilities are VISIBILITY_DEFAULT and
1396    VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
1397    extern".  There is no MACH-O equivalent of ELF's
1398    VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */
1399
1400 void
1401 darwin_assemble_visibility (tree decl, int vis)
1402 {
1403   if (vis == VISIBILITY_DEFAULT)
1404     ;
1405   else if (vis == VISIBILITY_HIDDEN)
1406     {
1407       fputs ("\t.private_extern ", asm_out_file);
1408       assemble_name (asm_out_file,
1409                      (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
1410       fputs ("\n", asm_out_file);
1411     }
1412   else
1413     warning (OPT_Wattributes, "internal and protected visibility attributes "
1414              "not supported in this configuration; ignored");
1415 }
1416
1417 /* Output a difference of two labels that will be an assembly time
1418    constant if the two labels are local.  (.long lab1-lab2 will be
1419    very different if lab1 is at the boundary between two sections; it
1420    will be relocated according to the second section, not the first,
1421    so one ends up with a difference between labels in different
1422    sections, which is bad in the dwarf2 eh context for instance.)  */
1423
1424 static int darwin_dwarf_label_counter;
1425
1426 void
1427 darwin_asm_output_dwarf_delta (FILE *file, int size,
1428                                const char *lab1, const char *lab2)
1429 {
1430   int islocaldiff = (lab1[0] == '*' && lab1[1] == 'L'
1431                      && lab2[0] == '*' && lab2[1] == 'L');
1432   const char *directive = (size == 8 ? ".quad" : ".long");
1433
1434   if (islocaldiff)
1435     fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
1436   else
1437     fprintf (file, "\t%s\t", directive);
1438   assemble_name_raw (file, lab1);
1439   fprintf (file, "-");
1440   assemble_name_raw (file, lab2);
1441   if (islocaldiff)
1442     fprintf (file, "\n\t%s L$set$%d", directive, darwin_dwarf_label_counter++);
1443 }
1444
1445 /* Output labels for the start of the DWARF sections if necessary.  */
1446 void
1447 darwin_file_start (void)
1448 {
1449   if (write_symbols == DWARF2_DEBUG)
1450     {
1451       static const char * const debugnames[] = 
1452         {
1453           DEBUG_FRAME_SECTION,
1454           DEBUG_INFO_SECTION,
1455           DEBUG_ABBREV_SECTION,
1456           DEBUG_ARANGES_SECTION,
1457           DEBUG_MACINFO_SECTION,
1458           DEBUG_LINE_SECTION,
1459           DEBUG_LOC_SECTION,
1460           DEBUG_PUBNAMES_SECTION,
1461           DEBUG_STR_SECTION,
1462           DEBUG_RANGES_SECTION
1463         };
1464       size_t i;
1465
1466       for (i = 0; i < ARRAY_SIZE (debugnames); i++)
1467         {
1468           int namelen;
1469
1470           switch_to_section (get_section (debugnames[i], SECTION_DEBUG, NULL));
1471           
1472           gcc_assert (strncmp (debugnames[i], "__DWARF,", 8) == 0);
1473           gcc_assert (strchr (debugnames[i] + 8, ','));
1474           
1475           namelen = strchr (debugnames[i] + 8, ',') - (debugnames[i] + 8);
1476           fprintf (asm_out_file, "Lsection%.*s:\n", namelen, debugnames[i] + 8);
1477         }
1478     }
1479 }
1480
1481 /* Output an offset in a DWARF section on Darwin.  On Darwin, DWARF section
1482    offsets are not represented using relocs in .o files; either the
1483    section never leaves the .o file, or the linker or other tool is
1484    responsible for parsing the DWARF and updating the offsets.  */
1485
1486 void
1487 darwin_asm_output_dwarf_offset (FILE *file, int size, const char * lab,
1488                                 section *base)
1489 {
1490   char sname[64];
1491   int namelen;
1492   
1493   gcc_assert (base->common.flags & SECTION_NAMED);
1494   gcc_assert (strncmp (base->named.name, "__DWARF,", 8) == 0);
1495   gcc_assert (strchr (base->named.name + 8, ','));
1496
1497   namelen = strchr (base->named.name + 8, ',') - (base->named.name + 8);
1498   sprintf (sname, "*Lsection%.*s", namelen, base->named.name + 8);
1499   darwin_asm_output_dwarf_delta (file, size, lab, sname);
1500 }
1501
1502 void
1503 darwin_file_end (void)
1504 {
1505   machopic_finish (asm_out_file);
1506   if (strcmp (lang_hooks.name, "GNU C++") == 0)
1507     {
1508       switch_to_section (darwin_sections[constructor_section]);
1509       switch_to_section (darwin_sections[destructor_section]);
1510       ASM_OUTPUT_ALIGN (asm_out_file, 1);
1511     }
1512   fprintf (asm_out_file, "\t.subsections_via_symbols\n");
1513 }
1514
1515 /* Cross-module name binding.  Darwin does not support overriding
1516    functions at dynamic-link time.  */
1517
1518 bool
1519 darwin_binds_local_p (tree decl)
1520 {
1521   return default_binds_local_p_1 (decl, 0);
1522 }
1523
1524 /* The Darwin's implementation of TARGET_ASM_OUTPUT_ANCHOR.  Define the
1525    anchor relative to ".", the current section position.  We cannot use
1526    the default one because ASM_OUTPUT_DEF is wrong for Darwin.  */
1527
1528 void
1529 darwin_asm_output_anchor (rtx symbol)
1530 {
1531   fprintf (asm_out_file, "\t.set\t");
1532   assemble_name (asm_out_file, XSTR (symbol, 0));
1533   fprintf (asm_out_file, ", . + " HOST_WIDE_INT_PRINT_DEC "\n",
1534            SYMBOL_REF_BLOCK_OFFSET (symbol));
1535 }
1536
1537 #include "gt-darwin.h"