diff options
author | Robert de Bath <rdebath@poboxes.com> | 2002-07-24 21:00:16 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2013-10-23 23:48:47 +0200 |
commit | 2060b4f4cc1c13975e495d088344825f7700181b (patch) | |
tree | 5efd3dbb269b09d4b3351fdb6b50d6dca0291d47 /ld | |
parent | 673f690a37f6673a3262e933709c79de8a66f48c (diff) | |
download | dev86-2060b4f4cc1c13975e495d088344825f7700181b.tar.gz |
Import Dev86src-0.16.5.tar.gzv0.16.5
Diffstat (limited to 'ld')
-rw-r--r-- | ld/globvar.h | 1 | ||||
-rw-r--r-- | ld/ld.c | 6 | ||||
-rw-r--r-- | ld/writex86.c | 32 | ||||
-rw-r--r-- | ld/x86_cpm86.h | 44 |
4 files changed, 81 insertions, 2 deletions
diff --git a/ld/globvar.h b/ld/globvar.h index 4a66e89..1554b98 100644 --- a/ld/globvar.h +++ b/ld/globvar.h @@ -13,6 +13,7 @@ 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 */ +extern int cpm86; /* Generate CP/M-86 CMD header */ extern bin_off_t text_base_value; /* Base address of text seg */ extern bin_off_t data_base_value; /* Base or alignment of data seg */ @@ -19,6 +19,7 @@ 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; +PUBLIC int cpm86 = 0; PUBLIC char hexdigit[] = "0123456789abcdef"; PRIVATE bool_t flag[128]; @@ -123,6 +124,7 @@ char **argv; case 'z': /* unmapped zero page */ case 'N': /* Native format a.out */ case 'd': /* Make a headerless outfile */ + case 'c': /* Write header in CP/M-86 format */ case 'y': /* Use a newer symbol table */ if (arg[2] == 0) flag[(int) arg[1]] = TRUE; @@ -237,6 +239,10 @@ char **argv; headerless = flag['d']; if( headerless ) flag['s'] = 1; + /* CP/M-86 executables can't use symbols. */ + cpm86 = flag['c']; + if ( cpm86 ) flag['s'] = 1; + linksyms(flag['r']); if (outfilename == NUL_PTR) outfilename = "a.out"; diff --git a/ld/writex86.c b/ld/writex86.c index 70ecdde..95ff040 100644 --- a/ld/writex86.c +++ b/ld/writex86.c @@ -4,6 +4,7 @@ #include "syshead.h" #include "x86_aout.h" +#include "x86_cpm86.h" #include "const.h" #include "obj.h" #include "type.h" @@ -17,7 +18,7 @@ #define ELF_SYMS 0 #endif -# define FILEHEADERLENGTH (headerless?0:A_MINHDR) +# define FILEHEADERLENGTH (headerless?0:(cpm86?CPM86_HEADERLEN:A_MINHDR)) /* part of header not counted in offsets */ #define DPSEG 2 @@ -76,6 +77,7 @@ FORWARD void symres P((char *name)); FORWARD void setseg P((fastin_pt newseg)); FORWARD void skip P((unsigned countsize)); FORWARD void writeheader P((void)); +FORWARD void cpm86header P((void)); FORWARD void writenulls P((bin_off_t count)); EXTERN bool_t reloc_output; @@ -322,7 +324,8 @@ bool_pt argxsym; setsym("__heap_top", (bin_off_t)heap_top_value); openout(outfilename); - writeheader(); + if (cpm86) cpm86header(); + else writeheader(); for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext) if (modptr->loadflag) { @@ -599,6 +602,31 @@ unsigned countsize; writenulls((bin_off_t) readsize(countsize)); } +PRIVATE void cpm86header() +{ + struct cpm86_exec header; + memset(&header, 0, sizeof header); + + if (sepid) + { + header.ce_group[0].cg_type = CG_CODE; + u2c2(header.ce_group[0].cg_len, (15 + etextpadoff) / 16); + u2c2(header.ce_group[0].cg_min, (15 + etextpadoff) / 16); + header.ce_group[1].cg_type = CG_DATA; + u2c2(header.ce_group[1].cg_len, (15 + edataoffset) / 16); + u2c2(header.ce_group[1].cg_min, (15 + endoffset ) / 16); + u2c2(header.ce_group[1].cg_max, 0x1000); + } + else + { + header.ce_group[0].cg_type = CG_CODE; + u2c2(header.ce_group[0].cg_len, (15 + edataoffset) / 16); + u2c2(header.ce_group[0].cg_min, (15 + endoffset ) / 16); + } + if( FILEHEADERLENGTH ) + writeout((char *) &header, FILEHEADERLENGTH); +} + PRIVATE void writeheader() { struct exec header; diff --git a/ld/x86_cpm86.h b/ld/x86_cpm86.h new file mode 100644 index 0000000..0a858f5 --- /dev/null +++ b/ld/x86_cpm86.h @@ -0,0 +1,44 @@ +/* Copyright (C) 2002 + * This file is part of the ld86 command for Linux-86 + * It is distributed under the GNU Library General Public License. + * + * CP/M-86 CMD file header + */ + +#ifndef __CPM86_H +#define __CPM86_H + +typedef char Short16[2]; + +struct cpm86_group { + unsigned char cg_type; /* 1=Code 2=Data */ + Short16 cg_len; /* Group length, paragraphs */ + Short16 cg_base; /* Group address, normally 0 for relocatable */ + Short16 cg_min; /* Minimum size, normally = group length */ + Short16 cg_max; /* Maximum size, normally 0x1000 (64k) */ +}; + + +struct cpm86_exec { /* CP/M-86 header */ + struct cpm86_group ce_group[8]; + unsigned char ce_spare[51]; + Short16 ce_rsxs; /* Record with RSX list */ + Short16 ce_fixups; /* Record with fixups */ + unsigned char ce_flags; /* Concurrent CP/M flags */ +}; + +/* Group types */ +#define CG_EMPTY 0 +#define CG_CODE 1 +#define CG_DATA 2 +#define CG_EXTRA 3 +#define CG_STACK 4 +#define CG_AUX1 5 +#define CG_AUX2 6 +#define CG_AUX3 7 +#define CG_AUX4 8 +#define CG_PURE 9 /* Code that is known to be pure */ + +#define CPM86_HEADERLEN 0x80 + +#endif /* _CPM86_H */ |