Back to index

cell-binutils  2.17cvs20070401
obj-aout.c
Go to the documentation of this file.
00001 /* a.out object file format
00002    Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000,
00003    2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
00004 
00005    This file is part of GAS, the GNU Assembler.
00006 
00007    GAS is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as
00009    published by the Free Software Foundation; either version 2,
00010    or (at your option) any later version.
00011 
00012    GAS is distributed in the hope that it will be useful, but
00013    WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
00015    the GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with GAS; see the file COPYING.  If not, write to the Free
00019    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
00020    02110-1301, USA.  */
00021 
00022 #define OBJ_HEADER "obj-aout.h"
00023 
00024 #include "as.h"
00025 #undef NO_RELOC
00026 #include "aout/aout64.h"
00027 #include "obstack.h"
00028 
00029 void
00030 obj_aout_frob_symbol (symbolS *sym, int *punt ATTRIBUTE_UNUSED)
00031 {
00032   flagword flags;
00033   asection *sec;
00034   int desc, type, other;
00035 
00036   flags = symbol_get_bfdsym (sym)->flags;
00037   desc = aout_symbol (symbol_get_bfdsym (sym))->desc;
00038   type = aout_symbol (symbol_get_bfdsym (sym))->type;
00039   other = aout_symbol (symbol_get_bfdsym (sym))->other;
00040   sec = S_GET_SEGMENT (sym);
00041 
00042   /* Only frob simple symbols this way right now.  */
00043   if (! (type & ~ (N_TYPE | N_EXT)))
00044     {
00045       if (type == (N_UNDF | N_EXT)
00046          && sec == &bfd_abs_section)
00047        {
00048          sec = bfd_und_section_ptr;
00049          S_SET_SEGMENT (sym, sec);
00050        }
00051 
00052       if ((type & N_TYPE) != N_INDR
00053          && (type & N_TYPE) != N_SETA
00054          && (type & N_TYPE) != N_SETT
00055          && (type & N_TYPE) != N_SETD
00056          && (type & N_TYPE) != N_SETB
00057          && type != N_WARNING
00058          && (sec == &bfd_abs_section
00059              || sec == &bfd_und_section))
00060        return;
00061       if (flags & BSF_EXPORT)
00062        type |= N_EXT;
00063 
00064       switch (type & N_TYPE)
00065        {
00066        case N_SETA:
00067        case N_SETT:
00068        case N_SETD:
00069        case N_SETB:
00070          /* Set the debugging flag for constructor symbols so that
00071             BFD leaves them alone.  */
00072          symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
00073 
00074          /* You can't put a common symbol in a set.  The way a set
00075             element works is that the symbol has a definition and a
00076             name, and the linker adds the definition to the set of
00077             that name.  That does not work for a common symbol,
00078             because the linker can't tell which common symbol the
00079             user means.  FIXME: Using as_bad here may be
00080             inappropriate, since the user may want to force a
00081             particular type without regard to the semantics of sets;
00082             on the other hand, we certainly don't want anybody to be
00083             mislead into thinking that their code will work.  */
00084          if (S_IS_COMMON (sym))
00085            as_bad (_("Attempt to put a common symbol into set %s"),
00086                   S_GET_NAME (sym));
00087          /* Similarly, you can't put an undefined symbol in a set.  */
00088          else if (! S_IS_DEFINED (sym))
00089            as_bad (_("Attempt to put an undefined symbol into set %s"),
00090                   S_GET_NAME (sym));
00091 
00092          break;
00093        case N_INDR:
00094          /* Put indirect symbols in the indirect section.  */
00095          S_SET_SEGMENT (sym, bfd_ind_section_ptr);
00096          symbol_get_bfdsym (sym)->flags |= BSF_INDIRECT;
00097          if (type & N_EXT)
00098            {
00099              symbol_get_bfdsym (sym)->flags |= BSF_EXPORT;
00100              symbol_get_bfdsym (sym)->flags &=~ BSF_LOCAL;
00101            }
00102          break;
00103        case N_WARNING:
00104          /* Mark warning symbols.  */
00105          symbol_get_bfdsym (sym)->flags |= BSF_WARNING;
00106          break;
00107        }
00108     }
00109   else
00110     symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING;
00111 
00112   aout_symbol (symbol_get_bfdsym (sym))->type = type;
00113 
00114   /* Double check weak symbols.  */
00115   if (S_IS_WEAK (sym) && S_IS_COMMON (sym))
00116     as_bad (_("Symbol `%s' can not be both weak and common"),
00117            S_GET_NAME (sym));
00118 }
00119 
00120 void
00121 obj_aout_frob_file_before_fix (void)
00122 {
00123   /* Relocation processing may require knowing the VMAs of the sections.
00124      Since writing to a section will cause the BFD back end to compute the
00125      VMAs, fake it out here....  */
00126   bfd_byte b = 0;
00127   bfd_boolean x = TRUE;
00128   if (bfd_section_size (stdoutput, text_section) != 0)
00129     x = bfd_set_section_contents (stdoutput, text_section, &b, (file_ptr) 0,
00130                               (bfd_size_type) 1);
00131   else if (bfd_section_size (stdoutput, data_section) != 0)
00132     x = bfd_set_section_contents (stdoutput, data_section, &b, (file_ptr) 0,
00133                               (bfd_size_type) 1);
00134 
00135   assert (x);
00136 }
00137 
00138 static void
00139 obj_aout_line (int ignore ATTRIBUTE_UNUSED)
00140 {
00141   /* Assume delimiter is part of expression.
00142      BSD4.2 as fails with delightful bug, so we
00143      are not being incompatible here.  */
00144   new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
00145   demand_empty_rest_of_line ();
00146 }
00147 
00148 /* Handle .weak.  This is a GNU extension.  */
00149 
00150 static void
00151 obj_aout_weak (int ignore ATTRIBUTE_UNUSED)
00152 {
00153   char *name;
00154   int c;
00155   symbolS *symbolP;
00156 
00157   do
00158     {
00159       name = input_line_pointer;
00160       c = get_symbol_end ();
00161       symbolP = symbol_find_or_make (name);
00162       *input_line_pointer = c;
00163       SKIP_WHITESPACE ();
00164       S_SET_WEAK (symbolP);
00165       if (c == ',')
00166        {
00167          input_line_pointer++;
00168          SKIP_WHITESPACE ();
00169          if (*input_line_pointer == '\n')
00170            c = '\n';
00171        }
00172     }
00173   while (c == ',');
00174   demand_empty_rest_of_line ();
00175 }
00176 
00177 /* Handle .type.  On {Net,Open}BSD, this is used to set the n_other field,
00178    which is then apparently used when doing dynamic linking.  Older
00179    versions of gas ignored the .type pseudo-op, so we also ignore it if
00180    we can't parse it.  */
00181 
00182 static void
00183 obj_aout_type (int ignore ATTRIBUTE_UNUSED)
00184 {
00185   char *name;
00186   int c;
00187   symbolS *sym;
00188 
00189   name = input_line_pointer;
00190   c = get_symbol_end ();
00191   sym = symbol_find_or_make (name);
00192   *input_line_pointer = c;
00193   SKIP_WHITESPACE ();
00194   if (*input_line_pointer == ',')
00195     {
00196       ++input_line_pointer;
00197       SKIP_WHITESPACE ();
00198       if (*input_line_pointer == '@')
00199        {
00200          ++input_line_pointer;
00201          if (strncmp (input_line_pointer, "object", 6) == 0)
00202            S_SET_OTHER (sym, 1);
00203          else if (strncmp (input_line_pointer, "function", 8) == 0)
00204            S_SET_OTHER (sym, 2);
00205        }
00206     }
00207 
00208   /* Ignore everything else on the line.  */
00209   s_ignore (0);
00210 }
00211 
00212 /* Support for an AOUT emulation.  */
00213 
00214 static void
00215 aout_pop_insert (void)
00216 {
00217   pop_insert (aout_pseudo_table);
00218 }
00219 
00220 static int
00221 obj_aout_s_get_other (symbolS *sym)
00222 {
00223   return aout_symbol (symbol_get_bfdsym (sym))->other;
00224 }
00225 
00226 static void
00227 obj_aout_s_set_other (symbolS *sym, int o)
00228 {
00229   aout_symbol (symbol_get_bfdsym (sym))->other = o;
00230 }
00231 
00232 static int
00233 obj_aout_sec_sym_ok_for_reloc (asection *sec ATTRIBUTE_UNUSED)
00234 {
00235   return obj_sec_sym_ok_for_reloc (sec);
00236 }
00237 
00238 static void
00239 obj_aout_process_stab (segT seg ATTRIBUTE_UNUSED,
00240                      int w,
00241                      const char *s,
00242                      int t,
00243                      int o,
00244                      int d)
00245 {
00246   aout_process_stab (w, s, t, o, d);
00247 }
00248 
00249 static int
00250 obj_aout_s_get_desc (symbolS *sym)
00251 {
00252   return aout_symbol (symbol_get_bfdsym (sym))->desc;
00253 }
00254 
00255 static void
00256 obj_aout_s_set_desc (symbolS *sym, int d)
00257 {
00258   aout_symbol (symbol_get_bfdsym (sym))->desc = d;
00259 }
00260 
00261 static int
00262 obj_aout_s_get_type (symbolS *sym)
00263 {
00264   return aout_symbol (symbol_get_bfdsym (sym))->type;
00265 }
00266 
00267 static void
00268 obj_aout_s_set_type (symbolS *sym, int t)
00269 {
00270   aout_symbol (symbol_get_bfdsym (sym))->type = t;
00271 }
00272 
00273 static int
00274 obj_aout_separate_stab_sections (void)
00275 {
00276   return 0;
00277 }
00278 
00279 /* When changed, make sure these table entries match the single-format
00280    definitions in obj-aout.h.  */
00281 
00282 const struct format_ops aout_format_ops =
00283 {
00284   bfd_target_aout_flavour,
00285   1,   /* dfl_leading_underscore.  */
00286   0,   /* emit_section_symbols.  */
00287   0,   /* begin.  */
00288   0,   /* app_file.  */
00289   obj_aout_frob_symbol,
00290   0,   /* frob_file.  */
00291   0,   /* frob_file_before_adjust.  */
00292   obj_aout_frob_file_before_fix,
00293   0,   /* frob_file_after_relocs.  */
00294   0,   /* s_get_size.  */
00295   0,   /* s_set_size.  */
00296   0,   /* s_get_align.  */
00297   0,   /* s_set_align.  */
00298   obj_aout_s_get_other,
00299   obj_aout_s_set_other,
00300   obj_aout_s_get_desc,
00301   obj_aout_s_set_desc,
00302   obj_aout_s_get_type,
00303   obj_aout_s_set_type,
00304   0,   /* copy_symbol_attributes.  */
00305   0,   /* generate_asm_lineno.  */
00306   obj_aout_process_stab,
00307   obj_aout_separate_stab_sections,
00308   0,   /* init_stab_section.  */
00309   obj_aout_sec_sym_ok_for_reloc,
00310   aout_pop_insert,
00311   0,   /* ecoff_set_ext.  */
00312   0,   /* read_begin_hook.  */
00313   0    /* symbol_new_hook.  */
00314 };
00315 
00316 const pseudo_typeS aout_pseudo_table[] =
00317 {
00318   {"line", obj_aout_line, 0},      /* Source code line number.  */
00319   {"ln", obj_aout_line, 0}, /* COFF line number that we use anyway.  */
00320 
00321   {"weak", obj_aout_weak, 0},      /* Mark symbol as weak.  */
00322 
00323   {"type", obj_aout_type, 0},
00324 
00325   /* coff debug pseudos (ignored) */
00326   {"def", s_ignore, 0},
00327   {"dim", s_ignore, 0},
00328   {"endef", s_ignore, 0},
00329   {"ident", s_ignore, 0},
00330   {"line", s_ignore, 0},
00331   {"ln", s_ignore, 0},
00332   {"scl", s_ignore, 0},
00333   {"size", s_ignore, 0},
00334   {"tag", s_ignore, 0},
00335   {"val", s_ignore, 0},
00336   {"version", s_ignore, 0},
00337 
00338   {"optim", s_ignore, 0},   /* For sun386i cc (?).  */
00339 
00340   /* other stuff */
00341   {"ABORT", s_abort, 0},
00342 
00343   {NULL, NULL, 0}
00344 };