File: tools86.patch

package info (click to toggle)
linux86 0.16.21-2
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,072 kB
  • sloc: ansic: 66,757; asm: 6,154; makefile: 1,374; sh: 703
file content (491 lines) | stat: -rw-r--r-- 14,485 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
Description: Add tools86 from DOSEMU
Author: Robert Millan <zeratul2@wanadoo.es>

--- /dev/null
+++ b/tools86/Makefile
@@ -0,0 +1,21 @@
+#
+# tools86 Makefile
+# $Id$
+#
+
+PREFIX=/usr
+LIBPRE=$(PREFIX)
+
+BINDIR	=$(PREFIX)/bin
+
+all: tools86
+
+install: all
+	install -d $(BINDIR)
+	install -m 755 tools86 $(BINDIR)/tools86
+
+clean:
+	rm -f tools86 tools86.o core test.out *~ \#*\#
+
+realclean: clean
+distclean: clean
--- /dev/null
+++ b/tools86/tools86.c
@@ -0,0 +1,396 @@
+/*
+ * (C) Copyright 1992, ..., 2007 the "DOSEMU-Development-Team".
+ *
+ * for details see file COPYING.DOSEMU in the DOSEMU distribution
+ */
+
+/*
+ * file: tools86.c
+ *
+ * Toolbox to make as86/ld86 usable for DOSEMU
+ *
+ * (C) 1994 under GPL:  Hans Lermen <lermen@elserv.ffm.fgan.de>
+ * (put under DOSEMU policy 1998, --Hans)
+ *
+ * Tools86 has two operation modes:
+ *
+ * 1. Additional Preprocessor for as86
+ *
+ *    Because some of the features in as86 are buggy or not
+ *    not implemented, we have to do work around.
+ *    I did not suceed in using the MACRO feature of the as86, but
+ *    with GCC -E we can use the GNU-CPP, and after pipeing the result
+ *    through tools86 we have the the following "extensions" to as86:
+ *
+ *    - We can have multiple asm instructions per line (needed if using
+ *      CPP macros).
+ *      The delimiter between the instructions is "!!!" (three bangs).
+ *      This will be translated by tools86 to "\n", which can't not be
+ *      passed through CPP macros. Example:
+ *
+ *          #define SAVE_FLAGS(s) pushfd !!! pop dword ptr s
+ *
+ *      and SAVE_FLAGS(saved_flags) will produce
+ *
+ *          pushfd
+ *          pop dword ptr saved_flags
+ *
+ *    - We can define repeatition of code of data as follows:
+ *      .REPT  count
+ *        ...any code or data...
+ *      .ENDR
+ *
+ *      "count" must be a simple number or a expression of form
+ *      "(count -const)" or "(count +const)", sorry, but I was too lazy to
+ *      to implement more.
+ *
+ *      .REPT and .ENDR may appear on the same line. So we can realize
+ *      a FILL_LONG macro as follows:
+ *
+ *          #define FILL_LONG(x,value) .long value .REPT (x-1) ,value .ENDR
+ *
+ *      And  FILL_LONG(5,-2) will produce the following output:
+ *
+ *          .long  -2  , -2  , -2  , -2  , -2
+ *
+ *      But NOTE: as86 does not work proper on more then 63 values per line !
+ *                ====      ==============               =========
+ *
+ *    You may call as86 for source file test.S as follows:
+ *
+ *      gcc -E test.S | tools86 -E >test.s
+ *      as86 -0 -w -j -g -o test.o
+ *
+ *    NOTE:
+ *    The -g switch is necessary to avoid local "a" labels to be
+ *    converted later (see below).
+ *    The -j switch is neccessary for jumping larger then +/-128.
+ *    However, you may compile without the -j switch and use the
+ *    macros from macros86.h for 16-bit (near) displacement.
+ *    e.g.  jmp label    <==>  JMPL (label)
+ *          jne label    <==>  JNEL (label)
+ *    This produces shorter and faster code.
+ *
+ * 2. Making the asm86/ld86 output linkable to GNU-ld
+ *
+ *    This is done by modifying the header of ld86 outfile to built a GNU-a.out
+ *    and by converting the symbol table ("a" flags become "T" flags):
+ *
+ *      ld86 -0 -r -o test test.o
+ *      tools86 test
+ *      mv test test.o
+ *
+ *    The resulting test.o is now linkable with ld and can be put into
+ *    a library.
+ *    The only restriction is, that you can only have a .text segment,
+ *    ( no .data or .bss). But you *can* have public
+ *    global symbols and reference them from other GCC produced code.
+ *
+ * NOTE:
+ *    Do not use the asm86 -a switch, else you get error on instructions like
+ *       pop word ptr [bx]
+ *    (don't know why)
+ *    Be careful if using .org (do not overlap areas), because ld86 will
+ *    then write infinitely to your disk ( be prepared for <Ctrl>C ! ).
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+
+#ifdef __linux__
+struct gnu_header {
+  unsigned long a_info;         /* Use macros N_MAGIC, etc for access */
+  unsigned long a_text;         /* length of text, in bytes */
+  unsigned long a_data;         /* length of data, in bytes */
+  unsigned long a_bss;          /* length of uninitialized data area for file, in bytes */
+  unsigned long a_syms;         /* length of symbol table data in file, in bytes */
+  unsigned long a_entry;        /* start address */
+  unsigned long a_trsize;       /* length of relocation info for text, in bytes */
+  unsigned long a_drsize;       /* length of relocation info for data, in bytes */
+};
+
+struct bsd_header {            /* a.out header */
+  unsigned char a_magic[2];     /* magic number */
+  unsigned char a_flags;        /* flags, see below */
+  unsigned char a_cpu;          /* cpu id */
+  unsigned char a_hdrlen;       /* length of header */
+  unsigned char a_unused;       /* reserved for future use */
+  unsigned short a_version;     /* version stamp (not used at present) */
+  long          a_text;         /* size of text segement in bytes */
+  long          a_data;         /* size of data segment in bytes */
+  long          a_bss;          /* size of bss segment in bytes */
+  long          a_entry;        /* entry point */
+  long          a_total;        /* total memory allocated */
+  long          a_syms;         /* size of symbol table */
+                                /* SHORT FORM ENDS HERE */
+#if 0 /* we support only short form */
+  long          a_trsize;       /* text relocation size */
+  long          a_drsize;       /* data relocation size */
+  long          a_tbase;        /* text relocation base */
+  long          a_dbase;        /* data relocation base */
+#endif
+};
+#endif
+
+#ifdef __linux__
+static int header_ld86out_to_gnuasout(struct bsd_header *bsd, struct gnu_header *gnu)
+{
+  if (bsd->a_magic[0] != 0x01 || bsd->a_magic[1] != 0x03 ||
+      bsd->a_flags != 0x00 || bsd->a_cpu != 0x10) return -1;
+  if (bsd->a_hdrlen != 0x20 || bsd->a_unused || bsd->a_version) return -1;
+  gnu->a_info   = 0x107;
+  gnu->a_text   = bsd->a_text;
+  gnu->a_data   = bsd->a_data;
+  gnu->a_bss    = bsd->a_bss;
+  gnu->a_syms   = bsd->a_syms;
+  gnu->a_entry  = bsd->a_entry;
+  gnu->a_trsize = 0;
+  gnu->a_drsize = 0;
+  return 0;
+}
+
+struct sym_entry {
+  unsigned long addr,flags,stringoffs;
+};
+#endif
+
+static int change_aout(char *objfile, int update_symtable)
+{
+  FILE * f;
+#ifdef __linux__
+  struct bsd_header bsd;
+  struct gnu_header gnu;
+#endif
+  int ret;
+  if ( (f = fopen(objfile,"r+")) == 0) {
+    perror("problems on opening obj file");
+    return errno;
+  }
+#ifdef __linux__
+  if (fread(&bsd,sizeof(gnu),1,f) != 1 ) {
+    fclose(f);
+    return -1;
+  }
+  if (header_ld86out_to_gnuasout(&bsd, &gnu)) {
+    fclose(f);
+    return -1;
+  }
+  fseek(f,0,SEEK_SET);
+  ret = fwrite(&gnu,sizeof(gnu),1,f);
+  if(ret != 1 ) {
+    fclose(f);
+    return -1;
+  }
+#endif
+  if (update_symtable && gnu.a_syms) {
+    struct sym_entry *b = malloc(gnu.a_syms);
+    int nsyms=gnu.a_syms / sizeof(struct sym_entry);
+    int i;
+    fseek(f,sizeof(gnu)+gnu.a_text,SEEK_SET);
+    if (fread(b,gnu.a_syms,1,f) != 1 ) {
+      fclose(f);
+      return -1;
+    }
+    for (i=0; i<nsyms; i++) {
+      if (b[i].flags == 2) b[i].flags = 5; /* convert a to T */
+    }
+#ifdef __linux__
+    fseek(f,sizeof(gnu)+gnu.a_text,SEEK_SET);
+#endif
+    ret = fwrite(b,gnu.a_syms,1,f);
+  }
+  fclose(f);
+  if(ret != 1 ) return -1;
+  return 0;
+}
+
+#define SIZE_BBUF 8
+#define MASK_BBUF (SIZE_BBUF-1)
+#define INC_BBUF(i,step) (i = (i+(step)) & MASK_BBUF)
+#define COPY_BUF_SIZE 0x4000
+
+static inline int _skipwhite(FILE *f) {
+  int c;
+  while ((c=fgetc(f)) != EOF) {
+    if (!isspace(c)) break;
+  }
+  ungetc(c,f);
+  return c;
+}
+
+static inline int was(char *s, char *b, int buf_i, int buf_n) {
+  int i=buf_i, n=buf_n;
+  while (*s) {
+    INC_BBUF(i,-1);
+    if ((--n) < 0) return 0;
+    if (*s != b[i]) return 0;
+    s++;
+  }
+  return 1;
+}
+
+static inline void _fputc(int c, FILE *fo, char *cb, int copy, int *cbuf_i) {
+  fputc(c,fo);
+  if (copy) {
+    cb[(*cbuf_i)++] = c;
+    if (*cbuf_i >= COPY_BUF_SIZE) {
+      fprintf(stderr, "copy buffer overflow\n");
+      exit(1);
+    }
+  }
+}
+
+static inline void _put(int c, FILE *fo, char *cb, int copy, int *cbuf_i,
+			char *b, int *buf_i, int *buf_n) {
+  if (*buf_n >= SIZE_BBUF) _fputc(b[*buf_i], fo, cb, copy, cbuf_i);
+  else (*buf_n)++;
+  b[*buf_i]=c;
+  INC_BBUF(*buf_i,1);
+}
+
+static inline void _flush(FILE *fo, char *cb, int copy, int *cbuf_i,
+			  char *b, int *buf_i, int *buf_n) {
+  INC_BBUF(*buf_i,-*buf_n);
+  while ((*buf_n)-- > 0) {
+    _fputc(b[*buf_i], fo, cb, copy, cbuf_i);
+    INC_BBUF(*buf_i,1);
+  }
+  *buf_i = 0;
+  *buf_n = 0;
+}
+
+static inline void _unget(int count, int *buf_i, int *buf_n) {
+  if (count > *buf_n) count = *buf_n;
+  INC_BBUF(*buf_i,-count);
+  *buf_n -= count;
+}
+
+static inline int _nextnum(int *pc, FILE *f) {
+  int c=*pc;
+  char auxb[40];
+  int i=0, ii=0;
+  c = _skipwhite(f);
+  while ((c=fgetc(f)) !=EOF) {
+    if ( c=='(' ) {
+      ii +=_nextnum(&c, f);
+    }
+    else {
+      if (isspace(c)) {
+	c = _skipwhite(f);
+	if (c==')') fgetc(f);
+	break;
+      }
+      if (c==')') break;
+      if (i && (c=='+' || c=='-')) {
+	ungetc(c,f);
+	break;
+      }
+      if (ispunct(c) && (!(c=='+' || c=='-'))) {
+	ungetc(c,f);
+	*pc = c;
+	return ii;
+      }
+      auxb[i++]=c;
+    }
+  }
+  if (c=='+' || c=='-') ii +=_nextnum(&c, f);
+  errno = 0;
+  if (i) {
+    auxb[i]=0;
+    i=strtol(auxb,0,0);
+  }
+  if (errno) i=0;
+  *pc = c;
+  return i+ii;
+}
+
+static int preprocess(FILE *f, FILE *fo)
+{
+  char b[MASK_BBUF+1];
+  char cb[COPY_BUF_SIZE];
+  int buf_i=0, buf_n=0, copy=0, cbuf_i=0, copy_count=0;
+  int c;
+
+  while ((c=fgetc(f)) != EOF) {
+    switch (c) {
+      case '!': {
+        if (was("!!", b, buf_i, buf_n)) {
+          _unget(2, &buf_i, &buf_n);
+          _put('\n', fo, cb, copy, &cbuf_i, b, &buf_i, &buf_n);
+        }
+        else _put(c, fo, cb, copy, &cbuf_i, b, &buf_i, &buf_n);
+        break;
+      }
+      case 'T': {
+        if ((!copy) && was("PER.", b, buf_i, buf_n)) {
+          _unget(4, &buf_i, &buf_n);
+          copy_count = _nextnum(&c, f)-1;
+	  _flush(fo, cb, copy, &cbuf_i, b, &buf_i, &buf_n);
+          cbuf_i=0;
+          copy=1;
+        }
+        else _put(c, fo, cb, copy, &cbuf_i, b, &buf_i, &buf_n);
+        break;
+      }
+      case 'R': {
+        if (copy && was("DNE.", b, buf_i, buf_n)) {
+          int i,j;
+          _unget(4, &buf_i, &buf_n);
+          _flush(fo, cb, copy, &cbuf_i, b, &buf_i, &buf_n);
+          copy=0;
+          if (copy_count <=0) {
+            fprintf(stderr, "tools86: illegal repeat count after .REPT\n");
+            exit(1);
+          }
+          for (j=0; j<copy_count; j++) {
+            for (i=0; i<cbuf_i; i++)
+	      _put(cb[i], fo, cb, copy, &cbuf_i, b, &buf_i, &buf_n);
+          }
+        }
+        else _put(c, fo, cb, copy, &cbuf_i, b, &buf_i, &buf_n);
+        break;
+      }
+      default: {
+        _put(c, fo, cb, copy, &cbuf_i, b, &buf_i, &buf_n);
+      }
+    }
+  }
+  _flush(fo, cb, copy, &cbuf_i, b, &buf_i, &buf_n);
+  return 0;
+}
+
+
+static int usage(void)
+{
+  fprintf(stderr,
+    "USAGE:\n\n"
+    "tools86 objfile\n"
+    "  if called like above, it converts the header of a ld86 output\n"
+    "  to GNU-a.out format, so you can use it later with ld as a normal\n"
+    "  linkable *.o object file. But you must only have *one* segment\n"
+    "  (e.g. .text or .data, but not both).\n\n"
+    "tools86 -E\n"
+    "  if called like above, it preprocesses stdin to stdout to support some\n"
+    "  features, the as86 normally does not support\n"
+  );
+  exit(1);
+}
+
+int main (int argc, char** argv)
+{
+  if (argc <= 1) usage();
+
+  if (!strcmp(argv[1],"-E")) {
+    return preprocess(stdin,stdout);
+  }
+
+  if (change_aout(argv[1],1)) {
+    fprintf(stderr, "conv_aout: error on converting\n");
+    return 1;
+  }
+  return 0;
+}
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@
 VERSION=0.16.21
 
 TARGETS=install clean other \
