|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.