|
|
1.1 ! root 1: static char ID[] = "@(#) util.c: 1.5 5/27/83"; ! 2: #include "system.h" ! 3: ! 4: #include <stdio.h> ! 5: #include <signal.h> ! 6: #include "structs.h" ! 7: #include "extrns.h" ! 8: #include "sgs.h" ! 9: #include "sgsmacros.h" ! 10: ! 11: #define INT int ! 12: #define BUSY 1 ! 13: #define testbusy(p) ((INT)(p)&BUSY) ! 14: /*eject*/ ! 15: ACTITEM * ! 16: dfnscngrp(type, bondaddr, align, block) ! 17: int type; ! 18: ADDRESS *bondaddr, *align, *block; ! 19: { ! 20: ! 21: /* ! 22: * Build a AIDFNSCN/AIDFNGRP action item ! 23: */ ! 24: ! 25: ACTITEM *p; ! 26: ! 27: p = (ACTITEM *) myalloc(sizeof(ACTITEM)); ! 28: ! 29: p->dfnscn.aiinflnm = curfilnm; ! 30: p->dfnscn.aiinlnno = lineno; ! 31: p->dfnscn.aitype = type; ! 32: p->dfnscn.aibndadr = -1L; ! 33: p->dfnscn.aialign = 0L; ! 34: p->dfnscn.aiblock = 0L; ! 35: ! 36: if ( bondaddr != NULL ) { /* there is a bond */ ! 37: p->dfnscn.aibndadr = *bondaddr; ! 38: } ! 39: ! 40: if (align != NULL) { /* there is alignment */ ! 41: p->dfnscn.aialign = *align; ! 42: chkpower2(p->dfnscn.aialign); ! 43: } ! 44: ! 45: if (block) { ! 46: p->dfnscn.aiblock = *block; ! 47: chkpower2(*block); ! 48: } ! 49: ! 50: return(p); ! 51: } ! 52: /*eject*/ ! 53: chkpower2(n) ! 54: long n; ! 55: { ! 56: ! 57: /* ! 58: * Determine if 'n' is a power of two ! 59: */ ! 60: ! 61: long c; ! 62: ! 63: for( c = n; c > 2; c >>= 1 ) ! 64: if( (c % 2) == 1 ) { ! 65: lderror(0, lineno, curfilnm, "%.1lx is not a power of 2", n ); ! 66: break; ! 67: } ! 68: } ! 69: /*eject*/ ! 70: char * ! 71: zero(ptr, cnt) ! 72: char *ptr; ! 73: int cnt; ! 74: { ! 75: ! 76: /* ! 77: * Zero "cnt" bytes starting at the address "ptr". ! 78: * Return "ptr". ! 79: */ ! 80: ! 81: register char *p, *w; ! 82: ! 83: if( cnt > 0 ) { ! 84: if( ((short) (p = ptr)) & 1 ) { ! 85: *p++ = '\0'; ! 86: --cnt; ! 87: } ! 88: ! 89: w = p + (cnt & (~1)); ! 90: while (p < w) { ! 91: *((short *) p) = 0; ! 92: p += sizeof(short); ! 93: } ! 94: ! 95: if (cnt & 1) ! 96: *p = '\0'; ! 97: } ! 98: ! 99: return( ptr ); ! 100: } ! 101: /*eject*/ ! 102: zerofile(fildes,bptr,bsiz) ! 103: FILE *fildes; /* write opened file */ ! 104: unsigned *bptr; /* zero filled buffer */ ! 105: int bsiz; /* size of buffer */ ! 106: { ! 107: long file_end; ! 108: OUTSECT *osptr; ! 109: /* ! 110: * Insure that fildes is zero filled up to the point ! 111: * of symbol table origin, or up to the last section if the symbol ! 112: * table is stripped. Under TS, we simply seek to the point ! 113: * and write one unsigned. Under RT or DMERT we must write 0's ! 114: * throughout the entire space. ! 115: */ ! 116: #if PAGING ! 117: if (Fflag || !sflag) ! 118: #else ! 119: if (!sflag) ! 120: #endif ! 121: file_end = symtborg - 4; ! 122: else ! 123: { ! 124: file_end = 0L; ! 125: for (osptr = (OUTSECT *) outsclst.head; osptr; osptr = osptr->osnext) ! 126: file_end = max( file_end, osptr->oshdr.s_scnptr ); ! 127: ! 128: } ! 129: ! 130: #if RT ! 131: rewind(fildes); ! 132: while ( file_end > ftell(fildes) ) ! 133: fwrite( (char*) bptr, bsiz, 1, fildes); ! 134: #else ! 135: fseek(fildes, file_end, 0); ! 136: fwrite( (char *) bptr, sizeof(long), 1, fildes); ! 137: #endif ! 138: rewind(fildes); /* leave everythiing as we found it */ ! 139: ! 140: return; ! 141: } ! 142: /*eject*/ ! 143: char * ! 144: sname(s) ! 145: char *s; ! 146: { ! 147: ! 148: /* ! 149: * Returns pointer to "simple" name of path name; that is, ! 150: * pointer to first character after last '/'. If no slashes, ! 151: * returns pointer to first char of arg. ! 152: * ! 153: * If the string ends in a slash: ! 154: * 1. replace the terminating slash with '\0' ! 155: * 2. return a pointer to the first character after the last ! 156: * '/', or the first character in the string ! 157: */ ! 158: ! 159: register char *p; ! 160: ! 161: p = s; ! 162: while( *p ) ! 163: if(*p++ == '/') ! 164: if( *p == '\0' ) { ! 165: *(p-1) = '\0'; ! 166: break; ! 167: } ! 168: else ! 169: s = p; ! 170: ! 171: return(s); ! 172: } ! 173: /*eject*/ ! 174: char * ! 175: myalloc(nbytes) ! 176: int nbytes; ! 177: { ! 178: ! 179: /* ! 180: * Allocate "nbytes" of memory, and exit from ld ! 181: * upon failure. ! 182: */ ! 183: ! 184: register char *mem; ! 185: extern char *calloc(); ! 186: ! 187: if( (mem = calloc(1,nbytes)) == NULL ) { ! 188: lderror(0,0,NULL, "memory allocation failure on %d-byte 'calloc' call", ! 189: nbytes); ! 190: lderror(2,0,NULL, "%s run is too large and complex", SGS ); ! 191: } ! 192: ! 193: allocspc += (long) nbytes; ! 194: maxalloc = max(maxalloc,allocspc); ! 195: ! 196: return(mem); ! 197: } ! 198: ! 199: ! 200: stoi(p) ! 201: char *p; ! 202: { ! 203: ! 204: /* ! 205: * Given a string of digits, perhaps beginning with "0" or "0x", ! 206: * convert to an integer ! 207: * ! 208: * Return 0x8000 on any type of error ! 209: */ ! 210: ! 211: register int base, num; ! 212: register char limit; ! 213: ! 214: num = 0; ! 215: ! 216: if (*p == '0') { ! 217: if (*++p == 'x' || *p == 'X') { /* string is hex */ ! 218: for (p++; *p; p++) { ! 219: num <<= 4; ! 220: if (*p >= '0' && *p <= '9') ! 221: num += *p - '0'; ! 222: else if (*p >= 'a' && *p <= 'f') ! 223: num += *p - 'a' + 10; ! 224: else if (*p >= 'A' && *p <= 'F') ! 225: num += *p - 'A' + 10; ! 226: else return(0x8000); ! 227: } ! 228: return (num); ! 229: } ! 230: else { ! 231: base = 8; ! 232: limit = '7'; ! 233: } ! 234: } ! 235: else { ! 236: base = 10; ! 237: limit = '9'; ! 238: } ! 239: ! 240: for ( ; *p; p++) ! 241: if( (*p >= '0') && (*p <= limit) ) ! 242: num = num * base + *p - '0'; ! 243: else ! 244: return(0x8000); ! 245: ! 246: return(num); ! 247: } ! 248: /*eject*/ ! 249: copybyts(src,dest,len) ! 250: char *src, *dest; ! 251: int len; ! 252: { ! 253: ! 254: /* ! 255: * Copy len bytes from src to dest ! 256: */ ! 257: ! 258: while( len-- > 0 ) ! 259: *dest++ = *src++; ! 260: } ! 261: /*eject*/ ! 262: /*VARARGS*/ ! 263: lderror(lvl, ln,fln,strng, a1,a2,a3,a4,a5,a6,a7,a8,a9,aa) ! 264: int lvl; /* error severity level */ ! 265: int ln; /* line in ifile containing the error */ ! 266: char *fln; /* name of the ifile containing the error */ ! 267: char *strng; /* error message format */ ! 268: int a1,a2,a3,a4,a5, /* error message format arguments */ ! 269: a6,a7,a8,a9,aa; ! 270: { ! 271: ! 272: /* ! 273: * Prepend a filename and a line number to an error message. ! 274: * used for printing all parsing-related errors. ! 275: */ ! 276: ! 277: errlev = (errlev < lvl ) ? lvl : errlev; ! 278: ! 279: if( Sflag && (lvl != 2) ) ! 280: return; ! 281: ! 282: fprintf(stderr, "%sld", SGS); ! 283: if (fln != NULL) ! 284: fprintf(stderr, " %s", sname(fln)); ! 285: if ( ln > 0 ) ! 286: fprintf(stderr, " %d", ln) ; ! 287: ! 288: switch(lvl) { ! 289: case 0: ! 290: fprintf(stderr, " warning: "); ! 291: break; ! 292: case 2: ! 293: fprintf(stderr, " fatal: "); ! 294: break; ! 295: default: ! 296: fprintf(stderr, ": "); ! 297: break; ! 298: } ! 299: ! 300: fprintf(stderr, strng, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa); ! 301: fprintf(stderr, "\n"); ! 302: fflush(stderr); ! 303: ! 304: if(lvl > 1) ! 305: ldexit(); ! 306: } ! 307:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.