* aoutx.h: Include <ctype.h>.

(struct aout_link_includes_table): Define.
	(struct aout_link_includes_totals): Define.
	(struct aout_link_includes_entry): Define.
	(aout_link_includes_lookup): Define macro.
	(struct aout_final_link_info): Add includes field.
	(aout_link_includes_newfunc): New static function.
	(NAME(aout,final_link)): Initialize includes hash table.
	(aout_link_write_symbols): Eliminate duplicate N_BINCL entries.
This commit is contained in:
Ian Lance Taylor 1995-12-13 20:47:36 +00:00
parent 480ccad563
commit 14dc2f774e
2 changed files with 213 additions and 0 deletions

View File

@ -1,3 +1,15 @@
Wed Dec 13 15:44:06 1995 Ian Lance Taylor <ian@cygnus.com>
* aoutx.h: Include <ctype.h>.
(struct aout_link_includes_table): Define.
(struct aout_link_includes_totals): Define.
(struct aout_link_includes_entry): Define.
(aout_link_includes_lookup): Define macro.
(struct aout_final_link_info): Add includes field.
(aout_link_includes_newfunc): New static function.
(NAME(aout,final_link)): Initialize includes hash table.
(aout_link_write_symbols): Eliminate duplicate N_BINCL entries.
Wed Dec 13 10:52:14 1995 Stan Shebs <shebs@andros.cygnus.com>
* mpw-config.in: Match on mips-*-* instead of mips-idt-ecoff.

View File

