summaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>2002-07-24 21:00:16 +0200
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:48:47 +0200
commit2060b4f4cc1c13975e495d088344825f7700181b (patch)
tree5efd3dbb269b09d4b3351fdb6b50d6dca0291d47 /ld
parent673f690a37f6673a3262e933709c79de8a66f48c (diff)
downloaddev86-2060b4f4cc1c13975e495d088344825f7700181b.tar.gz
Import Dev86src-0.16.5.tar.gzv0.16.5
Diffstat (limited to 'ld')
-rw-r--r--ld/globvar.h1
-rw-r--r--ld/ld.c6
-rw-r--r--ld/writex86.c32
-rw-r--r--ld/x86_cpm86.h44
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 */
diff --git a/ld/ld.c b/ld/ld.c
index 24391ca..29e03e9 100644
--- a/ld/ld.c
+++ b/ld/ld.c
@@ -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 */