improved version, generating .o files with much less relocation records

and name table entries
This commit is contained in:
ceriel 1988-10-13 15:53:31 +00:00
parent ce0ec1c143
commit d096f1882a
3 changed files with 76 additions and 9 deletions

View file

@ -70,10 +70,9 @@ static int been_here;
#ifdef OWNFLOAT #ifdef OWNFLOAT
if (argval == 4) { if (argval == 4) {
/* careful: avoid overflow */ /* careful: avoid overflow */
double ldexp(); double f1;
f = frexp(f, &i); f1 = frexp(f, &i);
fl = f; fl = frexp(f1,&j);
fl = frexp(fl,&j);
if (i+j > 127) { if (i+j > 127) {
/* overflow situation */ /* overflow situation */
gen1(f<0?0377:0177); gen1(f<0?0377:0177);
@ -90,7 +89,7 @@ static int been_here;
gen1(0); gen1(0);
return; return;
} }
fl = ldexp(fl, i+j); fl = f;
p = (char *) &fl; p = (char *) &fl;
} }
else { else {

View file

@ -13,7 +13,7 @@
#define NAME_FMT "_%s" #define NAME_FMT "_%s"
#define DNAM_FMT "_%s" #define DNAM_FMT "_%s"
#define DLB_FMT "_%ld" #define DLB_FMT "I_%ld"
#define ILB_FMT "I%x_%lx" #define ILB_FMT "I%x_%lx"
#define HOL_FMT "hol%d" #define HOL_FMT "hol%d"

View file

@ -21,14 +21,17 @@ struct exec u_header;
long ntext, ndata, nrelo, nchar, base_address(); long ntext, ndata, nrelo, nchar, base_address();
int trsize=0, drsize=0; int trsize=0, drsize=0;
struct relocation_info *u_reloc;
static reduce_name_table();
output() output()
{ {
register int i; register int i;
struct relocation_info *u_reloc; register struct nlist *u_name;
struct nlist *u_name;
/* /*
* first, convert relocation data structures. This also requires * Convert relocation data structures. This also requires
* some re-ordering, as SUN .o format needs has text relocation * some re-ordering, as SUN .o format needs has text relocation
* structures in front of the data relocation structures, whereas in * structures in front of the data relocation structures, whereas in
* ACK they can be in any order. * ACK they can be in any order.
@ -56,6 +59,8 @@ output()
nrelo = trsize + drsize; nrelo = trsize + drsize;
u_reloc -= nrelo; u_reloc -= nrelo;
reduce_name_table();
init_unixheader(); init_unixheader();
putbuf( (char *) &u_header, sizeof(struct exec)); putbuf( (char *) &u_header, sizeof(struct exec));
@ -80,6 +85,69 @@ output()
putbuf((char *) string_area, nchar); putbuf((char *) 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 int i;
char *new_str;
register char *p, *q;
*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() init_unixheader()
{ {