import of upstream version 1.17
[mw/micromonitor-lm32.git] / umon_main / host / src / utils / aout.c
1 /* aout.c:
2         Perform some dumps/displays of an aout file.
3
4         General notice:
5         This code is part of a boot-monitor package developed as a generic base
6         platform for embedded system designs.  As such, it is likely to be
7         distributed to various projects beyond the control of the original
8         author.  Please notify the author of any enhancements made or bugs found
9         so that all may benefit from the changes.  In addition, notification back
10         to the author will allow the new user to pick up changes that may have
11         been made by other users after this version of the code was distributed.
12
13         Author: Ed Sutter
14         email:  esutter@lucent.com
15         phone:  908-582-2351
16 */
17 #include <stdio.h>
18 #include <errno.h>
19 #include <signal.h>
20 #include <fcntl.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include "aout.h"
26 #include "utils.h"
27 #include "version.h"
28
29 #ifdef BUILD_WITH_VCC
30 #include <io.h>
31 #else
32 #include <unistd.h>
33 #endif
34
35 #ifndef O_BINARY
36 #define O_BINARY 0
37 #endif
38
39 #define btl32(val)      BeChk_btl32(val)
40
41 int     aoutFD = 0;
42 char    *aoutFname = (char *)0;
43
44 struct  exec    Ahdr;
45
46 #define SHOWHDR                 0x0001
47 #define SHOWSECTIONS    0x0002
48 #define SHOWMAP                 0x0004
49 #define SHOWMAPOFFSET   0x0008
50 #define SHOWAPPEND              0x0010
51
52 struct exec *GetAoutFileHdr();
53 struct exec *afhdr;
54 int     Ecvt, verbose, debug;
55
56 void
57 StripAoutFile(char *stripto,char *append)
58 {
59         int     size, sfd, afd;
60         struct  exec *ep;
61
62         unlink(stripto);
63         if ((sfd = open(stripto,O_WRONLY|O_BINARY|O_CREAT,0666))==-1) {
64                 perror(stripto);
65                 exit(1);
66         }
67         fprintf(stderr,"Stripping %s into %s...\n",
68                 aoutFname,stripto);
69         Lseek(aoutFD,0,SEEK_SET);
70         size = sizeof(struct exec) + Ahdr.a_text + Ahdr.a_data;
71         ep = (struct exec *)Malloc(size+32);
72         Read(aoutFD,(char *)ep,size);
73         ep->a_syms = 0;
74         if (write(sfd,(char *)ep,size) != size) {
75                 perror(stripto);
76                 exit(1);
77         }
78         if (append) {
79                 struct  stat buf;
80                 char    *aspace;
81                 if ((afd = open(append,O_RDONLY|O_BINARY))==-1) {
82                         perror(append);
83                         exit(1);
84                 }
85                 stat(append,&buf);
86                 aspace = Malloc(buf.st_size+32);
87                 read(afd,aspace,buf.st_size);
88                 write(sfd,aspace,buf.st_size);
89                 free(aspace);
90                 close(afd);
91         }
92         close(sfd);
93 }
94
95 void
96 AoutToBinary(char *binto)
97 {
98         int     fd;
99         struct  stat buf;
100         struct  exec *ep;
101         char    *tfrom, *dfrom, *cp;
102
103         unlink(binto);
104         if ((fd = open(binto,O_WRONLY|O_BINARY|O_CREAT,0777))==-1) {
105                 perror(binto);
106                 exit(1);
107         }
108         fprintf(stderr,"Converting %s into %s\n",
109                 aoutFname,binto);
110         Lseek(aoutFD,0,SEEK_SET);
111         stat(aoutFname,&buf);
112         cp = Malloc(buf.st_size+32);
113         Read(aoutFD,cp,buf.st_size);
114         ep = (struct exec *)cp;
115         tfrom = (char *)(ep+1);
116         dfrom = (char *)(tfrom + Ahdr.a_text);
117         if (write(fd,tfrom,Ahdr.a_text) != (int)Ahdr.a_text) {
118                 perror(binto);
119                 exit(1);
120         }
121         if (write(fd,dfrom,Ahdr.a_data) != (int)Ahdr.a_data) {
122                 perror(binto);
123                 exit(1);
124         }
125         close(fd);
126 }
127
128 void
129 ShowAppend(void)
130 {
131         char c;
132
133         Lseek(aoutFD,
134                 sizeof(struct exec)+Ahdr.a_text+Ahdr.a_data,SEEK_SET);
135         while(1) {
136                 if (read(aoutFD,&c,1) != 1)
137                         break;
138                 putchar(c);
139         }
140 }
141
142 void
143 ShowAoutHdr(void)
144 {
145         printf("\n\t\tA.OUT FILE HEADER\n");
146         printf("Magic:                          0x%x\n",Ahdr.a_magic);
147         printf("Text size:                      0x%x (%d)\n",
148                 Ahdr.a_text,Ahdr.a_text);
149         printf("Data size:                      0x%x (%d)\n",
150                 Ahdr.a_data,Ahdr.a_data);
151         printf("Bss size:                       0x%x (%d)\n",
152                 Ahdr.a_bss,Ahdr.a_bss);
153         printf("SymTable size:                  0x%x (%d)\n",
154                 Ahdr.a_syms,Ahdr.a_syms);
155         printf("Entrypoint:                     0x%x\n",Ahdr.a_entry);
156         printf("Text relocation table size:     0x%x (%d)\n",
157                 Ahdr.a_trsize,Ahdr.a_trsize);
158         printf("Data relocation table size:     0x%x (%d)\n",
159                 Ahdr.a_drsize,Ahdr.a_drsize);
160 }
161
162 void
163 ShowAoutMap(void)
164 {
165         unsigned long   tstart, dstart, bstart;
166
167         printf("\n\t\tA.OUT FILE MEMORY MAP\n");
168         tstart = Ahdr.a_entry;
169         dstart = tstart + Ahdr.a_text;
170         bstart = dstart + Ahdr.a_data;
171         printf("Text: 0x%08x .. 0x%08x, 0x%x (%d) bytes.\n",
172                 tstart,dstart-1,Ahdr.a_text,Ahdr.a_text);
173         printf("Data: 0x%08x .. 0x%08x, 0x%x (%d) bytes.\n",
174                 dstart,bstart-1,Ahdr.a_data,Ahdr.a_data);
175         printf("Bss:  0x%08x .. 0x%08x, 0x%x (%d) bytes.\n",
176                 bstart,bstart+Ahdr.a_bss-1,Ahdr.a_bss,Ahdr.a_bss);
177 }
178
179 void
180 ShowAoutOffsets(void)
181 {
182         unsigned long   tstart, dstart, bstart;
183
184         printf("\n\t\tA.OUT FILE SECTION FILE OFFSETS\n");
185         tstart = 0+sizeof(struct exec);
186         dstart = tstart + Ahdr.a_text;
187         bstart = dstart + Ahdr.a_data;
188         printf("Text: 0x%08x .. 0x%08x (%d bytes)\n",
189                 tstart,dstart-1,Ahdr.a_text);
190         printf("Data: 0x%08x .. 0x%08x (%d bytes)\n",
191                 dstart,bstart-1,Ahdr.a_data);
192         printf("Bss:  0x%08x .. 0x%08x (%d bytes)\n",
193                 bstart,bstart+Ahdr.a_bss-1,Ahdr.a_bss);
194 }
195
196 void
197 ShowAoutAppendedDate(void)
198 {
199         unsigned long   tstart, dstart, bstart;
200         char    c;
201
202         tstart = 0+sizeof(struct exec);
203         dstart = tstart + Ahdr.a_text;
204         bstart = dstart + Ahdr.a_data;
205         Lseek(aoutFD,bstart+Ahdr.a_bss,SEEK_SET);
206 printf("Offset at 0x%x...\n",bstart+Ahdr.a_bss);
207         while(read(aoutFD,&c,1) == 1)
208                 printf("%c",c);
209         printf("\n");
210 }
211
212
213 /* GetAoutFileHdr():
214    Retrieve the header from the file and do a BE-to-LE conversion
215    on each of its members.
216 */
217 struct exec *
218 GetAoutFileHdr(afhdr)
219 struct exec *afhdr;
220 {
221         if (verbose)
222                 fprintf(stderr,"GetAoutFileHdr()\n");
223
224         /* Read in the aout header. */
225         Lseek(aoutFD,0,SEEK_SET);
226         Read(aoutFD,(char *)afhdr,(unsigned)sizeof(struct exec));
227         afhdr->a_mid = otherEnd16(Ecvt,afhdr->a_mid);
228         afhdr->a_magic = otherEnd16(Ecvt,afhdr->a_magic);
229         afhdr->a_text = otherEnd32(Ecvt,afhdr->a_text);
230         afhdr->a_data = otherEnd32(Ecvt,afhdr->a_data);
231         afhdr->a_bss = otherEnd32(Ecvt,afhdr->a_bss);
232         afhdr->a_syms = otherEnd32(Ecvt,afhdr->a_syms);
233         afhdr->a_entry = otherEnd32(Ecvt,afhdr->a_entry);
234         afhdr->a_trsize = otherEnd32(Ecvt,afhdr->a_trsize);
235         afhdr->a_drsize = otherEnd32(Ecvt,afhdr->a_drsize);
236         return(afhdr);
237 }
238
239 char *usage_txt[] = {
240         "Usage: aout [options] {filename}",
241         " Options:",
242         " -a{filename}  append file to end of -S file",
243         " -A            print what was appended by -a",
244         " -B{filename}  aout-2-bin to filename",
245         " -c            BE-to-LE convert",
246         " -f            show aout file header",
247         " -M            show aout map with file offsets",
248         " -m            show aout map without file offsets",
249         " -s            show aout section headers",
250         " -S{filename}  strip to specified file",
251         " -V            display version of tool",
252         " -v            verbose (debug) mode",
253         0,
254 };
255
256 int
257 main(int argc,char *argv[])
258 {
259         char    fname[128], *append, *stripto, *binto;
260         int     opt, showstuff;
261
262         verbose = 0;
263         showstuff = 0;
264         stripto = (char *)0;
265         append = (char *)0;
266         binto = (char *)0;
267         Ecvt = 1;
268         while ((opt=getopt(argc,argv,"a:AcB:dfmMsS:vV")) != EOF) {
269                 switch(opt) {
270                 case 'a':
271                         append = optarg;
272                         break;
273                 case 'A':
274                         showstuff |= SHOWAPPEND;
275                         break;
276                 case 'B':
277                         binto = optarg;
278                         break;
279                 case 'c':
280                         Ecvt = 0;
281                         break;
282                 case 'f':
283                         showstuff |= SHOWHDR;
284                         break;
285                 case 'M':
286                         showstuff |= SHOWMAPOFFSET;
287                         break;
288                 case 'm':
289                         showstuff |= SHOWMAP;
290                         break;
291                 case 'S':
292                         stripto = optarg;
293                         break;
294                 case 's':
295                         showstuff |= SHOWSECTIONS;
296                         break;
297                 case 'v':
298                         verbose = 1;
299                         break;
300                 case 'V':
301                         showVersion();
302                         break;
303                 default:
304                         usage(0);
305                 }
306         }
307
308         if (argc != (optind+1))
309                 usage("Missing filename");
310
311         strcpy(fname,argv[optind]);
312
313         if (!fileexists(fname)) {
314                 fprintf(stderr,"No such file: %s\n",fname);
315                 exit(1);
316         }
317
318         if ((aoutFD = open(fname,O_RDONLY | O_BINARY)) == -1) {
319                 perror(fname);
320                 exit(1);
321         }
322
323         aoutFname = StrAllocAndCopy(fname);
324         GetAoutFileHdr(&Ahdr);
325
326         if (binto) {
327                 AoutToBinary(binto);
328         }
329         else if (stripto) {
330                 StripAoutFile(stripto,append);
331         }
332         else {
333                 if (showstuff & SHOWAPPEND)
334                         ShowAppend();
335                 if (showstuff & SHOWHDR)
336                         ShowAoutHdr();
337                 if (showstuff & SHOWMAP)
338                         ShowAoutMap();
339                 if (showstuff & SHOWMAPOFFSET)
340                         ShowAoutOffsets();
341         }
342         close(aoutFD);
343         return(0);
344 }