home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / cctools / as / sections.c < prev    next >
C/C++ Source or Header  |  1995-01-17  |  8KB  |  252 lines

  1. /* sections.c (was subsegs.c in original GAS version)
  2.    Copyright (C) 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.  * Mach-O sections are chains of fragments.
  22.  */
  23. #include <stdlib.h>
  24. #include <strings.h>
  25. #include "sections.h"
  26. #include "obstack.h"
  27. #include "xmalloc.h"
  28. #include "frags.h"
  29. #include "messages.h"
  30.  
  31. /*
  32.  * All sections' chains hang off here.  NULL means no frchains yet.
  33.  */
  34. frchainS *frchain_root = NULL;
  35.  
  36. /*
  37.  * The frchain we are assembling into now.  That is, the current section's
  38.  * frag chain, even if it contains no (complete) frags.
  39.  */
  40. frchainS *frchain_now = NULL;
  41.  
  42. /*
  43.  * sections_begin() sets up to allow sections to be created.
  44.  */
  45. void
  46. sections_begin(
  47. void)
  48. {
  49.     /* This may be needed if a section_new() for .text is not assumed */
  50.     /* obstack_begin(&frags, 5000); */
  51.     /* frag_now = (fragS *)obstack_alloc(&frags, SIZEOF_STRUCT_FRAG); */
  52. }
  53.  
  54. /*
  55.  * section_new() (for non-zerofill sections) switches to a new section, creating
  56.  * it if needed, and creates a fresh fragment.  If it is the current section
  57.  * nothing happens except checks to make sure the type, attributes and
  58.  * sizeof_stub are the same.  The segment and section names will be trimed to
  59.  * fit in the section structure and is the responsiblity of the caller to
  60.  * report errors if they don't.  For zerofill sections only the struct frchain
  61.  * for the section is returned after possibly being created (these section are
  62.  * never made the current section and no frags are ever touched).
  63.  *
  64.  * Globals on input:
  65.  *    frchain_now points to the (possibly none) struct frchain for the current
  66.  *    section.
  67.  *    frag_now points at an incomplete frag for current section.
  68.  *    If frag_now == NULL, then there is no old, incomplete frag, so the old
  69.  *    frag is not closed off.
  70.  *
  71.  * Globals on output:
  72.  *    frchain_now points to the (possibly new) struct frchain for this section.
  73.  *    frchain_root updated if needed (for the first section created).
  74.  *    frag_now is set to the last (possibly new) frag in the section.
  75.  */
  76. frchainS *
  77. section_new(
  78. char *segname,
  79. char *sectname,
  80. unsigned long type,
  81. unsigned long attributes,
  82. unsigned long sizeof_stub)
  83. {
  84.     frchainS *frcP;
  85.     frchainS **lastPP;
  86.     unsigned long last_nsect;
  87.  
  88.     if(frags.chunk_size == 0)
  89.         /*
  90.          * This line is use instead of:
  91.          *      obstack_begin(&frags, 5000);
  92.          * which the only difference is that frags are allocated on 4 byte
  93.          * boundaries instead of the default.  The problem with the default
  94.          * is that on some RISC machines the obstack uses 8 (the alignment
  95.          * of a double after a char in a struct) and then the common use of:
  96.          *     frag_now->fr_fix = obstack_next_free(&frags) -
  97.          *               frag_now->fr_literal;
  98.          * can get an extra 4 bytes that are not in the frag because of the
  99.          * 8 byte alignment where only 4 byte alignment for frags are
  100.          * needed.
  101.          */
  102.         _obstack_begin(&frags, 5000, 4,
  103.                obstack_chunk_alloc, obstack_chunk_free);
  104.  
  105.     /*
  106.      * Determine if this section has been seen.
  107.      */
  108.     last_nsect = 0;
  109.     for(frcP = *(lastPP = &frchain_root);
  110.         frcP != NULL;
  111.         frcP = *(lastPP = &frcP->frch_next)){
  112.         if(strncmp(frcP->frch_section.segname, segname,
  113.                sizeof(frcP->frch_section.segname)) == 0 &&
  114.            strncmp(frcP->frch_section.sectname, sectname,
  115.                sizeof(frcP->frch_section.sectname)) == 0)
  116.         break;
  117.         last_nsect = frcP->frch_nsect;
  118.     }
  119.  
  120.     /*
  121.      * If this section has been seen make sure it's type and attributes
  122.      * for this call are the same as when the section was created.
  123.      */
  124.     if(frcP != NULL){
  125.         if((frcP->frch_section.flags & SECTION_TYPE) != type){
  126.         as_warn("section type does not match previous section type");
  127.         }
  128.         if(type == S_SYMBOL_STUBS &&
  129.            frcP->frch_section.reserved2 != sizeof_stub){
  130.         as_warn("section stub size does not match previous section "
  131.             "stub size");
  132.         }
  133.         if((frcP->frch_section.flags & SECTION_ATTRIBUTES_USR) !=
  134.         attributes){
  135.         as_warn("section attributes does not match previous section "
  136.             "attributes");
  137.         }
  138.     }
  139.  
  140.     /*
  141.      * If the current section is the same as for this call there is nothing
  142.      * more to do.
  143.      */
  144.     if(frcP != NULL && (frchain_now == frcP || type == S_ZEROFILL)){
  145.         return(frcP);
  146.     }
  147.  
  148.     /*
  149.      * For non-zerofill sections it will be made the current section so deal
  150.      * with the current frag.
  151.      */
  152.     if(type != S_ZEROFILL){
  153.         /*
  154.          * If there is any current frag in the old section close it off.
  155.          */
  156.         if(frag_now != NULL){
  157.         frag_now->fr_fix = obstack_next_free(&frags) -
  158.                    frag_now->fr_literal;
  159.         frag_wane(frag_now);
  160.         }
  161.  
  162.         /*
  163.          * We must do the obstack_finish(), so the next object we put on
  164.          * obstack frags will not appear to start at the fr_literal of the
  165.          * current frag.  Also, it ensures that the next object will begin
  166.          * on a address that is aligned correctly for the engine that runs
  167.          * the assembler.
  168.          */
  169.         obstack_finish(&frags);
  170.     }
  171.  
  172.     /*
  173.      * If this section exists since it is not the current section switch to
  174.      * it by making it the current chain and create a new frag in it.
  175.      */
  176.     if(frcP != NULL){
  177.         /*
  178.          * For a zerofill section no frags are created here and since it
  179.          * exist just return a pointer to the section.
  180.          */
  181.         if((frcP->frch_section.flags & SECTION_TYPE) == S_ZEROFILL){
  182.         return(frcP);
  183.         }
  184.         else{
  185.         /*
  186.          * Make this section the current section.
  187.          */
  188.         frchain_now = frcP;
  189.  
  190.         /*
  191.          * Make a fresh frag for the section.
  192.          */
  193.         frag_now = (fragS *)obstack_alloc(&frags, SIZEOF_STRUCT_FRAG);
  194.         memset(frag_now, '\0', SIZEOF_STRUCT_FRAG);
  195.         frag_now->fr_next = NULL;
  196.  
  197.         /*
  198.          * Append the new frag to the existing frchain.
  199.          */
  200.         frchain_now->frch_last->fr_next = frag_now;
  201.         frchain_now->frch_last = frag_now;
  202.         }
  203.     }
  204.     else{
  205.         /*
  206.          * This section does not exist so create a new frchainS struct fill
  207.          * it in, link it to the chain
  208.          */
  209.         frcP = (frchainS *)xmalloc(sizeof(frchainS));
  210.         memset(frcP, '\0', sizeof(frchainS));
  211.         strncpy(frcP->frch_section.segname, segname,
  212.             sizeof(frcP->frch_section.segname));
  213.         strncpy(frcP->frch_section.sectname, sectname,
  214.             sizeof(frcP->frch_section.sectname));
  215.         frcP->frch_section.flags = attributes | type;
  216.         frcP->frch_section.reserved2 = sizeof_stub;
  217.  
  218.         frcP->frch_nsect = last_nsect + 1;
  219.  
  220.         *lastPP = frcP;
  221.  
  222.         /*
  223.          * For zerofill sections no frag is created here so just return.
  224.          * For non-zerofill section create the sections new frag and
  225.          * make the section the current chain.
  226.          */
  227.         if(type == S_ZEROFILL){
  228.         return(frcP);
  229.         }
  230.         else{
  231.         /*
  232.          * Make a fresh frag for the new section.
  233.          */
  234.         frag_now = (fragS *)obstack_alloc(&frags, SIZEOF_STRUCT_FRAG);
  235.         memset(frag_now, '\0', SIZEOF_STRUCT_FRAG);
  236.         frag_now->fr_next = NULL;
  237.  
  238.         /*
  239.          * Append the new frag to new frchain.
  240.          */
  241.         frcP->frch_root = frag_now;
  242.         frcP->frch_last = frag_now;
  243.  
  244.         /*
  245.          * Make this section the current section.
  246.          */
  247.         frchain_now = frcP;
  248.         }
  249.     }
  250.     return(frchain_now);
  251. }
  252.