home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / binutils.7 / binutils / binutils-2.7 / gas / config / obj-aout.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-04  |  15.3 KB  |  589 lines

  1. /* a.out object file format
  2.    Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 1996
  3.    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
  18. License along with GAS; see the file COPYING.  If not, write
  19. to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  20.  
  21. #include "as.h"
  22. #ifdef BFD_ASSEMBLER
  23. #undef NO_RELOC
  24. #include "aout/aout64.h"
  25. #endif
  26. #include "obstack.h"
  27.  
  28. #ifndef BFD_ASSEMBLER
  29. /* in: segT   out: N_TYPE bits */
  30. const short seg_N_TYPE[] =
  31. {
  32.   N_ABS,
  33.   N_TEXT,
  34.   N_DATA,
  35.   N_BSS,
  36.   N_UNDF,            /* unknown */
  37.   N_UNDF,            /* error */
  38.   N_UNDF,            /* expression */
  39.   N_UNDF,            /* debug */
  40.   N_UNDF,            /* ntv */
  41.   N_UNDF,            /* ptv */
  42.   N_REGISTER,            /* register */
  43. };
  44.  
  45. const segT N_TYPE_seg[N_TYPE + 2] =
  46. {                /* N_TYPE == 0x1E = 32-2 */
  47.   SEG_UNKNOWN,            /* N_UNDF == 0 */
  48.   SEG_GOOF,
  49.   SEG_ABSOLUTE,            /* N_ABS == 2 */
  50.   SEG_GOOF,
  51.   SEG_TEXT,            /* N_TEXT == 4 */
  52.   SEG_GOOF,
  53.   SEG_DATA,            /* N_DATA == 6 */
  54.   SEG_GOOF,
  55.   SEG_BSS,            /* N_BSS == 8 */
  56.   SEG_GOOF,
  57.   SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
  58.   SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
  59.   SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF,
  60.   SEG_REGISTER,            /* dummy N_REGISTER for regs = 30 */
  61.   SEG_GOOF,
  62. };
  63. #endif
  64.  
  65. static void obj_aout_line PARAMS ((int));
  66. static void obj_aout_weak PARAMS ((int));
  67.  
  68. const pseudo_typeS obj_pseudo_table[] =
  69. {
  70.   {"line", obj_aout_line, 0},    /* source code line number */
  71.   {"ln", obj_aout_line, 0},    /* coff line number that we use anyway */
  72.  
  73.   {"weak", obj_aout_weak, 0},    /* mark symbol as weak.  */
  74.  
  75.   /* coff debug pseudos (ignored) */
  76.   {"def", s_ignore, 0},
  77.   {"dim", s_ignore, 0},
  78.   {"endef", s_ignore, 0},
  79.   {"ident", s_ignore, 0},
  80.   {"line", s_ignore, 0},
  81.   {"ln", s_ignore, 0},
  82.   {"scl", s_ignore, 0},
  83.   {"size", s_ignore, 0},
  84.   {"tag", s_ignore, 0},
  85.   {"type", s_ignore, 0},
  86.   {"val", s_ignore, 0},
  87.   {"version", s_ignore, 0},
  88.  
  89.   {"optim", s_ignore, 0},    /* For sun386i cc (?) */
  90.  
  91.   /* other stuff */
  92.   {"ABORT", s_abort, 0},
  93.  
  94.   {NULL}            /* end sentinel */
  95. };                /* obj_pseudo_table */
  96.  
  97.  
  98. #ifdef BFD_ASSEMBLER
  99.  
  100. void
  101. obj_aout_frob_symbol (sym, punt)
  102.      symbolS *sym;
  103.      int *punt;
  104. {
  105.   flagword flags;
  106.   asection *sec;
  107.   int desc, type, other;
  108.  
  109.   flags = sym->bsym->flags;
  110.   desc = S_GET_DESC (sym);
  111.   type = S_GET_TYPE (sym);
  112.   other = S_GET_OTHER (sym);
  113.   sec = sym->bsym->section;
  114.  
  115.   /* Only frob simple symbols this way right now.  */
  116.   if (! (type & ~ (N_TYPE | N_EXT)))
  117.     {
  118.       if (type == (N_UNDF | N_EXT)
  119.       && sec == &bfd_abs_section)
  120.     sym->bsym->section = sec = bfd_und_section_ptr;
  121.  
  122.       if ((type & N_TYPE) != N_INDR
  123.       && (type & N_TYPE) != N_SETA
  124.       && (type & N_TYPE) != N_SETT
  125.       && (type & N_TYPE) != N_SETD
  126.       && (type & N_TYPE) != N_SETB
  127.       && type != N_WARNING
  128.       && (sec == &bfd_abs_section
  129.           || sec == &bfd_und_section))
  130.     return;
  131.       if (flags & BSF_EXPORT)
  132.     type |= N_EXT;
  133.  
  134.       switch (type & N_TYPE)
  135.     {
  136.     case N_SETA:
  137.     case N_SETT:
  138.     case N_SETD:
  139.     case N_SETB:
  140.       /* Set the debugging flag for constructor symbols so that
  141.          BFD leaves them alone.  */
  142.       sym->bsym->flags |= BSF_DEBUGGING;
  143.  
  144.       /* You can't put a common symbol in a set.  The way a set
  145.          element works is that the symbol has a definition and a
  146.          name, and the linker adds the definition to the set of
  147.          that name.  That does not work for a common symbol,
  148.          because the linker can't tell which common symbol the
  149.          user means.  FIXME: Using as_bad here may be
  150.          inappropriate, since the user may want to force a
  151.          particular type without regard to the semantics of sets;
  152.          on the other hand, we certainly don't want anybody to be
  153.          mislead into thinking that their code will work.  */
  154.       if (S_IS_COMMON (sym))
  155.         as_bad ("Attempt to put a common symbol into set %s",
  156.             S_GET_NAME (sym));
  157.       /* Similarly, you can't put an undefined symbol in a set.  */
  158.       else if (! S_IS_DEFINED (sym))
  159.         as_bad ("Attempt to put an undefined symbol into set %s",
  160.             S_GET_NAME (sym));
  161.  
  162.       break;
  163.     case N_INDR:
  164.       /* Put indirect symbols in the indirect section.  */
  165.       sym->bsym->section = bfd_ind_section_ptr;
  166.       sym->bsym->flags |= BSF_INDIRECT;
  167.       if (type & N_EXT)
  168.         {
  169.           sym->bsym->flags |= BSF_EXPORT;
  170.           sym->bsym->flags &=~ BSF_LOCAL;
  171.         }
  172.       break;
  173.     case N_WARNING:
  174.       /* Mark warning symbols.  */
  175.       sym->bsym->flags |= BSF_WARNING;
  176.       break;
  177.     }
  178.     }
  179.   else
  180.     {
  181.       sym->bsym->flags |= BSF_DEBUGGING;
  182.     }
  183.  
  184.   S_SET_TYPE (sym, type);
  185.  
  186.   /* Double check weak symbols.  */
  187.   if (sym->bsym->flags & BSF_WEAK)
  188.     {
  189.       if (S_IS_COMMON (sym))
  190.     as_bad ("Symbol `%s' can not be both weak and common",
  191.         S_GET_NAME (sym));
  192.     }
  193. }
  194.  
  195. void
  196. obj_aout_frob_file ()
  197. {
  198.   /* Relocation processing may require knowing the VMAs of the sections.
  199.      Since writing to a section will cause the BFD back end to compute the
  200.      VMAs, fake it out here....  */
  201.   bfd_byte b = 0;
  202.   boolean x = true;
  203.   if (bfd_section_size (stdoutput, text_section) != 0)
  204.     {
  205.       x = bfd_set_section_contents (stdoutput, text_section, &b, (file_ptr) 0,
  206.                     (bfd_size_type) 1);
  207.     }
  208.   else if (bfd_section_size (stdoutput, data_section) != 0)
  209.     {
  210.       x = bfd_set_section_contents (stdoutput, data_section, &b, (file_ptr) 0,
  211.                     (bfd_size_type) 1);
  212.     }
  213.   assert (x == true);
  214. }
  215.  
  216. #else
  217.  
  218. /* Relocation. */
  219.  
  220. /*
  221.  *        emit_relocations()
  222.  *
  223.  * Crawl along a fixS chain. Emit the segment's relocations.
  224.  */
  225. void
  226. obj_emit_relocations (where, fixP, segment_address_in_file)
  227.      char **where;
  228.      fixS *fixP;        /* Fixup chain for this segment. */
  229.      relax_addressT segment_address_in_file;
  230. {
  231.   for (; fixP; fixP = fixP->fx_next)
  232.     if (fixP->fx_done == 0)
  233.       {
  234.     symbolS *sym;
  235.  
  236.     sym = fixP->fx_addsy;
  237.     while (sym->sy_value.X_op == O_symbol
  238.            && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
  239.       sym = sym->sy_value.X_add_symbol;
  240.     fixP->fx_addsy = sym;
  241.  
  242.     if (! sym->sy_resolved && ! S_IS_DEFINED (sym))
  243.       {
  244.         char *file;
  245.         unsigned int line;
  246.  
  247.         if (expr_symbol_where (sym, &file, &line))
  248.           as_bad_where (file, line, "unresolved relocation");
  249.         else
  250.           as_bad ("bad relocation: symbol `%s' not in symbol table",
  251.               S_GET_NAME (sym));
  252.       }
  253.  
  254.     tc_aout_fix_to_chars (*where, fixP, segment_address_in_file);
  255.     *where += md_reloc_size;
  256.       }
  257. }
  258.  
  259. #ifndef obj_header_append
  260. /* Aout file generation & utilities */
  261. void
  262. obj_header_append (where, headers)
  263.      char **where;
  264.      object_headers *headers;
  265. {
  266.   tc_headers_hook (headers);
  267.  
  268. #ifdef CROSS_COMPILE
  269.   md_number_to_chars (*where, headers->header.a_info, sizeof (headers->header.a_info));
  270.   *where += sizeof (headers->header.a_info);
  271.   md_number_to_chars (*where, headers->header.a_text, sizeof (headers->header.a_text));
  272.   *where += sizeof (headers->header.a_text);
  273.   md_number_to_chars (*where, headers->header.a_data, sizeof (headers->header.a_data));
  274.   *where += sizeof (headers->header.a_data);
  275.   md_number_to_chars (*where, headers->header.a_bss, sizeof (headers->header.a_bss));
  276.   *where += sizeof (headers->header.a_bss);
  277.   md_number_to_chars (*where, headers->header.a_syms, sizeof (headers->header.a_syms));
  278.   *where += sizeof (headers->header.a_syms);
  279.   md_number_to_chars (*where, headers->header.a_entry, sizeof (headers->header.a_entry));
  280.   *where += sizeof (headers->header.a_entry);
  281.   md_number_to_chars (*where, headers->header.a_trsize, sizeof (headers->header.a_trsize));
  282.   *where += sizeof (headers->header.a_trsize);
  283.   md_number_to_chars (*where, headers->header.a_drsize, sizeof (headers->header.a_drsize));
  284.   *where += sizeof (headers->header.a_drsize);
  285.  
  286. #else /* CROSS_COMPILE */
  287.  
  288.   append (where, (char *) &headers->header, sizeof (headers->header));
  289. #endif /* CROSS_COMPILE */
  290.  
  291. }
  292. #endif
  293.  
  294. void
  295. obj_symbol_to_chars (where, symbolP)
  296.      char **where;
  297.      symbolS *symbolP;
  298. {
  299.   md_number_to_chars ((char *) &(S_GET_OFFSET (symbolP)), S_GET_OFFSET (symbolP), sizeof (S_GET_OFFSET (symbolP)));
  300.   md_number_to_chars ((char *) &(S_GET_DESC (symbolP)), S_GET_DESC (symbolP), sizeof (S_GET_DESC (symbolP)));
  301.   md_number_to_chars ((char *) &(symbolP->sy_symbol.n_value), S_GET_VALUE (symbolP), sizeof (symbolP->sy_symbol.n_value));
  302.  
  303.   append (where, (char *) &symbolP->sy_symbol, sizeof (obj_symbol_type));
  304. }
  305.  
  306. void
  307. obj_emit_symbols (where, symbol_rootP)
  308.      char **where;
  309.      symbolS *symbol_rootP;
  310. {
  311.   symbolS *symbolP;
  312.  
  313.   /* Emit all symbols left in the symbol chain.  */
  314.   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
  315.     {
  316.       /* Used to save the offset of the name. It is used to point
  317.      to the string in memory but must be a file offset. */
  318.       register char *temp;
  319.  
  320.       temp = S_GET_NAME (symbolP);
  321.       S_SET_OFFSET (symbolP, symbolP->sy_name_offset);
  322.  
  323.       /* Any symbol still undefined and is not a dbg symbol is made N_EXT. */
  324.       if (!S_IS_DEBUG (symbolP) && !S_IS_DEFINED (symbolP))
  325.     S_SET_EXTERNAL (symbolP);
  326.  
  327.       /* Adjust the type of a weak symbol.  */
  328.       if (S_GET_WEAK (symbolP))
  329.     {
  330.       switch (S_GET_TYPE (symbolP))
  331.         {
  332.         case N_UNDF: S_SET_TYPE (symbolP, N_WEAKU); break;
  333.         case N_ABS:     S_SET_TYPE (symbolP, N_WEAKA); break;
  334.         case N_TEXT: S_SET_TYPE (symbolP, N_WEAKT); break;
  335.         case N_DATA: S_SET_TYPE (symbolP, N_WEAKD); break;
  336.         case N_BSS:  S_SET_TYPE (symbolP, N_WEAKB); break;
  337.         default: as_bad ("%s: bad type for weak symbol", temp); break;
  338.         }
  339.     }
  340.  
  341.       obj_symbol_to_chars (where, symbolP);
  342.       S_SET_NAME (symbolP, temp);
  343.     }
  344. }
  345.  
  346. #endif /* ! BFD_ASSEMBLER */
  347.  
  348. static void
  349. obj_aout_line (ignore)
  350.      int ignore;
  351. {
  352.   /* Assume delimiter is part of expression.
  353.      BSD4.2 as fails with delightful bug, so we
  354.      are not being incompatible here. */
  355.   new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
  356.   demand_empty_rest_of_line ();
  357. }                /* obj_aout_line() */
  358.  
  359. /* Handle .weak.  This is a GNU extension.  */
  360.  
  361. static void
  362. obj_aout_weak (ignore)
  363.      int ignore;
  364. {
  365.   char *name;
  366.   int c;
  367.   symbolS *symbolP;
  368.  
  369.   do
  370.     {
  371.       name = input_line_pointer;
  372.       c = get_symbol_end ();
  373.       symbolP = symbol_find_or_make (name);
  374.       *input_line_pointer = c;
  375.       SKIP_WHITESPACE ();
  376.       S_SET_WEAK (symbolP);
  377.       if (c == ',')
  378.     {
  379.       input_line_pointer++;
  380.       SKIP_WHITESPACE ();
  381.       if (*input_line_pointer == '\n')
  382.         c = '\n';
  383.     }
  384.     }
  385.   while (c == ',');
  386.   demand_empty_rest_of_line ();
  387. }
  388.  
  389. void
  390. obj_read_begin_hook ()
  391. {
  392. }
  393.  
  394. #ifndef BFD_ASSEMBLER
  395.  
  396. void
  397. obj_crawl_symbol_chain (headers)
  398.      object_headers *headers;
  399. {
  400.   symbolS *symbolP;
  401.   symbolS **symbolPP;
  402.   int symbol_number = 0;
  403.  
  404.   tc_crawl_symbol_chain (headers);
  405.  
  406.   symbolPP = &symbol_rootP;    /*->last symbol chain link. */
  407.   while ((symbolP = *symbolPP) != NULL)
  408.     {
  409.       if (symbolP->sy_mri_common)
  410.     {
  411.       if (S_IS_EXTERNAL (symbolP))
  412.         as_bad ("%s: global symbols not supported in common sections",
  413.             S_GET_NAME (symbolP));
  414.       *symbolPP = symbol_next (symbolP);
  415.       continue;
  416.     }
  417.  
  418.       if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_DATA))
  419.     {
  420.       S_SET_SEGMENT (symbolP, SEG_TEXT);
  421.     }            /* if pusing data into text */
  422.  
  423.       resolve_symbol_value (symbolP);
  424.  
  425.       /* Skip symbols which were equated to undefined or common
  426.      symbols.  */
  427.       if (symbolP->sy_value.X_op == O_symbol
  428.       && (! S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP)))
  429.     {
  430.       *symbolPP = symbol_next (symbolP);
  431.       continue;
  432.     }
  433.  
  434.       /* OK, here is how we decide which symbols go out into the brave
  435.      new symtab.  Symbols that do are:
  436.  
  437.      * symbols with no name (stabd's?)
  438.      * symbols with debug info in their N_TYPE
  439.  
  440.      Symbols that don't are:
  441.      * symbols that are registers
  442.      * symbols with \1 as their 3rd character (numeric labels)
  443.      * "local labels" as defined by S_LOCAL_NAME(name) if the -L
  444.      switch was passed to gas.
  445.  
  446.      All other symbols are output.  We complain if a deleted
  447.      symbol was marked external. */
  448.  
  449.  
  450.       if (!S_IS_REGISTER (symbolP)
  451.       && (!S_GET_NAME (symbolP)
  452.           || S_IS_DEBUG (symbolP)
  453.           || !S_IS_DEFINED (symbolP)
  454.           || S_IS_EXTERNAL (symbolP)
  455.           || (S_GET_NAME (symbolP)[0] != '\001'
  456.           && (flag_keep_locals || !S_LOCAL_NAME (symbolP)))))
  457.     {
  458.       symbolP->sy_number = symbol_number++;
  459.  
  460.       /* The + 1 after strlen account for the \0 at the
  461.                end of each string */
  462.       if (!S_IS_STABD (symbolP))
  463.         {
  464.           /* Ordinary case. */
  465.           symbolP->sy_name_offset = string_byte_count;
  466.           string_byte_count += strlen (S_GET_NAME (symbolP)) + 1;
  467.         }
  468.       else            /* .Stabd case. */
  469.         symbolP->sy_name_offset = 0;
  470.       symbolPP = &(symbol_next (symbolP));
  471.     }
  472.       else
  473.     {
  474.       if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP))
  475.         /* This warning should never get triggered any more.
  476.            Well, maybe if you're doing twisted things with
  477.            register names...  */
  478.         {
  479.           as_bad ("Local symbol %s never defined.", decode_local_label_name (S_GET_NAME (symbolP)));
  480.         }            /* oops. */
  481.  
  482.       /* Unhook it from the chain */
  483.       *symbolPP = symbol_next (symbolP);
  484.     }            /* if this symbol should be in the output */
  485.     }                /* for each symbol */
  486.  
  487.   H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number);
  488. }
  489.  
  490. /*
  491.  * Find strings by crawling along symbol table chain.
  492.  */
  493.  
  494. void
  495. obj_emit_strings (where)
  496.      char **where;
  497. {
  498.   symbolS *symbolP;
  499.  
  500. #ifdef CROSS_COMPILE
  501.   /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
  502.   md_number_to_chars (*where, string_byte_count, sizeof (string_byte_count));
  503.   *where += sizeof (string_byte_count);
  504. #else /* CROSS_COMPILE */
  505.   append (where, (char *) &string_byte_count, (unsigned long) sizeof (string_byte_count));
  506. #endif /* CROSS_COMPILE */
  507.  
  508.   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
  509.     {
  510.       if (S_GET_NAME (symbolP))
  511.     append (&next_object_file_charP, S_GET_NAME (symbolP),
  512.         (unsigned long) (strlen (S_GET_NAME (symbolP)) + 1));
  513.     }                /* walk symbol chain */
  514. }
  515.  
  516. #ifndef AOUT_VERSION
  517. #define AOUT_VERSION 0
  518. #endif
  519.  
  520. void
  521. obj_pre_write_hook (headers)
  522.      object_headers *headers;
  523. {
  524.   H_SET_DYNAMIC (headers, 0);
  525.   H_SET_VERSION (headers, AOUT_VERSION);
  526.   H_SET_MACHTYPE (headers, AOUT_MACHTYPE);
  527.   tc_aout_pre_write_hook (headers);
  528. }
  529.  
  530. void
  531. DEFUN_VOID (s_sect)
  532. {
  533.   /* Strip out the section name */
  534.   char *section_name;
  535.   char *section_name_end;
  536.   char c;
  537.  
  538.   unsigned int len;
  539.   unsigned int exp;
  540.   char *save;
  541.  
  542.   section_name = input_line_pointer;
  543.   c = get_symbol_end ();
  544.   section_name_end = input_line_pointer;
  545.  
  546.   len = section_name_end - section_name;
  547.   input_line_pointer++;
  548.   save = input_line_pointer;
  549.  
  550.   SKIP_WHITESPACE ();
  551.   if (c == ',')
  552.     {
  553.       exp = get_absolute_expression ();
  554.     }
  555.   else if (*input_line_pointer == ',')
  556.     {
  557.       input_line_pointer++;
  558.       exp = get_absolute_expression ();
  559.     }
  560.   else
  561.     {
  562.       input_line_pointer = save;
  563.       exp = 0;
  564.     }
  565.   if (exp >= 1000)
  566.     {
  567.       as_bad ("subsegment index too high");
  568.     }
  569.  
  570.   if (strcmp (section_name, ".text") == 0)
  571.     {
  572.       subseg_set (SEG_TEXT, (subsegT) exp);
  573.     }
  574.  
  575.   if (strcmp (section_name, ".data") == 0)
  576.     {
  577.       if (flag_readonly_data_in_text)
  578.     subseg_set (SEG_TEXT, (subsegT) exp + 1000);
  579.       else
  580.     subseg_set (SEG_DATA, (subsegT) exp);
  581.     }
  582.  
  583.   *section_name_end = c;
  584. }
  585.  
  586. #endif /* ! BFD_ASSEMBLER */
  587.  
  588. /* end of obj-aout.c */
  589.