Home | History | Annotate | Download | only in config
      1 /* a.out object file format
      2    Copyright (C) 1989-2014 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 #define OBJ_HEADER "obj-aout.h"
     22 
     23 #include "as.h"
     24 #undef NO_RELOC
     25 #include "aout/aout64.h"
     26 
     27 void
     28 obj_aout_frob_symbol (symbolS *sym, int *punt ATTRIBUTE_UNUSED)
     29 {
     30   flagword flags;
     31   asection *sec;
     32   int type;
     33 
     34   flags = symbol_get_bfdsym (sym)->flags;
     35   type = aout_symbol (symbol_get_bfdsym (sym))->type;
     36   sec = S_GET_SEGMENT (sym);
     37 
     38   /* Only frob simple symbols this way right now.  */
     39   if (! (type & ~ (N_TYPE | N_EXT)))
     40     {
     41       if (type == (N_UNDF | N_EXT)
     42 	  && sec == bfd_abs_section_ptr)
     43 	{
     44 	  sec = bfd_und_section_ptr;
     45 	  S_SET_SEGMENT (sym, sec);
     46 	}
     47 
     48       if ((type & N_TYPE) != N_INDR
     49 	  && (type & N_TYPE) != N_SETA
     50 	  && (type & N_TYPE) != N_SETT
     51 	  && (type & N_TYPE) != N_SETD
     52 	  && (type & N_TYPE) != N_SETB
     53 	  && type != N_WARNING
     54 	  && (sec == bfd_abs_section_ptr
     55 	      || sec == bfd_und_section_ptr))
     56 	return;
     57       if (flags & BSF_EXPORT)
     58 	type |= N_EXT;
     59 
     60       switch (type & N_TYPE)
     61 	{
     62 	case N_SETA:
     63 	case N_SETT:
     64 	case N_SETD:
     65 	case N_SETB:
     66 	  /* Set the debugging flag for constructor symbols so that
     67 	     BFD leaves them alone.  */
     68 	  symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
     69 
     70 	  /* You can't put a common symbol in a set.  The way a set
     71 	     element works is that the symbol has a definition and a
     72 	     name, and the linker adds the definition to the set of
     73 	     that name.  That does not work for a common symbol,
     74 	     because the linker can't tell which common symbol the
     75 	     user means.  FIXME: Using as_bad here may be
     76 	     inappropriate, since the user may want to force a
     77 	     particular type without regard to the semantics of sets;
     78 	     on the other hand, we certainly don't want anybody to be
     79 	     mislead into thinking that their code will work.  */
     80 	  if (S_IS_COMMON (sym))
     81 	    as_bad (_("Attempt to put a common symbol into set %s"),
     82 		    S_GET_NAME (sym));
     83 	  /* Similarly, you can't put an undefined symbol in a set.  */
     84 	  else if (! S_IS_DEFINED (sym))
     85 	    as_bad (_("Attempt to put an undefined symbol into set %s"),
     86 		    S_GET_NAME (sym));
     87 
     88 	  break;
     89 	case N_INDR:
     90 	  /* Put indirect symbols in the indirect section.  */
     91 	  S_SET_SEGMENT (sym, bfd_ind_section_ptr);
     92 	  symbol_get_bfdsym (sym)->flags |= BSF_INDIRECT;
     93 	  if (type & N_EXT)
     94 	    {
     95 	      symbol_get_bfdsym (sym)->flags |= BSF_EXPORT;
     96 	      symbol_get_bfdsym (sym)->flags &=~ BSF_LOCAL;
     97 	    }
     98 	  break;
     99 	case N_WARNING:
    100 	  /* Mark warning symbols.  */
    101 	  symbol_get_bfdsym (sym)->flags |= BSF_WARNING;
    102 	  break;
    103 	}
    104     }
    105   else
    106     symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
    107 
    108   aout_symbol (symbol_get_bfdsym (sym))->type = type;
    109 
    110   /* Double check weak symbols.  */
    111   if (S_IS_WEAK (sym) && S_IS_COMMON (sym))
    112     as_bad (_("Symbol `%s' can not be both weak and common"),
    113 	    S_GET_NAME (sym));
    114 }
    115 
    116 void
    117 obj_aout_frob_file_before_fix (void)
    118 {
    119   /* Relocation processing may require knowing the VMAs of the sections.
    120      Since writing to a section will cause the BFD back end to compute the
    121      VMAs, fake it out here....  */
    122   bfd_byte b = 0;
    123   bfd_boolean x = TRUE;
    124   if (bfd_section_size (stdoutput, text_section) != 0)
    125     x = bfd_set_section_contents (stdoutput, text_section, &b, (file_ptr) 0,
    126 				  (bfd_size_type) 1);
    127   else if (bfd_section_size (stdoutput, data_section) != 0)
    128     x = bfd_set_section_contents (stdoutput, data_section, &b, (file_ptr) 0,
    129 				  (bfd_size_type) 1);
    130 
    131   gas_assert (x);
    132 }
    133 
    134 static void
    135 obj_aout_line (int ignore ATTRIBUTE_UNUSED)
    136 {
    137   /* Assume delimiter is part of expression.
    138      BSD4.2 as fails with delightful bug, so we
    139      are not being incompatible here.  */
    140   new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
    141   demand_empty_rest_of_line ();
    142 }
    143 
    144 /* Handle .weak.  This is a GNU extension.  */
    145 
    146 static void
    147 obj_aout_weak (int ignore ATTRIBUTE_UNUSED)
    148 {
    149   char *name;
    150   int c;
    151   symbolS *symbolP;
    152 
    153   do
    154     {
    155       name = input_line_pointer;
    156       c = get_symbol_end ();
    157       symbolP = symbol_find_or_make (name);
    158       *input_line_pointer = c;
    159       SKIP_WHITESPACE ();
    160       S_SET_WEAK (symbolP);
    161       if (c == ',')
    162 	{
    163 	  input_line_pointer++;
    164 	  SKIP_WHITESPACE ();
    165 	  if (*input_line_pointer == '\n')
    166 	    c = '\n';
    167 	}
    168     }
    169   while (c == ',');
    170   demand_empty_rest_of_line ();
    171 }
    172 
    173 /* Handle .type.  On {Net,Open}BSD, this is used to set the n_other field,
    174    which is then apparently used when doing dynamic linking.  Older
    175    versions of gas ignored the .type pseudo-op, so we also ignore it if
    176    we can't parse it.  */
    177 
    178 static void
    179 obj_aout_type (int ignore ATTRIBUTE_UNUSED)
    180 {
    181   char *name;
    182   int c;
    183   symbolS *sym;
    184 
    185   name = input_line_pointer;
    186   c = get_symbol_end ();
    187   sym = symbol_find_or_make (name);
    188   *input_line_pointer = c;
    189   SKIP_WHITESPACE ();
    190   if (*input_line_pointer == ',')
    191     {
    192       ++input_line_pointer;
    193       SKIP_WHITESPACE ();
    194       if (*input_line_pointer == '@')
    195 	{
    196 	  ++input_line_pointer;
    197 	  if (strncmp (input_line_pointer, "object", 6) == 0)
    198 	    S_SET_OTHER (sym, 1);
    199 	  else if (strncmp (input_line_pointer, "function", 8) == 0)
    200 	    S_SET_OTHER (sym, 2);
    201 	}
    202     }
    203 
    204   /* Ignore everything else on the line.  */
    205   s_ignore (0);
    206 }
    207 
    208 /* Support for an AOUT emulation.  */
    209 
    210 static void
    211 aout_pop_insert (void)
    212 {
    213   pop_insert (aout_pseudo_table);
    214 }
    215 
    216 static int
    217 obj_aout_s_get_other (symbolS *sym)
    218 {
    219   return aout_symbol (symbol_get_bfdsym (sym))->other;
    220 }
    221 
    222 static void
    223 obj_aout_s_set_other (symbolS *sym, int o)
    224 {
    225   aout_symbol (symbol_get_bfdsym (sym))->other = o;
    226 }
    227 
    228 static int
    229 obj_aout_sec_sym_ok_for_reloc (asection *sec ATTRIBUTE_UNUSED)
    230 {
    231   return obj_sec_sym_ok_for_reloc (sec);
    232 }
    233 
    234 static void
    235 obj_aout_process_stab (segT seg ATTRIBUTE_UNUSED,
    236 		       int w,
    237 		       const char *s,
    238 		       int t,
    239 		       int o,
    240 		       int d)
    241 {
    242   aout_process_stab (w, s, t, o, d);
    243 }
    244 
    245 static int
    246 obj_aout_s_get_desc (symbolS *sym)
    247 {
    248   return aout_symbol (symbol_get_bfdsym (sym))->desc;
    249 }
    250 
    251 static void
    252 obj_aout_s_set_desc (symbolS *sym, int d)
    253 {
    254   aout_symbol (symbol_get_bfdsym (sym))->desc = d;
    255 }
    256 
    257 static int
    258 obj_aout_s_get_type (symbolS *sym)
    259 {
    260   return aout_symbol (symbol_get_bfdsym (sym))->type;
    261 }
    262 
    263 static void
    264 obj_aout_s_set_type (symbolS *sym, int t)
    265 {
    266   aout_symbol (symbol_get_bfdsym (sym))->type = t;
    267 }
    268 
    269 static int
    270 obj_aout_separate_stab_sections (void)
    271 {
    272   return 0;
    273 }
    274 
    275 /* When changed, make sure these table entries match the single-format
    276    definitions in obj-aout.h.  */
    277 
    278 const struct format_ops aout_format_ops =
    279 {
    280   bfd_target_aout_flavour,
    281   1,	/* dfl_leading_underscore.  */
    282   0,	/* emit_section_symbols.  */
    283   0,	/* begin.  */
    284   0,	/* app_file.  */
    285   obj_aout_frob_symbol,
    286   0,	/* frob_file.  */
    287   0,	/* frob_file_before_adjust.  */
    288   obj_aout_frob_file_before_fix,
    289   0,	/* frob_file_after_relocs.  */
    290   0,	/* s_get_size.  */
    291   0,	/* s_set_size.  */
    292   0,	/* s_get_align.  */
    293   0,	/* s_set_align.  */
    294   obj_aout_s_get_other,
    295   obj_aout_s_set_other,
    296   obj_aout_s_get_desc,
    297   obj_aout_s_set_desc,
    298   obj_aout_s_get_type,
    299   obj_aout_s_set_type,
    300   0,	/* copy_symbol_attributes.  */
    301   0,	/* generate_asm_lineno.  */
    302   obj_aout_process_stab,
    303   obj_aout_separate_stab_sections,
    304   0,	/* init_stab_section.  */
    305   obj_aout_sec_sym_ok_for_reloc,
    306   aout_pop_insert,
    307   0,	/* ecoff_set_ext.  */
    308   0,	/* read_begin_hook.  */
    309   0,	/* symbol_new_hook.  */
    310   0,	/* symbol_clone_hook.  */
    311   0	/* adjust_symtab.  */
    312 };
    313 
    314 const pseudo_typeS aout_pseudo_table[] =
    315 {
    316   {"line", obj_aout_line, 0},	/* Source code line number.  */
    317   {"ln", obj_aout_line, 0},	/* COFF line number that we use anyway.  */
    318 
    319   {"weak", obj_aout_weak, 0},	/* Mark symbol as weak.  */
    320 
    321   {"type", obj_aout_type, 0},
    322 
    323   /* coff debug pseudos (ignored) */
    324   {"def", s_ignore, 0},
    325   {"dim", s_ignore, 0},
    326   {"endef", s_ignore, 0},
    327   {"ident", s_ignore, 0},
    328   {"line", s_ignore, 0},
    329   {"ln", s_ignore, 0},
    330   {"scl", s_ignore, 0},
    331   {"size", s_ignore, 0},
    332   {"tag", s_ignore, 0},
    333   {"val", s_ignore, 0},
    334   {"version", s_ignore, 0},
    335 
    336   {"optim", s_ignore, 0},	/* For sun386i cc (?).  */
    337 
    338   /* other stuff */
    339   {"ABORT", s_abort, 0},
    340 
    341   {NULL, NULL, 0}
    342 };
    343