1 /*
2 * kobj.c - identify and parse a sparc object file
3 */
4 #include <lib9.h>
5 #include <bio.h>
6 #include "mach.h"
7 #include "kc/k.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
_isk(char * s)23 _isk(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
_readk(Biobuf * bp,Prog * p)33 _readk(Biobuf *bp, Prog *p)
34 {
35 int as, n;
36 Addr a;
37
38 as = Bgetc(bp); /* as */
39 if(as < 0)
40 return 0;
41 p->kind = aNone;
42 p->sig = 0;
43 if(as == ANAME || as == ASIGNAME){
44 if(as == ASIGNAME){
45 Bread(bp, &p->sig, 4);
46 p->sig = beswal(p->sig);
47 }
48 p->kind = aName;
49 p->type = type2char(Bgetc(bp)); /* type */
50 p->sym = Bgetc(bp); /* sym */
51 n = 0;
52 for(;;) {
53 as = Bgetc(bp);
54 if(as < 0)
55 return 0;
56 n++;
57 if(as == 0)
58 break;
59 }
60 p->id = malloc(n);
61 if(p->id == 0)
62 return 0;
63 Bseek(bp, -n, 1);
64 if(Bread(bp, p->id, n) != n)
65 return 0;
66 return 1;
67 }
68 if(as == ATEXT)
69 p->kind = aText;
70 else if(as == AGLOBL)
71 p->kind = aData;
72 skip(bp, 5); /* reg (1 byte); lineno (4 bytes) */
73 a = addr(bp);
74 addr(bp);
75 if(a.type != D_OREG || a.name != D_STATIC && a.name != D_EXTERN)
76 p->kind = aNone;
77 p->sym = a.sym;
78 return 1;
79 }
80
81 static Addr
addr(Biobuf * bp)82 addr(Biobuf *bp)
83 {
84 Addr a;
85 long off;
86
87 a.type = Bgetc(bp); /* a.type */
88 skip(bp, 1); /* reg */
89 a.sym = Bgetc(bp); /* sym index */
90 a.name = Bgetc(bp); /* sym type */
91 switch(a.type) {
92 default:
93 case D_NONE: case D_REG: case D_FREG: case D_CREG: case D_PREG:
94 break;
95 case D_BRANCH:
96 case D_OREG:
97 case D_ASI:
98 case D_CONST:
99 off = Bgetc(bp);
100 off |= Bgetc(bp) << 8;
101 off |= Bgetc(bp) << 16;
102 off |= Bgetc(bp) << 24;
103 if(off < 0)
104 off = -off;
105 if(a.sym!=0 && (a.name==D_PARAM || a.name==D_AUTO))
106 _offset(a.sym, off);
107 break;
108 case D_SCONST:
109 skip(bp, NSNAME);
110 break;
111 case D_FCONST:
112 skip(bp, 8);
113 break;
114 }
115 return a;
116 }
117
118
119 static char
type2char(int t)120 type2char(int t)
121 {
122 switch(t){
123 case D_EXTERN: return 'U';
124 case D_STATIC: return 'b';
125 case D_AUTO: return 'a';
126 case D_PARAM: return 'p';
127 default: return UNKNOWN;
128 }
129 }
130
131 static void
skip(Biobuf * bp,int n)132 skip(Biobuf *bp, int n)
133 {
134 while (n-- > 0)
135 Bgetc(bp);
136 }
137