Annotation of GNUtools/cctools/as/sections.c, revision 1.1.1.1

1.1       root        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) != attributes){
                    134:                as_warn("section attributes does not match previous section "
                    135:                        "attributes");
                    136:            }
                    137:        }
                    138: 
                    139:        /*
                    140:         * If the current section is the same as for this call there is nothing
                    141:         * more to do.
                    142:         */
                    143:        if(frcP != NULL && (frchain_now == frcP || type == S_ZEROFILL)){
                    144:            return(frcP);
                    145:        }
                    146: 
                    147:        /*
                    148:         * For non-zerofill sections it will be made the current section so deal
                    149:         * with the current frag.
                    150:         */
                    151:        if(type != S_ZEROFILL){
                    152:            /*
                    153:             * If there is any current frag in the old section close it off.
                    154:             */
                    155:            if(frag_now != NULL){
                    156:                frag_now->fr_fix = obstack_next_free(&frags) -
                    157:                                   frag_now->fr_literal;
                    158:                frag_wane(frag_now);
                    159:            }
                    160: 
                    161:            /*
                    162:             * We must do the obstack_finish(), so the next object we put on
                    163:             * obstack frags will not appear to start at the fr_literal of the
                    164:             * current frag.  Also, it ensures that the next object will begin
                    165:             * on a address that is aligned correctly for the engine that runs
                    166:             * the assembler.
                    167:             */
                    168:            obstack_finish(&frags);
                    169:        }
                    170: 
                    171:        /*
                    172:         * If this section exists since it is not the current section switch to
                    173:         * it by making it the current chain and create a new frag in it.
                    174:         */
                    175:        if(frcP != NULL){
                    176:            /*
                    177:             * For a zerofill section no frags are created here and since it
                    178:             * exist just return a pointer to the section.
                    179:             */
                    180:            if((frcP->frch_section.flags & SECTION_TYPE) == S_ZEROFILL){
                    181:                return(frcP);
                    182:            }
                    183:            else{
                    184:                /*
                    185:                 * Make this section the current section.
                    186:                 */
                    187:                frchain_now = frcP;
                    188: 
                    189:                /*
                    190:                 * Make a fresh frag for the section.
                    191:                 */
                    192:                frag_now = (fragS *)obstack_alloc(&frags, SIZEOF_STRUCT_FRAG);
                    193:                memset(frag_now, '\0', SIZEOF_STRUCT_FRAG);
                    194:                frag_now->fr_next = NULL;
                    195: 
                    196:                /*
                    197:                 * Append the new frag to the existing frchain.
                    198:                 */
                    199:                frchain_now->frch_last->fr_next = frag_now;
                    200:                frchain_now->frch_last = frag_now;
                    201:            }
                    202:        }
                    203:        else{
                    204:            /*
                    205:             * This section does not exist so create a new frchainS struct fill
                    206:             * it in, link it to the chain
                    207:             */
                    208:            frcP = (frchainS *)xmalloc(sizeof(frchainS));
                    209:            memset(frcP, '\0', sizeof(frchainS));
                    210:            strncpy(frcP->frch_section.segname, segname,
                    211:                    sizeof(frcP->frch_section.segname));
                    212:            strncpy(frcP->frch_section.sectname, sectname,
                    213:                    sizeof(frcP->frch_section.sectname));
                    214:            frcP->frch_section.flags = attributes | type;
                    215:            frcP->frch_section.reserved2 = sizeof_stub;
                    216: 
                    217:            frcP->frch_nsect = last_nsect + 1;
                    218: 
                    219:            *lastPP = frcP;
                    220: 
                    221:            /*
                    222:             * For zerofill sections no frag is created here so just return.
                    223:             * For non-zerofill section create the sections new frag and
                    224:             * make the section the current chain.
                    225:             */
                    226:            if(type == S_ZEROFILL){
                    227:                return(frcP);
                    228:            }
                    229:            else{
                    230:                /*
                    231:                 * Make a fresh frag for the new section.
                    232:                 */
                    233:                frag_now = (fragS *)obstack_alloc(&frags, SIZEOF_STRUCT_FRAG);
                    234:                memset(frag_now, '\0', SIZEOF_STRUCT_FRAG);
                    235:                frag_now->fr_next = NULL;
                    236: 
                    237:                /*
                    238:                 * Append the new frag to new frchain.
                    239:                 */
                    240:                frcP->frch_root = frag_now;
                    241:                frcP->frch_last = frag_now;
                    242: 
                    243:                /*
                    244:                 * Make this section the current section.
                    245:                 */
                    246:                frchain_now = frcP;
                    247:            }
                    248:        }
                    249:        return(frchain_now);
                    250: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.