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