Pristine Ack-5.5
[Ack-5.5.git] / modules / src / object / rd.c
1 /* $Id: rd.c,v 1.10 1994/06/24 11:18:53 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 #include "obj.h"
7
8 extern long             lseek();
9
10 /*
11  * Parts of the output file.
12  */
13 #undef PARTEMIT
14 #undef PARTRELO
15 #undef PARTNAME
16 #undef PARTCHAR
17 #undef PARTDBUG
18 #undef NPARTS
19
20 #define PARTEMIT        0
21 #define PARTRELO        1
22 #define PARTNAME        2
23 #define PARTCHAR        3
24 #ifdef SYMDBUG
25 #define PARTDBUG        4
26 #else
27 #define PARTDBUG        3
28 #endif
29 #define NPARTS          (PARTDBUG + 1)
30
31 static long             offset[MAXSECT];
32
33 static int              outfile;
34 static long             outseek[NPARTS];
35 static long             currpos;
36 static long             rd_base;
37 #define OUTSECT(i) \
38         (outseek[PARTEMIT] = offset[i])
39 #define BEGINSEEK(p, o) \
40         (outseek[(p)] = (o))
41
42 static int sectionnr;
43
44 static void
45 OUTREAD(p, b, n)
46         char *b;
47         long n;
48 {
49         register long l = outseek[p];
50
51         if (currpos != l) {
52                 lseek(outfile, l, 0);
53         }
54         rd_bytes(outfile, b, n);
55         l += n;
56         currpos = l;
57         outseek[p] = l;
58 }
59
60 /*
61  * Open the output file according to the chosen strategy.
62  */
63 int
64 rd_open(f)
65         char *f;
66 {
67
68         if ((outfile = open(f, 0)) < 0)
69                 return 0;
70         return rd_fdopen(outfile);
71 }
72
73 static int offcnt;
74
75 int
76 rd_fdopen(fd)
77 {
78         register int i;
79
80         for (i = 0; i < NPARTS; i++) outseek[i] = 0;
81         offcnt = 0;
82         rd_base = lseek(fd, 0L, 1);
83         if (rd_base < 0) {
84                 return 0;
85         }
86         currpos = rd_base;
87         outseek[PARTEMIT] = currpos;
88         outfile = fd;
89         sectionnr = 0;
90         return 1;
91 }
92
93 void
94 rd_close()
95 {
96
97         close(outfile);
98         outfile = -1;
99 }
100
101 int
102 rd_fd()
103 {
104         return outfile;
105 }
106
107 void
108 rd_ohead(head)
109         register struct outhead *head;
110 {
111         register long off;
112
113         OUTREAD(PARTEMIT, (char *) head, (long) SZ_HEAD);
114 #if BYTE_ORDER == 0x0123
115         if (sizeof(struct outhead) != SZ_HEAD)
116 #endif
117         {
118                 register char *c = (char *) head + (SZ_HEAD-4);
119                 
120                 head->oh_nchar = get4(c);
121                 c -= 4; head->oh_nemit = get4(c);
122                 c -= 2; head->oh_nname = uget2(c);
123                 c -= 2; head->oh_nrelo = uget2(c);
124                 c -= 2; head->oh_nsect = uget2(c);
125                 c -= 2; head->oh_flags = uget2(c);
126                 c -= 2; head->oh_stamp = uget2(c);
127                 c -= 2; head->oh_magic = uget2(c);
128         }
129         off = OFF_RELO(*head) + rd_base;
130         BEGINSEEK(PARTRELO, off);
131         off += (long) head->oh_nrelo * SZ_RELO;
132         BEGINSEEK(PARTNAME, off);
133         off += (long) head->oh_nname * SZ_NAME;
134         BEGINSEEK(PARTCHAR, off);
135 #ifdef SYMDBUG
136         off += head->oh_nchar;
137         BEGINSEEK(PARTDBUG, off);
138 #endif
139 }
140
141 void
142 rd_rew_relos(head)
143         register struct outhead *head;
144 {
145         register long off = OFF_RELO(*head) + rd_base;
146
147         BEGINSEEK(PARTRELO, off);
148 }
149
150 void
151 rd_sect(sect, cnt)
152         register struct outsect *sect;
153         register unsigned int   cnt;
154 {
155         register char *c = (char *) sect + cnt * SZ_SECT;
156
157         OUTREAD(PARTEMIT, (char *) sect, (long)cnt * SZ_SECT);
158         sect += cnt;
159         offcnt += cnt;
160         while (cnt--) {
161                 sect--;
162 #if BYTE_ORDER == 0x0123
163                 if (sizeof(struct outsect) != SZ_SECT)
164 #endif
165                 {
166                         c -= 4; sect->os_lign = get4(c);
167                         c -= 4; sect->os_flen = get4(c);
168                         c -= 4; sect->os_foff = get4(c);
169                         c -= 4; sect->os_size = get4(c);
170                         c -= 4; sect->os_base = get4(c);
171                 }
172                 offset[--offcnt] = sect->os_foff + rd_base;
173         }
174 }
175
176 void
177 rd_outsect(s)
178 {
179         OUTSECT(s);
180         sectionnr = s;
181 }
182
183 /*
184  * We don't have to worry about byte order here.
185  */
186 void
187 rd_emit(emit, cnt)
188         char            *emit;
189         long            cnt;
190 {
191         OUTREAD(PARTEMIT, emit, cnt);
192         offset[sectionnr] += cnt;
193 }
194
195 void
196 rd_relo(relo, cnt)
197         register struct outrelo *relo;
198         register unsigned int cnt;
199 {
200
201         OUTREAD(PARTRELO, (char *) relo, (long) cnt * SZ_RELO);
202 #if BYTE_ORDER == 0x0123
203         if (sizeof(struct outrelo) != SZ_RELO)
204 #endif
205         {
206                 register char *c = (char *) relo + (long) cnt * SZ_RELO;
207
208                 relo += cnt;
209                 while (cnt--) {
210                         relo--;
211                         c -= 4; relo->or_addr = get4(c);
212                         c -= 2; relo->or_nami = uget2(c);
213                         relo->or_sect = *--c;
214                         relo->or_type = *--c;
215                 }
216         }
217 }
218
219 void
220 rd_name(name, cnt)
221         register struct outname *name;
222         register unsigned int cnt;
223 {
224
225         OUTREAD(PARTNAME, (char *) name, (long) cnt * SZ_NAME);
226 #if BYTE_ORDER == 0x0123
227         if (sizeof(struct outname) != SZ_NAME)
228 #endif
229         {
230                 register char *c = (char *) name + (long) cnt * SZ_NAME;
231
232                 name += cnt;
233                 while (cnt--) {
234                         name--;
235                         c -= 4; name->on_valu = get4(c);
236                         c -= 2; name->on_desc = uget2(c);
237                         c -= 2; name->on_type = uget2(c);
238                         c -= 4; name->on_foff = get4(c);
239                 }
240         }
241 }
242
243 void
244 rd_string(addr, len)
245         char *addr;
246         long len;
247 {
248         
249         OUTREAD(PARTCHAR, addr, len);
250 }
251
252 #ifdef SYMDBUG
253 void
254 rd_dbug(buf, size)
255         char            *buf;
256         long            size;
257 {
258         OUTREAD(PARTDBUG, buf, size);
259 }
260 #endif