symtable.c
text2.c
text4.c
+common.c
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
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
+
/* 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)
/* 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
--- /dev/null
+#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);
+}
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
}
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)
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;
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);
}
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);
}
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);
}
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);
}
+#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;
+ }
}
-
+#include <system.h>
#include "mach.h"
-
-gen4( l)
-FOUR_BYTES l;
+#include "back.h"
+
+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;
+ }
}
-
#include <out.h>
#include "back.h"
#include "hash.h"
+#include <alloc.h>
char *calloc();
/* 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;
relo = reloc_info;
size_text = MAXTEXT;
+ _text_cnt = MAXTEXT;
size_data = MAXDATA;
+ _data_cnt = MAXDATA;
size_reloc = MAXRELO;
size_symbol = MAXNAME;
size_string = MAXSTRING;
#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.
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;
}
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;
}
/* 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));
}
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;
}
#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)
- char *fmt;
- int args;
+/*VARARGS*/
+int mysprint(va_alist)
+ va_dcl
{
- 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;
}
#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.
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;
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");
/* 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);
- }
-}
-
-
-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;
+ 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;
- 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);
+ 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;
+ }
- rp->or_nami = seg_index(
- ( symbol_table[ rp->or_nami].on_type & S_TYP) - S_MIN);
+ 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];
+ }
}
- 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;
}
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
}
-
-
index_symbol_table = -1;
struct Hashitem *Hashitems ;
-int Hashtab[ MAXHASH];
+static int Hashtab[ MAXHASH];
+static int Hash();
int find_sym( sym, 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;
}
-int Hash(sym)
-char *sym;
+static int Hash(sym)
+register char *sym;
{
register unsigned h;
register c;
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
}
-