OSDN Git Service

support stabs on mach-o GAS.
[pf3gnuchains/pf3gnuchains4x.git] / gas / config / obj-macho.c
1 /* Mach-O object file format
2    Copyright 2009, 2011, 2012 Free Software Foundation, Inc.
3
4    This file is part of GAS, the GNU Assembler.
5
6    GAS is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as
8    published by the Free Software Foundation; either version 3,
9    or (at your option) any later version.
10
11    GAS is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14    the GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with GAS; see the file COPYING.  If not, write to the Free
18    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19    02110-1301, USA.  */
20
21 /* Here we handle the mach-o directives that are common to all architectures.
22
23    Most significant are mach-o named sections and a variety of symbol type
24    decorations.  */
25
26 /* Mach-O supports multiple, named segments each of which may contain
27    multiple named sections.  Thus the concept of subsectioning is 
28    handled by (say) having a __TEXT segment with appropriate flags from
29    which subsections are generated like __text, __const etc.  
30    
31    The well-known as short-hand section switch directives like .text, .data
32    etc. are mapped onto predefined segment/section pairs using facilites
33    supplied by the mach-o port of bfd.
34    
35    A number of additional mach-o short-hand section switch directives are
36    also defined.  */
37
38 #define OBJ_HEADER "obj-macho.h"
39
40 #include "as.h"
41 #include "subsegs.h"
42 #include "symbols.h"
43 #include "write.h"
44 #include "mach-o.h"
45 #include "mach-o/loader.h"
46 #include "obj-macho.h"
47
48 /* Forward decl.  */
49 static segT obj_mach_o_segT_from_bfd_name (const char *nam, int must_succeed);
50
51 /* TODO: Implement "-dynamic"/"-static" command line options.  */
52
53 static int obj_mach_o_is_static;
54
55 /* TODO: Implement the "-n" command line option to suppress the initial
56    switch to the text segment.  */
57 static int obj_mach_o_start_with_text_section = 1;
58
59 /* Allow for special re-ordering on output.  */
60
61 static int obj_mach_o_seen_objc_section;
62
63 /* Start-up: At present, just create the sections we want.  */
64 void
65 mach_o_begin (void)
66 {
67   /* Mach-O only defines the .text section by default, and even this can
68      be suppressed by a flag.  In the latter event, the first code MUST
69      be a section definition.  */
70   if (obj_mach_o_start_with_text_section)
71     {
72       text_section = obj_mach_o_segT_from_bfd_name (TEXT_SECTION_NAME, 1);
73       subseg_set (text_section, 0);
74       if (obj_mach_o_is_static)
75         {
76           bfd_mach_o_section *mo_sec 
77                         = bfd_mach_o_get_mach_o_section (text_section);
78           mo_sec->flags &= ~BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS;
79         }
80     }
81 }
82
83 /* Remember the subsections_by_symbols state in case we need to reset
84    the file flags.  */
85 static int obj_mach_o_subsections_by_symbols;
86
87 static void
88 obj_mach_o_weak (int ignore ATTRIBUTE_UNUSED)
89 {
90   char *name;
91   int c;
92   symbolS *symbolP;
93
94   do
95     {
96       /* Get symbol name.  */
97       name = input_line_pointer;
98       c = get_symbol_end ();
99       symbolP = symbol_find_or_make (name);
100       S_SET_WEAK (symbolP);
101       *input_line_pointer = c;
102       SKIP_WHITESPACE ();
103
104       if (c != ',')
105         break;
106       input_line_pointer++;
107       SKIP_WHITESPACE ();
108     }
109   while (*input_line_pointer != '\n');
110   demand_empty_rest_of_line ();
111 }
112
113 /* This will put at most 16 characters (terminated by a ',' or newline) from
114    the input stream into dest.  If there are more than 16 chars before the
115    delimiter, a warning is given and the string is truncated.  On completion of
116    this function, input_line_pointer will point to the char after the ',' or 
117    to the newline.  
118    
119    It trims leading and trailing space.  */
120
121 static int
122 collect_16char_name (char *dest, const char *msg, int require_comma)
123 {
124   char c, *namstart;
125
126   SKIP_WHITESPACE ();
127   namstart = input_line_pointer;
128
129   while ( (c = *input_line_pointer) != ',' 
130          && !is_end_of_line[(unsigned char) c])
131     input_line_pointer++;
132
133   {
134       int len = input_line_pointer - namstart; /* could be zero.  */
135       /* lose any trailing space.  */  
136       while (len > 0 && namstart[len-1] == ' ') 
137         len--;
138       if (len > 16)
139         {
140           *input_line_pointer = '\0'; /* make a temp string.  */
141           as_bad (_("the %s name '%s' is too long (maximum 16 characters)"),
142                      msg, namstart);
143           *input_line_pointer = c; /* restore for printing.  */
144           len = 16;
145         }
146       if (len > 0)
147         memcpy (dest, namstart, len);
148   }
149
150   if (c != ',' && require_comma)
151     {
152       as_bad (_("expected a %s name followed by a `,'"), msg);
153       return 1;
154     }
155
156   return 0;
157 }
158
159 /* .section
160
161    The '.section' specification syntax looks like:
162    .section <segment> , <section> [, type [, attribs [, size]]]
163
164    White space is allowed everywhere between elements.
165
166    <segment> and <section> may be from 0 to 16 chars in length - they may
167    contain spaces but leading and trailing space will be trimmed.  It is 
168    mandatory that they be present (or that zero-length names are indicated
169    by ",,").
170
171    There is only a single section type for any entry.
172
173    There may be multiple attributes, they are delimited by `+'.
174
175    Not all section types and attributes are accepted by the Darwin system
176    assemblers as user-specifiable - although, at present, we do here.  */
177
178 static void
179 obj_mach_o_section (int ignore ATTRIBUTE_UNUSED)
180 {
181   char *p;
182   char c;
183   unsigned int sectype = BFD_MACH_O_S_REGULAR;
184   unsigned int defsectype = BFD_MACH_O_S_REGULAR;
185   unsigned int sectype_given = 0;
186   unsigned int secattr = 0;
187   unsigned int defsecattr = 0;
188   int secattr_given = 0;
189   unsigned int secalign = 0;
190   offsetT sizeof_stub = 0;
191   const mach_o_section_name_xlat * xlat;
192   const char *name;
193   flagword oldflags, flags;
194   asection *sec;
195   bfd_mach_o_section *msect;
196   char segname[17];
197   char sectname[17];
198
199 #ifdef md_flush_pending_output
200   md_flush_pending_output ();
201 #endif
202
203   /* Zero-length segment and section names are allowed.  */
204   /* Parse segment name.  */
205   memset (segname, 0, sizeof(segname));
206   if (collect_16char_name (segname, "segment", 1))
207     {
208       ignore_rest_of_line ();
209       return;
210     }
211   input_line_pointer++; /* Skip the terminating ',' */
212
213   /* Parse section name.  */
214   memset (sectname, 0, sizeof(sectname));
215   collect_16char_name (sectname, "section", 0);
216
217   /* Parse type.  */
218   if (*input_line_pointer == ',')
219     {
220       char tmpc;
221       int len;
222       input_line_pointer++;
223       SKIP_WHITESPACE ();
224       p = input_line_pointer;
225       while ((c = *input_line_pointer) != ','
226               && !is_end_of_line[(unsigned char) c])
227         input_line_pointer++;
228
229       len = input_line_pointer - p;
230       /* strip trailing spaces.  */
231       while (len > 0 && p[len-1] == ' ')
232         len--;
233       tmpc = p[len];
234
235       /* Temporarily make a string from the token.  */
236       p[len] = 0;
237       sectype = bfd_mach_o_get_section_type_from_name (stdoutput, p);
238       if (sectype > 255) /* Max Section ID == 255.  */
239         {
240           as_bad (_("unknown or invalid section type '%s'"), p);
241           p[len] = tmpc;
242           ignore_rest_of_line ();
243           return;
244         }
245       else
246         sectype_given = 1;
247       /* Restore.  */
248       p[len] = tmpc;
249
250       /* Parse attributes.
251          TODO: check validity of attributes for section type.  */
252       if (sectype_given && c == ',')
253         {
254           do
255             {
256               int attr;
257
258               /* Skip initial `,' and subsequent `+'.  */
259               input_line_pointer++;
260               SKIP_WHITESPACE ();
261               p = input_line_pointer;
262               while ((c = *input_line_pointer) != '+'
263                       && c != ','
264                       && !is_end_of_line[(unsigned char) c])
265                 input_line_pointer++;
266
267               len = input_line_pointer - p;
268               /* strip trailing spaces.  */
269               while (len > 0 && p[len-1] == ' ')
270                 len--;
271               tmpc = p[len];
272
273               /* Temporarily make a string from the token.  */
274               p[len] ='\0';
275               attr = bfd_mach_o_get_section_attribute_from_name (p);
276               if (attr == -1)
277                 {
278                   as_bad (_("unknown or invalid section attribute '%s'"), p);
279                   p[len] = tmpc;
280                   ignore_rest_of_line ();
281                   return;
282                 }
283               else
284                 {
285                   secattr_given = 1;
286                   secattr |= attr;
287                 }
288               /* Restore.  */
289               p[len] = tmpc;
290             }
291           while (*input_line_pointer == '+');
292
293           /* Parse sizeof_stub.  */
294           if (secattr_given && *input_line_pointer == ',')
295             {
296               if (sectype != BFD_MACH_O_S_SYMBOL_STUBS)
297                 {
298                   as_bad (_("unexpected section size information"));
299                   ignore_rest_of_line ();
300                   return;
301                 }
302
303               input_line_pointer++;
304               sizeof_stub = get_absolute_expression ();
305             }
306           else if (secattr_given && sectype == BFD_MACH_O_S_SYMBOL_STUBS)
307             {
308               as_bad (_("missing sizeof_stub expression"));
309               ignore_rest_of_line ();
310               return;
311             }
312         }
313     }
314
315   flags = SEC_NO_FLAGS;
316   /* This provides default bfd flags and default mach-o section type and
317      attributes along with the canonical name.  */
318   xlat = bfd_mach_o_section_data_for_mach_sect (stdoutput, segname, sectname);
319   if (xlat != NULL)
320     {
321       name = xstrdup (xlat->bfd_name);
322       flags = xlat->bfd_flags;
323       defsectype = xlat->macho_sectype;
324       defsecattr = xlat->macho_secattr;
325       secalign = xlat->sectalign;
326     }
327   else
328     {
329       /* There is no normal BFD section name for this section.  Create one.
330          The name created doesn't really matter as it will never be written
331          on disk.  */
332       size_t seglen = strlen (segname);
333       size_t sectlen = strlen (sectname);
334       char *n;
335
336       n = xmalloc (seglen + 1 + sectlen + 1);
337       memcpy (n, segname, seglen);
338       n[seglen] = '.';
339       memcpy (n + seglen + 1, sectname, sectlen);
340       n[seglen + 1 + sectlen] = 0;
341       name = n;
342     }
343
344   /* Sub-segments don't exists as is on Mach-O.  */
345   sec = subseg_new (name, 0);
346
347   oldflags = bfd_get_section_flags (stdoutput, sec);
348   msect = bfd_mach_o_get_mach_o_section (sec);
349    if (oldflags == SEC_NO_FLAGS)
350     {
351       if (! bfd_set_section_flags (stdoutput, sec, flags))
352         as_warn (_("error setting flags for \"%s\": %s"),
353                  bfd_section_name (stdoutput, sec),
354                  bfd_errmsg (bfd_get_error ()));
355       strncpy (msect->segname, segname, sizeof (msect->segname));
356       msect->segname[16] = 0;
357       strncpy (msect->sectname, sectname, sizeof (msect->sectname));
358       msect->sectname[16] = 0;
359       msect->align = secalign;
360       if (sectype_given)
361         {
362           msect->flags = sectype;
363           if (secattr_given)
364             msect->flags |= secattr;
365           else
366             msect->flags |= defsecattr;
367         }
368       else
369         msect->flags = defsectype | defsecattr;
370       msect->reserved2 = sizeof_stub;
371     }
372   else if (flags != SEC_NO_FLAGS)
373     {
374       if (flags != oldflags
375           || msect->flags != (secattr | sectype))
376         as_warn (_("Ignoring changed section attributes for %s"), name);
377     }
378   demand_empty_rest_of_line ();
379 }
380
381 static segT 
382 obj_mach_o_segT_from_bfd_name (const char *nam, int must_succeed)
383 {
384   const mach_o_section_name_xlat *xlat;
385   const char *segn;
386   segT sec;
387
388   /* BFD has tables of flags and default attributes for all the sections that
389      have a 'canonical' name.  */
390   xlat = bfd_mach_o_section_data_for_bfd_name (stdoutput, nam, &segn);
391   if (xlat == NULL)
392     {
393       if (must_succeed)
394         as_fatal (_("BFD is out of sync with GAS, "
395                      "unhandled well-known section type `%s'"), nam);
396       return NULL;
397     }
398
399   sec = bfd_get_section_by_name (stdoutput, nam);
400   if (sec == NULL)
401     {
402       bfd_mach_o_section *msect;
403
404       sec = subseg_force_new (xlat->bfd_name, 0);
405
406       /* Set default type, attributes and alignment.  */
407       msect = bfd_mach_o_get_mach_o_section (sec);
408       msect->flags = xlat->macho_sectype | xlat->macho_secattr;
409       msect->align = xlat->sectalign;
410
411       if ((msect->flags & BFD_MACH_O_SECTION_TYPE_MASK) 
412           == BFD_MACH_O_S_ZEROFILL)
413         seg_info (sec)->bss = 1;
414     }
415
416   return sec;
417 }
418
419 static const char * const known_sections[] =
420 {
421   /*  0 */ NULL,
422   /* __TEXT */
423   /*  1 */ ".const",
424   /*  2 */ ".static_const",
425   /*  3 */ ".cstring",
426   /*  4 */ ".literal4",
427   /*  5 */ ".literal8",
428   /*  6 */ ".literal16",
429   /*  7 */ ".constructor",
430   /*  8 */ ".destructor",
431   /*  9 */ ".eh_frame",
432   /* __DATA */
433   /* 10 */ ".const_data",
434   /* 11 */ ".static_data",
435   /* 12 */ ".mod_init_func",
436   /* 13 */ ".mod_term_func",
437   /* 14 */ ".dyld",
438   /* 15 */ ".cfstring"
439 };
440
441 /* Interface for a known non-optional section directive.  */
442
443 static void
444 obj_mach_o_known_section (int sect_index)
445 {
446   segT section;
447
448 #ifdef md_flush_pending_output
449   md_flush_pending_output ();
450 #endif
451
452   section = obj_mach_o_segT_from_bfd_name (known_sections[sect_index], 1);
453   if (section != NULL)
454     subseg_set (section, 0);
455
456   /* else, we leave the section as it was; there was a fatal error anyway.  */
457 }
458
459 static const char * const objc_sections[] =
460 {
461   /*  0 */ NULL,
462   /*  1 */ ".objc_class",
463   /*  2 */ ".objc_meta_class",
464   /*  3 */ ".objc_cat_cls_meth",
465   /*  4 */ ".objc_cat_inst_meth",
466   /*  5 */ ".objc_protocol",
467   /*  6 */ ".objc_string_object",
468   /*  7 */ ".objc_cls_meth",
469   /*  8 */ ".objc_inst_meth",
470   /*  9 */ ".objc_cls_refs",
471   /* 10 */ ".objc_message_refs",
472   /* 11 */ ".objc_symbols",
473   /* 12 */ ".objc_category",
474   /* 13 */ ".objc_class_vars",
475   /* 14 */ ".objc_instance_vars",
476   /* 15 */ ".objc_module_info",
477   /* 16 */ ".cstring", /* objc_class_names Alias for .cstring */
478   /* 17 */ ".cstring", /* Alias objc_meth_var_types for .cstring */
479   /* 18 */ ".cstring", /* objc_meth_var_names Alias for .cstring */
480   /* 19 */ ".objc_selector_strs",
481   /* 20 */ ".objc_image_info", /* extension.  */
482   /* 21 */ ".objc_selector_fixup", /* extension.  */
483   /* 22 */ ".objc1_class_ext", /* ObjC-1 extension.  */
484   /* 23 */ ".objc1_property_list", /* ObjC-1 extension.  */
485   /* 24 */ ".objc1_protocol_ext" /* ObjC-1 extension.  */
486 };
487
488 /* This currently does the same as known_sections, but kept separate for
489    ease of maintenance.  */
490
491 static void
492 obj_mach_o_objc_section (int sect_index)
493 {
494   segT section;
495   
496 #ifdef md_flush_pending_output
497   md_flush_pending_output ();
498 #endif
499
500   section = obj_mach_o_segT_from_bfd_name (objc_sections[sect_index], 1);
501   if (section != NULL)
502     {
503       obj_mach_o_seen_objc_section = 1; /* We need to ensure that certain
504                                            sections are present and in the
505                                            right order.  */
506       subseg_set (section, 0);
507     }
508
509   /* else, we leave the section as it was; there was a fatal error anyway.  */
510 }
511
512 /* Debug section directives.  */
513
514 static const char * const debug_sections[] =
515 {
516   /*  0 */ NULL,
517   /* __DWARF */
518   /*  1 */ ".debug_frame",
519   /*  2 */ ".debug_info",
520   /*  3 */ ".debug_abbrev",
521   /*  4 */ ".debug_aranges",
522   /*  5 */ ".debug_macinfo",
523   /*  6 */ ".debug_line",
524   /*  7 */ ".debug_loc",
525   /*  8 */ ".debug_pubnames",
526   /*  9 */ ".debug_pubtypes",
527   /* 10 */ ".debug_str",
528   /* 11 */ ".debug_ranges",
529   /* 12 */ ".debug_macro"
530 };
531
532 /* ??? Maybe these should be conditional on gdwarf-*.
533    It`s also likely that we will need to be able to set them from the cfi
534    code.  */
535
536 static void
537 obj_mach_o_debug_section (int sect_index)
538 {
539   segT section;
540
541 #ifdef md_flush_pending_output
542   md_flush_pending_output ();
543 #endif
544
545   section = obj_mach_o_segT_from_bfd_name (debug_sections[sect_index], 1);
546   if (section != NULL)
547     subseg_set (section, 0);
548
549   /* else, we leave the section as it was; there was a fatal error anyway.  */
550 }
551
552 /* This could be moved to the tc-xx files, but there is so little dependency
553    there, that the code might as well be shared.  */
554
555 struct opt_tgt_sect 
556 {
557  const char *name;
558  unsigned x86_val;
559  unsigned ppc_val;
560 };
561
562 /* The extensions here are for specific sections that are generated by GCC
563    and Darwin system tools, but don't have directives in the `system as'.  */
564
565 static const struct opt_tgt_sect tgt_sections[] =
566 {
567   /*  0 */ { NULL, 0, 0},
568   /*  1 */ { ".lazy_symbol_pointer", 0, 0},
569   /*  2 */ { ".lazy_symbol_pointer2", 0, 0}, /* X86 - extension */
570   /*  3 */ { ".lazy_symbol_pointer3", 0, 0}, /* X86 - extension */
571   /*  4 */ { ".non_lazy_symbol_pointer", 0, 0},
572   /*  5 */ { ".non_lazy_symbol_pointer_x86", 0, 0}, /* X86 - extension */
573   /*  6 */ { ".symbol_stub", 16, 20},
574   /*  7 */ { ".symbol_stub1", 0, 16}, /* PPC - extension */
575   /*  8 */ { ".picsymbol_stub", 26, 36},
576   /*  9 */ { ".picsymbol_stub1", 0, 32}, /* PPC - extension */
577   /* 10 */ { ".picsymbol_stub2", 25, 0}, /* X86 - extension */
578   /* 11 */ { ".picsymbol_stub3", 5, 0}, /* X86 - extension  */
579 };
580
581 /* Interface for an optional section directive.  */
582
583 static void
584 obj_mach_o_opt_tgt_section (int sect_index)
585 {
586   const struct opt_tgt_sect *tgtsct = &tgt_sections[sect_index];
587   segT section;
588
589 #ifdef md_flush_pending_output
590   md_flush_pending_output ();
591 #endif
592
593   section = obj_mach_o_segT_from_bfd_name (tgtsct->name, 0);
594   if (section == NULL)
595     {
596       as_bad (_("%s is not used for the selected target"), tgtsct->name);
597       /* Leave the section as it is.  */
598     }
599   else
600     {
601       bfd_mach_o_section *mo_sec = bfd_mach_o_get_mach_o_section (section);
602       subseg_set (section, 0);
603 #if defined (TC_I386)
604       mo_sec->reserved2 = tgtsct->x86_val;
605 #elif defined (TC_PPC)
606       mo_sec->reserved2 = tgtsct->ppc_val;
607 #else
608       mo_sec->reserved2 = 0;
609 #endif
610     }
611 }
612
613 /* We don't necessarily have the three 'base' sections on mach-o.
614    Normally, we would start up with only the 'text' section defined.
615    However, even that can be suppressed with (TODO) c/l option "-n".
616    Thus, we have to be able to create all three sections on-demand.  */
617
618 static void
619 obj_mach_o_base_section (int sect_index)
620 {
621   segT section;
622
623 #ifdef md_flush_pending_output
624   md_flush_pending_output ();
625 #endif
626
627   /* We don't support numeric (or any other) qualifications on the
628      well-known section shorthands.  */
629   demand_empty_rest_of_line ();
630
631   switch (sect_index)
632     {
633       /* Handle the three sections that are globally known within GAS.
634          For Mach-O, these are created on demand rather than at startup.  */
635       case 1:
636         if (text_section == NULL)
637           text_section = obj_mach_o_segT_from_bfd_name (TEXT_SECTION_NAME, 1);
638         if (obj_mach_o_is_static)
639           {
640             bfd_mach_o_section *mo_sec
641                 = bfd_mach_o_get_mach_o_section (text_section);
642             mo_sec->flags &= ~BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS;
643           }
644         section = text_section;
645         break;
646       case 2:
647         if (data_section == NULL)
648           data_section = obj_mach_o_segT_from_bfd_name (DATA_SECTION_NAME, 1);
649         section = data_section;
650         break;
651       case 3:
652         /* ??? maybe this achieves very little, as an addition.  */
653         if (bss_section == NULL)
654           {
655             bss_section = obj_mach_o_segT_from_bfd_name (BSS_SECTION_NAME, 1);
656             seg_info (bss_section)->bss = 1;
657           }
658         section = bss_section;
659         break;
660       default:
661         as_fatal (_("internal error: base section index out of range"));
662         return;
663         break;
664     }
665   subseg_set (section, 0);
666 }
667
668 /* This finishes off parsing a .comm or .lcomm statement, which both can have
669    an (optional) alignment field.  It also allows us to create the bss section
670    on demand.  */
671
672 static symbolS *
673 obj_mach_o_common_parse (int is_local, symbolS *symbolP,
674                          addressT size)
675 {
676   addressT align = 0;
677
678   /* Both comm and lcomm take an optional alignment, as a power
679      of two between 1 and 15.  */
680   if (*input_line_pointer == ',')
681     {
682       /* We expect a power of 2.  */
683       align = parse_align (0);
684       if (align == (addressT) -1)
685         return NULL;
686       if (align > 15)
687         {
688           as_warn (_("Alignment (%lu) too large: 15 assumed."),
689                   (unsigned long)align);
690           align = 15;
691         }
692     }
693
694   if (is_local)
695     {
696       /* Create the BSS section on demand.  */
697       if (bss_section == NULL)
698         {
699           bss_section = obj_mach_o_segT_from_bfd_name (BSS_SECTION_NAME, 1);
700           seg_info (bss_section)->bss = 1;        
701         }
702       bss_alloc (symbolP, size, align);
703       S_CLEAR_EXTERNAL (symbolP);
704     }
705   else
706     {
707       S_SET_VALUE (symbolP, size);
708       S_SET_ALIGN (symbolP, align);
709       S_SET_EXTERNAL (symbolP);
710       S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
711     }
712
713   symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
714
715   return symbolP;
716 }
717
718 static void
719 obj_mach_o_comm (int is_local)
720 {
721   s_comm_internal (is_local, obj_mach_o_common_parse);
722 }
723
724 /* Set properties that apply to the whole file.  At present, the only
725    one defined, is subsections_via_symbols.  */
726
727 typedef enum obj_mach_o_file_properties {
728   OBJ_MACH_O_FILE_PROP_NONE = 0,
729   OBJ_MACH_O_FILE_PROP_SUBSECTS_VIA_SYMS,
730   OBJ_MACH_O_FILE_PROP_MAX
731 } obj_mach_o_file_properties;
732
733 static void 
734 obj_mach_o_fileprop (int prop)
735 {
736   if (prop < 0 || prop >= OBJ_MACH_O_FILE_PROP_MAX)
737     as_fatal (_("internal error: bad file property ID %d"), prop);
738     
739   switch ((obj_mach_o_file_properties) prop)
740     {
741       case OBJ_MACH_O_FILE_PROP_SUBSECTS_VIA_SYMS:
742         obj_mach_o_subsections_by_symbols = 1;
743         if (!bfd_set_private_flags (stdoutput, 
744                                     BFD_MACH_O_MH_SUBSECTIONS_VIA_SYMBOLS))
745           as_bad (_("failed to set subsections by symbols"));
746         demand_empty_rest_of_line ();
747         break;
748       default:
749         break;
750     }
751 }
752
753 /* Dummy function to allow test-code to work while we are working
754    on things.  */
755
756 static void
757 obj_mach_o_placeholder (int arg ATTRIBUTE_UNUSED)
758 {
759   ignore_rest_of_line ();
760 }
761
762 const pseudo_typeS mach_o_pseudo_table[] =
763 {
764   /* Section directives.  */
765   { "comm", obj_mach_o_comm, 0 },
766   { "lcomm", obj_mach_o_comm, 1 },
767
768   { "text", obj_mach_o_base_section, 1},
769   { "data", obj_mach_o_base_section, 2},
770   { "bss", obj_mach_o_base_section, 3},   /* extension */
771
772   { "const", obj_mach_o_known_section, 1},
773   { "static_const", obj_mach_o_known_section, 2},
774   { "cstring", obj_mach_o_known_section, 3},
775   { "literal4", obj_mach_o_known_section, 4},
776   { "literal8", obj_mach_o_known_section, 5},
777   { "literal16", obj_mach_o_known_section, 6},
778   { "constructor", obj_mach_o_known_section, 7},
779   { "destructor", obj_mach_o_known_section, 8},
780   { "eh_frame", obj_mach_o_known_section, 9},
781
782   { "const_data", obj_mach_o_known_section, 10},
783   { "static_data", obj_mach_o_known_section, 11},
784   { "mod_init_func", obj_mach_o_known_section, 12},
785   { "mod_term_func", obj_mach_o_known_section, 13},
786   { "dyld", obj_mach_o_known_section, 14},
787   { "cfstring", obj_mach_o_known_section, 15},
788
789   { "objc_class", obj_mach_o_objc_section, 1},
790   { "objc_meta_class", obj_mach_o_objc_section, 2},
791   { "objc_cat_cls_meth", obj_mach_o_objc_section, 3},
792   { "objc_cat_inst_meth", obj_mach_o_objc_section, 4},
793   { "objc_protocol", obj_mach_o_objc_section, 5},
794   { "objc_string_object", obj_mach_o_objc_section, 6},
795   { "objc_cls_meth", obj_mach_o_objc_section, 7},
796   { "objc_inst_meth", obj_mach_o_objc_section, 8},
797   { "objc_cls_refs", obj_mach_o_objc_section, 9},
798   { "objc_message_refs", obj_mach_o_objc_section, 10},
799   { "objc_symbols", obj_mach_o_objc_section, 11},
800   { "objc_category", obj_mach_o_objc_section, 12},
801   { "objc_class_vars", obj_mach_o_objc_section, 13},
802   { "objc_instance_vars", obj_mach_o_objc_section, 14},
803   { "objc_module_info", obj_mach_o_objc_section, 15},
804   { "objc_class_names", obj_mach_o_objc_section, 16}, /* Alias for .cstring */
805   { "objc_meth_var_types", obj_mach_o_objc_section, 17}, /* Alias for .cstring */
806   { "objc_meth_var_names", obj_mach_o_objc_section, 18}, /* Alias for .cstring */
807   { "objc_selector_strs", obj_mach_o_objc_section, 19},
808   { "objc_image_info", obj_mach_o_objc_section, 20}, /* extension.  */
809   { "objc_selector_fixup", obj_mach_o_objc_section, 21}, /* extension.  */
810   { "objc1_class_ext", obj_mach_o_objc_section, 22}, /* ObjC-1 extension.  */
811   { "objc1_property_list", obj_mach_o_objc_section, 23}, /* ObjC-1 extension.  */
812   { "objc1_protocol_ext", obj_mach_o_objc_section, 24}, /* ObjC-1 extension.  */
813
814   { "debug_frame", obj_mach_o_debug_section, 1}, /* extension.  */
815   { "debug_info", obj_mach_o_debug_section, 2}, /* extension.  */
816   { "debug_abbrev", obj_mach_o_debug_section, 3}, /* extension.  */
817   { "debug_aranges", obj_mach_o_debug_section, 4}, /* extension.  */
818   { "debug_macinfo", obj_mach_o_debug_section, 5}, /* extension.  */
819   { "debug_line", obj_mach_o_debug_section, 6}, /* extension.  */
820   { "debug_loc", obj_mach_o_debug_section, 7}, /* extension.  */
821   { "debug_pubnames", obj_mach_o_debug_section, 8}, /* extension.  */
822   { "debug_pubtypes", obj_mach_o_debug_section, 9}, /* extension.  */
823   { "debug_str", obj_mach_o_debug_section, 10}, /* extension.  */
824   { "debug_ranges", obj_mach_o_debug_section, 11}, /* extension.  */
825   { "debug_macro", obj_mach_o_debug_section, 12}, /* extension.  */
826   
827   { "lazy_symbol_pointer", obj_mach_o_opt_tgt_section, 1},
828   { "lazy_symbol_pointer2", obj_mach_o_opt_tgt_section, 2}, /* extension.  */
829   { "lazy_symbol_pointer3", obj_mach_o_opt_tgt_section, 3}, /* extension.  */
830   { "non_lazy_symbol_pointer", obj_mach_o_opt_tgt_section, 4},
831   { "non_lazy_symbol_pointer_x86", obj_mach_o_opt_tgt_section, 5}, /* extension.  */
832   { "symbol_stub", obj_mach_o_opt_tgt_section, 6},
833   { "symbol_stub1", obj_mach_o_opt_tgt_section, 7}, /* extension.  */
834   { "picsymbol_stub", obj_mach_o_opt_tgt_section, 8}, /* extension.  */
835   { "picsymbol_stub1", obj_mach_o_opt_tgt_section, 9}, /* extension.  */
836   { "picsymbol_stub2", obj_mach_o_opt_tgt_section, 4}, /* extension.  */
837   { "picsymbol_stub3", obj_mach_o_opt_tgt_section, 4}, /* extension.  */
838
839   { "section", obj_mach_o_section, 0},
840
841   /* Symbol-related.  */
842   { "indirect_symbol", obj_mach_o_placeholder, 0},
843   { "weak_definition", obj_mach_o_placeholder, 0},
844   { "private_extern", obj_mach_o_placeholder, 0},
845   { "weak", obj_mach_o_weak, 0},   /* extension */
846
847   /* File flags.  */
848   { "subsections_via_symbols", obj_mach_o_fileprop, 
849                                OBJ_MACH_O_FILE_PROP_SUBSECTS_VIA_SYMS},
850
851   {NULL, NULL, 0}
852 };
853
854 /* Support stabs for mach-o.  */
855
856 void
857 obj_mach_o_process_stab (int what, const char *string,
858                          int type, int other, int desc)
859 {
860   symbolS *symbolP;
861   bfd_mach_o_asymbol *s;
862
863   switch (what)
864     {
865       case 'd':
866         symbolP = symbol_new ("", now_seg, frag_now_fix (), frag_now);
867         /* Special stabd NULL name indicator.  */
868         S_SET_NAME (symbolP, NULL);
869         break;
870
871       case 'n':
872       case 's':
873         symbolP = symbol_new (string, undefined_section, (valueT) 0,
874                               &zero_address_frag);
875         pseudo_set (symbolP);
876         break;
877
878       default:
879         as_bad(_("unrecognized stab type '%c'"), (char)what);
880         abort ();
881         break;
882     }
883
884   s = (bfd_mach_o_asymbol *) symbol_get_bfdsym (symbolP);
885   s->n_type = type;
886   s->n_desc = desc;
887   /* For stabd, this will eventually get overwritten by the section number.  */
888   s->n_sect = other;
889
890   /* It's a debug symbol.  */
891   s->symbol.flags |= BSF_DEBUGGING;
892 }