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