Pristine Ack-5.5
[Ack-5.5.git] / mach / pmds / cv / cv.c
1 /* $Id: cv.c,v 2.8 1994/06/24 13:21:19 ceriel Exp $ */
2 /*
3  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4  * See the copyright notice in the ACK home directory, in the file "Copyright".
5  *
6  */
7
8 /*
9  * Fortunately we sold our PMDS machine. Unfortunately, we also sold the
10  * documentation that came with it, so I don't know the a.out format
11  * of the machine. This program is written partly by guessing, and partly from
12  * an older conversion program for the PMDS, which put the whole program
13  * in data. The produced object file does not contain a namelist.
14  */
15
16 #include <stdio.h>
17 #include <out.h>
18
19 #define ASSERT(x) switch (2) { case 0: case (x): ; }
20
21 /*
22  * Header and section table of new format object file.
23  */
24 struct outhead  outhead;
25 struct outsect  outsect[S_MAX];
26
27 char    *output_file;
28 int     outputfile_created;
29
30 int rom_in_data;
31
32 char *program ;
33
34 char flag ;
35
36 #define writef(a, b, c) fwrite((a), (b), (int)(c), output)
37
38 /* Output file definitions and such */
39
40
41 #define ENTRY 0
42 #define HDRSIZE 40
43
44 char hdr[HDRSIZE];
45
46
47 #define TEXTSG  0
48 #define ROMSG   1
49 #define DATASG  2
50 #define BSSSG   3
51 #define LSECT   BSSSG+1
52 #define NSECT   LSECT+1
53
54 FILE            *output;
55
56 long align(a,b)
57         long a,b;
58 {
59         a += b - 1;
60         return a - a % b;
61 }
62
63 int
64 follows(pa, pb)
65         register struct outsect *pa, *pb;
66 {
67         /* return 1 if pa follows pb */
68
69         return pa->os_base == align(pb->os_base+pb->os_size, pa->os_lign);
70 }
71
72 main(argc, argv)
73         int     argc;
74         char    *argv[];
75 {
76         register int            nsect;
77         long                    magic ;
78         long                    textsize ;
79         long                    datasize ;
80         long                    bsssize;
81         long                    symstart;
82         extern long             ftell();
83
84         output = stdout;
85         program= argv[0] ;
86         if ( argc>1 && argv[1][0]=='-' ) {
87                 flag=argv[1][1] ;
88                 argc-- ; argv++ ;
89         }
90         switch (argc) {
91         case 3: if ((output = fopen(argv[2], "w")) == (FILE *)0)
92                         fatal("Can't write %s.\n", argv[2]);
93                 output_file = argv[2];
94                 outputfile_created = 1;
95                 if (! rd_open(argv[1]))
96                         fatal("Can't read %s.\n", argv[1]);
97                 break;
98         default:fatal("Usage: %s <ACK object> <Mantra object>.\n", argv[0]);
99         }
100         rd_ohead(&outhead);
101         if (BADMAGIC(outhead))
102                 fatal("Not an ack object file.\n");
103         if (outhead.oh_flags & HF_LINK)
104                 fatal("Contains unresolved references.\n");
105         if (outhead.oh_nrelo > 0)
106                 fprintf(stderr, "Warning: relocation information present.\n");
107         if ( outhead.oh_nsect!=LSECT && outhead.oh_nsect!=NSECT )
108                 fatal("Input file must have %d sections, not %ld\n",
109                         NSECT,outhead.oh_nsect) ;
110         rd_sect(outsect, outhead.oh_nsect);
111         /* A few checks */
112         if ( outsect[TEXTSG].os_base != ENTRY)
113                 fatal("text must start at %d not at 0x%lx\n", ENTRY,
114                         outsect[TEXTSG].os_base) ;
115         if ( outsect[BSSSG].os_flen != 0 )
116                 fatal("bss space contains initialized data\n") ;
117         if (! follows(&outsect[BSSSG], &outsect[DATASG]))
118                 fatal("bss segment must follow data segment\n") ;
119         if ( outsect[ROMSG].os_lign == 0x8000 ) {
120                 /* 410 file with ROMSG in data space */
121                 rom_in_data = 1;
122                 magic= 0410 ;
123                 if (! follows(&outsect[DATASG], &outsect[ROMSG]))
124                         fatal("data segment must follow rom\n") ;
125                 textsize= outsect[TEXTSG].os_size ;
126                 outsect[ROMSG].os_size = outsect[DATASG].os_base - outsect[ROMSG].os_base;
127                 outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base;
128                 datasize= outsect[ROMSG].os_size + outsect[DATASG].os_size ;
129         } else
130         if ( outsect[DATASG].os_lign == 0x8000 ) {
131                 /* 410 file with ROMSG in instruction space */
132                 rom_in_data = 0;
133                 magic= 0410 ;
134                 if (! follows(&outsect[ROMSG], &outsect[TEXTSG]))
135                         fatal("rom segment must follow text\n") ;
136                 outsect[TEXTSG].os_size = outsect[ROMSG].os_base - outsect[TEXTSG].os_base;
137                 textsize= outsect[TEXTSG].os_size + outsect[ROMSG].os_size ;
138                 outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base;
139                 datasize= outsect[DATASG].os_size ;
140         } else {
141                 /* Plain 407 file */
142                 rom_in_data = 1;
143                 magic= 0407 ;
144                 if (! follows(&outsect[ROMSG], &outsect[TEXTSG]))
145                         fatal("rom segment must follow text\n") ;
146                 if (! follows(&outsect[DATASG], &outsect[ROMSG]))
147                         fatal("data segment must follow rom\n") ;
148                 outsect[TEXTSG].os_size = outsect[ROMSG].os_base - outsect[TEXTSG].os_base;
149                 outsect[ROMSG].os_size = outsect[DATASG].os_base - outsect[ROMSG].os_base;
150                 outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base;
151                 textsize= outsect[TEXTSG].os_size ;
152                 datasize= outsect[ROMSG].os_size + outsect[DATASG].os_size ;
153         }
154         bsssize = outsect[BSSSG].os_size;
155         if ( outhead.oh_nsect==NSECT ) {
156                 if (! follows(&outsect[LSECT], &outsect[BSSSG]))
157                         fatal("end segment must follow bss\n") ;
158                 if ( outsect[LSECT].os_size != 0 )
159                         fatal("end segment must be empty\n") ;
160         }
161
162         /* Action at last */
163         fseek(output,(long) HDRSIZE,0);
164         emits(&outsect[TEXTSG]) ;
165         emits(&outsect[ROMSG]) ;
166         emits(&outsect[DATASG]) ;
167         fseek(output,0L,0);
168         sethdr(0, (long) magic);
169         sethdr(4, textsize);
170         sethdr(8, datasize);
171         sethdr(12, bsssize);
172         writef(hdr, 1, 40);
173         if ( ferror(output) ) {
174                 fatal("output write error\n") ;
175         }
176         if ( outputfile_created ) chmod(argv[2],0755);
177         return 0;
178 }
179
180
181 sethdr(off,val) long val ; {
182         hdr[off]        = val>>24 ;
183         hdr[off+1]      = val>>16 ;
184         hdr[off+2]      = val>>8 ;
185         hdr[off+3]      = val ;
186 }
187
188 /*
189  * Transfer the emitted byted from one file to another.
190  */
191 emits(section) struct outsect *section ; {
192         char            *p;
193         char            *calloc();
194         long length = section->os_size;
195
196         rd_outsect(section - outsect);
197         while (section->os_size > 0) {
198                 int i = section->os_size > 10*1024 ? 10*1024 : section->os_size;
199
200                 section->os_size -= i;
201                 if (!(p = calloc(i, 1))) {
202                         fatal("No memory.\n");
203                 }
204                 rd_emit(p, i >= section->os_flen ? section->os_flen:(long) i);
205                 section->os_flen -= i;
206                 writef(p, 1, i);
207                 free(p);
208         }
209 }
210
211 /* VARARGS1 */
212 fatal(s, a1, a2)
213         char    *s;
214 {
215         fprintf(stderr,"%s: ",program) ;
216         fprintf(stderr, s, a1, a2);
217         if (outputfile_created)
218                 unlink(output_file);
219         exit(-1);
220 }
221
222 rd_fatal() { fatal("read error.\n"); }