From af164f42c91e976802628de8195d84299a251ba9 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Sun, 20 Jun 2010 10:42:12 +0200 Subject: 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. --- ld/globvar.h | 3 +++ ld/ld.c | 11 +++++++++++ ld/v7_aout.h | 26 ++++++++++++++++++++++++++ ld/writex86.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+) create mode 100644 ld/v7_aout.h (limited to 'ld') 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 @@ -335,6 +345,11 @@ bool_pt argxsym; #ifndef MSDOS if (cpm86) cpm86header(); else +#endif +#ifndef VERY_SMALL_MEMORY + if (v7) + v7header(); + else #endif writeheader(); for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext) @@ -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; { -- cgit v1.2.1