* linker.c (_bfd_generic_final_link): Set reloc_count to 0 before

counting relocs.  Set SEC_RELOC flag for any section which has
	relocs.

	* linker.c (_bfd_default_link_order): Handle bfd_data_link_order.

	* linker.c (_bfd_generic_link_add_symbols): Just call
	generic_link_add_symbols.
	(_bfd_generic_link_add_symbols_collect): New function, like
	_bfd_generic_link_add_symbols but also collect constructors and
	destructors by name as collect2 does.
	(generic_link_add_symbols): New function, like old
	_bfd_generic_link_add_symbols but with collect argument.
	(generic_link_add_object_symbols): Take collect argument.
	(generic_link_check_archive_element_no_collect): New function.
	(generic_link_check_archive_element_collect): New function.
	(generic_link_check_archive_element): Take collect argument.
	(generic_link_add_symbol_list): Take collect argument.
	(_bfd_generic_link_add_one_symbol): Rename constructor argument to
	collect.
	* libbfd-in.h (_bfd_generic_link_add_symbols_collect): Declare.
	* libbfd.h: Rebuilt.
This commit is contained in:
Ian Lance Taylor 1994-03-22 18:18:40 +00:00
parent f3bc3ac3fa
commit 4335ce642d
3 changed files with 142 additions and 27 deletions

View File

@ -1,3 +1,34 @@
Tue Mar 22 13:09:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
* elf32-mips.c (mips_elf_final_link): Account for link_order
relocs when allocating space for relocations. Set SEC_RELOC flag
for any section which has relocs. Handle link_order relocs in
link_order loop. Use _bfd_generic_link_add_symbols_collect for
add_symbls entry point.
* linker.c (_bfd_generic_final_link): Set reloc_count to 0 before
counting relocs. Set SEC_RELOC flag for any section which has
relocs.
* linker.c (_bfd_default_link_order): Handle bfd_data_link_order.
* linker.c (_bfd_generic_link_add_symbols): Just call
generic_link_add_symbols.
(_bfd_generic_link_add_symbols_collect): New function, like
_bfd_generic_link_add_symbols but also collect constructors and
destructors by name as collect2 does.
(generic_link_add_symbols): New function, like old
_bfd_generic_link_add_symbols but with collect argument.
(generic_link_add_object_symbols): Take collect argument.
(generic_link_check_archive_element_no_collect): New function.
(generic_link_check_archive_element_collect): New function.
(generic_link_check_archive_element): Take collect argument.
(generic_link_add_symbol_list): Take collect argument.
(_bfd_generic_link_add_one_symbol): Rename constructor argument to
collect.
* libbfd-in.h (_bfd_generic_link_add_symbols_collect): Declare.
* libbfd.h: Rebuilt.
Tue Mar 22 10:04:00 1994 Jeffrey A. Law (law@snake.cs.utah.edu) Tue Mar 22 10:04:00 1994 Jeffrey A. Law (law@snake.cs.utah.edu)
* archive.c (bfd_construct_extended_name_table): Use ar_padchar * archive.c (bfd_construct_extended_name_table): Use ar_padchar

View File

