many changes, mostly for efficiency

This commit is contained in:
ceriel 1988-10-20 13:06:10 +00:00
parent a281cc38a4
commit f69a7e3e5d
18 changed files with 276 additions and 261 deletions

View file

@ -33,3 +33,4 @@ symboldef.c
symtable.c
text2.c
text4.c
common.c

View file

@ -15,7 +15,8 @@ LIBS=$(EM)/modules/lib/*.a
all : data.o con2.o con4.o relocation.o end_back.o gen1.o gen2.o\
gen4.o init_back.o mysprint.o output.o reloc1.o reloc2.o reloc4.o\
rom2.o rom4.o set_global.o set_local.o switchseg.o symboldef.o text2.o\
text4.o do_open.o do_close.o memory.o label.o misc.o extnd.o symtable.o
text4.o do_open.o do_close.o memory.o label.o misc.o extnd.o symtable.o\
common.o
data.o : data.h back.h header.h $(SOURCE)/data.c
$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/data.c
@ -104,3 +105,6 @@ misc.o : data.h back.h ../mach.h $(SOURCE)/misc.c
label.o : data.h back.h ../mach.h $(SOURCE)/label.c
$(CC) $(CFLAGS) -c $(IDIRS) -I.. $(SOURCE)/label.c
common.o : data.h back.h ../mach.h $(SOURCE)/common.c
$(CC) $(CFLAGS) -c $(IDIRS) -I.. $(SOURCE)/common.c

View file

@ -10,9 +10,9 @@ extern holno, procno;
/* These routines are called very often, thus we turned them into macros. */
#define text1(b) {if (text-text_area>=size_text) mem_text() ; *text++=b;}
#define con1(b) {if (data-data_area>=size_data) mem_data(); *data++ = b;}
#define rom1(b) {if (data-data_area>=size_data) mem_data(); *data++=b;}
#define text1(b) {if (--_text_cnt < 0) mem_text(); *text++ = b;}
#define con1(b) {if (--_data_cnt < 0) mem_data(); *data++ = b;}
#define rom1(b) {if (--_data_cnt < 0) mem_data(); *data++ = b;}
#define bss( n) ( nbss += n)
@ -32,10 +32,10 @@ extern holno, procno;
/* Initialize values. */
#define MAXTEXT 20
#define MAXDATA 20
#define MAXRELO 3
#define MAXNAME 5
#define MAXSTRING 20
#define MAXTEXT 4096
#define MAXDATA 2048
#define MAXRELO 100
#define MAXNAME 100
#define MAXSTRING 2048
#define MAXHASH 256

View file

@ -0,0 +1,22 @@
#include <out.h>
#include <em.h>
#include "back.h"
common(n)
arith n;
{
extern int Label, label_waiting;
register struct outname *nm = &symbol_table[Label];
if (label_waiting && (nm->on_type & S_EXT)) {
symbol_table[Label].on_type |= S_COM | (S_MIN+SEGBSS);
if (n > symbol_table[Label].on_valu) {
symbol_table[Label].on_valu = n;
}
label_waiting = 0;
return;
}
switchseg(SEGBSS);
dump_label();
bss(n);
}

View file

@ -4,12 +4,13 @@
con2( w)
TWO_BYTES w;
{
if ((_data_cnt -= 2) < 0) mem_data();
#ifdef BYTES_REVERSED
con1( (char) ( ( unsigned short)w>>8));
con1( (char) w);
*data++ = ( unsigned short)w>>8;
*data++ = w;
#else
con1( (char) w);
con1( (char) ( ( unsigned short)w>>8));
*data++ = w;
*data++ = ( unsigned short)w>>8;
#endif
}

View file

@ -33,7 +33,7 @@ struct outname *symbol_table;
int cur_seg = -1 , nname = 0;
long nbss = 0, size_text, size_data, size_reloc, size_symbol,
size_string;
size_string, _text_cnt, _data_cnt;
put1(sect,addr,b)

View file

@ -7,7 +7,7 @@ extern int cur_seg;
extern char *text, *data, *string;
extern int nname;
extern long nbss, size_text, size_data, size_reloc, size_symbol,
size_string;
size_string, _text_cnt, _data_cnt;
extern char *text_area, *data_area, *string_area;
extern struct outrelo *reloc_info, *relo;

View file

