summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2010-06-20 10:42:12 +0200
committerLubomir Rintel <lkundrak@v3.sk>2013-10-29 16:30:52 +0100
commitaf164f42c91e976802628de8195d84299a251ba9 (patch)
treed72507c6ace88133f925584026060f54742217b4
parent6632a39575ae931f0532c84d78245c012fbb8773 (diff)
downloaddev86-af164f42c91e976802628de8195d84299a251ba9.tar.gz
Add support for creating V7 executables
Only really usable for executables; relocatables can still happily use the new (Linux, ELKS, 386BSD) format. Probably only impure executables will be correctly generated; moreover without a symbol table.
-rw-r--r--ld/globvar.h3
-rw-r--r--ld/ld.c11
-rw-r--r--ld/v7_aout.h26
-rw-r--r--ld/writex86.c52
-rw-r--r--man/ld86.13
5 files changed, 95 insertions, 0 deletions
diff --git a/ld/globvar.h b/ld/globvar.h
index 84cf8ff..5663cc0 100644
--- a/ld/globvar.h
+++ b/ld/globvar.h
@@ -13,6 +13,9 @@ EXTERN struct redlist *redfirst; /* first on list of redefined symbols */
/* K&R _explicitly_ says extern followed by public is OK */
extern char hexdigit[]; /* constant */
extern int headerless; /* Don't output header on exe */
+#ifndef VERY_SMALL_MEMORY
+extern int v7; /* Generate an UNIX v7 a.out header */
+#endif
#ifndef MSDOS
extern int cpm86; /* Generate CP/M-86 CMD header */
#endif
diff --git a/ld/ld.c b/ld/ld.c
index 2d31f13..a021e57 100644
--- a/ld/ld.c
+++ b/ld/ld.c
@@ -19,6 +19,9 @@ PUBLIC bin_off_t text_base_value = 0; /* XXX */
PUBLIC bin_off_t data_base_value = 0; /* XXX */
PUBLIC bin_off_t heap_top_value = 0; /* XXX */
PUBLIC int headerless = 0;
+#ifndef VERY_SMALL_MEMORY
+PUBLIC int v7 = 0;
+#endif
#ifndef MSDOS
PUBLIC int cpm86 = 0;
#endif
@@ -125,6 +128,9 @@ char **argv;
case 'c': /* Write header in CP/M-86 format */
#endif
case 'y': /* Use a newer symbol table */
+#ifndef VERY_SMALL_MEMORY
+ case '7': /* Produce a UNIX v7 a.out header */
+#endif
if (arg[2] == 0)
flag[(int) arg[1]] = TRUE;
else if (arg[2] == '-' && arg[3] == 0)
@@ -237,6 +243,11 @@ char **argv;
headerless = flag['d'];
if( headerless ) flag['s'] = 1;
+#ifndef VERY_SMALL_MEMORY
+ /* UNIX seventh edition executables */
+ v7 = flag['7'];
+#endif
+
#ifndef MSDOS
/* CP/M-86 executables can't use symbols. */
cpm86 = flag['c'];
diff --git a/ld/v7_aout.h b/ld/v7_aout.h
new file mode 100644
index 0000000..020079b
--- /dev/null
+++ b/ld/v7_aout.h
@@ -0,0 +1,26 @@
+/* Header format of 16-bit
+ * Seventh edition UNIX executables */
+
+#ifndef _V7_A_OUT_H
+#define _V7_A_OUT_H
+
+#define V7_MAGIC4 0405 /* v7 overlay */
+#define V7_OMAGIC 0407 /* I&D in one segment (impure) */
+#define V7_NMAGIC 0410 /* read-only text */
+#define V7_MAGIC3 0411 /* v7 separate I&D (pure) */
+#define V7_ZMAGIC 0413 /* v8 demand load */
+
+#define V7_HEADERLEN 16
+
+struct v7_exec {
+ short magic;
+ unsigned short textsize;
+ unsigned short datasize;
+ unsigned short bsssize;
+ unsigned short symtabsize;
+ unsigned short entry;
+ unsigned short pad;
+ unsigned short noreloc;
+};
+
+#endif /* _V7_A_OUT_H */
diff --git a/ld/writex86.c b/ld/writex86.c
index eaf4881..feb7b55 100644
--- a/ld/writex86.c
+++ b/ld/writex86.c
@@ -4,6 +4,9 @@
#include "syshead.h"
#include "x86_aout.h"
+#ifndef VERY_SMALL_MEMORY
+#include "v7_aout.h"
+#endif
#ifndef MSDOS
#include "x86_cpm86.h"
#endif
@@ -23,7 +26,11 @@
#ifdef MSDOS
# define FILEHEADERLENGTH (headerless?0:A_MINHDR)
#else
+# ifdef VERY_SMALL_MEMORY
# define FILEHEADERLENGTH (headerless?0:(cpm86?CPM86_HEADERLEN:A_MINHDR))
+# else
+# define FILEHEADERLENGTH (headerless?0:(cpm86?CPM86_HEADERLEN:(v7?V7_HEADERLEN:A_MINHDR)))
+# endif
#endif
/* part of header not counted in offsets */
#define DPSEG 2
@@ -83,6 +90,9 @@ FORWARD void symres P((char *name));
FORWARD void setseg P((fastin_pt newseg));
FORWARD void skip P((unsigned countsize));
FORWARD void writeheader P((void));
+#ifndef VERY_SMALL_MEMORY
+FORWARD void v7header P((void));
+#endif
#ifndef MSDOS
FORWARD void cpm86header P((void));
#endif
@@ -336,6 +346,11 @@ bool_pt argxsym;
if (cpm86) cpm86header();
else
#endif
+#ifndef VERY_SMALL_MEMORY
+ if (v7)
+ v7header();
+ else
+#endif
writeheader();
for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext)
if (modptr->loadflag)
@@ -669,6 +684,43 @@ PRIVATE void writeheader()
writeout((char *) &header, FILEHEADERLENGTH);
}
+#ifndef VERY_SMALL_MEMORY
+PRIVATE void v7header()
+{
+ struct v7_exec header;
+
+ if( sizeof header != FILEHEADERLENGTH )
+ fatalerror("Executable miscompiled, computed wrong header size");
+
+ memset(&header, 0, sizeof header);
+
+ if( bits32 )
+ fatalerror("V7 a.out format is for 16-bit only");
+
+ offtocn((char *) &header.magic, sepid ? V7_MAGIC3 : V7_OMAGIC,
+ sizeof header.magic);
+
+ offtocn((char *) &header.textsize, etextpadoff - btextoffset,
+ sizeof header.textsize);
+ offtocn((char *) &header.datasize, edataoffset - bdataoffset,
+ sizeof header.datasize);
+ offtocn((char *) &header.bsssize, endoffset - edataoffset,
+ sizeof header.bsssize);
+
+ if( !stripflag )
+ fatalerror("Symbol table not implemented for V7 yet");
+
+ if( uzp )
+ fatalerror("No QMAGIC for V7");
+
+ offtocn((char *) &header.entry, entryfirst->elsymptr->value,
+ sizeof header.entry);
+
+ if( FILEHEADERLENGTH )
+ writeout((char *) &header, FILEHEADERLENGTH);
+}
+#endif
+
PRIVATE void writenulls(count)
bin_off_t count;
{
diff --git a/man/ld86.1 b/man/ld86.1
index 7a87473..7665e65 100644
--- a/man/ld86.1
+++ b/man/ld86.1
@@ -38,6 +38,9 @@ produce header with 16-bit magic
produce header with 32-bit magic
.\"and use library subdir i386 for -lx
.TP
+.B -7
+produce Seventh Edition UNIX a.out header.
+.TP
.B -d
delete the header from the output file, used for MSDOS COM files. As a side
effect this also includes -s as there's nowhere to put a symbol table.