ftp.nice.ch/pub/next/developer/languages/lisp/AKCL.1.599.s.tar.gz#/akcl-1-599/ustation/ild.c

This is ild.c in view mode; [Download] [Up]

#include <stdio.h>
#include <a.out.h>

#define	POOLSIZ		100000
#define	MY_SYMTABSIZ	10000
#define	SYMTABSIZ	10000

struct Nlist {
	char	*N_name;
	int	N_type;
	int	N_value;
};

char pool[POOLSIZ+128];
char *pp = pool;

struct bhdr my_header;
struct Nlist my_Symtab[MY_SYMTABSIZ];
int my_Sx;

struct bhdr header;
char *text, *data, *bss;
char *rtext, *rdata, *rbss;
struct Nlist Symtab[SYMTABSIZ];
int Sx;
struct reloc rinfo;

main(argc, argv)
int argc;
char **argv;
{
	if (argc < 5) {
		fprintf(stderr, "Arg count.\n");
		exit(1);
	}
	get_myself(argv[1]);
	rtext = (char *)atoi(argv[2]);
	fasload(argv[3], argv[4]);
}

get_myself(filename)
char *filename;
{
	struct sym sym;
	int i;
	FILE *fp;
	extern char *malloc();
	
	fp = fopen(filename, "r");
	if (fp == NULL) {
		fprintf(stderr, "Can't open %s.\n", filename);
		exit(1);
	}
	fread(&my_header, sizeof(struct bhdr), 1, fp);
	if (my_header.fmagic != FMAGIC && my_header.fmagic != NMAGIC) {
		fprintf(stderr, "Illegal magic number: 0%o.\n", my_header.fmagic);
		exit(1);
	}
	fseek(fp, my_header.tsize+my_header.dsize, 1);
	for (my_Sx=0, i=0;  i<my_header.ssize-sizeof(struct sym);  my_Sx++) {
		if (my_Sx >= MY_SYMTABSIZ) {
			fprintf(stderr, "Too many symbols in %s.\n", filename);
			exit(1);
		}
		if (pp >= &pool[POOLSIZ]) {
			fprintf(stderr, "String table overflow.\n");
			exit(1);
		}
		fread(&sym, 1, sizeof(struct sym), fp);
		i += sizeof(struct sym);
		my_Symtab[my_Sx].N_name = pp;
		my_Symtab[my_Sx].N_type = sym.stype;
		my_Symtab[my_Sx].N_value = sym.svalue;
		while ((*pp = getc(fp)) != '\0') {
			pp++;
			i++;
		}
		pp++;
		i++;
	}
	fclose(fp);
}

fasload(filename, outputfilename)
char *filename, *outputfilename;
{
	struct sym sym;
	int i, n;
	char name[100], *p;
	int type, value;
	int msx;
	FILE *fp;
	extern char *malloc();

	fp = fopen(filename, "r");
	if (fp == NULL) {
		fprintf(stderr, "Can't open %s.\n", filename);
		exit(1);
	}
	fread(&header, sizeof(struct bhdr), 1, fp);
	if (header.fmagic != FMAGIC) {
		fprintf(stderr, "Illegal magic number: 0%o.\n", header.fmagic);
		exit(1);
	}
	text = malloc(header.tsize+header.dsize);
	data = text + header.tsize;
	bss = data + header.dsize;
	rdata = rtext + header.tsize;
	rbss = rdata + header.dsize;
	fread(text, 1, header.tsize+header.dsize, fp);
	for (Sx=0, i=0;  i<header.ssize-sizeof(struct sym);  Sx++) {
		if (Sx >= SYMTABSIZ) {
			fprintf(stderr, "Too many symbols in %s.\n", filename);
			exit(1);
		}
		fread(&sym, 1, sizeof(struct sym), fp);
		i += sizeof(struct sym);
		Symtab[Sx].N_type = type = sym.stype;
		Symtab[Sx].N_value = value = sym.svalue;
		p = name;
		while ((*p++ = getc(fp)) != '\0')
			i++;
		i++;
		if ((type & N_EXT) == 0 || (type & N_TYPE) != N_UNDF)
			continue;
		for (msx = 0;  msx < my_Sx;  msx++) {
			if ((my_Symtab[msx].N_type & N_EXT) == 0)
				continue;
			if (strcmp(my_Symtab[msx].N_name, name) == 0) {
				Symtab[Sx].N_value = my_Symtab[msx].N_value;
				goto CONTINUE;
			}
		}
/*
		if (value == 0)
*/
			fprintf(stderr, "Undefined symbol: %s.\n", name);
/*
		Symtab[Sx].N_value = (int)(rtext + header.bsize);
		header.bsize += value;
*/
	CONTINUE:
		;
	}
	fseek(fp, sizeof(struct bhdr)+header.tsize+header.dsize+header.ssize, 0);
	for (i = 0, n = header.rtsize / sizeof(struct reloc);
		i < n;  i++) {
		fread(&rinfo, sizeof(struct reloc), 1, fp);
		relocate(text);
	}
	for (i = 0, n = header.rdsize / sizeof(struct reloc);
		i < n;  i++) {
		fread(&rinfo, sizeof(struct reloc), 1, fp);
		relocate(data);
	}
	fclose(fp);
	fp = fopen(outputfilename, "w");
	if (fp == NULL) {
		fprintf(stderr, "Can't open %s.\n", outputfilename);
		exit(1);
	}
	fwrite(&header, sizeof(struct bhdr), 1, fp);
	fwrite(text, 1, header.tsize+header.dsize, fp);
	fclose(fp);
}

relocate(where)
char *where;
{
	int value;

	where += rinfo.rpos;
	switch (rinfo.rsegment) {
	case RTEXT:
		value = (int)rtext;
		break;

	case RDATA:
		value = (int)rtext;
		break;

	case RBSS:
		value = (int)rtext;
		break;

	case REXT:
		value = Symtab[rinfo.rsymbol].N_value;
		break;
	}
	switch (rinfo.rsize) {
	case RBYTE:
		*(char *)where += value;
		break;

	case RWORD:
		*(short *)where += value;
		break;
	
	case RLONG:
		*(int *)where += value;
		break;
	}
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.