@ -18,7 +18,7 @@ int procno = 0, holno = 0;
char *extnd_pro( procno)
int procno;
{
string_lengte = mysprint( "pro%d", procno);
string_lengte = mysprint( "%cprc%d", GENLAB, procno);
index_symbol_table = find_sym( string, STORE_STRING);
return( symbol_table[ index_symbol_table].on_foff + string_area);
}
@ -27,7 +27,7 @@ int procno;
char *extnd_start( procno)
int procno;
{
string_lengte = mysprint( "start%d", procno);
string_lengte = mysprint( "%cstrt%d", GENLAB, procno);
index_symbol_table = find_sym( string, STORE_STRING);
return( symbol_table[ index_symbol_table].on_foff + string_area);
}
@ -81,7 +81,7 @@ int hol;
char *extnd_part( d)
int d;
{
string_lengte = mysprint( "part%x", d);
string_lengte = mysprint( "%cprt%x", GENLAB, d);
index_symbol_table = find_sym( string, STORE_STRING);
return( symbol_table[ index_symbol_table].on_foff + string_area);
}
@ -90,7 +90,7 @@ int d;
char *extnd_cont( d)
int d;
{
string_lengte = mysprint( "cont%x", d);
string_lengte = mysprint( "%ccnt%x", GENLAB, d);
index_symbol_table = find_sym( string, STORE_STRING);
return( symbol_table[ index_symbol_table].on_foff + string_area);
}

View file

@ -1,15 +1,20 @@
#include <system.h>
#include "mach.h"
#include "back.h"
gen2( w)
TWO_BYTES w;
gen2( c)
TWO_BYTES c;
{
#ifdef BYTES_REVERSED
gen1( (char) ( ( unsigned short)w>>8));
gen1( (char) w);
#else
gen1( (char) w);
gen1( (char) ( ( unsigned short)w>>8));
#endif
switch ( cur_seg) {
case SEGTXT : text2( c);
return;
case SEGCON : con2( c);
return;
case SEGROM : rom2( c);
return;
case SEGBSS : bss( 2);
return;
default : fprint( STDERR, "gen2() : bad seg number\n");
return;
}
}

View file

@ -1,14 +1,20 @@
#include <system.h>
#include "mach.h"
#include "back.h"
gen4( l)
FOUR_BYTES l;
gen4( c)
FOUR_BYTES c;
{
#ifdef WORDS_REVERSED
gen2( (short) ((unsigned long)l>>16));
gen2( (short) l);
#else
gen2( (short) l);
gen2( (short) ((unsigned long)l>>16));
#endif
switch ( cur_seg) {
case SEGTXT : text4( c);
return;
case SEGCON : con4( c);
return;
case SEGROM : rom4( c);
return;
case SEGBSS : bss( 4);
return;
default : fprint( STDERR, "gen4() : bad seg number\n");
return;
}
}

View file

