home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 5 / FreshFish_July-August1994.bin / bbs / gnu / gas-1.38-src.lha / src / amiga / gas-1.38 / write.c < prev    next >
C/C++ Source or Header  |  1993-09-09  |  39KB  |  1,269 lines

  1. /* write.c - emit .o file - Copyright(C)1986 Free Software Foundation, Inc.
  2.    Copyright (C) 1986,1987 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 published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GAS is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. 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
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /* 
  21.  
  22.    Umm, with real good luck, this thing should be set up to do byteordering
  23.    correctly, but I may have managed to miss a place or two.  Treat a.out
  24.    very carefully until you're SURE that it works. . .
  25.  
  26.    In order to cross-assemble the target machine must have an a.out header
  27.    similar to the one in a.out.h on THIS machine.  Byteorder doesn't matter;
  28.    we take special care of it, but the numbers must be the same SIZE (# of
  29.    bytes) and in the same PLACE.  If this is not true, you will have some
  30.    trouble.
  31.  */
  32.  
  33. #include "as.h"
  34. #include "md.h"
  35. #include "subsegs.h"
  36. #include "obstack.h"
  37. #include "struc-symbol.h"
  38. #include "write.h"
  39. #include "symbols.h"
  40.  
  41. #ifdef SPARC
  42. #include "sparc.h"
  43. #endif
  44. #ifdef I860
  45. #include "i860.h"
  46. #endif
  47.  
  48. void    append();
  49.  
  50. #ifdef hpux
  51. #define EXEC_MACHINE_TYPE HP9000S200_ID
  52. #endif
  53.  
  54. #ifdef DOT_LABEL_PREFIX
  55. #define LOCAL_LABEL(name) (name[0] =='.' \
  56.                          && ( name [1] == 'L' || name [1] == '.' ))
  57. #else  /* not defined DOT_LABEL_PREFIX */
  58. #define LOCAL_LABEL(name) (name [0] == 'L' )
  59. #endif /* not defined DOT_LABEL_PREFIX */
  60.  
  61. /*
  62.  * In: length of relocation (or of address) in chars: 1, 2 or 4.
  63.  * Out: GNU LD relocation length code: 0, 1, or 2.
  64.  */
  65.  
  66. static unsigned char
  67.  
  68. nbytes_r_length [] = {
  69.   42, 0, 1, 42, 2
  70.   };
  71.  
  72.  
  73. static struct frag *    text_frag_root;
  74. static struct frag *    data_frag_root;
  75.  
  76. static struct frag *    text_last_frag;    /* Last frag in segment. */
  77. static struct frag *    data_last_frag;    /* Last frag in segment. */
  78.  
  79. static struct exec    the_exec;
  80.  
  81. static long int string_byte_count;
  82.  
  83. static char *        the_object_file;
  84.  
  85. #if !defined(SPARC) && !defined(I860)
  86. static
  87. #endif
  88. char *        next_object_file_charP;    /* Tracks object file bytes. */
  89.  
  90. static long int        size_of_the_object_file; /* # bytes in object file. */
  91.  
  92. /* static long int        length; JF unused */    /* String length, including trailing '\0'. */
  93.  
  94. static void    relax_segment();
  95. void        emit_segment();
  96. static relax_addressT    relax_align();
  97. static long int    fixup_segment();
  98. #if !defined(SPARC) && !defined(I860)
  99. static void        emit_relocations();
  100. #endif
  101. /*
  102.  *            fix_new()
  103.  *
  104.  * Create a fixS in obstack 'notes'.
  105.  */
  106. void
  107. #if defined(SPARC) || defined(I860)
  108. fix_new (frag, where, size, add_symbol, sub_symbol, offset, pcrel, r_type)
  109. #else
  110. fix_new (frag, where, size, add_symbol, sub_symbol, offset, pcrel, baserel)
  111. #endif
  112.      fragS *    frag;        /* Which frag? */
  113.      int    where;        /* Where in that frag? */
  114.      short int    size;        /* 1, 2  or 4 usually. */
  115.      symbolS *    add_symbol;    /* X_add_symbol. */
  116.      symbolS *    sub_symbol;    /* X_subtract_symbol. */
  117.      long int    offset;        /* X_add_number. */
  118.      int    pcrel;        /* TRUE if PC-relative relocation. */
  119.      int    baserel;        /* true if base-relative data */
  120. #if defined(SPARC) || defined(I860)
  121.     int        r_type;
  122. #endif
  123. {
  124.   register fixS *    fixP;
  125.  
  126.   fixP = (fixS *)obstack_alloc(¬es,sizeof(fixS));
  127.  
  128.   fixP -> fx_frag    = frag;
  129.   fixP -> fx_where    = where;
  130.   fixP -> fx_size    = size;
  131.   fixP -> fx_addsy    = add_symbol;
  132.   fixP -> fx_subsy    = sub_symbol;
  133.   fixP -> fx_offset    = offset;
  134.   fixP -> fx_pcrel    = pcrel;
  135.   fixP -> fx_next    = * seg_fix_rootP;
  136.  
  137.   /* JF these 'cuz of the NS32K stuff */
  138.   fixP -> fx_im_disp    = 0;
  139.   fixP -> fx_pcrel_adjust = 0;
  140.   fixP -> fx_bsr    = baserel;
  141.   fixP ->fx_bit_fixP    = 0;
  142.  
  143. #if defined(SPARC) || defined(I860)
  144.   fixP->fx_r_type = r_type;
  145. #endif
  146.  
  147.   * seg_fix_rootP = fixP;
  148. }
  149.  
  150. void
  151. write_object_file()
  152. {
  153.   register struct frchain *    frchainP; /* Track along all frchains. */
  154.   register fragS *        fragP;    /* Track along all frags. */
  155.   register struct frchain *    next_frchainP;
  156.   register fragS * *        prev_fragPP;
  157.   register char *        name;
  158.   register symbolS *        symbolP;
  159.   register symbolS **        symbolPP;
  160.   /* register fixS *        fixP; JF unused */
  161.   unsigned
  162.       text_siz,
  163.     data_siz,
  164.     syms_siz,
  165.     tr_siz,
  166.     dr_siz;
  167.   void output_file_create();
  168.   void output_file_append();
  169.   void output_file_close();
  170. #ifdef DONTDEF
  171.   void gdb_emit();
  172.   void gdb_end();
  173. #endif
  174.   extern short omagic;        /* JF magic # to write out.  Is different for
  175.                    Suns and Vaxen and other boxes */
  176.   extern short mid;
  177.  
  178. #ifdef    VMS
  179.   /*
  180.    *    Under VMS we try to be compatible with VAX-11 "C".  Thus, we
  181.    *    call a routine to check for the definition of the procedure
  182.    *    "_main", and if so -- fix it up so that it can be program
  183.    *    entry point.
  184.    */
  185.   VMS_Check_For_Main();
  186. #endif /* VMS */
  187.   /*
  188.    * After every sub-segment, we fake an ".align ...". This conforms to BSD4.2
  189.    * brane-damage. We then fake ".fill 0" because that is the kind of frag
  190.    * that requires least thought. ".align" frags like to have a following
  191.    * frag since that makes calculating their intended length trivial.
  192.    */
  193. #define SUB_SEGMENT_ALIGN (2)
  194.   for ( frchainP=frchain_root; frchainP; frchainP=frchainP->frch_next )
  195.     {
  196. #ifdef    VMS
  197.       /*
  198.        *    Under VAX/VMS, the linker (and PSECT specifications)
  199.        *    take care of correctly aligning the segments.
  200.        *    Doing the alignment here (on initialized data) can
  201.        *    mess up the calculation of global data PSECT sizes.
  202.        */
  203. #undef    SUB_SEGMENT_ALIGN
  204. #define    SUB_SEGMENT_ALIGN ((frchainP->frch_seg != SEG_DATA) ? 2 : 0)
  205. #endif    /* VMS */
  206.       subseg_new (frchainP -> frch_seg, frchainP -> frch_subseg);
  207.       frag_align (SUB_SEGMENT_ALIGN, 0);
  208.                 /* frag_align will have left a new frag. */
  209.                 /* Use this last frag for an empty ".fill". */
  210.       /*
  211.        * For this segment ...
  212.        * Create a last frag. Do not leave a "being filled in frag".
  213.        */
  214.       frag_wane (frag_now);
  215.       frag_now -> fr_fix    = 0;
  216.       know( frag_now -> fr_next == NULL );
  217.       /* know( frags . obstack_c_base == frags . obstack_c_next_free ); */
  218.       /* Above shows we haven't left a half-completed object on obstack. */
  219.     }
  220.  
  221.   /*
  222.    * From now on, we don't care about sub-segments.
  223.    * Build one frag chain for each segment. Linked thru fr_next.
  224.    * We know that there is at least 1 text frchain & at least 1 data frchain.
  225.    */
  226.   prev_fragPP = &text_frag_root;
  227.   for ( frchainP=frchain_root; frchainP; frchainP=next_frchainP )
  228.     {
  229.       know( frchainP -> frch_root );
  230.       * prev_fragPP = frchainP -> frch_root;
  231.       prev_fragPP = & frchainP -> frch_last -> fr_next;
  232.       if (   ((next_frchainP = frchainP->frch_next) == NULL)
  233.       || next_frchainP == data0_frchainP)
  234.     {
  235.       prev_fragPP = & data_frag_root;
  236.       if ( next_frchainP )
  237.         {
  238.           text_last_frag = frchainP -> frch_last;
  239.         }
  240.       else
  241.         {
  242.           data_last_frag = frchainP -> frch_last;
  243.         }
  244.     }
  245.     }                /* for(each struct frchain) */
  246.  
  247.   /*
  248.    * We have two segments. If user gave -R flag, then we must put the
  249.    * data frags into the text segment. Do this before relaxing so
  250.    * we know to take advantage of -R and make shorter addresses.
  251.    */
  252.   if ( flagseen [ 'R' ] )
  253.     {
  254.       fixS *tmp;
  255.  
  256.       text_last_frag -> fr_next = data_frag_root;
  257.       text_last_frag = data_last_frag;
  258.       data_last_frag = NULL;
  259.       data_frag_root = NULL;
  260.       if(text_fix_root) {
  261.     for(tmp=text_fix_root;tmp->fx_next;tmp=tmp->fx_next)
  262.       ;
  263.     tmp->fx_next=data_fix_root;
  264.       } else
  265.         text_fix_root=data_fix_root;
  266.       data_fix_root=NULL;
  267.     }
  268.  
  269.   relax_segment (text_frag_root, SEG_TEXT);
  270.   relax_segment (data_frag_root, SEG_DATA);
  271.   /*
  272.    * Now the addresses of frags are correct within the segment.
  273.    */
  274.  
  275.   know(   text_last_frag -> fr_type   == rs_fill && text_last_frag -> fr_offset == 0 );
  276.   text_siz=text_last_fra