867
|
1 #include <stdio.h>
|
|
2
|
|
3 /* rdump: prints formatted dump of .r and .l files
|
|
4
|
|
5 rdump [opts] <file>[ <file>] [opts]
|
|
6
|
|
7 options:
|
|
8 -g - add global definition info
|
|
9 -r - add reference info
|
|
10 -o - add reference and local offset info
|
|
11 -a - all of the above
|
|
12 */
|
|
13
|
|
14 /* symbol table types */
|
|
15
|
|
16 /* symbol definition/reference type/location */
|
|
17
|
|
18 /* type flags */
|
|
19 #define CODENT 0x04 /* data/code flag */
|
|
20 /* data type flags */
|
|
21 #define DIRENT 0x02 /* global/direct flag */
|
|
22 #define INIENT 0x01 /* clear/init. data flag */
|
|
23
|
|
24 /* location flags */
|
|
25 #define CODLOC 0x20 /* data/code flag */
|
|
26 #define DIRLOC 0x10 /* global/direct flag */
|
|
27 #define LOC1BYT 0x08 /* two/one byte size flag */
|
|
28 #define LOCMASK (CODLOC|DIRLOC)
|
|
29
|
|
30 #define NEGMASK 0x40 /* negate on resolution */
|
|
31 #define RELATIVE 0x80 /* relative reference */
|
|
32
|
|
33 /* misc. constants */
|
|
34 #define ROFSYNC 0x62CD2387
|
|
35 #define SYMLEN 9 /* Length of symbols */
|
|
36 #define MAXNAME 16 /* length of module name */
|
|
37
|
|
38 /* definition/reference */
|
|
39 typedef struct {
|
|
40 char r_flag; /* type/location */
|
|
41 unsigned r_offset;
|
|
42 } def_ref;
|
|
43
|
|
44 /* rof header structure */
|
|
45 typedef struct {
|
|
46 long h_sync;
|
|
47 unsigned h_tylan;
|
|
48 char h_valid;
|
|
49 char h_date[5];
|
|
50 char h_edit;
|
|
51 char h_spare;
|
|
52 unsigned h_glbl;
|
|
53 unsigned h_dglbl;
|
|
54 unsigned h_data;
|
|
55 unsigned h_ddata;
|
|
56 unsigned h_ocode;
|
|
57 unsigned h_stack;
|
|
58 unsigned h_entry;
|
|
59 } binhead;
|
|
60
|
|
61 #define MAXSOURCE 20
|
|
62 #define puts(s) fputs(s,stdout)
|
|
63 #define mc(c) ((c)&0xff)
|
|
64
|
|
65 #define DEF 1
|
|
66 #define REF 2
|
|
67
|
|
68 direct char *snames[MAXSOURCE],*fname;
|
|
69 direct int scount;
|
|
70 direct int gflag,rflag,oflag;
|
|
71
|
|
72 binhead hd;
|
|
73 FILE *in;
|
|
74
|
|
75 main(argc,argv)
|
|
76 int argc;
|
|
77 char **argv;
|
|
78 {
|
|
79
|
|
80 register char *p;
|
|
81
|
|
82 while (--argc>0) {
|
|
83 if(*(p=*++argv)=='-') {
|
|
84 while(*++p) switch(*p) {
|
|
85 case 'g': gflag=1; break;
|
|
86 case 'r': rflag=1; break;
|
|
87 case 'o': oflag=1; break;
|
|
88 case 'a': gflag=rflag=oflag=1; break;
|
|
89 default: error("unknown option -%c",*p);
|
|
90 }
|
|
91 done: ;
|
|
92 }
|
|
93 else {
|
|
94 if(scount==MAXSOURCE) error(0,"too many source files");
|
|
95 snames[scount++]=*argv;
|
|
96 }
|
|
97 }
|
|
98 pass1();
|
|
99 }
|
|
100
|
|
101 pass1()
|
|
102 {
|
|
103 int count;
|
|
104
|
|
105 if(scount == 0)
|
|
106 return;
|
|
107
|
|
108 for(count=0; count<scount; ++count) {
|
|
109 fname = snames[count];
|
|
110 if((in = fopen(fname,"r")) == NULL) {
|
|
111 printf("can't open '%s'",fname);
|
|
112 continue;
|
|
113 }
|
|
114
|
|
115 for(;;) {
|
|
116 if(fread(&hd,sizeof(hd),1,in) == 0)
|
|
117 break;
|
|
118
|
|
119 if(hd.h_sync != ROFSYNC) {
|
|
120 printf("'%s' is not a relocatable module",fname);
|
|
121 break;
|
|
122 }
|
|
123
|
|
124 showhead();
|
|
125 showglobs();
|
|
126
|
|
127 /* skip code and initialized data */
|
|
128 fseek(in,(long)(hd.h_ocode + hd.h_ddata + hd.h_data),1);
|
|
129
|
|
130 showrefs();
|
|
131 showlcls();
|
|
132
|
|
133 }
|
|
134 fclose(in);
|
|
135 }
|
|
136 }
|
|
137
|
|
138 showhead()
|
|
139 {
|
|
140 int c;
|
|
141
|
|
142 puts("\nModule name: ");
|
|
143 while(c=getc(in))
|
|
144 putchar(c);
|
|
145 if(ferror(in)) ferr(fname);
|
|
146
|
|
147 printf("\nTyLa/RvAt: %02x/%02x\n",mc(hd.h_tylan>>8),mc(hd.h_tylan));
|
|
148 printf("Asm valid: %s\n",hd.h_valid ? "No" : "Yes");
|
|
149 printf("Create date: %.3s %2d, %4d %02d:%02d\n",
|
|
150 &("JanFebMarAprMayJunJulAugSepOctNovDec"[(mc(hd.h_date[1])-1)*3]),
|
|
151 mc(hd.h_date[2]),1900+mc(hd.h_date[0]),
|
|
152 mc(hd.h_date[3]),mc(hd.h_date[4]));
|
|
153 printf("Edition: %2d\n",hd.h_edit);
|
|
154 puts(" Section Init Uninit\n");
|
|
155 printf(" Code: %04x\n",hd.h_ocode);
|
|
156 printf(" DP: %02x %02x\n",hd.h_ddata,hd.h_dglbl);
|
|
157 printf(" Data: %04x %04x\n",hd.h_data,hd.h_glbl);
|
|
158 printf(" Stack: %04x\n",hd.h_stack);
|
|
159 printf("Entry point: %04x\n",hd.h_entry);
|
|
160 }
|
|
161 showglobs()
|
|
162 {
|
|
163 register unsigned count,offset;
|
|
164 char sym[SYMLEN+1],flag;
|
|
165
|
|
166 count=getw(in); /* global def count */
|
|
167 if(gflag)
|
|
168 printf("\n%u global symbols defined:\n",count);
|
|
169
|
|
170 while(count--) {
|
|
171 getname(sym);
|
|
172 flag=getc(in);
|
|
173 offset=getw(in);
|
|
174 if(gflag) {
|
|
175 printf(" %9s %04x ",sym,offset);
|
|
176 ftext(flag,DEF);
|
|
177 }
|
|
178 }
|
|
179 }
|
|
180
|
|
181 getname(s)
|
|
182 register char *s;
|
|
183 {
|
|
184 while(*s++ = getc(in));
|
|
185 *s = '\0';
|
|
186 if(ferror(in)) ferr(fname);
|
|
187 }
|
|
188
|
|
189 ftext(c,ref)
|
|
190 char c;
|
|
191 int ref;
|
|
192 {
|
|
193
|
|
194 printf("(%02x) ",mc(c));
|
|
195 if(ref & REF) {
|
|
196 if(c & CODLOC)
|
|
197 puts("in code");
|
|
198 else puts(c & DIRLOC ? "in dp data" : "in non-dp data");
|
|
199
|
|
200 puts(c & LOC1BYT ? "/byte" : "/word");
|
|
201 if(c & NEGMASK)
|
|
202 puts("/neg");
|
|
203 if(c & RELATIVE)
|
|
204 puts("/pcr");
|
|
205 }
|
|
206 if(ref & DEF) {
|
|
207 if(ref & REF)
|
|
208 puts(" - ");
|
|
209 if(c & CODENT)
|
|
210 puts("to code");
|
|
211 else {
|
|
212 puts(c & DIRENT ? "to dp" : "to non-dp");
|
|
213 puts(c & INIENT ? " data" : " bss");
|
|
214 }
|
|
215 }
|
|
216 putchar('\n');
|
|
217 }
|
|
218 showrefs()
|
|
219 {
|
|
220 register unsigned count,rcount;
|
|
221 def_ref ref;
|
|
222 char sym[SYMLEN+1];
|
|
223 int fflag;
|
|
224
|
|
225 count=getw(in);
|
|
226 if(rflag)
|
|
227 printf("\n%u external references:\n",count);
|
|
228
|
|
229 while(count--) {
|
|
230 getname(sym);
|
|
231 rcount=getw(in);
|
|
232 if(rflag)
|
|
233 printf(" %9s ",sym);
|
|
234 fflag=0;
|
|
235 while(rcount--) {
|
|
236 fread(&ref,sizeof(ref),1,in);
|
|
237 if(ferror(in)) ferr(fname);
|
|
238 if(rflag && oflag) {
|
|
239 if(fflag)
|
|
240 puts(" ");
|
|
241 else fflag=1;
|
|
242 printf("%04x ",ref.r_offset);
|
|
243 ftext(ref.r_flag,REF);
|
|
244 }
|
|
245 }
|
|
246 if(rflag && !oflag)
|
|
247 putchar('\n');
|
|
248 }
|
|
249 }
|
|
250 showlcls()
|
|
251 {
|
|
252 register unsigned count;
|
|
253 def_ref ref;
|
|
254
|
|
255 count=getw(in);
|
|
256 if(oflag)
|
|
257 printf("\n%u local references\n",count);
|
|
258
|
|
259 while(count--) {
|
|
260 fread(&ref,sizeof(ref),1,in);
|
|
261 if(ferror(in)) ferr(fname);
|
|
262 if(oflag) {
|
|
263 printf(" %04x ",ref.r_offset);
|
|
264 ftext(ref.r_flag,DEF | REF);
|
|
265 }
|
|
266 }
|
|
267 }
|
|
268 error(s1,s2,s3,s4)
|
|
269 {
|
|
270 fprintf(stderr,"rdump: ");
|
|
271 fprintf(stderr,s1,s2,s3,s4);
|
|
272 putc('\n',stderr);
|
|
273 exit(1);
|
|
274 }
|
|
275 ferr(s)
|
|
276 {
|
|
277 error("error reading '%s'",s);
|
|
278 }
|