Pristine Ack-5.5
[Ack-5.5.git] / mach / sun3 / cv / Xcv.c
1 /* $Id: Xcv.c,v 1.3 1994/06/24 13:34: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  * Convert SUN-3 object format to ACK object format. Only on Sun-3
10  */
11 #include <stdio.h>
12 #include <out.h>
13 #include <a.out.h>
14         
15 /*
16  * Header and section table of new format object file.
17  */
18 struct outhead  outhead;
19 struct outsect  outsect[4];
20
21 #define TEXTSG 0
22 #define ROMSG 1
23 #define DATASG 2
24 #define BSSSG 3
25
26 char    *output_file;
27
28 char *program ;
29
30 char flag ;
31
32 #define readf(a, b, c)  fread((a), (b), (int)(c), input)
33
34 /* Output file definitions and such */
35
36 struct exec bh;
37
38 FILE            *input;
39
40 struct outname *oname = 0;
41 char *strings = 0;
42 char *txt = 0;
43 char *data = 0;
44 unsigned nstrings;
45
46 main(argc, argv)
47         int     argc;
48         char    *argv[];
49 {
50         register struct outsect *p;
51         char *malloc();
52
53         input = stdin;
54         program= argv[0] ;
55         if ( argc>1 && argv[1][0]=='-' ) {
56                 flag=argv[1][1] ;
57                 argc-- ; argv++ ;
58         }
59         switch (argc) {
60         case 3: if (! wr_open(argv[2]))
61                         fatal("Can't write %s.\n", argv[2]);
62                 output_file = argv[2];
63                 if ((input = fopen(argv[1], "r")) == (FILE *)0)
64                         fatal("Can't read %s.\n", argv[1]);
65                 break;
66         default:fatal("Usage: %s <Sun-3 object> <ACK object>.\n", argv[0]);
67         }
68         if (! readf(&bh, sizeof(struct exec), 1)) rd_fatal();
69         if (N_BADMAG(bh)) fatal("bad magic number\n");
70         outhead.oh_magic = O_MAGIC;
71         outhead.oh_stamp = 0;
72         outhead.oh_nsect = 4;
73         outhead.oh_nname = 3 + bh.a_syms / sizeof(struct nlist);
74         outhead.oh_nrelo = (bh.a_trsize + bh.a_drsize) / sizeof(struct reloc_info_68k);
75         outhead.oh_flags = outhead.oh_nrelo ? HF_LINK : 0;
76         outhead.oh_nemit = bh.a_text + bh.a_data - (bh.a_magic == ZMAGIC ? sizeof(struct exec) : 0);
77         fseek(input, N_STROFF(bh), 0);
78         nstrings = getw(input);
79         strings = malloc(nstrings + 20);
80         oname = (struct outname *)
81                         malloc((unsigned) (3 + bh.a_syms / sizeof(struct nlist)) * sizeof (struct outname));
82         txt = malloc(bh.a_text);
83         data = malloc(bh.a_data);
84         if (!strings || !oname || !txt || !data) {
85                 fatal("No memory\n");
86         }
87         if (! readf(strings, nstrings, 1)) rd_fatal();
88         p = &outsect[TEXTSG];
89         p->os_base = N_TXTADDR(bh); p->os_size = p->os_flen = bh.a_text;
90         if (bh.a_magic == ZMAGIC) {
91                 p->os_base += sizeof(struct exec);
92                 p->os_size -= sizeof(struct exec);
93                 p->os_flen -= sizeof(struct exec);
94                 p->os_foff = OFF_EMIT(outhead); p->os_lign = 1;
95         }
96         p = &outsect[ROMSG];
97         p->os_base = (p-1)->os_base + (p-1)->os_size;
98         p->os_size = p->os_flen = 0;
99         p->os_foff = OFF_EMIT(outhead) + bh.a_text; p->os_lign = 1;
100         p = &outsect[DATASG];
101         p->os_base = N_DATADDR(bh); p->os_size = p->os_flen = bh.a_data;
102         p->os_foff = OFF_EMIT(outhead) + (p-2)->os_flen;
103         p->os_lign = bh.a_magic == ZMAGIC ? 0x20000 : 1;
104         p = &outsect[BSSSG];
105         p->os_base = N_BSSADDR(bh);
106         p->os_flen = 0; p->os_size = bh.a_bss;
107         p->os_foff = OFF_EMIT(outhead)+(p-1)->os_foff + (p-1)->os_flen;
108         p->os_lign = 1;
109
110         if (bh.a_magic == ZMAGIC) bh.a_text -= sizeof(struct exec);
111         fseek(input, sizeof(struct exec), 0);
112         if (bh.a_text && ! readf(txt, 1, bh.a_text)) rd_fatal();
113         if (bh.a_data && ! readf(data, 1, bh.a_data)) rd_fatal();
114
115         symtab(oname, strings);
116         wr_ohead(&outhead);
117         wr_sect(outsect, 4);
118         wr_outsect(TEXTSG);
119         wr_emit(txt, bh.a_text);
120         wr_outsect(DATASG);
121         wr_emit(data,bh.a_data);
122         wr_name(oname, outhead.oh_nname);
123         wr_string(strings, outhead.oh_nchar);
124         wr_close();
125         exit(0);
126 }
127
128 symtab(name, string)
129         struct outname *name;
130         char *string;
131 {
132         register struct outname *oname = name;
133         register char *strings = string+nstrings;
134         register int c;
135         register char *b;
136         struct nlist n;
137
138         oname->on_valu = 0; oname->on_foff = strings - string + OFF_CHAR(outhead); oname->on_desc = 0;
139         oname->on_type = (S_MIN+TEXTSG) | S_SCT;
140         b = ".text"; while (*strings++ = *b) b++;
141         oname++;
142         oname->on_valu = 0; oname->on_foff = strings - string + OFF_CHAR(outhead); oname->on_desc = 0;
143         oname->on_type = (S_MIN+DATASG) | S_SCT;
144         b = ".data"; while (*strings++ = *b) b++;
145         oname++;
146         oname->on_valu = 0; oname->on_foff = strings - string + OFF_CHAR(outhead); oname->on_desc = 0;
147         oname->on_type = (S_MIN+BSSSG) | S_SCT;
148         b = ".bss"; while (*strings++ = *b) b++;
149         oname++;
150         outhead.oh_nchar = strings - string;
151         while (bh.a_syms > 0) {
152                 if (! readf(&n, sizeof(struct nlist), 1)) rd_fatal();
153                 bh.a_syms -= sizeof(struct nlist);
154                 oname->on_desc = n.n_desc;
155                 if (n.n_un.n_strx - 4 < 0) oname->on_foff = 0;
156                 else oname->on_foff = OFF_CHAR(outhead) - 4 + n.n_un.n_strx;
157                 oname->on_valu = n.n_value;
158
159                 if (n.n_type & N_STAB) {
160                         oname->on_type = n.n_type << 8;
161                         oname++;
162                         continue;
163                 }
164                 switch(n.n_type & ~N_EXT) {
165                 case N_ABS:
166                         oname->on_type = S_ABS;
167                         break;
168                 case N_TEXT:
169                         oname->on_type = S_MIN + TEXTSG;
170                         break;
171                 case N_DATA:
172                         oname->on_type = S_MIN + DATASG;
173                         oname->on_valu -= bh.a_text;
174                         break;
175                 case N_BSS:
176                         oname->on_type = S_MIN + BSSSG;
177                         oname->on_valu -= bh.a_text + bh.a_data;
178                         break;
179                 case N_UNDF:
180                         if (! oname->on_valu) {
181                                 oname->on_type = S_UND;
182                                 break;
183                         }
184                         oname->on_type = (S_MIN + BSSSG) | S_COM;
185                         break;
186                 case N_FN:
187                         oname->on_type = S_FIL;
188                         break;
189                 default:
190                         fatal("Illegal type field %d in namelist\n", c);
191                 }
192                 if (n.n_type & N_EXT) oname->on_type |= S_EXT;
193                 oname++;
194         }
195 }
196
197 /* VARARGS1 */
198 fatal(s, a1, a2)
199         char    *s;
200 {
201         fprintf(stderr,"%s: ",program) ;
202         fprintf(stderr, s, a1, a2);
203         unlink(output_file);
204         exit(-1);
205 }
206
207 wr_fatal() { fatal("Write error\n"); }
208 rd_fatal() { fatal("Read error\n"); }