-    bcc86 unproto copt as86 ld86 elksemu \
+    bcc86 unproto copt as86 ld86 elksemu tools86 \
     install-all install-bcc install-emu install-lib \
     install-lib2 install-ln install-man install-other \
     all-libs alt-libs library lib-386 lib-bsd lib-dos lib-fast lib-stand \
--- a/makefile.in
+++ b/makefile.in
@@ -88,7 +88,7 @@
 #endif
 
 #ifdef GNUMAKE
-all: check_config bcc86 cpp unproto copt as86 ar86 ld86 objdump86 \
+all: check_config bcc86 cpp unproto copt as86 ar86 ld86 objdump86 tools86 \
      library lib-bsd alt-libs elksemu
 
 install: check_config install-bcc install-man \
@@ -97,7 +97,7 @@
 install-all: install install-other
 
 #else
-all: check_config bcc86 cpp unproto copt as86 ar86 ld86 objdump86
+all: check_config bcc86 cpp unproto copt as86 ar86 ld86 objdump86 tools86
 	@echo
 	@echo 'NOTE: To build the libraries you need GNU-Make.'
 	@echo '      They are available precompiled in the Dev86clb-X.X.X.zip file.'
@@ -135,7 +135,7 @@
 # Others to install
 OTHERS=  tests dis88 doselks bootblocks
 
