13e12c5d1SDavid du Colombier /*
2bd389b36SDavid du Colombier * 8obj.c - identify and parse a 386 object file
33e12c5d1SDavid du Colombier */
43e12c5d1SDavid du Colombier #include <u.h>
53e12c5d1SDavid du Colombier #include <libc.h>
63e12c5d1SDavid du Colombier #include <bio.h>
7*0c547597SDavid du Colombier #include <mach.h>
83e12c5d1SDavid du Colombier #include "8c/8.out.h"
93e12c5d1SDavid du Colombier #include "obj.h"
103e12c5d1SDavid du Colombier
113e12c5d1SDavid du Colombier typedef struct Addr Addr;
123e12c5d1SDavid du Colombier struct Addr
133e12c5d1SDavid du Colombier {
143e12c5d1SDavid du Colombier char sym;
153e12c5d1SDavid du Colombier char flags;
163e12c5d1SDavid du Colombier };
17bd389b36SDavid du Colombier static Addr addr(Biobuf*);
183e12c5d1SDavid du Colombier static char type2char(int);
19bd389b36SDavid du Colombier static void skip(Biobuf*, int);
203e12c5d1SDavid du Colombier
213e12c5d1SDavid du Colombier int
_is8(char * t)223e12c5d1SDavid du Colombier _is8(char *t)
233e12c5d1SDavid du Colombier {
243e12c5d1SDavid du Colombier uchar *s = (uchar*)t;
253e12c5d1SDavid du Colombier
263e12c5d1SDavid du Colombier return s[0] == (ANAME&0xff) /* aslo = ANAME */
273e12c5d1SDavid du Colombier && s[1] == ((ANAME>>8)&0xff)
283e12c5d1SDavid du Colombier && s[2] == D_FILE /* type */
293e12c5d1SDavid du Colombier && s[3] == 1 /* sym */
303e12c5d1SDavid du Colombier && s[4] == '<'; /* name of file */
313e12c5d1SDavid du Colombier }
323e12c5d1SDavid du Colombier
33bd389b36SDavid du Colombier int
_read8(Biobuf * bp,Prog * p)34bd389b36SDavid du Colombier _read8(Biobuf *bp, Prog* p)
353e12c5d1SDavid du Colombier {
36219b2ee8SDavid du Colombier int as, n, c;
373e12c5d1SDavid du Colombier Addr a;
383e12c5d1SDavid du Colombier
39bd389b36SDavid du Colombier as = Bgetc(bp); /* as(low) */
403e12c5d1SDavid du Colombier if(as < 0)
413e12c5d1SDavid du Colombier return 0;
42bd389b36SDavid du Colombier c = Bgetc(bp); /* as(high) */
433e12c5d1SDavid du Colombier if(c < 0)
443e12c5d1SDavid du Colombier return 0;
453e12c5d1SDavid du Colombier as |= ((c & 0xff) << 8);
463e12c5d1SDavid du Colombier p->kind = aNone;
47*0c547597SDavid du Colombier p->sig = 0;
48061a3f44SDavid du Colombier if(as == ANAME || as == ASIGNAME){
49*0c547597SDavid du Colombier if(as == ASIGNAME){
50*0c547597SDavid du Colombier Bread(bp, &p->sig, 4);
51*0c547597SDavid du Colombier p->sig = leswal(p->sig);
52*0c547597SDavid du Colombier }
533e12c5d1SDavid du Colombier p->kind = aName;
54bd389b36SDavid du Colombier p->type = type2char(Bgetc(bp)); /* type */
55bd389b36SDavid du Colombier p->sym = Bgetc(bp); /* sym */
56219b2ee8SDavid du Colombier n = 0;
57219b2ee8SDavid du Colombier for(;;) {
58219b2ee8SDavid du Colombier as = Bgetc(bp);
59219b2ee8SDavid du Colombier if(as < 0)
60219b2ee8SDavid du Colombier return 0;
61219b2ee8SDavid du Colombier n++;
62219b2ee8SDavid du Colombier if(as == 0)
63219b2ee8SDavid du Colombier break;
643e12c5d1SDavid du Colombier }
65219b2ee8SDavid du Colombier p->id = malloc(n);
66219b2ee8SDavid du Colombier if(p->id == 0)
67219b2ee8SDavid du Colombier return 0;
68219b2ee8SDavid du Colombier Bseek(bp, -n, 1);
69219b2ee8SDavid du Colombier if(Bread(bp, p->id, n) != n)
70219b2ee8SDavid du Colombier return 0;
71bd389b36SDavid du Colombier return 1;
723e12c5d1SDavid du Colombier }
733e12c5d1SDavid du Colombier if(as == ATEXT)
743e12c5d1SDavid du Colombier p->kind = aText;
753e12c5d1SDavid du Colombier if(as == AGLOBL)
763e12c5d1SDavid du Colombier p->kind = aData;
77bd389b36SDavid du Colombier skip(bp, 4); /* lineno(4) */
78bd389b36SDavid du Colombier a = addr(bp);
79bd389b36SDavid du Colombier addr(bp);
803e12c5d1SDavid du Colombier if(!(a.flags & T_SYM))
813e12c5d1SDavid du Colombier p->kind = aNone;
823e12c5d1SDavid du Colombier p->sym = a.sym;
83bd389b36SDavid du Colombier return 1;
843e12c5d1SDavid du Colombier }
853e12c5d1SDavid du Colombier
863e12c5d1SDavid du Colombier static Addr
addr(Biobuf * bp)87bd389b36SDavid du Colombier addr(Biobuf *bp)
883e12c5d1SDavid du Colombier {
893e12c5d1SDavid du Colombier Addr a;
90bd389b36SDavid du Colombier int t;
913e12c5d1SDavid du Colombier long off;
923e12c5d1SDavid du Colombier
933e12c5d1SDavid du Colombier off = 0;
94bd389b36SDavid du Colombier a.sym = -1;
95bd389b36SDavid du Colombier a.flags = Bgetc(bp); /* flags */
96bd389b36SDavid du Colombier if(a.flags & T_INDEX)
97bd389b36SDavid du Colombier skip(bp, 2);
983e12c5d1SDavid du Colombier if(a.flags & T_OFFSET){
99bd389b36SDavid du Colombier off = Bgetc(bp);
100bd389b36SDavid du Colombier off |= Bgetc(bp) << 8;
101bd389b36SDavid du Colombier off |= Bgetc(bp) << 16;
102bd389b36SDavid du Colombier off |= Bgetc(bp) << 24;
1033e12c5d1SDavid du Colombier if(off < 0)
1043e12c5d1SDavid du Colombier off = -off;
1053e12c5d1SDavid du Colombier }
1063e12c5d1SDavid du Colombier if(a.flags & T_SYM)
107bd389b36SDavid du Colombier a.sym = Bgetc(bp);
1083e12c5d1SDavid du Colombier if(a.flags & T_FCONST)
109bd389b36SDavid du Colombier skip(bp, 8);
1103e12c5d1SDavid du Colombier else
1113e12c5d1SDavid du Colombier if(a.flags & T_SCONST)
112bd389b36SDavid du Colombier skip(bp, NSNAME);
113bd389b36SDavid du Colombier if(a.flags & T_TYPE) {
114bd389b36SDavid du Colombier t = Bgetc(bp);
1153e12c5d1SDavid du Colombier if(a.sym > 0 && (t==D_PARAM || t==D_AUTO))
116bd389b36SDavid du Colombier _offset(a.sym, off);
117bd389b36SDavid du Colombier }
1183e12c5d1SDavid du Colombier return a;
1193e12c5d1SDavid du Colombier }
1203e12c5d1SDavid du Colombier
1213e12c5d1SDavid du Colombier static char
type2char(int t)1223e12c5d1SDavid du Colombier type2char(int t)
1233e12c5d1SDavid du Colombier {
1243e12c5d1SDavid du Colombier switch(t){
1253e12c5d1SDavid du Colombier case D_EXTERN: return 'U';
1263e12c5d1SDavid du Colombier case D_STATIC: return 'b';
1273e12c5d1SDavid du Colombier case D_AUTO: return 'a';
1283e12c5d1SDavid du Colombier case D_PARAM: return 'p';
1293e12c5d1SDavid du Colombier default: return UNKNOWN;
1303e12c5d1SDavid du Colombier }
1313e12c5d1SDavid du Colombier }
132bd389b36SDavid du Colombier
133bd389b36SDavid du Colombier static void
skip(Biobuf * bp,int n)134bd389b36SDavid du Colombier skip(Biobuf *bp, int n)
135bd389b36SDavid du Colombier {
136bd389b36SDavid du Colombier while (n-- > 0)
137bd389b36SDavid du Colombier Bgetc(bp);
138bd389b36SDavid du Colombier }
139