@ -120,6 +120,7 @@ DESCRIPTION
#define KEEPIT udata.i
#include <string.h> /* For strchr and friends */
#include <ctype.h>
#include "bfd.h"
#include <sysdep.h>
#include "bfdlink.h"
@ -3369,6 +3370,37 @@ aout_link_add_symbols (abfd, info)
return true;
}
/* A hash table used for header files with N_BINCL entries. */
struct aout_link_includes_table
{
struct bfd_hash_table root;
};
/* A linked list of totals that we have found for a particular header
file. */
struct aout_link_includes_totals
{
struct aout_link_includes_totals *next;
bfd_vma total;
};
/* An entry in the header file hash table. */
struct aout_link_includes_entry
{
struct bfd_hash_entry root;
/* List of totals we have found for this file. */
struct aout_link_includes_totals *totals;
};
/* Look up an entry in an the header file hash table. */
#define aout_link_includes_lookup(table, string, create, copy) \
((struct aout_link_includes_entry *) \
bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
/* During the final link step we need to pass around a bunch of
information, so we do it in an instance of this structure. */
@ -3385,6 +3417,8 @@ struct aout_final_link_info
file_ptr symoff;
/* String table. */
struct bfd_strtab_hash *strtab;
/* Header file hash table. */
struct aout_link_includes_table includes;
/* A buffer large enough to hold the contents of any section. */
bfd_byte *contents;
/* A buffer large enough to hold the relocs of any section. */
@ -3395,6 +3429,8 @@ struct aout_final_link_info
struct external_nlist *output_syms;
};
static struct bfd_hash_entry *aout_link_includes_newfunc
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
static boolean aout_link_input_bfd
PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
static boolean aout_link_write_symbols
@ -3419,6 +3455,38 @@ static boolean aout_link_reloc_link_order
PARAMS ((struct aout_final_link_info *, asection *,
struct bfd_link_order *));
/* The function to create a new entry in the header file hash table. */
static struct bfd_hash_entry *
aout_link_includes_newfunc (entry, table, string)
struct bfd_hash_entry *entry;
struct bfd_hash_table *table;
const char *string;
{
struct aout_link_includes_entry *ret =
(struct aout_link_includes_entry *) entry;
/* Allocate the structure if it has not already been allocated by a
subclass. */
if (ret == (struct aout_link_includes_entry *) NULL)
ret = ((struct aout_link_includes_entry *)
bfd_hash_allocate (table,
sizeof (struct aout_link_includes_entry)));
if (ret == (struct aout_link_includes_entry *) NULL)
return (struct bfd_hash_entry *) ret;
/* Call the allocation method of the superclass. */
ret = ((struct aout_link_includes_entry *)
bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
if (ret)
{
/* Set local fields. */
ret->totals = NULL;
}
return (struct bfd_hash_entry *) ret;
}
/* Do the final link step. This is called on the output BFD. The
INFO structure should point to a list of BFDs linked through the
link_next field which can be used to find each BFD which takes part
@ -3433,6 +3501,7 @@ NAME(aout,final_link) (abfd, info, callback)
void (*callback) PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
{
struct aout_final_link_info aout_info;
boolean includes_hash_initialized = false;
register bfd *sub;
bfd_size_type trsize, drsize;
size_t max_contents_size;
@ -3451,6 +3520,14 @@ NAME(aout,final_link) (abfd, info, callback)
aout_info.output_bfd = abfd;
aout_info.contents = NULL;
aout_info.relocs = NULL;
aout_info.symbol_map = NULL;
aout_info.output_syms = NULL;
if (! bfd_hash_table_init_n (&aout_info.includes.root,
aout_link_includes_newfunc,
251))
goto error_return;
includes_hash_initialized = true;
/* Figure out the largest section size. Also, if generating
relocateable output, count the relocs. */
@ -3684,6 +3761,11 @@ NAME(aout,final_link) (abfd, info, callback)
free (aout_info.output_syms);
aout_info.output_syms = NULL;
}
if (includes_hash_initialized)
{
bfd_hash_table_free (&aout_info.includes.root);
includes_hash_initialized = false;
}
/* Finish up any dynamic linking we may be doing. */
if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
@ -3715,6 +3797,8 @@ NAME(aout,final_link) (abfd, info, callback)
free (aout_info.symbol_map);
if (aout_info.output_syms != NULL)
free (aout_info.output_syms);
if (includes_hash_initialized)
bfd_hash_table_free (&aout_info.includes.root);
return false;
}
@ -3833,6 +3917,7 @@ aout_link_write_symbols (finfo, input_bfd)
sym_end = sym + sym_count;
sym_hash = obj_aout_sym_hashes (input_bfd);
symbol_map = finfo->symbol_map;
memset (symbol_map, 0, sym_count * sizeof *symbol_map);
for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
{
const char *name;
@ -3843,6 +3928,16 @@ aout_link_write_symbols (finfo, input_bfd)
bfd_vma val = 0;
boolean copy;
/* We set *symbol_map to 0 above for all symbols. If it has
already been set to -1 for this symbol, it means that we are
discarding it because it appears in a duplicate header file.
See the N_BINCL code below. */
if (*symbol_map == -1)
continue;
/* Initialize *symbol_map to -1, which means that the symbol was
not copied into the output file. We will change it later if
we do copy the symbol over. */
*symbol_map = -1;
type = bfd_h_get_8 (input_bfd, sym->e_type);
@ -4092,6 +4187,112 @@ aout_link_write_symbols (finfo, input_bfd)
continue;
}
}
/* An N_BINCL symbol indicates the start of the stabs
entries for a header file. We need to scan ahead to the
next N_EINCL symbol, ignoring nesting, adding up all the
characters in the symbol names, not including the file
numbers in types (the first number after an open
parenthesis). */
if (type == N_BINCL)
{
struct external_nlist *incl_sym;
int nest;
struct aout_link_includes_entry *incl_entry;
struct aout_link_includes_totals *t;
val = 0;
nest = 0;
for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++)
{
int incl_type;
incl_type = bfd_h_get_8 (input_bfd, incl_sym->e_type);
if (incl_type == N_EINCL)
{
if (nest == 0)
break;
--nest;
}
else if (incl_type == N_BINCL)
++nest;
else if (nest == 0)
{
const char *s;
s = strings + GET_WORD (input_bfd, incl_sym->e_strx);
for (; *s != '\0'; s++)
{
val += *s;
if (*s == '(')
{
/* Skip the file number. */
++s;
while (isdigit ((unsigned char) *s))
++s;
--s;
}
}
}
}
/* If we have already included a header file with the
same value, then replace this one with an N_EXCL
symbol. */
copy = ! finfo->info->keep_memory;
incl_entry = aout_link_includes_lookup (&finfo->includes,
name, true, copy);
if (incl_entry == NULL)
return false;
for (t = incl_entry->totals; t != NULL; t = t->next)
if (t->total == val)
break;
if (t == NULL)
{
/* This is the first time we have seen this header
file with this set of stabs strings. */
t = ((struct aout_link_includes_totals *)
bfd_hash_allocate (&finfo->includes.root,
sizeof *t));
if (t == NULL)
return false;
t->total = val;
t->next = incl_entry->totals;
incl_entry->totals = t;
}
else
{
int *incl_map;
/* This is a duplicate header file. We must change
it to be an N_EXCL entry, and mark all the
included symbols to prevent outputting them. */
type = N_EXCL;
nest = 0;
for (incl_sym = sym + 1, incl_map = symbol_map + 1;
incl_sym < sym_end;
incl_sym++, incl_map++)
{
int incl_type;
incl_type = bfd_h_get_8 (input_bfd, incl_sym->e_type);
if (incl_type == N_EINCL)
{
if (nest == 0)
{
*incl_map = -1;
break;
}
--nest;
}
else if (incl_type == N_BINCL)
++nest;
else if (nest == 0)
*incl_map = -1;
}
}
}
}
/* Copy this symbol into the list of symbols we are going to