@ -178,6 +178,12 @@ extern struct bfd_link_hash_table *_bfd_generic_link_hash_table_create
extern boolean _bfd_generic_link_add_symbols extern boolean _bfd_generic_link_add_symbols
PARAMS ((bfd *, struct bfd_link_info *)); PARAMS ((bfd *, struct bfd_link_info *));
/* Generic add symbol routine. This version is used by targets for
which the linker must collect constructors and destructors by name,
as the collect2 program does. */
extern boolean _bfd_generic_link_add_symbols_collect
PARAMS ((bfd *, struct bfd_link_info *));
/* Generic archive add symbol routine. */ /* Generic archive add symbol routine. */
extern boolean _bfd_generic_link_add_archive_symbols extern boolean _bfd_generic_link_add_archive_symbols
PARAMS ((bfd *, struct bfd_link_info *, PARAMS ((bfd *, struct bfd_link_info *,

View File

@ -313,7 +313,10 @@ SUBSUBSECTION
<<bfdlink.h>>). These structures describe how to create the <<bfdlink.h>>). These structures describe how to create the
contents of the output section in terms of the contents of contents of the output section in terms of the contents of
various input sections, fill constants, and, eventually, other various input sections, fill constants, and, eventually, other
types of information. types of information. They also describe relocs that must be
created by the BFD backend, but do not correspond to any input
file; this is used to support -Ur, which builds constructors
while generating a relocateable object file.
INODE INODE
Relocating the section contents, Writing the symbol table, Information provided by the linker, Performing the Final Link Relocating the section contents, Writing the symbol table, Information provided by the linker, Performing the Final Link
@ -409,12 +412,19 @@ SUBSUBSECTION
static struct bfd_hash_entry *generic_link_hash_newfunc static struct bfd_hash_entry *generic_link_hash_newfunc
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
const char *)); const char *));
static boolean generic_link_add_symbols
PARAMS ((bfd *, struct bfd_link_info *, boolean collect));
static boolean generic_link_add_object_symbols static boolean generic_link_add_object_symbols
PARAMS ((bfd *, struct bfd_link_info *)); PARAMS ((bfd *, struct bfd_link_info *, boolean collect));
static boolean generic_link_check_archive_element static boolean generic_link_check_archive_element_no_collect
PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded)); PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded));
static boolean generic_link_check_archive_element_collect
PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded));
static boolean generic_link_check_archive_element
PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded, boolean collect));
static boolean generic_link_add_symbol_list static boolean generic_link_add_symbol_list
PARAMS ((bfd *, struct bfd_link_info *, bfd_size_type count, asymbol **)); PARAMS ((bfd *, struct bfd_link_info *, bfd_size_type count, asymbol **,
boolean collect));
static boolean generic_add_output_symbol static boolean generic_add_output_symbol
PARAMS ((bfd *, size_t *psymalloc, asymbol *)); PARAMS ((bfd *, size_t *psymalloc, asymbol *));
static boolean default_fill_link_order static boolean default_fill_link_order
@ -601,24 +611,54 @@ _bfd_generic_link_hash_table_create (abfd)
return &ret->root; return &ret->root;
} }
/* Generic function to add symbols from an object file to the global /* Generic function to add symbols to from an object file to the
hash table. */ global hash table. This version does not automatically collect
constructors by name. */
boolean boolean
_bfd_generic_link_add_symbols (abfd, info) _bfd_generic_link_add_symbols (abfd, info)
bfd *abfd; bfd *abfd;
struct bfd_link_info *info; struct bfd_link_info *info;
{
return generic_link_add_symbols (abfd, info, false);
}
/* Generic function to add symbols from an object file to the global
hash table. This version automatically collects constructors by
name, as the collect2 program does. It should be used for any
target which does not provide some other mechanism for setting up
constructors and destructors; these are approximately those targets
for which gcc uses collect2 and do not support stabs. */
boolean
_bfd_generic_link_add_symbols_collect (abfd, info)
bfd *abfd;
struct bfd_link_info *info;
{
return generic_link_add_symbols (abfd, info, true);
}
/* Add symbols from an object file to the global hash table. */
static boolean
generic_link_add_symbols (abfd, info, collect)
bfd *abfd;
struct bfd_link_info *info;
boolean collect;
{ {
boolean ret; boolean ret;
switch (bfd_get_format (abfd)) switch (bfd_get_format (abfd))
{ {
case bfd_object: case bfd_object:
ret = generic_link_add_object_symbols (abfd, info); ret = generic_link_add_object_symbols (abfd, info, collect);
break; break;
case bfd_archive: case bfd_archive:
ret = _bfd_generic_link_add_archive_symbols ret = (_bfd_generic_link_add_archive_symbols
(abfd, info, generic_link_check_archive_element); (abfd, info,
(collect
? generic_link_check_archive_element_collect
: generic_link_check_archive_element_no_collect)));
break; break;
default: default:
bfd_set_error (bfd_error_wrong_format); bfd_set_error (bfd_error_wrong_format);
@ -631,9 +671,10 @@ _bfd_generic_link_add_symbols (abfd, info)
/* Add symbols from an object file to the global hash table. */ /* Add symbols from an object file to the global hash table. */
static boolean static boolean
generic_link_add_object_symbols (abfd, info) generic_link_add_object_symbols (abfd, info, collect)
bfd *abfd; bfd *abfd;
struct bfd_link_info *info; struct bfd_link_info *info;
boolean collect;
{ {
size_t symsize; size_t symsize;
asymbol **symbols; asymbol **symbols;
@ -649,7 +690,8 @@ generic_link_add_object_symbols (abfd, info)
} }
symbol_count = bfd_canonicalize_symtab (abfd, symbols); symbol_count = bfd_canonicalize_symtab (abfd, symbols);
result = generic_link_add_symbol_list (abfd, info, symbol_count, symbols); result = generic_link_add_symbol_list (abfd, info, symbol_count, symbols,
collect);
free (symbols); free (symbols);
return result; return result;
} }
@ -926,13 +968,42 @@ _bfd_generic_link_add_archive_symbols (abfd, info, checkfn)
return false; return false;
} }
/* See if we should include an archive element. */ /* See if we should include an archive element. This version is used
when we do not want to automatically collect constructors based on
the symbol name, presumably because we have some other mechanism
for finding them. */
static boolean static boolean
generic_link_check_archive_element (abfd, info, pneeded) generic_link_check_archive_element_no_collect (abfd, info, pneeded)
bfd *abfd; bfd *abfd;
struct bfd_link_info *info; struct bfd_link_info *info;
boolean *pneeded; boolean *pneeded;
{
return generic_link_check_archive_element (abfd, info, pneeded, false);
}
/* See if we should include an archive element. This version is used
when we want to automatically collect constructors based on the
symbol name, as collect2 does. */
static boolean
generic_link_check_archive_element_collect (abfd, info, pneeded)
bfd *abfd;
struct bfd_link_info *info;
boolean *pneeded;
{
return generic_link_check_archive_element (abfd, info, pneeded, true);
}
/* See if we should include an archive element. Optionally collect
constructors. */
static boolean
generic_link_check_archive_element (abfd, info, pneeded, collect)
bfd *abfd;
struct bfd_link_info *info;
boolean *pneeded;
boolean collect;
{ {
size_t symsize; size_t symsize;
asymbol **symbols = NULL; asymbol **symbols = NULL;
@ -986,7 +1057,7 @@ generic_link_check_archive_element (abfd, info, pneeded)
bfd_asymbol_name (p))) bfd_asymbol_name (p)))
goto error_return; goto error_return;
if (! generic_link_add_symbol_list (abfd, info, symbol_count, if (! generic_link_add_symbol_list (abfd, info, symbol_count,
symbols)) symbols, collect))
goto error_return; goto error_return;
*pneeded = true; *pneeded = true;
goto successful_return; goto successful_return;
@ -1051,14 +1122,19 @@ generic_link_check_archive_element (abfd, info, pneeded)
return false; return false;
} }
/* Add the symbol from an object file to the global hash table. */ /* Add the symbols from an object file to the global hash table. ABFD
is the object file. INFO is the linker information. SYMBOL_COUNT
is the number of symbols. SYMBOLS is the list of symbols. COLLECT
is true if constructors should be automatically collected by name
as is done by collect2. */
static boolean static boolean
generic_link_add_symbol_list (abfd, info, symbol_count, symbols) generic_link_add_symbol_list (abfd, info, symbol_count, symbols, collect)
bfd *abfd; bfd *abfd;
struct bfd_link_info *info; struct bfd_link_info *info;
bfd_size_type symbol_count; bfd_size_type symbol_count;
asymbol **symbols; asymbol **symbols;
boolean collect;
{ {
asymbol **pp, **ppend; asymbol **pp, **ppend;
@ -1098,14 +1174,9 @@ generic_link_add_symbol_list (abfd, info, symbol_count, symbols)
else else
string = NULL; string = NULL;
/* We pass the constructor argument as false, for
compatibility. As backends are converted they can
arrange to pass the right value (the right value is the
size of a function pointer if gcc uses collect2 for the
object file format, zero if it does not). */
if (! (_bfd_generic_link_add_one_symbol if (! (_bfd_generic_link_add_one_symbol
(info, abfd, name, p->flags, bfd_get_section (p), (info, abfd, name, p->flags, bfd_get_section (p),
p->value, string, false, 0, p->value, string, false, collect,
(struct bfd_link_hash_entry **) &h))) (struct bfd_link_hash_entry **) &h)))
return false; return false;
@ -1208,14 +1279,14 @@ static const enum link_action link_action[8][7] =
which case it is the warning string. which case it is the warning string.
COPY is true if NAME or STRING must be copied into locally COPY is true if NAME or STRING must be copied into locally
allocated memory if they need to be saved. allocated memory if they need to be saved.
CONSTRUCTOR is true if we should automatically collect gcc COLLECT is true if we should automatically collect gcc constructor
constructor or destructor names. or destructor names as collect2 does.
HASHP, if not NULL, is a place to store the created hash table HASHP, if not NULL, is a place to store the created hash table
entry. */ entry. */
boolean boolean
_bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value, _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
string, copy, constructor, hashp) string, copy, collect, hashp)
struct bfd_link_info *info; struct bfd_link_info *info;
bfd *abfd; bfd *abfd;
const char *name; const char *name;
@ -1224,7 +1295,7 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
bfd_vma value; bfd_vma value;
const char *string; const char *string;
boolean copy; boolean copy;
boolean constructor; boolean collect;
struct bfd_link_hash_entry **hashp; struct bfd_link_hash_entry **hashp;
{ {
enum link_row row; enum link_row row;
@ -1308,7 +1379,7 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
and destructors and pass them up in a callback. We only and destructors and pass them up in a callback. We only
do this for certain object file types, since many object do this for certain object file types, since many object
file types can handle this automatically. */ file types can handle this automatically. */
if (constructor && name[0] == '_') if (collect && name[0] == '_')
{ {
const char *s; const char *s;
@ -1526,6 +1597,7 @@ _bfd_generic_final_link (abfd, info)
o != (asection *) NULL; o != (asection *) NULL;
o = o->next) o = o->next)
{ {
o->reloc_count = 0;
for (p = o->link_order_head; for (p = o->link_order_head;
p != (struct bfd_link_order *) NULL; p != (struct bfd_link_order *) NULL;
p = p->next) p = p->next)
@ -1571,6 +1643,7 @@ _bfd_generic_final_link (abfd, info)
bfd_set_error (bfd_error_no_memory); bfd_set_error (bfd_error_no_memory);
return false; return false;
} }
o->flags |= SEC_RELOC;
/* Reset the count so that it can be used as an index /* Reset the count so that it can be used as an index
when putting in the output relocs. */ when putting in the output relocs. */
o->reloc_count = 0; o->reloc_count = 0;
@ -2091,6 +2164,11 @@ _bfd_default_link_order (abfd, info, sec, link_order)
return default_indirect_link_order (abfd, info, sec, link_order); return default_indirect_link_order (abfd, info, sec, link_order);
case bfd_fill_link_order: case bfd_fill_link_order:
return default_fill_link_order (abfd, info, sec, link_order); return default_fill_link_order (abfd, info, sec, link_order);
case bfd_data_link_order:
return bfd_set_section_contents (abfd, sec,
(PTR) link_order->u.data.contents,
(file_ptr) link_order->offset,
link_order->size);
} }
} }