-CLEANLIST= bcc as ar ld cpp unproto copt libc elksemu libbsd $(OTHERS)
+CLEANLIST= bcc as ar ld tools86 cpp unproto copt libc elksemu libbsd $(OTHERS)
 
 ##############################################################################
 
@@ -192,6 +192,10 @@
 	$(MAKEC) ld $(MAKEARG) objdump86
 	cp -p ld/objdump86$(EXE) bin/objdump86$(EXE)
 
+tools86: bindir
+	$(MAKEC) tools86 $(MAKEARG) all
+	cp -p tools86/tools86 bin/tools86
+
 #ifndef __AS386_16__
 #ifdef __elksemu_works__
 elksemu: bindir
@@ -200,11 +204,12 @@
 #endif
 #endif
 
-install-bcc: bcc86 cpp unproto copt as86 ar86 ld86 objdump86
+install-bcc: bcc86 cpp unproto copt as86 ar86 ld86 objdump86 tools86
 	install -d $(DISTBIN) $(DISTLIB)
 	install $(INEXE) bin/Bcc$(EXE) 		$(DISTBIN)/bcc$(EXE)
 	install $(INEXE) bin/as86$(EXE) 	$(DISTASLD)/as86$(EXE)
 	install $(INEXE) bin/ld86$(EXE) 	$(DISTASLD)/ld86$(EXE)
+	install $(INEXE) bin/tools86		$(DISTBIN)/tools86
 	install $(INEXE) bin/ar86$(EXE) 	$(DISTBIN)/ar86$(EXE)
 	install $(INEXE) bin/objdump86$(EXE) 	$(DISTBIN)/objdump86$(EXE)
 	install $(INEXE) bin/objdump86$(EXE) 	$(DISTBIN)/nm86$(EXE)