]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - contrib/binutils/gas/config/obj-aout.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / contrib / binutils / gas / config / obj-aout.c
1 /* a.out object file format
2    Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000,
3    2001, 2002 Free Software Foundation, Inc.
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2,
10 or (at your option) any later version.
11
12 GAS is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15 the GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 #define OBJ_HEADER "obj-aout.h"
23
24 #include "as.h"
25 #ifdef BFD_ASSEMBLER
26 #undef NO_RELOC
27 #include "aout/aout64.h"
28 #endif
29 #include "obstack.h"
30
31 #ifndef BFD_ASSEMBLER
32 /* in: segT   out: N_TYPE bits */
33 const short seg_N_TYPE[] =
34 {
35   N_ABS,
36   N_TEXT,
37   N_DATA,
38   N_BSS,
39   N_UNDF,                       /* unknown */
40   N_UNDF,                       /* error */
41   N_UNDF,                       /* expression */
42   N_UNDF,                       /* debug */
43   N_UNDF,                       /* ntv */
44   N_UNDF,                       /* ptv */
45   N_REGISTER,                   /* register */
46 };
47
48 const segT N_TYPE_seg[N_TYPE + 2] =
49 {                               /* N_TYPE == 0x1E = 32-2 */
50   SEG_UNKNOWN,                  /* N_UNDF == 0 */
51   SEG_GOOF,
52   SEG_ABSOLUTE,                 /* N_ABS == 2 */
53   SEG_GOOF,
54   SEG_TEXT,                     /* N_TEXT == 4 */
55   SEG_GOOF,
56   SEG_DATA,                     /* N_DATA == 6 */
57   SEG_GOOF,
58   SEG_BSS,                      /* N_BSS == 8 */
59   SEG_GOOF,
60   SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
61   SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
62   SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
63   SEG_REGISTER,                 /* dummy N_REGISTER for regs = 30 */
64   SEG_GOOF,
65 };
66 #endif
67
68 static void obj_aout_line PARAMS ((int));
69 static void obj_aout_weak PARAMS ((int));
70 static void obj_aout_type PARAMS ((int));
71
72 const pseudo_typeS aout_pseudo_table[] =
73 {
74   {"line", obj_aout_line, 0},   /* source code line number */
75   {"ln", obj_aout_line, 0},     /* coff line number that we use anyway */
76
77   {"weak", obj_aout_weak, 0},   /* mark symbol as weak.  */
78
79   {"type", obj_aout_type, 0},
80
81   /* coff debug pseudos (ignored) */
82   {"def", s_ignore, 0},
83   {"dim", s_ignore, 0},
84   {"endef", s_ignore, 0},
85   {"ident", s_ignore, 0},
86   {"line", s_ignore, 0},
87   {"ln", s_ignore, 0},
88   {"scl", s_ignore, 0},
89   {"size", s_ignore, 0},
90   {"tag", s_ignore, 0},
91   {"val", s_ignore, 0},
92   {"version", s_ignore, 0},
93
94   {"optim", s_ignore, 0},       /* For sun386i cc (?) */
95
96   /* other stuff */
97   {"ABORT", s_abort, 0},
98
99   {NULL, NULL, 0}               /* end sentinel */
100 };                              /* aout_pseudo_table */
101
102 #ifdef BFD_ASSEMBLER
103
104 void
105 obj_aout_frob_symbol (sym, punt)
106      symbolS *sym;
107      int *punt ATTRIBUTE_UNUSED;
108 {
109   flagword flags;
110   asection *sec;
111   int desc, type, other;
112
113   flags = symbol_get_bfdsym (sym)->flags;
114   desc = aout_symbol (symbol_get_bfdsym (sym))->desc;
115   type = aout_symbol (symbol_get_bfdsym (sym))->type;
116   other = aout_symbol (symbol_get_bfdsym (sym))->other;
117   sec = S_GET_SEGMENT (sym);
118
119   /* Only frob simple symbols this way right now.  */
120   if (! (type & ~ (N_TYPE | N_EXT)))
121     {
122       if (type == (N_UNDF | N_EXT)
123           && sec == &bfd_abs_section)
124         {
125           sec = bfd_und_section_ptr;
126           S_SET_SEGMENT (sym, sec);
127         }
128
129       if ((type & N_TYPE) != N_INDR
130           && (type & N_TYPE) != N_SETA
131           && (type & N_TYPE) != N_SETT
132           && (type & N_TYPE) != N_SETD
133           && (type & N_TYPE) != N_SETB
134           && type != N_WARNING
135           && (sec == &bfd_abs_section
136               || sec == &bfd_und_section))
137         return;
138       if (flags & BSF_EXPORT)
139         type |= N_EXT;
140
141       switch (type & N_TYPE)
142         {
143         case N_SETA:
144         case N_SETT:
145         case N_SETD:
146         case N_SETB:
147           /* Set the debugging flag for constructor symbols so that
148              BFD leaves them alone.  */
149           symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
150
151           /* You can't put a common symbol in a set.  The way a set
152              element works is that the symbol has a definition and a
153              name, and the linker adds the definition to the set of
154              that name.  That does not work for a common symbol,
155              because the linker can't tell which common symbol the
156              user means.  FIXME: Using as_bad here may be
157              inappropriate, since the user may want to force a
158              particular type without regard to the semantics of sets;
159              on the other hand, we certainly don't want anybody to be
160              mislead into thinking that their code will work.  */
161           if (S_IS_COMMON (sym))
162             as_bad (_("Attempt to put a common symbol into set %s"),
163                     S_GET_NAME (sym));
164           /* Similarly, you can't put an undefined symbol in a set.  */
165           else if (! S_IS_DEFINED (sym))
166             as_bad (_("Attempt to put an undefined symbol into set %s"),
167                     S_GET_NAME (sym));
168
169           break;
170         case N_INDR:
171           /* Put indirect symbols in the indirect section.  */
172           S_SET_SEGMENT (sym, bfd_ind_section_ptr);
173           symbol_get_bfdsym (sym)->flags |= BSF_INDIRECT;
174           if (type & N_EXT)
175             {
176               symbol_get_bfdsym (sym)->flags |= BSF_EXPORT;
177               symbol_get_bfdsym (sym)->flags &=~ BSF_LOCAL;
178             }
179           break;
180         case N_WARNING:
181           /* Mark warning symbols.  */
182           symbol_get_bfdsym (sym)->flags |= BSF_WARNING;
183           break;
184         }
185     }
186   else
187     {
188       symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
189     }
190
191   aout_symbol (symbol_get_bfdsym (sym))->type = type;
192
193   /* Double check weak symbols.  */
194   if (S_IS_WEAK (sym))
195     {
196       if (S_IS_COMMON (sym))
197         as_bad (_("Symbol `%s' can not be both weak and common"),
198                 S_GET_NAME (sym));
199     }
200 }
201
202 void
203 obj_aout_frob_file_before_fix ()
204 {
205   /* Relocation processing may require knowing the VMAs of the sections.
206      Since writing to a section will cause the BFD back end to compute the
207      VMAs, fake it out here....  */
208   bfd_byte b = 0;
209   bfd_boolean x = TRUE;
210   if (bfd_section_size (stdoutput, text_section) != 0)
211     {
212       x = bfd_set_section_contents (stdoutput, text_section, &b, (file_ptr) 0,
213                                     (bfd_size_type) 1);
214     }
215   else if (bfd_section_size (stdoutput, data_section) != 0)
216     {
217       x = bfd_set_section_contents (stdoutput, data_section, &b, (file_ptr) 0,
218                                     (bfd_size_type) 1);
219     }
220   assert (x);
221 }
222
223 #else /* ! BFD_ASSEMBLER */
224
225 /* Relocation.  */
226
227 /*
228  *              emit_relocations()
229  *
230  * Crawl along a fixS chain. Emit the segment's relocations.
231  */
232 void
233 obj_emit_relocations (where, fixP, segment_address_in_file)
234      char **where;
235      fixS *fixP;                /* Fixup chain for this segment.  */
236      relax_addressT segment_address_in_file;
237 {
238   for (; fixP; fixP = fixP->fx_next)
239     if (fixP->fx_done == 0)
240       {
241         symbolS *sym;
242
243         sym = fixP->fx_addsy;
244         while (sym->sy_value.X_op == O_symbol
245                && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
246           sym = sym->sy_value.X_add_symbol;
247         fixP->fx_addsy = sym;
248
249         if (! sym->sy_resolved && ! S_IS_DEFINED (sym))
250           {
251             char *file;
252             unsigned int line;
253
254             if (expr_symbol_where (sym, &file, &line))
255               as_bad_where (file, line, _("unresolved relocation"));
256             else
257               as_bad (_("bad relocation: symbol `%s' not in symbol table"),
258                       S_GET_NAME (sym));
259           }
260
261         tc_aout_fix_to_chars (*where, fixP, segment_address_in_file);
262         *where += md_reloc_size;
263       }
264 }
265
266 #ifndef obj_header_append
267 /* Aout file generation & utilities */
268 void
269 obj_header_append (where, headers)
270      char **where;
271      object_headers *headers;
272 {
273   tc_headers_hook (headers);
274
275 #ifdef CROSS_COMPILE
276   md_number_to_chars (*where, headers->header.a_info, sizeof (headers->header.a_info));
277   *where += sizeof (headers->header.a_info);
278   md_number_to_chars (*where, headers->header.a_text, sizeof (headers->header.a_text));
279   *where += sizeof (headers->header.a_text);
280   md_number_to_chars (*where, headers->header.a_data, sizeof (headers->header.a_data));
281   *where += sizeof (headers->header.a_data);
282   md_number_to_chars (*where, headers->header.a_bss, sizeof (headers->header.a_bss));
283   *where += sizeof (headers->header.a_bss);
284   md_number_to_chars (*where, headers->header.a_syms, sizeof (headers->header.a_syms));
285   *where += sizeof (headers->header.a_syms);
286   md_number_to_chars (*where, headers->header.a_entry, sizeof (headers->header.a_entry));
287   *where += sizeof (headers->header.a_entry);
288   md_number_to_chars (*where, headers->header.a_trsize, sizeof (headers->header.a_trsize));
289   *where += sizeof (headers->header.a_trsize);
290   md_number_to_chars (*where, headers->header.a_drsize, sizeof (headers->header.a_drsize));
291   *where += sizeof (headers->header.a_drsize);
292
293 #else /* CROSS_COMPILE */
294
295   append (where, (char *) &headers->header, sizeof (headers->header));
296 #endif /* CROSS_COMPILE */
297
298 }
299 #endif /* ! defined (obj_header_append) */
300
301 void
302 obj_symbol_to_chars (where, symbolP)
303      char **where;
304      symbolS *symbolP;
305 {
306   md_number_to_chars ((char *) &(S_GET_OFFSET (symbolP)), S_GET_OFFSET (symbolP), sizeof (S_GET_OFFSET (symbolP)));
307   md_number_to_chars ((char *) &(S_GET_DESC (symbolP)), S_GET_DESC (symbolP), sizeof (S_GET_DESC (symbolP)));
308   md_number_to_chars ((char *) &(symbolP->sy_symbol.n_value), S_GET_VALUE (symbolP), sizeof (symbolP->sy_symbol.n_value));
309
310   append (where, (char *) &symbolP->sy_symbol, sizeof (obj_symbol_type));
311 }
312
313 void
314 obj_emit_symbols (where, symbol_rootP)
315      char **where;
316      symbolS *symbol_rootP;
317 {
318   symbolS *symbolP;
319
320   /* Emit all symbols left in the symbol chain.  */
321   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
322     {
323       /* Used to save the offset of the name. It is used to point
324          to the string in memory but must be a file offset.  */
325       register char *temp;
326
327       temp = S_GET_NAME (symbolP);
328       S_SET_OFFSET (symbolP, symbolP->sy_name_offset);
329
330       /* Any symbol still undefined and is not a dbg symbol is made N_EXT.  */
331       if (!S_IS_DEBUG (symbolP) && !S_IS_DEFINED (symbolP))
332         S_SET_EXTERNAL (symbolP);
333
334       /* Adjust the type of a weak symbol.  */
335       if (S_GET_WEAK (symbolP))
336         {
337           switch (S_GET_TYPE (symbolP))
338             {
339             case N_UNDF: S_SET_TYPE (symbolP, N_WEAKU); break;
340             case N_ABS:  S_SET_TYPE (symbolP, N_WEAKA); break;
341             case N_TEXT: S_SET_TYPE (symbolP, N_WEAKT); break;
342             case N_DATA: S_SET_TYPE (symbolP, N_WEAKD); break;
343             case N_BSS:  S_SET_TYPE (symbolP, N_WEAKB); break;
344             default: as_bad (_("%s: bad type for weak symbol"), temp); break;
345             }
346         }
347
348       obj_symbol_to_chars (where, symbolP);
349       S_SET_NAME (symbolP, temp);
350     }
351 }
352
353 #endif /* ! BFD_ASSEMBLER */
354
355 static void
356 obj_aout_line (ignore)
357      int ignore ATTRIBUTE_UNUSED;
358 {
359   /* Assume delimiter is part of expression.
360      BSD4.2 as fails with delightful bug, so we
361      are not being incompatible here.  */
362   new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
363   demand_empty_rest_of_line ();
364 }                               /* obj_aout_line() */
365
366 /* Handle .weak.  This is a GNU extension.  */
367
368 static void
369 obj_aout_weak (ignore)
370      int ignore ATTRIBUTE_UNUSED;
371 {
372   char *name;
373   int c;
374   symbolS *symbolP;
375
376   do
377     {
378       name = input_line_pointer;
379       c = get_symbol_end ();
380       symbolP = symbol_find_or_make (name);
381       *input_line_pointer = c;
382       SKIP_WHITESPACE ();
383       S_SET_WEAK (symbolP);
384       if (c == ',')
385         {
386           input_line_pointer++;
387           SKIP_WHITESPACE ();
388           if (*input_line_pointer == '\n')
389             c = '\n';
390         }
391     }
392   while (c == ',');
393   demand_empty_rest_of_line ();
394 }
395
396 /* Handle .type.  On {Net,Open}BSD, this is used to set the n_other field,
397    which is then apparently used when doing dynamic linking.  Older
398    versions of gas ignored the .type pseudo-op, so we also ignore it if
399    we can't parse it.  */
400
401 static void
402 obj_aout_type (ignore)
403      int ignore ATTRIBUTE_UNUSED;
404 {
405   char *name;
406   int c;
407   symbolS *sym;
408
409   name = input_line_pointer;
410   c = get_symbol_end ();
411   sym = symbol_find_or_make (name);
412   *input_line_pointer = c;
413   SKIP_WHITESPACE ();
414   if (*input_line_pointer == ',')
415     {
416       ++input_line_pointer;
417       SKIP_WHITESPACE ();
418       if (*input_line_pointer == '@')
419         {
420           ++input_line_pointer;
421           if (strncmp (input_line_pointer, "object", 6) == 0)
422 #ifdef BFD_ASSEMBLER
423             aout_symbol (symbol_get_bfdsym (sym))->other = 1;
424 #else
425           S_SET_OTHER (sym, 1);
426 #endif
427           else if (strncmp (input_line_pointer, "function", 8) == 0)
428 #ifdef BFD_ASSEMBLER
429             aout_symbol (symbol_get_bfdsym (sym))->other = 2;
430 #else
431           S_SET_OTHER (sym, 2);
432 #endif
433         }
434     }
435
436   /* Ignore everything else on the line.  */
437   s_ignore (0);
438 }
439
440 #ifndef BFD_ASSEMBLER
441
442 void
443 obj_crawl_symbol_chain (headers)
444      object_headers *headers;
445 {
446   symbolS *symbolP;
447   symbolS **symbolPP;
448   int symbol_number = 0;
449
450   tc_crawl_symbol_chain (headers);
451
452   symbolPP = &symbol_rootP;     /*->last symbol chain link.  */
453   while ((symbolP = *symbolPP) != NULL)
454     {
455       if (symbolP->sy_mri_common)
456         {
457           if (S_IS_EXTERNAL (symbolP))
458             as_bad (_("%s: global symbols not supported in common sections"),
459                     S_GET_NAME (symbolP));
460           *symbolPP = symbol_next (symbolP);
461           continue;
462         }
463
464       if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_DATA))
465         {
466           S_SET_SEGMENT (symbolP, SEG_TEXT);
467         }                       /* if pushing data into text */
468
469       resolve_symbol_value (symbolP);
470
471       /* Skip symbols which were equated to undefined or common
472          symbols.  Also skip defined uncommon symbols which can
473          be resolved since in this case they should have been
474          resolved to a non-symbolic constant.  */
475       if (symbolP->sy_value.X_op == O_symbol
476           && (! S_IS_DEFINED (symbolP)
477               || S_IS_COMMON (symbolP)
478               || symbol_resolved_p (symbolP)))
479         {
480           *symbolPP = symbol_next (symbolP);
481           continue;
482         }
483
484       /* OK, here is how we decide which symbols go out into the brave
485          new symtab.  Symbols that do are:
486
487          * symbols with no name (stabd's?)
488          * symbols with debug info in their N_TYPE
489
490          Symbols that don't are:
491          * symbols that are registers
492          * symbols with \1 as their 3rd character (numeric labels)
493          * "local labels" as defined by S_LOCAL_NAME(name) if the -L
494          switch was passed to gas.
495
496          All other symbols are output.  We complain if a deleted
497          symbol was marked external.  */
498
499       if (!S_IS_REGISTER (symbolP)
500           && (!S_GET_NAME (symbolP)
501               || S_IS_DEBUG (symbolP)
502               || !S_IS_DEFINED (symbolP)
503               || S_IS_EXTERNAL (symbolP)
504               || (S_GET_NAME (symbolP)[0] != '\001'
505                   && (flag_keep_locals || !S_LOCAL_NAME (symbolP)))))
506         {
507           symbolP->sy_number = symbol_number++;
508
509           /* The + 1 after strlen account for the \0 at the
510                            end of each string */
511           if (!S_IS_STABD (symbolP))
512             {
513               /* Ordinary case.  */
514               symbolP->sy_name_offset = string_byte_count;
515               string_byte_count += strlen (S_GET_NAME (symbolP)) + 1;
516             }
517           else                  /* .Stabd case.  */
518             symbolP->sy_name_offset = 0;
519           symbolPP = &symbolP->sy_next;
520         }
521       else
522         {
523           if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP))
524             /* This warning should never get triggered any more.
525                Well, maybe if you're doing twisted things with
526                register names...  */
527             {
528               as_bad (_("Local symbol %s never defined."), decode_local_label_name (S_GET_NAME (symbolP)));
529             }                   /* oops.  */
530
531           /* Unhook it from the chain */
532           *symbolPP = symbol_next (symbolP);
533         }                       /* if this symbol should be in the output */
534     }                           /* for each symbol */
535
536   H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number);
537 }
538
539 /*
540  * Find strings by crawling along symbol table chain.
541  */
542
543 void
544 obj_emit_strings (where)
545      char **where;
546 {
547   symbolS *symbolP;
548
549 #ifdef CROSS_COMPILE
550   /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
551   md_number_to_chars (*where, string_byte_count, sizeof (string_byte_count));
552   *where += sizeof (string_byte_count);
553 #else /* CROSS_COMPILE */
554   append (where, (char *) &string_byte_count, (unsigned long) sizeof (string_byte_count));
555 #endif /* CROSS_COMPILE */
556
557   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
558     {
559       if (S_GET_NAME (symbolP))
560         append (&next_object_file_charP, S_GET_NAME (symbolP),
561                 (unsigned long) (strlen (S_GET_NAME (symbolP)) + 1));
562     }                           /* walk symbol chain */
563 }
564
565 #ifndef AOUT_VERSION
566 #define AOUT_VERSION 0
567 #endif
568
569 void
570 obj_pre_write_hook (headers)
571      object_headers *headers;
572 {
573   H_SET_DYNAMIC (headers, 0);
574   H_SET_VERSION (headers, AOUT_VERSION);
575   H_SET_MACHTYPE (headers, AOUT_MACHTYPE);
576   tc_aout_pre_write_hook (headers);
577 }
578
579 #endif /* ! BFD_ASSEMBLER */
580
581 #ifdef BFD_ASSEMBLER
582
583 /* Support for an AOUT emulation.  */
584
585 static void aout_pop_insert PARAMS ((void));
586 static int obj_aout_s_get_other PARAMS ((symbolS *));
587 static void obj_aout_s_set_other PARAMS ((symbolS *, int));
588 static int obj_aout_s_get_desc PARAMS ((symbolS *));
589 static void obj_aout_s_set_desc PARAMS ((symbolS *, int));
590 static int obj_aout_s_get_type PARAMS ((symbolS *));
591 static void obj_aout_s_set_type PARAMS ((symbolS *, int));
592 static int obj_aout_separate_stab_sections PARAMS ((void));
593 static int obj_aout_sec_sym_ok_for_reloc PARAMS ((asection *));
594 static void obj_aout_process_stab PARAMS ((segT, int, const char *, int, int, int));
595
596 static void
597 aout_pop_insert ()
598 {
599   pop_insert (aout_pseudo_table);
600 }
601
602 static int
603 obj_aout_s_get_other (sym)
604      symbolS *sym;
605 {
606   return aout_symbol (symbol_get_bfdsym (sym))->other;
607 }
608
609 static void
610 obj_aout_s_set_other (sym, o)
611      symbolS *sym;
612      int o;
613 {
614   aout_symbol (symbol_get_bfdsym (sym))->other = o;
615 }
616
617 static int
618 obj_aout_sec_sym_ok_for_reloc (sec)
619      asection *sec ATTRIBUTE_UNUSED;
620 {
621   return obj_sec_sym_ok_for_reloc (sec);
622 }
623
624 static void
625 obj_aout_process_stab (seg, w, s, t, o, d)
626      segT seg ATTRIBUTE_UNUSED;
627      int w;
628      const char *s;
629      int t;
630      int o;
631      int d;
632 {
633   aout_process_stab (w, s, t, o, d);
634 }
635
636 static int
637 obj_aout_s_get_desc (sym)
638      symbolS *sym;
639 {
640   return aout_symbol (symbol_get_bfdsym (sym))->desc;
641 }
642
643 static void
644 obj_aout_s_set_desc (sym, d)
645      symbolS *sym;
646      int d;
647 {
648   aout_symbol (symbol_get_bfdsym (sym))->desc = d;
649 }
650
651 static int
652 obj_aout_s_get_type (sym)
653      symbolS *sym;
654 {
655   return aout_symbol (symbol_get_bfdsym (sym))->type;
656 }
657
658 static void
659 obj_aout_s_set_type (sym, t)
660      symbolS *sym;
661      int t;
662 {
663   aout_symbol (symbol_get_bfdsym (sym))->type = t;
664 }
665
666 static int
667 obj_aout_separate_stab_sections ()
668 {
669   return 0;
670 }
671
672 /* When changed, make sure these table entries match the single-format
673    definitions in obj-aout.h.  */
674 const struct format_ops aout_format_ops =
675 {
676   bfd_target_aout_flavour,
677   1,    /* dfl_leading_underscore */
678   0,    /* emit_section_symbols */
679   0,    /* begin */
680   0,    /* app_file */
681   obj_aout_frob_symbol,
682   0,    /* frob_file */
683   0,    /* frob_file_before_adjust */
684   obj_aout_frob_file_before_fix,
685   0,    /* frob_file_after_relocs */
686   0,    /* s_get_size */
687   0,    /* s_set_size */
688   0,    /* s_get_align */
689   0,    /* s_set_align */
690   obj_aout_s_get_other,
691   obj_aout_s_set_other,
692   obj_aout_s_get_desc,
693   obj_aout_s_set_desc,
694   obj_aout_s_get_type,
695   obj_aout_s_set_type,
696   0,    /* copy_symbol_attributes */
697   0,    /* generate_asm_lineno */
698   obj_aout_process_stab,
699   obj_aout_separate_stab_sections,
700   0,    /* init_stab_section */
701   obj_aout_sec_sym_ok_for_reloc,
702   aout_pop_insert,
703   0,    /* ecoff_set_ext */
704   0,    /* read_begin_hook */
705   0     /* symbol_new_hook */
706 };
707 #endif /* BFD_ASSEMBLER */