@ -1,6 +1,7 @@
#include <out.h>
#include "back.h"
#include "hash.h"
#include <alloc.h>
char *calloc();
@ -9,13 +10,13 @@ init_back()
/* Allocate space for the tables and set the default values.
*/
{
text_area = calloc( MAXTEXT, sizeof( char));
data_area = calloc( MAXDATA, sizeof( char));
reloc_info = (struct outrelo *)calloc( MAXRELO, SZ_RELO);
symbol_table = (struct outname *)calloc( MAXNAME, SZ_NAME);
Hashitems = (struct Hashitem *)calloc( MAXNAME + 1,
text_area = Malloc( MAXTEXT);
data_area = Malloc( MAXDATA);
reloc_info = (struct outrelo *)Malloc( MAXRELO* sizeof(struct outrelo));
symbol_table = (struct outname *)Malloc( MAXNAME* sizeof(struct outname));
Hashitems = (struct Hashitem *)Malloc( (MAXNAME + 1)*
sizeof( struct Hashitem));
string_area = calloc( MAXSTRING, sizeof( char));
string_area = Malloc( MAXSTRING);
text = text_area;
data = data_area;
@ -23,7 +24,9 @@ init_back()
relo = reloc_info;
size_text = MAXTEXT;
_text_cnt = MAXTEXT;
size_data = MAXDATA;
_data_cnt = MAXDATA;
size_reloc = MAXRELO;
size_symbol = MAXNAME;
size_string = MAXSTRING;

View file

@ -2,8 +2,8 @@
#include <system.h>
#include "data.h"
#include "hash.h"
#include <alloc.h>
char *realloc();
/* The routines allocate more space for the segments and update the
* global variables. Each time the space asked for is multiplied with 2.
@ -12,9 +12,11 @@ char *realloc();
mem_text()
{
/* print( "text_area too small %d %d \n", text_area, text); */
int diff = text - text_area;
text_area = realloc( text_area, sizeof( char) * 2 * size_text);
text = text_area + size_text;
text_area = Realloc( text_area, sizeof( char) * 2 * size_text);
text = text_area + diff;
_text_cnt += size_text;
size_text = 2 * size_text;
}
@ -22,9 +24,11 @@ mem_text()
mem_data()
{
/* print( "data_area too small\n"); */
int diff = data - data_area;
data_area = realloc( data_area, sizeof( char) * 2 * size_data);
data = data_area + size_data;
data_area = Realloc( data_area, sizeof( char) * 2 * size_data);
data = data_area + diff;
_data_cnt += size_data;
size_data = 2 * size_data;
}
@ -34,12 +38,12 @@ mem_symbol_hash()
/* print( "symbol_table out of memory\n"); */
size_symbol = 2 * size_symbol;
symbol_table = (struct outname *) realloc( (char *) symbol_table,
symbol_table = (struct outname *) Realloc( (char *) symbol_table,
sizeof( struct outname) * size_symbol);
/* print( "hash out of memory\n"); */
Hashitems = (struct Hashitem *) realloc( (char *) Hashitems,
Hashitems = (struct Hashitem *) Realloc( (char *) Hashitems,
sizeof( struct Hashitem)*(size_symbol+1));
}
@ -47,21 +51,22 @@ mem_symbol_hash()
mem_relo()
{
/* print( "reloc_table out of memory\n"); */
int diff = relo - reloc_info;
reloc_info = (struct outrelo *) realloc( (char *) reloc_info,
reloc_info = (struct outrelo *) Realloc( (char *) reloc_info,
sizeof( struct outrelo) * 2 * size_reloc);
relo = reloc_info + size_reloc;
relo = reloc_info + diff;
size_reloc = 2 * size_reloc;
}
mem_string()
{
int i = string - string_area;
int diff = string - string_area;
/* print( "string_area out of memory %d %d \n", string_area, string);*/
size_string = 2 * size_string;
string_area = realloc( string_area, sizeof( char) * size_string);
string = string_area + i;
string_area = Realloc( string_area, sizeof( char) * size_string);
string = string_area + diff;
}

View file

@ -1,126 +1,25 @@
#include <system.h>
#include "data.h"
#include <varargs.h>
/* Mysprint() stores the string directly in the string_arae. This saves
* a copy action.
*/
int mysprint( fmt, args)
/*VARARGS*/
int mysprint(va_alist)
va_dcl
{
char *fmt;
int args;
{
return( _myformat( fmt, &args));
}
char *long2str();
static int integral(c)
{
switch (c) {
case 'b':
return -2;
case 'd':
return 10;
case 'o':
return -8;
case 'u':
return -10;
case 'x':
return -16;
}
return 0;
}
int _myformat( fmt, argp)
char *fmt;
char *argp;
{
register char *pf = fmt, *pa = argp;
register char *pb = string;
int n = 0;
while (*pf) {
if (*pf == '%') {
register width, base, pad, npad, s_l;
char *arg;
char cbuf[2];
char *badformat = "<bad format>";
/* get padder */
if (*++pf == '0') {
pad = '0';
++pf;
}
else
pad = ' ';
/* get width */
width = 0;
while (*pf >= '0' && *pf <= '9')
width = 10 * width + *pf++ - '0';
/* get text and move pa */
if (*pf == 's') {
arg = *(char **)pa;
pa += sizeof(char *);
}
else
if (*pf == 'c') {
cbuf[0] = * (int *) pa;
cbuf[1] = '\0';
pa += sizeof(int);
arg = &cbuf[0];
}
else
if (*pf == 'l') {
/* alignment ??? */
if (base = integral(*++pf)) {
arg = long2str(*(long *)pa, base);
pa += sizeof(long);
}
else {
pf--;
arg = badformat;
}
}
else
if (base = integral(*pf)) {
arg = long2str((long)*(int *)pa, base);
pa += sizeof(int);
}
else
if (*pf == '%')
arg = "%";
else
arg = badformat;
s_l = strlen( arg);
npad = width - s_l;
if ( npad > 0)
s_l += npad;
if ( n + s_l + string - string_area >= size_string) {
mem_string();
pb = string + n;
}
while (npad-- > 0)
*pb++ = pad;
while (*pb++ = *arg++);
n += s_l;
pb--;
pf++;
}
else {
if ( n + ( string - string_area) >= size_string) {
mem_string();
pb = string + n;
}
n++;
*pb++ = *pf++;
}
}
return n ;
va_list args;
int retval;
va_start(args);
fmt = va_arg(args, char *);
while (string + 1024 - string_area > size_string)
mem_string();
retval = _format(string, fmt, args);
string[retval] = '\0';
va_end(args);
return retval;
}

View file

@ -1,7 +1,13 @@
#include <system.h>
#include <alloc.h>
#include <out.h>
#include "mach.h"
#include "data.h"
static reduce_name_table();
static int nrelo;
output_back()
/* Dump the tables.
* Notice : entries in the symbol_table are converted.
@ -12,9 +18,13 @@ output_back()
struct outsect sect;
long ntext = text - text_area,
ndata = data - data_area,
nchar = string - string_area;
int nrelo = relo - reloc_info;
nchar;
nrelo = relo - reloc_info;
reduce_name_table();
nchar = string - string_area;
header.oh_magic = O_MAGIC;
header.oh_stamp = 0;
header.oh_flags = HF_LINK;
@ -71,6 +81,70 @@ output_back()
wr_string( string_area, nchar);
}
static
reduce_name_table()
{
/*
* Reduce the name table size. This is done by first marking
* the name-table entries that are needed for relocation, then
* removing the entries that are compiler-generated and not
* needed for relocation, while remembering how many entries were
* removed at each point, and then updating the relocation info.
* After that, the string table is reduced.
*/
#define S_NEEDED 0x8000
#define removable(nm) (!(nm.on_type & S_NEEDED) && *(nm.on_foff+string_area) == GENLAB)
register int *diff_index =
(int *) Malloc((unsigned)(nname + 1) * sizeof(int));
register struct outrelo *rp = reloc_info;
register int i;
char *new_str;
register char *p, *q;
*diff_index++ = 0;
for (i = 0; i < nrelo; i++) {
if (symbol_table[rp->or_nami].on_valu == -1 ||
(symbol_table[rp->or_nami].on_type & S_COM)) {
symbol_table[rp->or_nami].on_type |= S_NEEDED;
}
rp++;
}
for (i = 0; i < nname; i++) {
diff_index[i] = diff_index[i-1];
if (removable(symbol_table[i])) {
diff_index[i]++;
}
}
rp = reloc_info;
for (i = 0; i < nrelo; i++) {
rp->or_nami -= diff_index[rp->or_nami];
rp++;
}
for (i = 0; i < nname; i++) {
symbol_table[i].on_type &= ~S_NEEDED;
if (diff_index[i] && diff_index[i] == diff_index[i-1]) {
symbol_table[i - diff_index[i]] = symbol_table[i];
}
}
nname -= diff_index[nname - 1];
free((char *)(diff_index-1));
new_str = q = Malloc((unsigned)(string - string_area));
for (i = 0; i < nname; i++) {
p = symbol_table[i].on_foff + string_area;
symbol_table[i].on_foff = q - new_str;
while (*q++ = *p) p++;
}
free(string_area);
string_area = new_str;
string = q;
}
wr_fatal()
{
fprint( STDERR, "write failed\n");

View file

@ -16,73 +16,64 @@ do_local_relocation()
/* Check if this reference is solvable. External references contain
* -1 in 'on_valu'.
* Also remove useless relocation structures.
*/
{
register struct outrelo *ptr;
register int s;
register struct outrelo *rp;
int diff = 0;
for ( ptr = reloc_info; ptr < relo; ptr++) {
s = ptr->or_nami;
if ( symbol_table[ s].on_valu != -1)
do_relo(&symbol_table[ s], ptr);
for ( rp = reloc_info; rp < relo; rp++) {
register struct outname *np = &symbol_table[rp->or_nami];
int olddiff = diff;
if ( np->on_valu != -1 && ! (np->on_type & S_COM)) {
register long oldval,newval;
register char *sect;
switch( rp->or_sect - S_MIN) {
case SEGTXT:
sect = text_area;
if ((rp->or_type & RELPC) &&
(np->on_type & S_TYP) - S_MIN == SEGTXT) {
diff++;
}
break;
case SEGCON:
sect = data_area;
break;
default:
fprint( STDERR,
"do_local_relo(): bad section %d\n",
rp->or_sect - S_MIN);
break;
}
if ( rp->or_type & RELO4) {
oldval = get4( sect, rp->or_addr);
newval = oldval + np->on_valu;
put4( sect, rp->or_addr, newval);
}
else if ( rp->or_type & RELO2) {
oldval = (long) get2( sect, rp->or_addr);
newval = oldval + np->on_valu;
put2( sect, rp->or_addr, (int) newval);
}
else if ( rp->or_type & RELO1) {
oldval = (long) get1( sect, rp->or_addr);
newval = oldval + np->on_valu;
put1( sect, rp->or_addr, (char) newval);
}
else
print( STDERR, "do_relo() : bad relocation size\n");
rp->or_nami = seg_index((np->on_type & S_TYP) - S_MIN);
/* print(
"reloc %s adrr=%ld sect=%ld oldval=%ld newval=%ld def = %ld\n",
np->on_foff+string_area, rp->or_addr, rp->or_sect-S_MIN, oldval, newval, np->on_valu);
*/
}
if (diff && diff == olddiff) {
rp[-diff] = rp[0];
}
}
}
do_relo(np,rp)
struct outname *np;
struct outrelo *rp;
/* Solve the reference relative to the start of the segment where the symbol
* is defined.
*/
{
long oldval,newval;
char *sect;
switch( rp->or_sect - S_MIN) {
case SEGTXT:
sect = text_area;
break;
case SEGCON:
sect = data_area;
break;
default:
fprint( STDERR,
"do_local_relo(): bad section %d\n",
rp->or_sect - S_MIN);
break;
}
if ( rp->or_type & RELO4) {
oldval = get4( sect, rp->or_addr);
newval = oldval + np->on_valu;
put4( sect, rp->or_addr, newval);
rp->or_nami = seg_index(
( symbol_table[ rp->or_nami].on_type & S_TYP) - S_MIN);
}
else if ( rp->or_type & RELO2) {
oldval = (long) get2( sect, rp->or_addr);
newval = oldval + np->on_valu;
put2( sect, rp->or_addr, (int) newval);
rp->or_nami = seg_index(
( symbol_table[ rp->or_nami].on_type & S_TYP) - S_MIN);
}
else if ( rp->or_type & RELO1) {
oldval = (long) get1( sect, rp->or_addr);
newval = oldval + np->on_valu;
put1( sect, rp->or_addr, (char) newval);
rp->or_nami = seg_index(
( symbol_table[ rp->or_nami].on_type & S_TYP) - S_MIN);
}
else
print( STDERR, "do_relo() : bad relocation size\n");
/* print(
"reloc %s adrr=%ld sect=%ld oldval=%ld newval=%ld def = %ld\n",
np->on_foff+string_area, rp->or_addr, rp->or_sect-S_MIN, oldval, newval, np->on_valu);
*/
relo -= diff;
}

View file

@ -4,13 +4,12 @@
rom2( w)
TWO_BYTES w;
{
if ((_data_cnt -= 2) < 0) mem_data();
#ifdef BYTES_REVERSED
rom1( (char) ( ( unsigned short)w>>8));
rom1( (char) w);
*data++ = ( unsigned short)w>>8;
*data++ = w;
#else
rom1( (char) w);
rom1( (char) ( ( unsigned short)w>>8));
*data++ = w;
*data++ = ( unsigned short)w>>8;
#endif
}

View file

@ -30,7 +30,8 @@ int string_lengte = 0,
index_symbol_table = -1;
struct Hashitem *Hashitems ;
int Hashtab[ MAXHASH];
static int Hashtab[ MAXHASH];
static int Hash();
int find_sym( sym, isdef)
@ -90,14 +91,18 @@ int isdef;
else { /* zie C_fil, C_lin, C_lni */
string_lengte = 0;
for( p=sym; *p != '\0' ; p++) {
if ( (string - string_area) >= size_string)
mem_string();
*string++ = *p;
string_lengte++;
}
while ( (string + string_lengte - string_area) >= size_string) {
mem_string();
}
for( p=sym; *p != '\0' ; p++) {
*string++ = *p;
}
}
if ( (string - string_area) >= size_string)
if ( (string - string_area) >= size_string) {
mem_string();
}
*string++ = '\0';
s->on_foff = string - (string_lengte + 1) - string_area;
@ -105,8 +110,8 @@ int isdef;
}
int Hash(sym)
char *sym;
static int Hash(sym)
register char *sym;
{
register unsigned h;
register c;

View file

@ -4,12 +4,12 @@
text2( w)
TWO_BYTES w;
{
if ((_text_cnt -= 2) < 0) mem_text();
#ifdef BYTES_REVERSED
text1( (char) ( ( unsigned short)w>>8));
text1( (char) w);
*text++ = ( unsigned short)w>>8;
*text++ = w;
#else
text1( (char) w);
text1( (char) ( ( unsigned short)w>>8));
*text++ = w;
*text++ = ( unsigned short)w>>8;
#endif
}