|
|
1.1 root 1: /*
2: * xobj.c - identify and parse a 3210 object file
3: */
4: #include <u.h>
5: #include <libc.h>
6: #include <bio.h>
7: #include "xc/x.out.h"
8: #include "obj.h"
9:
10: typedef struct Addr Addr;
11: struct Addr
12: {
13: char type;
14: char sym;
15: char name;
16: };
17: static Addr addr(Biobuf*);
18: static char type2char(int);
19: static void skip(Biobuf*, int);
20:
21:
22: int
23: _isx(char *s)
24: {
25: return s[0] == ANAME /* ANAME */
26: && s[1] == D_FILE /* type */
27: && s[2] == 1 /* sym */
28: && s[3] == '<'; /* name of file */
29: }
30:
31:
32: int
33: _readx(Biobuf *bp, Prog *p)
34: {
35: int as, n, isf;
36: Addr a;
37:
38: as = Bgetc(bp); /* as */
39: if(as < 0)
40: return 0;
41: p->kind = aNone;
42: if(as == ANAME){
43: p->kind = aName;
44: p->type = type2char(Bgetc(bp)); /* type */
45: p->sym = Bgetc(bp); /* sym */
46: n = 0;
47: for(;;) {
48: as = Bgetc(bp);
49: if(as < 0)
50: return 0;
51: n++;
52: if(as == 0)
53: break;
54: }
55: p->id = malloc(n);
56: if(p->id == 0)
57: return 0;
58: Bseek(bp, -n, 1);
59: if(Bread(bp, p->id, n) != n)
60: return 0;
61: return 1;
62: }
63: if(as == ATEXT)
64: p->kind = aText;
65: else if(as == AGLOBL)
66: p->kind = aData;
67: Bgetc(bp); /* reg */
68: isf = Bgetc(bp) >> 6; /* cc & flt */
69: skip(bp, 4); /* lineno */
70: a = addr(bp);
71: addr(bp);
72: if(isf > 1)
73: addr(bp);
74: if(isf > 2)
75: addr(bp);
76: if(a.type != D_NAME || a.name != D_STATIC && a.name != D_EXTERN)
77: p->kind = aNone;
78: p->sym = a.sym;
79: return 1;
80: }
81:
82: static Addr
83: addr(Biobuf *bp)
84: {
85: Addr a;
86: long off;
87:
88: a.type = Bgetc(bp); /* a.type */
89: skip(bp, 1); /* reg */
90: a.sym = Bgetc(bp); /* sym index */
91: a.name = Bgetc(bp); /* sym type */
92: switch(a.type) {
93: default:
94: case D_NONE: case D_REG: case D_FREG: case D_CREG:
95: case D_INDREG: case D_INC: case D_DEC:
96: break;
97: case D_INCREG:
98: Bgetc(bp);
99: break;
100: case D_BRANCH:
101: case D_OREG:
102: case D_NAME:
103: case D_CONST:
104: off = Bgetc(bp);
105: off |= Bgetc(bp) << 8;
106: off |= Bgetc(bp) << 16;
107: off |= Bgetc(bp) << 24;
108: if(off < 0)
109: off = -off;
110: if(a.sym!=0 && (a.name==D_PARAM || a.name==D_AUTO))
111: _offset(a.sym, off);
112: break;
113: case D_SCONST:
114: skip(bp, NSNAME);
115: break;
116: case D_FCONST:
117: case D_AFCONST:
118: skip(bp, 4);
119: break;
120: }
121: return a;
122: }
123:
124:
125: static char
126: type2char(int t)
127: {
128: switch(t){
129: case D_EXTERN: return 'U';
130: case D_STATIC: return 'b';
131: case D_AUTO: return 'a';
132: case D_PARAM: return 'p';
133: default: return UNKNOWN;
134: }
135: }
136:
137: static void
138: skip(Biobuf *bp, int n)
139: {
140: while (n-- > 0)
141: Bgetc(bp);
142: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.