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