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 	 * symbols marked "forceout" (to force out local `L' symbols in Net-
490 				      or OpenBSD PIC code)
491 
492 	 Symbols that don't are:
493 	 * symbols that are registers
494 	 * symbols with \1 as their 3rd character (numeric labels)
495 	 * "local labels" as defined by S_LOCAL_NAME(name) if the -L
496 	 switch was passed to gas.
497 
498 	 All other symbols are output.  We complain if a deleted
499 	 symbol was marked external.  */
500 
501       if (!S_IS_REGISTER (symbolP)
502 	  && (!S_GET_NAME (symbolP)
503 	      || S_IS_DEBUG (symbolP)
504 	      || !S_IS_DEFINED (symbolP)
505 	      || S_IS_EXTERNAL (symbolP)
506 	      || (S_GET_NAME (symbolP)[0] != '\001'
507 		  && (flag_keep_locals || !S_LOCAL_NAME (symbolP))
508 #if defined(TE_NetBSD) || defined(TE_OpenBSD)
509 		 || (flag_pic && symbolP->sy_forceout)
510 #endif
511 		 ))
512 #if defined(TE_NetBSD) || defined(TE_OpenBSD)
513 	 && (!flag_pic || symbolP != GOT_symbol || got_referenced != 0)
514 #endif
515          )
516 	{
517 	  symbolP->sy_number = symbol_number++;
518 
519 	  /* The + 1 after strlen account for the \0 at the
520 			   end of each string */
521 	  if (!S_IS_STABD (symbolP))
522 	    {
523 	      /* Ordinary case.  */
524 	      symbolP->sy_name_offset = string_byte_count;
525 	      string_byte_count += strlen (S_GET_NAME (symbolP)) + 1;
526 	    }
527 	  else			/* .Stabd case.  */
528 	    symbolP->sy_name_offset = 0;
529 	  symbolPP = &symbolP->sy_next;
530 	}
531       else
532 	{
533 	  if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP)
534 #if defined(TE_NetBSD) || defined(TE_OpenBSD)
535 	     && (!flag_pic || symbolP != GOT_symbol || got_referenced != 0)
536 #endif
537 	     )
538 	  if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP))
539 	    /* This warning should never get triggered any more.
540 	       Well, maybe if you're doing twisted things with
541 	       register names...  */
542 	    {
543 	      as_bad (_("Local symbol %s never defined."), decode_local_label_name (S_GET_NAME (symbolP)));
544 	    }			/* oops.  */
545 
546 	  /* Unhook it from the chain */
547 	  *symbolPP = symbol_next (symbolP);
548 	}			/* if this symbol should be in the output */
549     }				/* for each symbol */
550 
551   H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number);
552 }
553 
554 /*
555  * Find strings by crawling along symbol table chain.
556  */
557 
558 void
559 obj_emit_strings (where)
560      char **where;
561 {
562   symbolS *symbolP;
563 
564 #ifdef CROSS_COMPILE
565   /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
566   md_number_to_chars (*where, string_byte_count, sizeof (string_byte_count));
567   *where += sizeof (string_byte_count);
568 #else /* CROSS_COMPILE */
569   append (where, (char *) &string_byte_count, (unsigned long) sizeof (string_byte_count));
570 #endif /* CROSS_COMPILE */
571 
572   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
573     {
574       if (S_GET_NAME (symbolP))
575 	append (&next_object_file_charP, S_GET_NAME (symbolP),
576 		(unsigned long) (strlen (S_GET_NAME (symbolP)) + 1));
577     }				/* walk symbol chain */
578 }
579 
580 #ifndef AOUT_VERSION
581 #define AOUT_VERSION 0
582 #endif
583 
584 void
585 obj_pre_write_hook (headers)
586      object_headers *headers;
587 {
588   H_SET_DYNAMIC (headers, 0);
589   H_SET_VERSION (headers, AOUT_VERSION);
590   H_SET_MACHTYPE (headers, AOUT_MACHTYPE);
591   tc_aout_pre_write_hook (headers);
592 }
593 
594 #endif /* ! BFD_ASSEMBLER */
595 
596 #ifdef BFD_ASSEMBLER
597 
598 /* Support for an AOUT emulation.  */
599 
600 static void aout_pop_insert PARAMS ((void));
601 static int obj_aout_s_get_other PARAMS ((symbolS *));
602 static void obj_aout_s_set_other PARAMS ((symbolS *, int));
603 static int obj_aout_s_get_desc PARAMS ((symbolS *));
604 static void obj_aout_s_set_desc PARAMS ((symbolS *, int));
605 static int obj_aout_s_get_type PARAMS ((symbolS *));
606 static void obj_aout_s_set_type PARAMS ((symbolS *, int));
607 static int obj_aout_separate_stab_sections PARAMS ((void));
608 static int obj_aout_sec_sym_ok_for_reloc PARAMS ((asection *));
609 static void obj_aout_process_stab PARAMS ((segT, int, const char *, int, int, int));
610 
611 static void
612 aout_pop_insert ()
613 {
614   pop_insert (aout_pseudo_table);
615 }
616 
617 static int
618 obj_aout_s_get_other (sym)
619      symbolS *sym;
620 {
621   return aout_symbol (symbol_get_bfdsym (sym))->other;
622 }
623 
624 static void
625 obj_aout_s_set_other (sym, o)
626      symbolS *sym;
627      int o;
628 {
629   aout_symbol (symbol_get_bfdsym (sym))->other = o;
630 }
631 
632 static int
633 obj_aout_sec_sym_ok_for_reloc (sec)
634      asection *sec ATTRIBUTE_UNUSED;
635 {
636   return obj_sec_sym_ok_for_reloc (sec);
637 }
638 
639 static void
640 obj_aout_process_stab (seg, w, s, t, o, d)
641      segT seg ATTRIBUTE_UNUSED;
642      int w;
643      const char *s;
644      int t;
645      int o;
646      int d;
647 {
648   aout_process_stab (w, s, t, o, d);
649 }
650 
651 static int
652 obj_aout_s_get_desc (sym)
653      symbolS *sym;
654 {
655   return aout_symbol (symbol_get_bfdsym (sym))->desc;
656 }
657 
658 static void
659 obj_aout_s_set_desc (sym, d)
660      symbolS *sym;
661      int d;
662 {
663   aout_symbol (symbol_get_bfdsym (sym))->desc = d;
664 }
665 
666 static int
667 obj_aout_s_get_type (sym)
668      symbolS *sym;
669 {
670   return aout_symbol (symbol_get_bfdsym (sym))->type;
671 }
672 
673 static void
674 obj_aout_s_set_type (sym, t)
675      symbolS *sym;
676      int t;
677 {
678   aout_symbol (symbol_get_bfdsym (sym))->type = t;
679 }
680 
681 static int
682 obj_aout_separate_stab_sections ()
683 {
684   return 0;
685 }
686 
687 /* When changed, make sure these table entries match the single-format
688    definitions in obj-aout.h.  */
689 const struct format_ops aout_format_ops =
690 {
691   bfd_target_aout_flavour,
692   1,	/* dfl_leading_underscore */
693   0,	/* emit_section_symbols */
694   0,	/* begin */
695   0,	/* app_file */
696   obj_aout_frob_symbol,
697   0,	/* frob_file */
698   0,	/* frob_file_before_adjust */
699   obj_aout_frob_file_before_fix,
700   0,	/* frob_file_after_relocs */
701   0,	/* s_get_size */
702   0,	/* s_set_size */
703   0,	/* s_get_align */
704   0,	/* s_set_align */
705   obj_aout_s_get_other,
706   obj_aout_s_set_other,
707   obj_aout_s_get_desc,
708   obj_aout_s_set_desc,
709   obj_aout_s_get_type,
710   obj_aout_s_set_type,
711   0,	/* copy_symbol_attributes */
712   0,	/* generate_asm_lineno */
713   obj_aout_process_stab,
714   obj_aout_separate_stab_sections,
715   0,	/* init_stab_section */
716   obj_aout_sec_sym_ok_for_reloc,
717   aout_pop_insert,
718   0,	/* ecoff_set_ext */
719   0,	/* read_begin_hook */
720   0 	/* symbol_new_hook */
721 };
722 #endif /* BFD_ASSEMBLER */
723