Annotation of GNUtools/cctools/as/sections.c, revision 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.