|
|
1.1 ! root 1: /* ! 2: * obj.c ! 3: * routines universal to all object files ! 4: */ ! 5: #include <u.h> ! 6: #include <libc.h> ! 7: #include <bio.h> ! 8: #include <ar.h> ! 9: #include <mach.h> ! 10: #include "obj.h" ! 11: ! 12: #define islocal(t) ((t)=='a' || (t)=='p') ! 13: ! 14: enum ! 15: { ! 16: NNAMES = 50, ! 17: MAXIS = 8, /* max length to determine if a file is a .? file */ ! 18: MAXOFF = 0x7fffffff, /* larger than any possible local offset */ ! 19: NHASH = 1024, /* must be power of two */ ! 20: HASHMUL = 79L, ! 21: }; ! 22: ! 23: int _is2(char*), /* in [$OS].c */ ! 24: _is6(char*), ! 25: _is8(char*), ! 26: _isk(char*), ! 27: _isv(char*), ! 28: _isx(char*), ! 29: _read2(Biobuf*, Prog*), ! 30: _read6(Biobuf*, Prog*), ! 31: _read8(Biobuf*, Prog*), ! 32: _readk(Biobuf*, Prog*), ! 33: _readv(Biobuf*, Prog*), ! 34: _readx(Biobuf*, Prog*); ! 35: ! 36: typedef struct Obj Obj; ! 37: typedef struct Symtab Symtab; ! 38: ! 39: struct Obj /* functions to handle each intermediate (.$O) file */ ! 40: { ! 41: char *name; /* name of each $O file */ ! 42: int (*is)(char*); /* test for each type of $O file */ ! 43: int (*read)(Biobuf*, Prog*); /* read for each type of $O file*/ ! 44: }; ! 45: ! 46: static Obj obj[] = ! 47: { /* functions to identify and parse each type of obj */ ! 48: [Obj68020] "68020 .2", _is2, _read2, ! 49: [ObjSparc] "sparc .k", _isk, _readk, ! 50: [ObjMips] "mips .v", _isv, _readv, ! 51: [Obj386] "386 .8", _is8, _read8, ! 52: [Obj960] "960 .6", _is6, _read6, ! 53: [Obj3210] "3210 .x", _isx, _readx, ! 54: [Maxobjtype] 0, 0 ! 55: }; ! 56: ! 57: struct Symtab ! 58: { ! 59: struct Sym s; ! 60: struct Symtab *next; ! 61: }; ! 62: ! 63: static Symtab *hash[NHASH]; ! 64: static Sym *names[NNAMES]; /* working set of active names */ ! 65: ! 66: static int processprog(Prog*,int); /* decode each symbol reference */ ! 67: static void objreset(void); ! 68: static void objlookup(int, char *, int ); ! 69: static void objupdate(int, int); ! 70: ! 71: int ! 72: objtype(Biobuf *bp, char **name) ! 73: { ! 74: int i; ! 75: char buf[MAXIS]; ! 76: ! 77: if(Bread(bp, buf, MAXIS) < MAXIS) ! 78: return -1; ! 79: Bseek(bp, -MAXIS, 1); ! 80: for (i = 0; obj[i].is; i++) { ! 81: if ((*obj[i].is)(buf)) { ! 82: if (name) ! 83: *name = obj[i].name; ! 84: return i; ! 85: } ! 86: } ! 87: return -1; ! 88: } ! 89: ! 90: int ! 91: isar(Biobuf *bp) ! 92: { ! 93: int n; ! 94: char magbuf[SARMAG]; ! 95: ! 96: n = Bread(bp, magbuf, SARMAG); ! 97: if(n == SARMAG && strncmp(magbuf, ARMAG, SARMAG) == 0) ! 98: return 1; ! 99: return 0; ! 100: } ! 101: ! 102: /* ! 103: * determine what kind of object file this is and process it. ! 104: * return whether or not this was a recognized intermediate file. ! 105: */ ! 106: int ! 107: readobj(Biobuf *bp, int objtype) ! 108: { ! 109: Prog p; ! 110: ! 111: if (objtype < 0 || objtype >= Maxobjtype) ! 112: return 1; ! 113: objreset(); ! 114: while ((*obj[objtype].read)(bp, &p)) ! 115: if (!processprog(&p, 1)) ! 116: return 0; ! 117: return 1; ! 118: } ! 119: ! 120: int ! 121: readar(Biobuf *bp, int objtype, int end, int doautos) ! 122: { ! 123: Prog p; ! 124: ! 125: if (objtype < 0 || objtype >= Maxobjtype) ! 126: return 1; ! 127: objreset(); ! 128: while ((*obj[objtype].read)(bp, &p) && BOFFSET(bp) < end) ! 129: if (!processprog(&p, doautos)) ! 130: return 0; ! 131: return 1; ! 132: } ! 133: ! 134: /* ! 135: * decode a symbol reference or definition ! 136: */ ! 137: static int ! 138: processprog(Prog *p, int doautos) ! 139: { ! 140: if(p->kind == aNone) ! 141: return 1; ! 142: if(p->sym < 0 || p->sym >= NNAMES) ! 143: return 0; ! 144: switch(p->kind) ! 145: { ! 146: case aName: ! 147: if (!doautos) ! 148: if(p->type != 'U' && p->type != 'b') ! 149: break; ! 150: objlookup(p->sym, p->id, p->type); ! 151: break; ! 152: case aText: ! 153: objupdate(p->sym, 'T'); ! 154: break; ! 155: case aData: ! 156: objupdate(p->sym, 'D'); ! 157: break; ! 158: default: ! 159: break; ! 160: } ! 161: return 1; ! 162: } ! 163: ! 164: /* ! 165: * find the entry for s in the symbol array. ! 166: * make a new entry if it is not already there. ! 167: */ ! 168: static void ! 169: objlookup(int id, char *name, int type) ! 170: { ! 171: long h; ! 172: char *cp; ! 173: Sym *s; ! 174: Symtab *sp; ! 175: ! 176: s = names[id]; ! 177: if(s && strcmp(s->name, name) == 0) { ! 178: s->type = type; ! 179: return; ! 180: } ! 181: ! 182: h = *name; ! 183: for(cp = name+1; *cp; h += *cp++) ! 184: h *= HASHMUL; ! 185: if(h < 0) ! 186: h = ~h; ! 187: h &= (NHASH-1); ! 188: if (type == 'U' || type == 'b' || islocal(type)) { ! 189: for(sp = hash[h]; sp; sp = sp->next) ! 190: if(strcmp(sp->s.name, name) == 0) { ! 191: switch(sp->s.type) { ! 192: case 'T': ! 193: case 'D': ! 194: case 'U': ! 195: if (type == 'U') { ! 196: names[id] = &sp->s; ! 197: return; ! 198: } ! 199: break; ! 200: case 't': ! 201: case 'd': ! 202: case 'b': ! 203: if (type == 'b') { ! 204: names[id] = &sp->s; ! 205: return; ! 206: } ! 207: break; ! 208: case 'a': ! 209: case 'p': ! 210: if (islocal(type)) { ! 211: names[id] = &sp->s; ! 212: return; ! 213: } ! 214: break; ! 215: default: ! 216: break; ! 217: } ! 218: } ! 219: } ! 220: sp = malloc(sizeof(Symtab)); ! 221: sp->s.name = name; ! 222: sp->s.type = type; ! 223: sp->s.value = islocal(type) ? MAXOFF : 0; ! 224: names[id] = &sp->s; ! 225: sp->next = hash[h]; ! 226: hash[h] = sp; ! 227: return; ! 228: } ! 229: /* ! 230: * traverse the symbol lists ! 231: */ ! 232: void ! 233: objtraverse(void (*fn)(Sym*, void*), void *pointer) ! 234: { ! 235: int i; ! 236: Symtab *s; ! 237: ! 238: for(i = 0; i < NHASH; i++) ! 239: for(s = hash[i]; s; s = s->next) ! 240: (*fn)(&s->s, pointer); ! 241: } ! 242: ! 243: /* ! 244: * update the offset information for a 'a' or 'p' symbol in an intermediate file ! 245: */ ! 246: void ! 247: _offset(int id, long off) ! 248: { ! 249: Sym *s; ! 250: ! 251: s = names[id]; ! 252: if (s && s->name[0] && islocal(s->type) && s->value > off) ! 253: s->value = off; ! 254: } ! 255: ! 256: /* ! 257: * update the type of a global text or data symbol ! 258: */ ! 259: static void ! 260: objupdate(int id, int type) ! 261: { ! 262: Sym *s; ! 263: ! 264: s = names[id]; ! 265: if (s && s->name[0]) ! 266: if (s->type == 'U') ! 267: s->type = type; ! 268: else if (s->type == 'b') ! 269: s->type = tolower(type); ! 270: } ! 271: ! 272: /* ! 273: * look for the next file in an archive ! 274: */ ! 275: int ! 276: nextar(Biobuf *bp, int offset, char *buf) ! 277: { ! 278: struct ar_hdr a; ! 279: int i, r; ! 280: long arsize; ! 281: ! 282: if (offset&01) ! 283: offset++; ! 284: Bseek(bp, offset, 0); ! 285: r = Bread(bp, &a, SAR_HDR); ! 286: if(r != SAR_HDR) ! 287: return 0; ! 288: if(strncmp(a.fmag, ARFMAG, sizeof(a.fmag))) ! 289: return -1; ! 290: for(i=0; i<sizeof(a.name) && i<SARNAME && a.name[i] != ' '; i++) ! 291: buf[i] = a.name[i]; ! 292: buf[i] = 0; ! 293: arsize = atol(a.size); ! 294: if (arsize&1) ! 295: arsize++; ! 296: return arsize + SAR_HDR; ! 297: } ! 298: ! 299: static void ! 300: objreset(void) ! 301: { ! 302: int i; ! 303: Symtab *s, *n; ! 304: ! 305: for(i = 0; i < NHASH; i++) { ! 306: for(s = hash[i]; s; s = n) { ! 307: n = s->next; ! 308: free(s->s.name); ! 309: free(s); ! 310: } ! 311: hash[i] = 0; ! 312: } ! 313: memset(names, 0, sizeof names); ! 314: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.