Home | History | Annotate | Download | only in config
      1 /* a.out object file format
      2    Copyright (C) 1989-2016 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       c = get_symbol_name (&name);
    156       symbolP = symbol_find_or_make (name);
    157       (void) restore_line_pointer (c);
    158       SKIP_WHITESPACE ();
    159       S_SET_WEAK (symbolP);
    160       if (c == ',')
    161 	{
    162 	  input_line_pointer++;
    163 	  SKIP_WHITESPACE ();
    164 	  if (*input_line_pointer == '\n')
    165 	    c = '\n';
    166 	}
    167     }
    168   while (c == ',');
    169   demand_empty_rest_of_line ();
    170 }
    171 
    172 /* Handle .type.  On {Net,Open}BSD, this is used to set the n_other field,
    173    which is then apparently used when doing dynamic linking.  Older
    174    versions of gas ignored the .type pseudo-op, so we also ignore it if
    175    we can't parse it.  */
    176 
    177 static void
    178 obj_aout_type (int ignore ATTRIBUTE_UNUSED)
    179 {
    180   char *name;
    181   int c;
    182   symbolS *sym;
    183 
    184   c = get_symbol_name (&name);
    185   sym = symbol_find_or_make (name);
    186   (void) restore_line_pointer (c);
    187   SKIP_WHITESPACE ();
    188   if (*input_line_pointer == ',')
    189     {
    190       ++input_line_pointer;
    191       SKIP_WHITESPACE ();
    192       if (*input_line_pointer == '@')
    193 	{
    194 	  ++input_line_pointer;
    195 	  if (strncmp (input_line_pointer, "object", 6) == 0)
    196 	    S_SET_OTHER (sym, 1);
    197 	  else if (strncmp (input_line_pointer, "function", 8) == 0)
    198 	    S_SET_OTHER (sym, 2);
    199 	}
    200     }
    201 
    202   /* Ignore everything else on the line.  */
    203   s_ignore (0);
    204 }
    205 
    206 /* Support for an AOUT emulation.  */
    207 
    208 static void
    209 aout_pop_insert (void)
    210 {
    211   pop_insert (aout_pseudo_table);
    212 }
    213 
    214 static int
    215 obj_aout_s_get_other (symbolS *sym)
    216 {
    217   return aout_symbol (symbol_get_bfdsym (sym))->other;
    218 }
    219 
    220 static void
    221 obj_aout_s_set_other (symbolS *sym, int o)
    222 {
    223   aout_symbol (symbol_get_bfdsym (sym))->other = o;
    224 }
    225 
    226 static int
    227 obj_aout_sec_sym_ok_for_reloc (asection *sec ATTRIBUTE_UNUSED)
    228 {
    229   return obj_sec_sym_ok_for_reloc (sec);
    230 }
    231 
    232 static void
    233 obj_aout_process_stab (segT seg ATTRIBUTE_UNUSED,
    234 		       int w,
    235 		       const char *s,
    236 		       int t,
    237 		       int o,
    238 		       int d)
    239 {
    240   aout_process_stab (w, s, t, o, d);
    241 }
    242 
    243 static int
    244 obj_aout_s_get_desc (symbolS *sym)
    245 {
    246   return aout_symbol (symbol_get_bfdsym (sym))->desc;
    247 }
    248 
    249 static void
    250 obj_aout_s_set_desc (symbolS *sym, int d)
    251 {
    252   aout_symbol (symbol_get_bfdsym (sym))->desc = d;
    253 }
    254 
    255 static int
    256 obj_aout_s_get_type (symbolS *sym)
    257 {
    258   return aout_symbol (symbol_get_bfdsym (sym))->type;
    259 }
    260 
    261 static void
    262 obj_aout_s_set_type (symbolS *sym, int t)
    263 {
    264   aout_symbol (symbol_get_bfdsym (sym))->type = t;
    265 }
    266 
    267 static int
    268 obj_aout_separate_stab_sections (void)
    269 {
    270   return 0;
    271 }
    272 
    273 /* When changed, make sure these table entries match the single-format
    274    definitions in obj-aout.h.  */
    275 
    276 const struct format_ops aout_format_ops =
    277 {
    278   bfd_target_aout_flavour,
    279   1,	/* dfl_leading_underscore.  */
    280   0,	/* emit_section_symbols.  */
    281   0,	/* begin.  */
    282   0,	/* app_file.  */
    283   obj_aout_frob_symbol,
    284   0,	/* frob_file.  */
    285   0,	/* frob_file_before_adjust.  */
    286   obj_aout_frob_file_before_fix,
    287   0,	/* frob_file_after_relocs.  */
    288   0,	/* s_get_size.  */
    289   0,	/* s_set_size.  */
    290   0,	/* s_get_align.  */
    291   0,	/* s_set_align.  */
    292   obj_aout_s_get_other,
    293   obj_aout_s_set_other,
    294   obj_aout_s_get_desc,
    295   obj_aout_s_set_desc,
    296   obj_aout_s_get_type,
    297   obj_aout_s_set_type,
    298   0,	/* copy_symbol_attributes.  */
    299   0,	/* generate_asm_lineno.  */
    300   obj_aout_process_stab,
    301   obj_aout_separate_stab_sections,
    302   0,	/* init_stab_section.  */
    303   obj_aout_sec_sym_ok_for_reloc,
    304   aout_pop_insert,
    305   0,	/* ecoff_set_ext.  */
    306   0,	/* read_begin_hook.  */
    307   0,	/* symbol_new_hook.  */
    308   0,	/* symbol_clone_hook.  */
    309   0	/* adjust_symtab.  */
    310 };
    311 
    312 const pseudo_typeS aout_pseudo_table[] =
    313 {
    314   {"line", obj_aout_line, 0},	/* Source code line number.  */
    315   {"ln", obj_aout_line, 0},	/* COFF line number that we use anyway.  */
    316 
    317   {"weak", obj_aout_weak, 0},	/* Mark symbol as weak.  */
    318 
    319   {"type", obj_aout_type, 0},
    320 
    321   /* coff debug pseudos (ignored) */
    322   {"def", s_ignore, 0},
    323   {"dim", s_ignore, 0},
    324   {"endef", s_ignore, 0},
    325   {"ident", s_ignore, 0},
    326   {"line", s_ignore, 0},
    327   {"ln", s_ignore, 0},
    328   {"scl", s_ignore, 0},
    329   {"size", s_ignore, 0},
    330   {"tag", s_ignore, 0},
    331   {"val", s_ignore, 0},
    332   {"version", s_ignore, 0},
    333 
    334   {"optim", s_ignore, 0},	/* For sun386i cc (?).  */
    335 
    336   /* other stuff */
    337   {"ABORT", s_abort, 0},
    338 
    339   {NULL, NULL, 0}
    340 };
    341