Digital Research
This commit is contained in:
2020-11-06 18:50:37 +01:00
parent 621ed8ccaf
commit 31738079c4
8481 changed files with 1888323 additions and 0 deletions

View File

@@ -0,0 +1,413 @@
/* this is the archiver for the Zilog edition of the C compiler */
typedef long time_t; /* a time */
typedef int dev_t; /* device code */
typedef long off_t; /* offset in file */
struct stat
{
dev_t st_dev;
unsigned int st_ino;
unsigned short st_mode;
short st_nlink;
short st_uid;
short st_gid;
dev_t st_rdev;
off_t st_size;
time_t st_atime;
time_t st_mtime;
time_t st_ctime;
};
#define S_IFMT 0170000 /* type of file */
#define S_IFDIR 0040000 /* directory */
#define S_IFCHR 0020000 /* character special */
#define S_IFBLK 0060000 /* block special */
#define S_IFREG 0100000 /* regular */
#define S_IFMPC 0030000 /* multiplexed char special */
#define S_IFMPB 0070000 /* multiplexed block special */
#define S_ISUID 0004000 /* set user id on execution */
#define S_ISGID 0002000 /* set group id on execution */
#define S_ISVTX 0001000 /* save swapped text even after use */
#define S_IREAD 0000400 /* read permission, owner */
#define S_IWRITE 0000200 /* write permission, owner */
#define S_IEXEC 0000100 /* execute/search permission, owner */
#define AR8KMAGIC 0177545
#define EVEN 0
#define ODD 1
struct ar8k_hd {
char ar8k_name[14];
long ar8k_date;
char ar8k_uid, /* not used except for compatibility */
ar8k_gid; /* only for compatibility */
int ar8k_mode; /* compatibility */
long ar8k_size;
}
head; /* header from the old archive */
struct stat statbuf;
char **filvec, /* pointer to start of vertor of files */
*filename, /* current file being processed */
*archive, /* the name of the archive file */
*tail(), /* find the real name of the file */
filmrk[256], /* marks for up to 256 files */
buffer[512]; /* the copying buffer */
char *tmpname = "ar8kxxxx.tmp";
int key = 0, /* one of d r q t x */
verbose, /* set if the 'v' key is used */
arfile, /* file number of the archive file */
tpfile, /* file number of the temporary file */
tmpflag = 0, /* flag set if a tempfile created */
file, /* file number of the input or output file */
magic = {AR8KMAGIC}, /* the output magic word */
inmagic, /* the file magic word is read here */
filyet, /* count of files not yet processed */
filcnt; /* count of files in filvec to process */
main(argc,argv) char **argv;{
register i;
register char *cp;
if( argc < 3 ){
printf("usage: ar8k key archfile [files ...]\n");
exit(1);
}
cp = argv[1];
while( i = *cp++ ) switch( i ){
case 'd':
case 'q':
case 'r':
case 't':
case 'x':
if( key ) errex("only one of d q r t x allowed");
key = i;
continue;
case 'v': verbose++;
continue;
default: errex("illegal key");
}
if( key == 0 ) errex("no key specified");
archive = argv[2];
filvec = &argv[3];
filyet = filcnt = argc-3;
if( filcnt > 256 ) errex( "too many file names" );
/* now create a temporary file for the functions needing it */
switch( key ){
case 'd':
case 'r':
tmpflag = settmp();
}
/* now open the archive for the functions needing to read it */
switch( key ){
case 'd':
case 'r':
case 't':
case 'x':
arfile = openb( archive , 0 );
if( arfile < 0 ){ /* can't read */
if( key != 'r' ) errex("can't read %s\n",archive );
key = 'q';
} else {
chmagic( arfile );
}
}
if( key == 'q' ){ /* quick append to end */
arfile = openb( archive , 2 );
if( arfile < 0 ){
arfile = creatb( archive , 0666 );
if( arfile >= 0 ) wrmagic( arfile );
else errex("can't append to %s",archive);
} else {
chmagic( arfile );
lseek( arfile , 0L , 2 ); /* seek to end */
}
append( arfile );
close(arfile);
exit(0);
}
/* now do the main body of processing */
while( read( arfile, (char *) &head, sizeof head ) == sizeof head ){
switch( key ){
case 'd': /* deletion */
if( inlist() ){
comment("deleting");
skip();
} else {
puthead( tpfile );
copy( tpfile , EVEN , arfile , EVEN );
}
break;
case 'r': /* replacement */
if( inlist() && (file = openb(filename,0)) >= 0 ){
skip();
getfile( tpfile , "replacing");
} else {
puthead( tpfile );
copy( tpfile , EVEN , arfile , EVEN );
}
break;
case 't': /* listing */
if( filcnt == 0 || inlist() ){
if( verbose ){
printf(" %7D ", head.ar8k_size );
}
printf("%-14.14s\n",head.ar8k_name);
}
skip();
break;
case 'x': /* extracting */
if( (filcnt == 0 || inlist()) &&
(file=creatb(head.ar8k_name,0666)) >=0 ){
comment("extracting");
copy( file , ODD , arfile , EVEN );
close( file );
} else {
skip();
}
break;
}
}
/* the main body of the work is done, copy the archive file back */
switch( key ){
case 'r':
if( filyet )append( tpfile );
case 'd':
close( arfile );
arfile = creatb( archive , 0666 );
if( arfile < 0 ){
printf("cannot create %s\n",archive );
} else {
lseek( tpfile , 0L , 0 );
while( (i = read( tpfile , buffer , 512)) > 0 )
if( write( arfile , buffer , i ) != i )
errex("botch in recopying the archive");
}
}
if( filyet != 0 ){
printf("\nfiles not processed:\n\n");
for( i=0; i<filcnt; i++ )
if( !filmrk[i] )
printf("\t%s\n",filvec[i] );
}
if (tmpflag) {
close(tpfile);
unlink(tmpname);
}
}
settmp(){ /* create a temporary archive file */
close( creatb( tmpname ) , 0600 );
tpfile = openb( tmpname , 2 );
/* unlink( "/tmp/ar8kxxxxxxx" ); */
if( tpfile < 0 ){
printf("cannot create tempfile\n" );
exit(1);
}
wrmagic( tpfile );
return(1);
}
wrmagic( f ){ /* write the magic word */
if( write( f , (char *) &magic , sizeof(int) ) != sizeof(int) )
errex("can't write magic word\n");
}
char *
tail( s ) char *s; {
register i;
register char *t,*u;
for(;;){
u = t = s;
while( i = *u++ )
if( i == '/' ) t = u;
if( *t ) return( t );
if( t == s )errex("bad file name");
}
}
comment(s) register char *s; {
if( verbose ) printf("%s:\t%-14.14s\n",s,head.ar8k_name);
}
errex(s,a,b,c) char *s; {
printf("fatal:\t");
printf(s,a,b,c);
printf("\n");
exit(1);
}
getfile( f , s ) char *s;{ /* make a header and copy a file to f */
register char *cp;
register i;
cp = tail( filename );
fstat( file , &statbuf );
lseek(file, 0L, 0); /* reposition at head; "fstat" */
/* corrupts the file position. */
head.ar8k_size = statbuf.st_size;
head.ar8k_uid = statbuf.st_uid;
head.ar8k_gid = statbuf.st_gid;
head.ar8k_date = statbuf.st_mtime;
head.ar8k_mode = statbuf.st_mode;
for( i=0; i<14; i++ )
if( head.ar8k_name[i] = *cp )
cp++;
comment( s );
puthead( f );
copy( f , EVEN , file , ODD );
close( file );
}
inlist(){ /* check to see if the current header name is in the list */
register char *cp,*bp;
register j;
int i;
for( i=0; i<filcnt; i++ ){
if( !filmrk[i] ){
cp = tail( filvec[i] );
bp = head.ar8k_name;
for( j=0; j<14; j++ ){
if( *cp != *bp++ ) break;
if( *cp ) cp++;
}
if( j == 14 ){
filmrk[i]++;
filyet--;
filename = filvec[i];
return( 1 );
}
}
}
return( 0 );
}
copy( outf, outflag , inf, inflag ){
register i,j;
i = head.ar8k_size >> 9;
while( --i >= 0 ){
if( read( inf , buffer , 512 ) != 512 ) errex("bad read");
if( write( outf , buffer , 512) != 512 ) errex("bad write");
}
i = head.ar8k_size;
j = i = i & 0777;
if( i & 1 ){ /* odd length */
if( inflag == EVEN ) i++;
if( outflag == EVEN ) j++;
}
if( i ){
if( read( inf , buffer , i ) != i ) errex("bad read.");
buffer[i] = 0;
if( write( outf , buffer , j ) != j ) errex("bad write.");
}
}
skip(){ /* skip over a file */
long size;
size = head.ar8k_size;
if( size & 1 ) size++;
lseek( arfile , size , 1 );
}
puthead( f ){ /* write the header */
if( write( f , (char *) &head , sizeof head ) != sizeof head )
errex( "header write error" );
}
append( f ){
register i;
for( i=0; i<filcnt; i++ ){
if( !filmrk[i] ){
filename = filvec[i];
if( (file = openb(filename,0)) >= 0 ){
filmrk[i]++;
filyet--;
getfile( f ,"appending");
} else {
printf("cannot read %s\n",filename);
}
}
}
}
chmagic( f ){ /* check the file for the magic code */
read( f , (char *) &inmagic , sizeof(int) );
if( inmagic != AR8KMAGIC ) errex("%s is not an archive",archive);
}
/* Dummy fstat since we're not in UNIX anymore. The call to _filesz */
/* has the side effect of positioning the file at the end. */
fstat(fd,stp)
int fd;
struct stat *stp;
{
register long fsize;
fsize = _filesz(fd);
stp->st_size = fsize;
stp->st_uid = 0;
stp->st_gid = 0;
stp->st_mtime = 0;
stp->st_mode = 0666;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,598 @@
/******************************************************************************
*******************************************************************************
**
** Unidot object format to x.out convertor.
**
** Usage is:
**
** xcon [-o outfile] [-s] file.obj
**
** The input file (file.obj) must be in the standard Unidot object file format,
** and its name must end with ".obj". The input file is converted into the
** x.out format, and the result is put in the output file specified by the
** "-o" switch. If no "-o" switch is given, the file "x.out" is created as
** a default.
**
** The "-s" switch will force the output to be marked as segmented, for
** those rare cases where xcon cannot determine that from the input file.
**
** Care has been taken to ensure machine independence. The output file
** generated by this program will be correct for a Z8000 regardless of
** the processor on which this program is run. In particular, this program
** may be run on a PDP-11 or on a VAX without any byte swap problems in the
** output file. One consequence of this policy is that routines are used
** to output the various structures defined in "xout.h". If the x.out
** file format is changed, or if "xout.h" is changed, the corresponding
** routines will probably need changing too. The routines to check are
** outhdr(), outrel(), outseg(), outsym(), and outtxt().
**
** John D. Polstra
** September 13, 1982
**
*******************************************************************************
******************************************************************************/
#include "stdio.h"
#include "xout.h"
#include "obj.h"
/*
* Constants.
*/
#define EXTMAX (RBMSK+1-RBEXT) /* Maximum number of external symbols allowed */
#define SEGMAX 128 /* Maximum number of segments allowed */
/*
* Type definitions.
*/
typedef unsigned short uns;
/*
* Global variables.
*/
uns exttab[EXTMAX]; /* Mapping from external # to symbol # */
uns *exttop = exttab; /* Pointer to top of exttab */
struct x_sg segtab[SEGMAX]; /* Table of information about segments */
struct x_hdr header; /* Header for x.out file */
long curoff; /* Current x.out file offset */
long reloff; /* X.out file offset for next reloc. entry */
long segoff[SEGMAX]; /* X.out file offsets for segments */
long symoff; /* X.out file offset for next symbol */
uns symct; /* Number of symbols for the x.out file */
char dbgflg = 0; /* Debug output flag on =1 off =0 */
char objbuf[255]; /* Buffer holding body of current .obj block */
FILE *objiop; /* Standard I/O pointer for .obj file */
char *objname; /* Name of .obj file */
char *objpt, *objtop; /* Pointers into objbuf */
int objtyp; /* Type of current .obj block */
int outfd; /* File descriptor for x.out file */
char *outname = "x.out"; /* Name of x.out file */
int firstseg; /* First segment (0 or 1) actually output */
char pass2; /* Flag set for second pass over .obj file */
char *prname; /* Name of this program */
/*
* Here is a brief description of our section / segment numbering
* scheme. The tables segtab[] and segoff[] are indexed by the Unidot
* section number; thus they always have a slot for the absolute section
* (number 0) whether it is used or not. However, we do not want to
* output a segment descriptor for the absolute section unless it is
* really used. So in the interlude we set the variable firstseg to
* one iff the absolute section is used. Within the various x.out
* outputting routines (outrel, outsym, etc.) we adjust the section numbers
* according to the value of firstseg. The general philosophy is that
* the outputting routines are called with Unidot section numbers; they
* perform the necessary adjustments to produce the required x.out
* segment numbers in the output file.
*
* Got it?
*/
/*
* Function declarations.
*/
long lseek(); /* Move I/O pointer to new file position */
uns ogetb(); /* Get next byte from object block */
long ogetl(); /* Get next long from object block */
char *ogets(); /* Get next string from object block */
uns ogetw(); /* Get next word from object block */
/*
* main - The main program consists simply of some initialization followed
* by two processing passes, with some interlude processing in between
* the two passes.
*/
main(argc, argv)
int argc;
char *argv[];
{
init(argc, argv);
dopass();
interlude();
pass2 = 1;
rewind(objiop);
dopass();
close(outfd);
fclose(objiop);
return(0);
}
/*
* dopass - Performs a scan of the .obj file.
*/
dopass() {
uns action;
uns adr;
uns base;
uns len;
uns relent;
uns relpos;
uns sec;
char *sym;
int type;
uns val;
header.x_nseg = 1; /* We always leave room for an absolute segment */
if(ofill() != OBOST)
ferr("Bad .obj file format\n");
while(ofill() != OBOND) {
switch(objtyp) {
case OBSEC: /* Sections block */
while(objpt < objtop) {
ogetb(); /* Discard alignment */
ogetb(); /* Discard extent */
ogetb(); /* Discard attributes */
sym = ogets(); /* Get section name */
if(pass2 && dbgflg) printf("sections %s\n",sym);
if(!pass2) {
/*
* Enter a new segment into segtab.
* Increment the number of segments
* in the header. Also increase
* the symbol table size to account
* for the segment name symbol.
*/
segtab[header.x_nseg].x_sg_no = 255;
if (strcmp(sym,"__text")== 0)
segtab[header.x_nseg].x_sg_typ = X_SG_COD;
if (strcmp(sym,"__con")== 0)
segtab[header.x_nseg].x_sg_typ = X_SG_CON;
if (strcmp(sym,"__data")== 0)
segtab[header.x_nseg].x_sg_typ = X_SG_DAT;
if (strcmp(sym,"__bss")== 0)
segtab[header.x_nseg].x_sg_typ = X_SG_BSS;
header.x_symb += sizeof(struct x_sym);
symct++;
} else
outsym(sym, X_SY_SEG, 0, header.x_nseg);
header.x_nseg++;
}
break;
case OBGLO: /* Global symbols block */
if(pass2 && dbgflg) printf("global ");
case OBLOC: /* Local symbols block */
if(pass2 && dbgflg) printf("symbols block\n");
while(objpt < objtop) {
val = (uns)ogetl();
sec = ogetb();
sym = ogets();
if(!pass2) {
if(sec == RBUND) /* Enter symbol # of new external */
*exttop++ = symct;
header.x_symb += sizeof(struct x_sym);
symct++;
} else {
type = objtyp==OBGLO ? X_SY_GLB : X_SY_LOC;
if(sec == RBUND)
type = X_SY_UNX;
outsym(sym, type, val, sec);
}
}
break;
case OBTXT: /* Text block */
adr = (uns)ogetl();
sec = ogetb();
len = ogetb();
if(pass2 && dbgflg)
printf("text section[%x] at %x for %x bytes\n",sec,adr,len);
if(!pass2) {
if(adr+len > segtab[sec].x_sg_len)
segtab[sec].x_sg_len = adr+len;
objpt += len;
while(objpt < objtop) {
ogetb(); /* Relocation byte number */
relent = ogetw(); /* Relocation entry */
header.x_reloc += sizeof(struct x_rel);
relent &= RAMSK;
if(relent==RAZLS || relent==RAZSS || relent==RAZOF)
header.x_magic = X_SU_MAGIC;
}
} else {
outtxt(adr, sec, objpt, len);
objpt += len;
while(objpt < objtop) {
relpos = adr + ogetb() - 6;
relent = ogetw();
action = relent & RAMSK;
base = relent & RBMSK;
switch(action) {
case RAA32M: /* absolute 32-bit address */
/*
* The loader can only relocate the least
* significant half of a 32-bit item.
*/
relpos += 2;
/* Fall through to next case */
case RAA16M: /* absolute 16-bit address */
case RAZOF: /* segmented offset */
type = base<RBEXT ? X_RL_OFF : X_RL_XOF;
break;
case RAZSS: /* short segmented address */
type = base<RBEXT ? X_RL_SSG : X_RL_XSSG;
break;
case RAZLS: /* long segmented address */
type = base<RBEXT ? X_RL_LSG : X_RL_XLSG;
break;
default:
ferr("Illegal reloc. 0x%x at loc. 0x%x of sec. 0x%x\n",
relent, relpos, sec);
}
outrel(type, relpos, sec, base);
}
}
break;
}
}
}
/*
* ferr - Issues a fatal error message and terminates.
*/
ferr(a, b, c, d, e)
char *a;
int b, c, d, e;
{
fprintf(stderr, a, b, c, d, e);
exit(1);
}
/*
* init - Initialization.
*/
init(argc, argv)
int argc;
char *argv[];
{
char *ap;
prname = argv[0];
argv[argc] = (char *)0; /* For the benefit of UNIX Version 6 */
header.x_magic = X_NU_MAGIC;
while(*++argv != (char *)0) {
ap = *argv;
if(*ap == '-') /* options */
while(*++ap != '\0')
switch(*ap) {
case 'd': /* debug flag on */
dbgflg = 1;
break;
case 'o': /* Next argument is output file */
if((outname = *++argv) == (char *)0)
usage();
break;
case 's': /* Force segmented magic number */
header.x_magic = X_SU_MAGIC;
break;
default: /* Illegal switch */
usage();
}
else { /* object file name */
if(objname != (char *)0)
usage();
objname = ap;
}
}
if(objname==(char *)0 || strcmp(&objname[strlen(objname)-4], ".obj")!=0)
usage();
if((objiop = fopenb(objname, "r")) == NULL)
ferr("Cannot open %s\n", objname);
if(strcmp(objname, outname) == 0)
ferr("Would destroy %s\n", objname);
/*
* The 0th entry in the segment table is the absolute segment.
* We will output it only if some code is generated into it. If we
* do end up outputting it, we will hard assign it to segment number 0.
*/
segtab[0].x_sg_typ = X_SG_BSS;
}
/*
* interlude - Performs interpass processing.
*/
interlude() {
long off;
uns *extptr;
int segno;
if(exttop == exttab) { /* No undefined externals, make executable */
header.x_magic = header.x_magic==X_SU_MAGIC ? X_SX_MAGIC : X_NXN_MAGIC;
outfd = creatb(outname, 0777);
} else
outfd = creatb(outname, 0666);
if(outfd == -1)
ferr("Cannot create %s\n", outname);
if(segtab[0].x_sg_typ==X_SG_BSS || segtab[0].x_sg_typ==X_SG_STK)
/*
* There is no code going into the absolute segment, so we skip it.
*/
firstseg = 1;
off = (sizeof header) + (header.x_nseg - firstseg) * sizeof(struct x_sg);
for(segno=0 ; segno<header.x_nseg ; segno++) {
segoff[segno] = off;
if(segtab[segno].x_sg_typ!=X_SG_BSS &&
segtab[segno].x_sg_typ!=X_SG_STK) {
off += segtab[segno].x_sg_len;
header.x_init += segtab[segno].x_sg_len;
}
}
reloff = off;
symoff = reloff + header.x_reloc;
curoff = 0L;
outhdr();
outseg();
}
/*
* ofill - Reads the next object block into objbuf, and returns the block type.
*/
ofill() {
int ch;
if((objtyp = getc(objiop)) == EOF) return(0);
if((ch = getc(objiop)) == EOF) ferr("Premature EOF\n");
objtop = &objbuf[ch];
for(objpt=objbuf ; objpt<objtop ; objpt++) {
if((ch = getc(objiop)) == EOF) ferr("Premature EOF\n");
*objpt = ch;
}
objpt = objbuf;
return(objtyp);
}
/*
* ogetb - Returns the next byte from the object buffer.
*/
uns
ogetb() {
if(objpt >= objtop) {
ferr("Off the end of objbuf\n");
}
return(*objpt++&0377);
}
/*
* ogetl - Returns the next long word from the object buffer.
*/
long
ogetl() {
long l;
l = ogetw();
return((long)ogetw()<<16|l);
}
/*
* ogets - Returns a pointer to the next string in the object buffer.
*/
char *
ogets() {
char *s;
s = objpt; while(ogetb());
return(s);
}
/*
* ogetw - Returns the next word from the object buffer.
*/
uns
ogetw() {
uns w;
w = ogetb();
return(ogetb()<<8|w);
}
/*
* outb - Outputs a single byte to the .out file.
*/
outb(val)
char val;
{
write(outfd, &val, 1);
curoff++;
}
/*
* outhdr - Outputs the header section of the .out file.
*/
outhdr()
{
outw(header.x_magic);
outw(header.x_nseg - firstseg);
outl(header.x_init);
outl(header.x_reloc);
outl(header.x_symb);
}
/*
* outl - Outputs a single long word to the .out file. The long word is
* written in Z8000 (MSB first) format, regardless of the host processor.
*/
outl(val)
long val;
{
char buf[4];
buf[3] = val;
val >>= 8;
buf[2] = val;
val >>= 8;
buf[1] = val;
val >>= 8;
buf[0] = val;
write(outfd, buf, 4);
curoff += 4;
}
/*
* outrel - Outputs a relocation entry with the specified type, offset,
* segment, and relocation base.
*/
outrel(type, offset, segment, base)
int type;
uns offset;
int segment;
uns base;
{
if(curoff != reloff)
lseek(outfd, curoff = reloff, 0);
if(base >= RBEXT)
base = exttab[base-RBEXT];
else
base -= firstseg;
outb(segment - firstseg);
outb(type);
outw(offset);
outw(base);
reloff = curoff;
}
/*
* outseg - Outputs the segments section of the .out file.
*/
outseg()
{
struct x_sg *p;
for(p = &segtab[firstseg] ; p < &segtab[header.x_nseg] ; p++) {
outb(p->x_sg_no);
outb(p->x_sg_typ);
outw(p->x_sg_len);
}
}
/*
* outsym - Outputs a symbol table entry with the specified name,
* type, value, and segment.
*/
outsym(name, type, value, segment)
register char *name;
int type;
unsigned short value;
int segment;
{
register int i;
if(curoff != symoff)
lseek(outfd, curoff = symoff, 0);
if(segment==RBABS || segment==RBUND)
segment = 255;
else
segment -= firstseg;
outb(segment);
outb(type);
outw(value);
for(i=0 ; i<XNAMELN ; i++) {
outb(*name);
if(*name != '\0')
name++;
}
symoff = curoff;
}
/*
* outtxt - Outputs a block of text for the specified offset in the specified
* segment. The text comes from txtptr and has txtct bytes.
*/
outtxt(offset, segment, txtptr, txtct)
uns offset;
int segment;
char *txtptr;
int txtct;
{
long txtoff;
txtoff = segoff[segment] + (long)offset;
if(curoff != txtoff)
lseek(outfd, curoff = txtoff, 0);
write(outfd, txtptr, txtct);
curoff += txtct;
}
/*
* outw - Outputs a single word to the .out file. The word is written in
* Z8000 (MSB first) format, regardless of the host processor.
*/
outw(val)
uns val;
{
char buf[2];
buf[1] = val;
val >>= 8;
buf[0] = val;
write(outfd, buf, 2);
curoff += 2;
}
/*
* usage - Issues a fatal error message for incorrect usage.
*/
usage() {
ferr("Usage: %s [-o x.out] [-s] file.obj\n", prname);
}

View File

@@ -0,0 +1,162 @@
/* quickie program to dump x.out files */
#include "stdio.h"
#include "x.out.h"
struct x_hdr x_hdr;
struct x_sg x_sg[10];
struct x_rel x_rel;
struct x_sym x_sym;
short sbuf[2048];
char *segtypes[] {
"unknown",
"bss",
"stack",
"code",
"constant pool",
"initialized data",
"mixed code/data, not protectable",
"mixed code/data, protectable"
};
int floc,
bigs,
dflag = {1}, /* dump init data */
rflag = {1}, /* dump relocation data */
sflag = {1}; /* dump symbol table data */
main( argc, argv ) char **argv; {
register i,
j,
k,
l;
unsigned len,
offset;
i = 1;
if( i < argc && argv[i][0] == '-' ) doargs( argv[i++] );
if( i < argc ){
close( 0 );
if( openb( argv[i] , 0 ) != 0 ){
printf(stderr,"cannot open '%s'\n",argv[i] );
exit(0);
}
}
read( 0 , &x_hdr , sizeof( x_hdr ) );
if( !bigs )fprintf( stdout,
"magic = %x nseg = %d init = %ld reloc = %ld symb = %ld\n",
x_hdr.x_magic,
x_hdr.x_nseg,
x_hdr.x_init,
x_hdr.x_reloc,
x_hdr.x_symb );
floc = sizeof( x_hdr );
for( i=0; i<x_hdr.x_nseg; i++ ){
read( 0 , &x_sg[i] , sizeof( x_sg[0] ) );
if( !bigs )fprintf( stdout,
"%4x sg[%d]: sgno = %d typ = %d len = %u\n",
floc,
i,
x_sg[i].x_sg_no & 0377,
x_sg[i].x_sg_typ & 0377,
x_sg[i].x_sg_len );
floc += sizeof( x_sg[0] );
}
for( i=0; i<x_hdr.x_nseg; i++ ){ /* dump the segments */
k = x_sg[i].x_sg_typ;
if( !bigs )
fprintf( stdout, "segment %d\ttype is %s\n",
i, segtypes[k]);
if( k == X_SG_BSS || k == X_SG_STK ){
if( !bigs )fprintf(stdout,"\nNo initialization");
} else {
len = x_sg[i].x_sg_len;
offset = 0;
while(len>0) {
l = (len>4096)?4096:len;
j = read( 0, sbuf, l );
if( j != l ){
fprintf(stdout,
"unexpected eof: length is %u\n",
offset + j);
j = 0;
}
for( k = 0; k<j; offset += 2, k += 2 ){
if( dflag ){
if( (k & 017) == 0 )
fprintf(stdout,"\n%4x %5d %4x ",
floc,offset,offset);
puth( sbuf[ k>>1 ] );
}
floc += 2;
}
len -= l;
}
}
if( dflag ) fprintf(stdout,"\n\n" );
}
if(x_hdr.x_reloc && rflag && !bigs)
fprintf(stdout,"floc sgn flg loc bas\n");
for( i=0; i<x_hdr.x_reloc; i += sizeof( x_rel ) ){
if( read( 0 , &x_rel, sizeof( x_rel ) ) != sizeof(x_rel)) eof();
if( rflag ) fprintf(stdout,
"%4x %4d%4d%6d%6d\n",
floc,
x_rel.x_rl_sgn & 0377,
x_rel.x_rl_flg & 0377,
x_rel.x_rl_loc,
x_rel.x_rl_bas );
floc += sizeof( x_rel );
}
if( sflag || bigs ){
if( !bigs )fprintf(stdout,"\nsymbols: \n\n");
for( i=0; i<x_hdr.x_symb; i+= sizeof( x_sym ) ){
if(read(0, &x_sym, sizeof(x_sym)) != sizeof( x_sym ))
eof();
if( !bigs )fprintf(stdout,
"%4x %4d%4d",
floc,
x_sym.x_sy_sg & 0377,
x_sym.x_sy_fl & 0377);
fprintf(stdout,"%6x %.8s\n",
x_sym.x_sy_val,
x_sym.x_sy_name );
floc += sizeof( x_sym );
}
}
}
doargs( s ) register char *s; {
sflag = dflag = rflag = 0;
for(;;) switch( *s++ ){
case 0: return;
case 'd': dflag++; continue;
case 'r': rflag++; continue;
case 'S': bigs++;
case 's': sflag++; continue;
}
}
char hextab[] {"0123456789abcdef"};
puth( n ){ /* put out a word in hex */
register i;
putchar( ' ' );
for( i=12; i>= 0; i -= 4 ) putchar( hextab[ (n>>i) & 017 ] );
}
eof(){
fprintf(stdout,"\n\n*****unexpected eof*****\n");
exit(0);
}

View File

@@ -0,0 +1,66 @@
struct x_hdr {
short x_magic; /* magic number */
short x_nseg; /* number of segments in file */
long x_init; /* length of initialized part of file */
long x_reloc; /* length of relocation part of file */
long x_symb; /* length of symbol table part of file */
};
struct x_sg {
char x_sg_no; /* assigned number of segment */
char x_sg_typ; /* type of segment */
unsigned x_sg_len; /* length of segment */
}; /* x_sg[] is an array of size x_nseg */
#define X_SU_MAGIC 0xEE00 /* segmented, non executable */
#define X_SX_MAGIC 0xEE01 /* segmented, executable */
#define X_NU_MAGIC 0xEE02 /* non-segmented, non executable */
#define X_NXN_MAGIC 0xEE03 /* non-segmented, executable, non-shared */
#define X_NUS_MAGIC 0xEE06 /* non-segmented, non executable, shared */
#define X_NXS_MAGIC 0xEE07 /* non-segmented, executable, shared */
#define X_NUI_MAGIC 0xEE0A /* non-segmented, non executable, split ID */
#define X_NXI_MAGIC 0xEE0B /* non-segmented, executable, split ID */
#define X_SG_BSS 1 /* non-initialized data segment */
#define X_SG_STK 2 /* stack segment, no data in file */
#define X_SG_COD 3 /* code segment */
#define X_SG_CON 4 /* constant pool */
#define X_SG_DAT 5 /* initialized data */
#define X_SG_MXU 6 /* mixed code and data, not protectable */
#define X_SG_MXP 7 /* mixed code and data, protectable */
struct x_rel { /* relocation item */
char x_rl_sgn; /* segment containing item to be relocated */
char x_rl_flg; /* relocation type (see below) */
unsigned x_rl_loc; /* location of item to be relocated */
unsigned x_rl_bas; /* number of (external) element in symbol table
or (internal) segment by which to relocate */
};
#define X_RL_OFF 1 /* adjust a 16 bit offset value only */
#define X_RL_SSG 2 /* adjust a short form segment plus offset */
#define X_RL_LSG 3 /* adjust a long form (32 bit) seg plus off */
#define X_RL_XOF 5 /* adjust a 16 bit offset by an external */
#define X_RL_XSSG 6 /* adjust a short seg ref by an external */
#define X_RL_XLSG 7 /* adjust a long seg ref by an external */
#define XNAMELN 8 /* length of a symbol */
struct x_sym {
char x_sy_sg; /* the segment number */
char x_sy_fl; /* the type of entry */
unsigned x_sy_val; /* the value of this entry */
char x_sy_name[XNAMELN]; /* the symbol name, padded with 0's */
};
#define X_SY_LOC 1 /* local symbol (for debug only) */
#define X_SY_UNX 2 /* undefined external entry */
#define X_SY_GLB 3 /* global definition */
#define X_SY_SEG 4 /* segmenIq


This directory contains the source and object files for the Z8000 CP/M Ccp,