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

View file

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

View file

@ -21,14 +21,17 @@ struct exec u_header;
long ntext, ndata, nrelo, nchar, base_address();
int trsize=0, drsize=0;
struct relocation_info *u_reloc;
static reduce_name_table();
output()
{
register int i;
struct relocation_info *u_reloc;
struct nlist *u_name;
register 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
* structures in front of the data relocation structures, whereas in
* ACK they can be in any order.
@ -56,6 +59,8 @@ output()
nrelo = trsize + drsize;
u_reloc -= nrelo;
reduce_name_table();
init_unixheader();
putbuf( (char *) &u_header, sizeof(struct exec));
@ -80,6 +85,69 @@ output()
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()
{