From: ceriel Date: Thu, 20 Oct 1988 14:21:37 +0000 (+0000) Subject: Many changes: X-Git-Tag: release-5-5~2781 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=e0fc646222a3a5bf6f9cdaf90a815b05cd58be94;p=ack.git Many changes: - added floating point - improved assembler part, now uses short encodings when possible - reduced generated relocation - and name table --- diff --git a/mach/vax4/ce/EM_table b/mach/vax4/ce/EM_table index fce731ca7..8a59faad6 100644 --- a/mach/vax4/ce/EM_table +++ b/mach/vax4/ce/EM_table @@ -61,7 +61,7 @@ C_loi "movl ~$1/4, r1"; "addl2 ~$1, r0"; "2:"; - "movl -(r0), -(sp)"; + "pushl -(r0)"; "sobgtr r1, 2b". default ==> arg_error( "loi", $1). @@ -222,6 +222,37 @@ C_sru ==> "movl ~$1, r0"; /* */ /******************************************************************************/ +C_adf + $1 == 4 ==> "addf2 (sp)+, (sp)". + $1 == 8 ==> "addd2 (sp)+, (sp)". + default ==> arg_error( "adf", $1). + +C_sbf + $1 == 4 ==> "subf2 (sp)+, (sp)". + $1 == 8 ==> "subd2 (sp)+, (sp)". + default ==> arg_error( "sbf", $1). + +C_mlf + $1 == 4 ==> "mulf2 (sp)+, (sp)". + $1 == 8 ==> "muld2 (sp)+, (sp)". + default ==> arg_error( "mlf", $1). + +C_dvf + $1 == 4 ==> "divf2 (sp)+, (sp)". + $1 == 8 ==> "divd2 (sp)+, (sp)". + default ==> arg_error( "dvf", $1). + +C_ngf + $1 == 4 ==> "mnegf (sp), (sp)". + $1 == 8 ==> "mnegd (sp), (sp)". + default ==> arg_error( "ngf", $1). + +C_fif ==> "movl ~$1,r0"; + "jsb .fif". + +C_fef ==> "movl ~$1,r0"; + "jsb .fef". + /******************************************************************************/ /* */ /* Group 6 : Pointer arithmetic */ @@ -287,19 +318,19 @@ C_zer C_cii ==> "jsb .cii". -C_cui ==> "jsb .cui". +C_cui ==> C_cuu(). C_cfi ==> "jsb .cfi". -C_cif ==> "jsb cif". +C_cif ==> "jsb .cif". C_cuf ==> "jsb .cuf". C_cff ==> "jsb .cff". -C_ciu ==> "jsb .cuu". +C_ciu ==> C_cuu(). -C_cuu ==> "jsb .cuu ". +C_cuu ==> "addl2 ~8,sp". C_cfu ==> "jsb .cfu". @@ -470,44 +501,62 @@ C_cmp ==> /* bug : "subl2 (sp)+, (sp)". */ "br 2f"; "1 : decl r0"; "2 : pushl r0". +C_cmf + $1==4 ==> "clrl r0"; + "cmpf (sp)+, (sp)+"; + "beql 2f"; + "bgtr 1f"; + "incl r0"; + "br 2f"; + "1 : decl r0"; + "2 : pushl r0". + $1==8 ==> "clrl r0"; + "cmpd (sp)+, (sp)+"; + "beql 2f"; + "bgtr 1f"; + "incl r0"; + "br 2f"; + "1 : decl r0"; + "2 : pushl r0". + default ==> arg_error("cmf", $1). C_tlt ==> "movl (sp)+, r0"; - "movl ~1, -(sp)"; + "pushl ~1"; "tstl r0"; "blss 1f"; "clrl (sp)"; "1:". C_tle ==> "movl (sp)+, r0"; - "movl ~1, -(sp)"; + "pushl ~1"; "tstl r0"; "bleq 1f"; "clrl (sp)"; "1:". C_teq ==> "movl (sp)+, r0"; - "movl ~1, -(sp)"; + "pushl ~1"; "tstl r0"; "beql 1f"; "clrl (sp)"; "1:". C_tne ==> "movl (sp)+, r0"; - "movl ~1, -(sp)"; + "pushl ~1"; "tstl r0"; "bneq 1f"; "clrl (sp)"; "1:". C_tge ==> "movl (sp)+, r0"; - "movl ~1, -(sp)"; + "pushl ~1"; "tstl r0"; "bgeq 1f"; "clrl (sp)"; "1:". C_tgt ==> "movl (sp)+, r0"; - "movl ~1, -(sp)"; + "pushl ~1"; "tstl r0"; "bgtr 1f"; "clrl (sp)"; @@ -643,7 +692,7 @@ C_dup default ==> "movl ~$1/4, r0"; "addl3 ~$1, sp, r1"; "1:"; - "movl -(r1), -(sp)"; + "pushl -(r1)"; "sobgtr r0, 1b". C_dus @@ -651,7 +700,7 @@ C_dus "addl3 r0, sp, r1"; "ashl ~-2, r0, r0"; "1:"; - "movl -(r1), -(sp)"; + "pushl -(r1)"; "sobgtr r0, 1b". default ==> arg_error( "dus", $1). @@ -663,7 +712,7 @@ C_fil.. ==> "moval $1 + $2, hol0 + 4". C_gto.. ==> "pushal $1+$2"; "jmp .gto". -C_lim ==> "movl .trpim, -(sp)". +C_lim ==> "pushl .trpim". C_lin ==> "movl ~$1, hol0". @@ -715,6 +764,7 @@ C_trp ==> "jsb .trp". $2 == 2 ==> gen2( (short) atoi( $1)). $2 == 4 ==> gen4( (long) atol( $1)). default ==> arg_error( "icon", $2). +..fcon ==> con_float($1, $2). /*****************************************************************************/ diff --git a/mach/vax4/ce/Make.back b/mach/vax4/ce/Make.back index 8ec23d68a..cecf394b5 100644 --- a/mach/vax4/ce/Make.back +++ b/mach/vax4/ce/Make.back @@ -12,7 +12,8 @@ IDIRS=-I.\ 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 @@ -101,3 +102,5 @@ 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 header.h $(SOURCE)/common.c + $(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/common.c diff --git a/mach/vax4/ce/as.c b/mach/vax4/ce/as.c index 89a3a9324..3a97c6b1f 100644 --- a/mach/vax4/ce/as.c +++ b/mach/vax4/ce/as.c @@ -57,10 +57,10 @@ char *m; process_operand( arg, op) -char *arg; -struct t_operand *op; +register char *arg; +register struct t_operand *op; { - char *einde; + register char *einde; if ( n_index == 3) n_index = 0; @@ -116,7 +116,7 @@ struct t_operand *op; char *ind( buf, str) -char *buf, *str; +register char *buf, *str; /* Reads the index in front of '(register)'. */ @@ -129,7 +129,7 @@ char *buf, *str; char *lab( buf, str) -char *buf, *str; +register char *buf, *str; /* Reads 'label' in front of '+offset'. */ @@ -146,8 +146,8 @@ char *buf, *str; int is_reg( str, num) -char *str; -int *num; +register char *str; +register int *num; /* Is "str" a 'registers' ? */ @@ -181,7 +181,7 @@ int *num; char *end_arg( str) -char *str; +register char *str; /* Shift to the last character of "str". */ @@ -193,7 +193,8 @@ char *str; char *match( str, sym) -char *str, sym; +register char *str; +char sym; { while ( *str != sym) str++; @@ -206,14 +207,27 @@ char *str, sym; char my_buf[256]; gen_operand( op) -struct t_operand *op; +register struct t_operand *op; /* Generate object-code for a argument. */ { switch( op->type) { - case CONST : @text1( 0x8f); - @text4( %$(op->const)); + case CONST : + if (isdigit(op->const[0])) { + long l, atol(); + l = atol(op->const); + if (fit_6bits(l)) { + @text1(%$(op->const)); + } + else { + @text1( 0x8f); + @text4( %$(op->const)); + } + } + else { + @as_const(%$(op->const)); + } break; case REGISTER: @text1( %d(0x50 | op->num)); break; @@ -223,8 +237,24 @@ struct t_operand *op; break; case AUTO_INC : @text1( %d(0x80 | op->num)); break; - case IND_REG : @text1( %d(0xe0 | op->num)); - @text4( %$(op->index)); + case IND_REG : + if (isdigit(op->index[0])) { + long l, atol(); + l = atol(op->index); + if (fit_byte(l)) { + @text1( %d(0xa0 | op->num)); + @text1( %$(op->index)); + } else if (fit_word(l)) { + @text1( %d(0xc0 | op->num)); + @text2( %$(op->index)); + } else { + @text1( %d(0xe0 | op->num)); + @text4( %$(op->index)); + } + } + else { + @as_indexed(%$(op->index) , %d(op->num)); + } break; case LABEL : @text1( 0xef); if ( strindex( op->lab, DOLLAR)) { diff --git a/mach/vax4/ce/as.h b/mach/vax4/ce/as.h index b50763e60..841c70894 100644 --- a/mach/vax4/ce/as.h +++ b/mach/vax4/ce/as.h @@ -23,3 +23,7 @@ struct t_operand { int type, num; char *lab, *index, *const, *offset; }; + +#define fit_6bits(val) ((unsigned long)(val) < 64) +#define fit_byte(val) ((unsigned long)((val)+128) < 256) +#define fit_word(val) ((unsigned long)((val)+32768L) < 65536L) diff --git a/mach/vax4/ce/as_table b/mach/vax4/ce/as_table index 66026793a..de0ebc1bc 100644 --- a/mach/vax4/ce/as_table +++ b/mach/vax4/ce/as_table @@ -1,3 +1,13 @@ +addd2 src, dst ==> + @text1( 0x60); + gen_operand( src); + gen_operand( dst). + +addf2 src, dst ==> + @text1( 0x40); + gen_operand( src); + gen_operand( dst). + addl2 src, dst ==> @text1( 0xc0); gen_operand( src); @@ -110,6 +120,16 @@ clrq src ==> @text1( 0x7c); gen_operand( src). +cmpf src, dest ==> + @text1( 0x51); + gen_operand( src); + gen_operand( dest). + +cmpd src, dest ==> + @text1( 0x71); + gen_operand( src); + gen_operand( dest). + cmpl src, dest ==> @text1( 0xd1); gen_operand( src); @@ -124,6 +144,16 @@ decl src ==> @text1( 0xd7); gen_operand( src). +divf2 src, dst ==> + @text1( 0x46); + gen_operand( src); + gen_operand( dst). + +divd2 src, dst ==> + @text1( 0x66); + gen_operand( src); + gen_operand( dst). + divl2 src, dst ==> @text1( 0xc6); gen_operand( src); @@ -152,6 +182,16 @@ mcoml src, dst ==> gen_operand( src); gen_operand( dst). +mnegf src, dst ==> + @text1( 0x52); + gen_operand( src); + gen_operand( dst). + +mnegd src, dst ==> + @text1( 0x72); + gen_operand( src); + gen_operand( dst). + mnegl src, dst ==> @text1( 0xce); gen_operand( src); @@ -189,6 +229,16 @@ movq src : const, dst ==> gen_operand( dst). +mulf2 src, dst ==> + @text1( 0x44); + gen_operand( src); + gen_operand( dst). + +muld2 src, dst ==> + @text1( 0x64); + gen_operand( src); + gen_operand( dst). + mull2 src, dst ==> @text1( 0xc4); gen_operand( src); @@ -216,6 +266,16 @@ sobgtr tel, ilb ==> gen_operand( tel); gen_operand( ilb). +subf2 src, dst ==> + @text1( 0x42); + gen_operand( src); + gen_operand( dst). + +subd2 src, dst ==> + @text1( 0x62); + gen_operand( src); + gen_operand( dst). + subl2 src, dst ==> @text1( 0xc2); gen_operand( src); diff --git a/mach/vax4/ce/do_close.c b/mach/vax4/ce/do_close.c index 5bb0fbd07..a9f3721de 100644 --- a/mach/vax4/ce/do_close.c +++ b/mach/vax4/ce/do_close.c @@ -2,7 +2,7 @@ extern File *out_file; -do_close() +close_back() { sys_close( out_file); } diff --git a/mach/vax4/ce/do_open.c b/mach/vax4/ce/do_open.c index 83f529ab7..337fc6253 100644 --- a/mach/vax4/ce/do_open.c +++ b/mach/vax4/ce/do_open.c @@ -2,7 +2,7 @@ File *out_file; -do_open( filename) +open_back( filename) char *filename; { if ( filename == (char *) '\0') diff --git a/mach/vax4/ce/end_back.c b/mach/vax4/ce/end_back.c index 60d42a11b..f776e41ad 100644 --- a/mach/vax4/ce/end_back.c +++ b/mach/vax4/ce/end_back.c @@ -4,16 +4,18 @@ #include "back.h" #include "header.h" +static do_algn(); end_back() { - sync(); + do_algn(); do_local_relocation(); output(); } -sync() +static +do_algn() { while ( ( text - text_area) % EM_WSIZE != 0 ) text1( '\0'); diff --git a/mach/vax4/ce/mach.c b/mach/vax4/ce/mach.c index 5598352df..11c878fd8 100644 --- a/mach/vax4/ce/mach.c +++ b/mach/vax4/ce/mach.c @@ -10,3 +10,171 @@ int arg; { fprint( STDERR, "arg_error %s %d\n", s, arg); } + +#define OWNFLOAT /* compile on VAX, generate code for VAX FP ... */ + +con_float(str, argval) + char *str; + int argval; +{ +#ifdef NOFLOAT + +static int been_here; + if (argval != 4 && argval != 8) + arg_error("fcon", argval); + if (argval == 8) + gen4((FOUR_BYTES) 0); + gen4((FOUR_BYTES) 0); + if ( !been_here++) + { + fputs("Warning : dummy float-constant(s)\n", stderr); + } +#else + double f; + double atof(); + int i; + int j; + double frexp(); +#ifndef OWNFLOAT + int sign = 0; + int fraction[4] ; +#else OWNFLOAT + float fl; + char *p; +#endif OWNFLOAT + + if (argval!= 4 && argval!= 8) { + arg_error("fcon", argval); + argval = 8; + } + f = atof(str); + if (f == 0) { + if (argval == 8) gen4((FOUR_BYTES) 0); + gen4((FOUR_BYTES) 0); + return; + } +#ifdef OWNFLOAT + if (argval == 4) { + /* careful: avoid overflow */ + fl = frexp(f, &i); + fl = frexp(fl,&j); + if (i+j > 127) { + /* overflow situation */ + gen1(0377); + gen1(f<0?0377:0177); + gen1(0377); + gen1(0377); + return; + } + if (i+j < -127) { + /* underflow situation */ + gen1(0200); + gen1(f<0?0200:0); + gen1(0); + gen1(0); + return; + } + fl = f; + p = (char *) &fl; + } + else { + p = (char *) &f; + } + gen1(*p++&0377); + for (i = argval-1; i; i--) { + gen1(*p++&0377); + } +#else OWNFLOAT + f = frexp(f, &i); + if (f < 0) { + f = -f; + sign = 1; + } + while (f < 0.5) { + f += f; + i --; + } + f = 2*f - 1.0; /* hidden bit */ + i--; /* exponent is one lower for SUN floating point! */ +#ifdef IEEEFLOAT + if (argval == 4) { +#endif IEEEFLOAT + i = (i + 128) & 0377; + fraction[0] = (sign << 15) | (i << 7); + for (j = 6; j>= 0; j--) { + f *= 2; + if (f >= 1.0) { + f -= 1.0; + fraction[0] |= (1 << j); + } + } +#ifdef IEEEFLOAT + } + else { + i = (i + 1024) & 03777; + fraction[0] = (sign << 15) | (i << 4); + for (j = 3; j>= 0; j--) { + f *= 2; + if (f >= 1.0) { + fraction[0] |= (1 << j); + f -= 1.0; + } + } + } +#endif IEEEFLOAT + for (i = 1; i < argval / 2; i++) { + fraction[i] = 0; + for (j = 15; j>= 0; j--) { + f *= 2; + if (f >= 1.0) { + fraction[i] |= (1 << j); + f -= 1.0; + } + } + } + if (f >= 0.5) { + for (i = argval/2 - 1; i >= 0; i--) { + for (j = 0; j < 16; j++) { + if (fraction[i] & (1 << j)) { + fraction[i] &= ~(1 << j); + } + else { + fraction[i] |= (1 << j); + break; + } + } + if (j != 16) break; + } + } + for (i = 0; i < argval/2; i++) { + gen1(fraction[i]&0377); + gen1((fraction[i]>>8)&0377); + } +#endif OWNFLOAT +#endif +} + +as_indexed(val, num) +{ + if (fit_byte(val)) { + text1( 0xa0 | num); + text1( val); + } else if (fit_word(val)) { + text1( 0xc0 | num); + text2( val); + } else { + text1( 0xe0 | num); + text4( val); + } +} + +as_const(val) +{ + if (fit_6bits(val)) { + text1(val); + } + else { + text1(0x8f); + text4(val); + } +} diff --git a/mach/vax4/ce/mach.h b/mach/vax4/ce/mach.h index f19995e97..eff4e298a 100644 --- a/mach/vax4/ce/mach.h +++ b/mach/vax4/ce/mach.h @@ -1,5 +1,5 @@ -#define ONE_BYTE char -#define TWO_BYTES short +#define ONE_BYTE int +#define TWO_BYTES int #define FOUR_BYTES long #define EM_WSIZE 4 @@ -10,10 +10,11 @@ #define NAME_FMT "_%s" #define DNAM_FMT "_%s" -#define DLB_FMT "_%ld" +#define DLB_FMT "I_%ld" #define ILB_FMT "I%03d%ld" #define HOL_FMT "hol%d" +#define GENLAB 'I' /* compiler generated labels start with I */ #define ALIGN_FMT "" @@ -33,4 +34,8 @@ #define RELOC1_FMT ".byte %s + %ld\n" #define RELOC2_FMT ".word %s + %ld\n" #define RELOC4_FMT ".long %s + %ld\n" + +#define fit_6bits(val) ((unsigned long)(val) < 64) +#define fit_byte(val) ((unsigned long)((val)+128) < 256) +#define fit_word(val) ((unsigned long)((val)+32768L) < 65536L) diff --git a/mach/vax4/ce/output.c b/mach/vax4/ce/output.c index 34f98eeec..f344d1edc 100644 --- a/mach/vax4/ce/output.c +++ b/mach/vax4/ce/output.c @@ -5,50 +5,79 @@ #include "back.h" #include "data.h" -extern File *out_file; - -/* This program converts an ACK a.out format to A BSD4.1 a.out. - * It is written for the a.out's generated by a code expander. So be - * carefull it is not very powerfull. - */ +/* Unportable code. Written for VAX, meant to be run on a VAX. +*/ +#ifndef vax +Read above comment ... +#endif +extern File *out_file; #include +#include -struct exec u_header; -struct relocation_info u_reloc; -struct nlist u_name; +static struct exec u_header; long ntext, ndata, nrelo, nchar, base_address(); -int trsize=0, drsize=0; +static int trsize=0, drsize=0; + +static struct relocation_info *u_reloc; + +static reduce_name_table(); output() { register int i; + register struct nlist *u_name; - init_unixheader(); + /* + * Convert relocation data structures. This also requires + * some re-ordering, as SUN .o format needs has text relocation + * structures in front of the data relocation structures, whereas in + * ACK they can be in any order. + */ + + nrelo = relo - reloc_info; + u_reloc = (struct relocation_info *) + Malloc((unsigned)nrelo*sizeof(struct relocation_info)); - putbuf( (char *) &u_header, 32); - putbuf( (char *) text_area, ntext); - putbuf( (char *) data_area, ndata); - for (i = 0; i < nrelo; i++) { - if ( ( reloc_info[i].or_sect-S_MIN) == SEGTXT) { - convert_reloc( &reloc_info[i], &u_reloc); - putbuf((char *) &u_reloc, 8); + if ( ( reloc_info[i].or_sect-S_MIN) == SEGTXT && + convert_reloc( &reloc_info[i], u_reloc)) { + trsize++; + u_reloc++; } } for (i = 0; i < nrelo; i++) { - if (( reloc_info[i].or_sect-S_MIN) != SEGTXT) { - convert_reloc( &reloc_info[i], &u_reloc); - putbuf((char *) &u_reloc, 8); + if ( ( reloc_info[i].or_sect-S_MIN) != SEGTXT && + convert_reloc( &reloc_info[i], u_reloc)) { + u_reloc++; + drsize++; } } + nrelo = trsize + drsize; + u_reloc -= nrelo; + + reduce_name_table(); + + init_unixheader(); + + putbuf( (char *) &u_header, sizeof(struct exec)); + putbuf( (char *) text_area, ntext); + putbuf( (char *) data_area, ndata); + putbuf((char *) u_reloc, sizeof(struct relocation_info)*nrelo); + free(u_reloc); + + u_name = (struct nlist *) + Malloc((unsigned)nname * sizeof(struct nlist)); + for (i = 0; i < nname ; i++) { /* The segment names can be omitted */ - convert_name( &symbol_table[i], &u_name); - putbuf((char *) &u_name, 12); + convert_name( &symbol_table[i], u_name++); } + u_name -= nname; + putbuf((char *) u_name, sizeof(struct nlist)*nname); + free(u_name); /* print( "size string_area %d\n", nchar); */ @@ -56,30 +85,84 @@ output() putbuf((char *) string_area, nchar); } - -init_unixheader() +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 int i; + char *new_str; + register char *p, *q; - for ( i = 0; i < (relo - reloc_info); i++) - if ( ( reloc_info[ i].or_sect - S_MIN) == SEGTXT) - trsize++; - else - drsize++; + *diff_index++ = 0; + for (i = 0; i < nrelo; i++) { + if (u_reloc[i].r_extern) { + symbol_table[u_reloc[i].r_symbolnum].on_type |= S_NEEDED; + } + } + + for (i = 0; i < nname; i++) { + int old_diff_index = diff_index[i-1]; + + if (removable(symbol_table[i])) { + diff_index[i] = old_diff_index + 1; + } + else { + diff_index[i] = old_diff_index; + if (old_diff_index) { + symbol_table[i - old_diff_index] = symbol_table[i]; + } + } + } + nname -= diff_index[nname - 1]; + + for (i = 0; i < nrelo; i++) { + register struct relocation_info *rp = &u_reloc[i]; + + if (rp->r_extern) { + rp->r_symbolnum -= diff_index[rp->r_symbolnum]; + } + } + 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; +} + +init_unixheader() +{ ntext = text - text_area; ndata = data - data_area; nchar = string - string_area; - nrelo = relo - reloc_info; u_header.a_magic = OMAGIC; u_header.a_text = ntext; u_header.a_data = ndata; u_header.a_bss = nbss; - u_header.a_syms = nname * 12; + u_header.a_syms = nname * sizeof(struct nlist); u_header.a_entry = 0; - u_header.a_trsize = trsize * 8; - u_header.a_drsize = drsize * 8; + u_header.a_trsize = trsize * sizeof(struct relocation_info); + u_header.a_drsize = drsize * sizeof(struct relocation_info); /* print( "header %o %d %d %d %d %d %d %d\n", u_header.a_magic, u_header.a_text, u_header.a_data, u_header.a_bss, u_header.a_syms, u_header.a_entry, @@ -91,17 +174,23 @@ convert_reloc( a_relo, u_relo) struct outrelo *a_relo; struct relocation_info *u_relo; { + int retval = 1; + u_relo->r_address = a_relo->or_addr; u_relo->r_symbolnum = a_relo->or_nami; u_relo->r_pcrel = (a_relo->or_type & RELPC) >> 3; - u_relo->r_length = convert_length( (a_relo->or_type) & RELSZ); - if ( symbol_table[ a_relo->or_nami].on_valu == -1) + u_relo->r_length = 2; + if ( symbol_table[ a_relo->or_nami].on_valu == -1 || + (symbol_table[ a_relo->or_nami].on_type & S_COM)) u_relo->r_extern = 1; else u_relo->r_extern = 0; - if ( symbol_table[ a_relo->or_nami].on_valu != -1) { + if ( u_relo->r_extern == 0) { switch ( (symbol_table[ a_relo->or_nami].on_type & S_TYP) - S_MIN) { case SEGTXT : u_relo->r_symbolnum = N_TEXT; + if (u_relo->r_pcrel && + (a_relo->or_sect-S_MIN == SEGTXT)) + retval = 0; break; case SEGCON : u_relo->r_symbolnum = N_DATA; break; @@ -112,27 +201,12 @@ struct relocation_info *u_relo; (symbol_table[ a_relo->or_nami].on_type & S_TYP) - S_MIN); } } -} - - -int convert_length( length) -int length; -{ - if ( length & RELO1) - return( 0); - else if ( length & RELO2) - return( 1); - else if ( length & RELO4) - return( 2); - else - fprint( STDERR, "convert_length(): size is impossible %d\n", - length); + return retval; } #define n_mptr n_un.n_name #define n_str n_un.n_strx - convert_name( a_name, u_name) struct outname *a_name; struct nlist *u_name; @@ -143,7 +217,9 @@ struct nlist *u_name; fill_type( &(u_name->n_type), &(a_name->on_type), a_name->on_valu); u_name->n_other = '\0'; u_name->n_desc = 0; - if ( a_name->on_valu != -1) + if (a_name->on_type & S_COM) + u_name->n_value = a_name->on_valu; + else if ( a_name->on_valu != -1) u_name->n_value = a_name->on_valu + base_address( ( a_name->on_type & S_TYP) - S_MIN); else @@ -158,10 +234,9 @@ long valu; { int sect; - *u_type = '\0'; - *u_type |= ( *a_type & S_EXT) ? N_EXT : N_UNDF; + *u_type = ((*a_type&S_TYP) == S_UND || (*a_type & S_EXT)) ? N_EXT : 0; - if ( valu != -1) { + if ( valu != -1 && (! (*a_type & S_COM))) { sect = ( *a_type & S_TYP ) - S_MIN; switch ( sect) { case SEGTXT: *u_type |= N_TEXT; @@ -193,9 +268,9 @@ int seg; } put_stringtablesize( n) -int n; +long n; { - putbuf( (char *)&n, 4); + putbuf( (char *)&n, 4L); } diff --git a/mach/vax4/ce/relocation.c b/mach/vax4/ce/relocation.c index ab4b44f6d..e4a92c58c 100644 --- a/mach/vax4/ce/relocation.c +++ b/mach/vax4/ce/relocation.c @@ -3,74 +3,53 @@ #include "data.h" #include "back.h" -#define seg_index( s) ( nname - SEGBSS - 1 + s) - long get4(); -long base_adres(); +extern long base_address(); +/* extern short get2(); extern char get1(); - +*/ do_local_relocation() { - register struct outrelo *ptr; - register int s; + register struct outrelo *rp; /* print( "n relocation records %d\n", relo - reloc_info); */ - 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; -{ - 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; - } - oldval = get4( sect, rp->or_addr); - newval = oldval + np->on_valu + - base_address( (np->on_type & S_TYP) -S_MIN); - if ( rp->or_type & RELO4) - put4( sect, rp->or_addr, newval); - else if ( rp->or_type & RELO2) - put2( sect, rp->or_addr, (int) newval); - else if ( rp->or_type & RELO1) - put1( sect, rp->or_addr, (char) newval); - 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); - */ -} - - -long base_adres( seg) -int seg; -{ - switch ( seg) { - case SEGTXT : return( 0); - case SEGCON : return( text-text_area); - case SEGBSS : return( text-text_area + data-data_area); - default : fprint( STDERR, "base_adres() wrong seg %d\n", seg); + for ( rp = reloc_info; rp < relo; rp++) { + register struct outname *np = &symbol_table[rp->or_nami]; + + 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; + } + oldval = get4( sect, rp->or_addr); + newval = oldval + np->on_valu + + base_address( (np->on_type & S_TYP) -S_MIN); + if ( rp->or_type & RELO4) + put4( sect, rp->or_addr, newval); + /* + else if ( rp->or_type & RELO2) + put2( sect, rp->or_addr, (int) newval); + else if ( rp->or_type & RELO1) + put1( sect, rp->or_addr, (char) newval); + */ + else + print( STDERR, + "do_relo() : bad relocation size\n"); + } } }