Annotation of lucent/sys/src/libmach/obj.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

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