| /* linker.c -- BFD linker routines | 
 |    Copyright (C) 1993-2025 Free Software Foundation, Inc. | 
 |    Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support | 
 |  | 
 |    This file is part of BFD, the Binary File Descriptor library. | 
 |  | 
 |    This program is free software; you can redistribute it and/or modify | 
 |    it under the terms of the GNU General Public License as published by | 
 |    the Free Software Foundation; either version 3 of the License, or | 
 |    (at your option) any later version. | 
 |  | 
 |    This program is distributed in the hope that it will be useful, | 
 |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 |    GNU General Public License for more details. | 
 |  | 
 |    You should have received a copy of the GNU General Public License | 
 |    along with this program; if not, write to the Free Software | 
 |    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, | 
 |    MA 02110-1301, USA.  */ | 
 |  | 
 | #include "sysdep.h" | 
 | #include "bfd.h" | 
 | #include "libbfd.h" | 
 | #include "bfdlink.h" | 
 | #include "genlink.h" | 
 |  | 
 | /* | 
 | SECTION | 
 | 	Linker Functions | 
 |  | 
 | @cindex Linker | 
 | 	The linker uses three special entry points in the BFD target | 
 | 	vector.  It is not necessary to write special routines for | 
 | 	these entry points when creating a new BFD back end, since | 
 | 	generic versions are provided.  However, writing them can | 
 | 	speed up linking and make it use significantly less runtime | 
 | 	memory. | 
 |  | 
 | 	The first routine creates a hash table used by the other | 
 | 	routines.  The second routine adds the symbols from an object | 
 | 	file to the hash table.  The third routine takes all the | 
 | 	object files and links them together to create the output | 
 | 	file.  These routines are designed so that the linker proper | 
 | 	does not need to know anything about the symbols in the object | 
 | 	files that it is linking.  The linker merely arranges the | 
 | 	sections as directed by the linker script and lets BFD handle | 
 | 	the details of symbols and relocs. | 
 |  | 
 | 	The second routine and third routines are passed a pointer to | 
 | 	a <<struct bfd_link_info>> structure (defined in | 
 | 	<<bfdlink.h>>) which holds information relevant to the link, | 
 | 	including the linker hash table (which was created by the | 
 | 	first routine) and a set of callback functions to the linker | 
 | 	proper. | 
 |  | 
 | 	The generic linker routines are in <<linker.c>>, and use the | 
 | 	header file <<genlink.h>>.  As of this writing, the only back | 
 | 	ends which have implemented versions of these routines are | 
 | 	a.out (in <<aoutx.h>>) and ECOFF (in <<ecoff.c>>).  The a.out | 
 | 	routines are used as examples throughout this section. | 
 |  | 
 | @menu | 
 | @* Creating a Linker Hash Table:: | 
 | @* Adding Symbols to the Hash Table:: | 
 | @* Performing the Final Link:: | 
 | @end menu | 
 |  | 
 | INODE | 
 | Creating a Linker Hash Table, Adding Symbols to the Hash Table, Linker Functions, Linker Functions | 
 | SUBSECTION | 
 | 	Creating a linker hash table | 
 |  | 
 | @cindex _bfd_link_hash_table_create in target vector | 
 | @cindex target vector (_bfd_link_hash_table_create) | 
 | 	The linker routines must create a hash table, which must be | 
 | 	derived from <<struct bfd_link_hash_table>> described in | 
 | 	<<bfdlink.c>>.  @xref{Hash Tables}, for information on how to | 
 | 	create a derived hash table.  This entry point is called using | 
 | 	the target vector of the linker output file. | 
 |  | 
 | 	The <<_bfd_link_hash_table_create>> entry point must allocate | 
 | 	and initialize an instance of the desired hash table.  If the | 
 | 	back end does not require any additional information to be | 
 | 	stored with the entries in the hash table, the entry point may | 
 | 	simply create a <<struct bfd_link_hash_table>>.  Most likely, | 
 | 	however, some additional information will be needed. | 
 |  | 
 | 	For example, with each entry in the hash table the a.out | 
 | 	linker keeps the index the symbol has in the final output file | 
 | 	(this index number is used so that when doing a relocatable | 
 | 	link the symbol index used in the output file can be quickly | 
 | 	filled in when copying over a reloc).  The a.out linker code | 
 | 	defines the required structures and functions for a hash table | 
 | 	derived from <<struct bfd_link_hash_table>>.  The a.out linker | 
 | 	hash table is created by the function | 
 | 	<<NAME(aout,link_hash_table_create)>>; it simply allocates | 
 | 	space for the hash table, initializes it, and returns a | 
 | 	pointer to it. | 
 |  | 
 | 	When writing the linker routines for a new back end, you will | 
 | 	generally not know exactly which fields will be required until | 
 | 	you have finished.  You should simply create a new hash table | 
 | 	which defines no additional fields, and then simply add fields | 
 | 	as they become necessary. | 
 |  | 
 | INODE | 
 | Adding Symbols to the Hash Table, Performing the Final Link, Creating a Linker Hash Table, Linker Functions | 
 | SUBSECTION | 
 | 	Adding symbols to the hash table | 
 |  | 
 | @cindex _bfd_link_add_symbols in target vector | 
 | @cindex target vector (_bfd_link_add_symbols) | 
 | 	The linker proper will call the <<_bfd_link_add_symbols>> | 
 | 	entry point for each object file or archive which is to be | 
 | 	linked (typically these are the files named on the command | 
 | 	line, but some may also come from the linker script).  The | 
 | 	entry point is responsible for examining the file.  For an | 
 | 	object file, BFD must add any relevant symbol information to | 
 | 	the hash table.  For an archive, BFD must determine which | 
 | 	elements of the archive should be used and adding them to the | 
 | 	link. | 
 |  | 
 | 	The a.out version of this entry point is | 
 | 	<<NAME(aout,link_add_symbols)>>. | 
 |  | 
 | @menu | 
 | @* Differing file formats:: | 
 | @* Adding symbols from an object file:: | 
 | @* Adding symbols from an archive:: | 
 | @end menu | 
 |  | 
 | INODE | 
 | Differing file formats, Adding symbols from an object file, Adding Symbols to the Hash Table, Adding Symbols to the Hash Table | 
 | SUBSUBSECTION | 
 | 	Differing file formats | 
 |  | 
 | 	Normally all the files involved in a link will be of the same | 
 | 	format, but it is also possible to link together different | 
 | 	format object files, and the back end must support that.  The | 
 | 	<<_bfd_link_add_symbols>> entry point is called via the target | 
 | 	vector of the file to be added.  This has an important | 
 | 	consequence: the function may not assume that the hash table | 
 | 	is the type created by the corresponding | 
 | 	<<_bfd_link_hash_table_create>> vector.  All the | 
 | 	<<_bfd_link_add_symbols>> function can assume about the hash | 
 | 	table is that it is derived from <<struct | 
 | 	bfd_link_hash_table>>. | 
 |  | 
 | 	Sometimes the <<_bfd_link_add_symbols>> function must store | 
 | 	some information in the hash table entry to be used by the | 
 | 	<<_bfd_final_link>> function.  In such a case the output bfd | 
 | 	xvec must be checked to make sure that the hash table was | 
 | 	created by an object file of the same format. | 
 |  | 
 | 	The <<_bfd_final_link>> routine must be prepared to handle a | 
 | 	hash entry without any extra information added by the | 
 | 	<<_bfd_link_add_symbols>> function.  A hash entry without | 
 | 	extra information will also occur when the linker script | 
 | 	directs the linker to create a symbol.  Note that, regardless | 
 | 	of how a hash table entry is added, all the fields will be | 
 | 	initialized to some sort of null value by the hash table entry | 
 | 	initialization function. | 
 |  | 
 | 	See <<ecoff_link_add_externals>> for an example of how to | 
 | 	check the output bfd before saving information (in this | 
 | 	case, the ECOFF external symbol debugging information) in a | 
 | 	hash table entry. | 
 |  | 
 | INODE | 
 | Adding symbols from an object file, Adding symbols from an archive, Differing file formats, Adding Symbols to the Hash Table | 
 | SUBSUBSECTION | 
 | 	Adding symbols from an object file | 
 |  | 
 | 	When the <<_bfd_link_add_symbols>> routine is passed an object | 
 | 	file, it must add all externally visible symbols in that | 
 | 	object file to the hash table.  The actual work of adding the | 
 | 	symbol to the hash table is normally handled by the function | 
 | 	<<_bfd_generic_link_add_one_symbol>>.  The | 
 | 	<<_bfd_link_add_symbols>> routine is responsible for reading | 
 | 	all the symbols from the object file and passing the correct | 
 | 	information to <<_bfd_generic_link_add_one_symbol>>. | 
 |  | 
 | 	The <<_bfd_link_add_symbols>> routine should not use | 
 | 	<<bfd_canonicalize_symtab>> to read the symbols.  The point of | 
 | 	providing this routine is to avoid the overhead of converting | 
 | 	the symbols into generic <<asymbol>> structures. | 
 |  | 
 | @findex _bfd_generic_link_add_one_symbol | 
 | 	<<_bfd_generic_link_add_one_symbol>> handles the details of | 
 | 	combining common symbols, warning about multiple definitions, | 
 | 	and so forth.  It takes arguments which describe the symbol to | 
 | 	add, notably symbol flags, a section, and an offset.  The | 
 | 	symbol flags include such things as <<BSF_WEAK>> or | 
 | 	<<BSF_INDIRECT>>.  The section is a section in the object | 
 | 	file, or something like <<bfd_und_section_ptr>> for an undefined | 
 | 	symbol or <<bfd_com_section_ptr>> for a common symbol. | 
 |  | 
 | 	If the <<_bfd_final_link>> routine is also going to need to | 
 | 	read the symbol information, the <<_bfd_link_add_symbols>> | 
 | 	routine should save it somewhere attached to the object file | 
 | 	BFD.  However, the information should only be saved if the | 
 | 	<<keep_memory>> field of the <<info>> argument is TRUE, so | 
 | 	that the <<-no-keep-memory>> linker switch is effective. | 
 |  | 
 | 	The a.out function which adds symbols from an object file is | 
 | 	<<aout_link_add_object_symbols>>, and most of the interesting | 
 | 	work is in <<aout_link_add_symbols>>.  The latter saves | 
 | 	pointers to the hash tables entries created by | 
 | 	<<_bfd_generic_link_add_one_symbol>> indexed by symbol number, | 
 | 	so that the <<_bfd_final_link>> routine does not have to call | 
 | 	the hash table lookup routine to locate the entry. | 
 |  | 
 | INODE | 
 | Adding symbols from an archive, , Adding symbols from an object file, Adding Symbols to the Hash Table | 
 | SUBSUBSECTION | 
 | 	Adding symbols from an archive | 
 |  | 
 | 	When the <<_bfd_link_add_symbols>> routine is passed an | 
 | 	archive, it must look through the symbols defined by the | 
 | 	archive and decide which elements of the archive should be | 
 | 	included in the link.  For each such element it must call the | 
 | 	<<add_archive_element>> linker callback, and it must add the | 
 | 	symbols from the object file to the linker hash table.  (The | 
 | 	callback may in fact indicate that a replacement BFD should be | 
 | 	used, in which case the symbols from that BFD should be added | 
 | 	to the linker hash table instead.) | 
 |  | 
 | @findex _bfd_generic_link_add_archive_symbols | 
 | 	In most cases the work of looking through the symbols in the | 
 | 	archive should be done by the | 
 | 	<<_bfd_generic_link_add_archive_symbols>> function. | 
 | 	<<_bfd_generic_link_add_archive_symbols>> is passed a function | 
 | 	to call to make the final decision about adding an archive | 
 | 	element to the link and to do the actual work of adding the | 
 | 	symbols to the linker hash table.  If the element is to | 
 | 	be included, the <<add_archive_element>> linker callback | 
 | 	routine must be called with the element as an argument, and | 
 | 	the element's symbols must be added to the linker hash table | 
 | 	just as though the element had itself been passed to the | 
 | 	<<_bfd_link_add_symbols>> function. | 
 |  | 
 | 	When the a.out <<_bfd_link_add_symbols>> function receives an | 
 | 	archive, it calls <<_bfd_generic_link_add_archive_symbols>> | 
 | 	passing <<aout_link_check_archive_element>> as the function | 
 | 	argument. <<aout_link_check_archive_element>> calls | 
 | 	<<aout_link_check_ar_symbols>>.  If the latter decides to add | 
 | 	the element (an element is only added if it provides a real, | 
 | 	non-common, definition for a previously undefined or common | 
 | 	symbol) it calls the <<add_archive_element>> callback and then | 
 | 	<<aout_link_check_archive_element>> calls | 
 | 	<<aout_link_add_symbols>> to actually add the symbols to the | 
 | 	linker hash table - possibly those of a substitute BFD, if the | 
 | 	<<add_archive_element>> callback avails itself of that option. | 
 |  | 
 | 	The ECOFF back end is unusual in that it does not normally | 
 | 	call <<_bfd_generic_link_add_archive_symbols>>, because ECOFF | 
 | 	archives already contain a hash table of symbols.  The ECOFF | 
 | 	back end searches the archive itself to avoid the overhead of | 
 | 	creating a new hash table. | 
 |  | 
 | INODE | 
 | Performing the Final Link, , Adding Symbols to the Hash Table, Linker Functions | 
 | SUBSECTION | 
 | 	Performing the final link | 
 |  | 
 | @cindex _bfd_link_final_link in target vector | 
 | @cindex target vector (_bfd_final_link) | 
 | 	When all the input files have been processed, the linker calls | 
 | 	the <<_bfd_final_link>> entry point of the output BFD.  This | 
 | 	routine is responsible for producing the final output file, | 
 | 	which has several aspects.  It must relocate the contents of | 
 | 	the input sections and copy the data into the output sections. | 
 | 	It must build an output symbol table including any local | 
 | 	symbols from the input files and the global symbols from the | 
 | 	hash table.  When producing relocatable output, it must | 
 | 	modify the input relocs and write them into the output file. | 
 | 	There may also be object format dependent work to be done. | 
 |  | 
 | 	The linker will also call the <<write_object_contents>> entry | 
 | 	point when the BFD is closed.  The two entry points must work | 
 | 	together in order to produce the correct output file. | 
 |  | 
 | 	The details of how this works are inevitably dependent upon | 
 | 	the specific object file format.  The a.out | 
 | 	<<_bfd_final_link>> routine is <<NAME(aout,final_link)>>. | 
 |  | 
 | @menu | 
 | @* Information provided by the linker:: | 
 | @* Relocating the section contents:: | 
 | @* Writing the symbol table:: | 
 | @end menu | 
 |  | 
 | INODE | 
 | Information provided by the linker, Relocating the section contents, Performing the Final Link, Performing the Final Link | 
 | SUBSUBSECTION | 
 | 	Information provided by the linker | 
 |  | 
 | 	Before the linker calls the <<_bfd_final_link>> entry point, | 
 | 	it sets up some data structures for the function to use. | 
 |  | 
 | 	The <<input_bfds>> field of the <<bfd_link_info>> structure | 
 | 	will point to a list of all the input files included in the | 
 | 	link.  These files are linked through the <<link.next>> field | 
 | 	of the <<bfd>> structure. | 
 |  | 
 | 	Each section in the output file will have a list of | 
 | 	<<link_order>> structures attached to the <<map_head.link_order>> | 
 | 	field (the <<link_order>> structure is defined in | 
 | 	<<bfdlink.h>>).  These structures describe how to create the | 
 | 	contents of the output section in terms of the contents of | 
 | 	various input sections, fill constants, and, eventually, other | 
 | 	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 relocatable object file. | 
 |  | 
 | INODE | 
 | Relocating the section contents, Writing the symbol table, Information provided by the linker, Performing the Final Link | 
 | SUBSUBSECTION | 
 | 	Relocating the section contents | 
 |  | 
 | 	The <<_bfd_final_link>> function should look through the | 
 | 	<<link_order>> structures attached to each section of the | 
 | 	output file.  Each <<link_order>> structure should either be | 
 | 	handled specially, or it should be passed to the function | 
 | 	<<_bfd_default_link_order>> which will do the right thing | 
 | 	(<<_bfd_default_link_order>> is defined in <<linker.c>>). | 
 |  | 
 | 	For efficiency, a <<link_order>> of type | 
 | 	<<bfd_indirect_link_order>> whose associated section belongs | 
 | 	to a BFD of the same format as the output BFD must be handled | 
 | 	specially.  This type of <<link_order>> describes part of an | 
 | 	output section in terms of a section belonging to one of the | 
 | 	input files.  The <<_bfd_final_link>> function should read the | 
 | 	contents of the section and any associated relocs, apply the | 
 | 	relocs to the section contents, and write out the modified | 
 | 	section contents.  If performing a relocatable link, the | 
 | 	relocs themselves must also be modified and written out. | 
 |  | 
 | @findex _bfd_relocate_contents | 
 | @findex _bfd_final_link_relocate | 
 | 	The functions <<_bfd_relocate_contents>> and | 
 | 	<<_bfd_final_link_relocate>> provide some general support for | 
 | 	performing the actual relocations, notably overflow checking. | 
 | 	Their arguments include information about the symbol the | 
 | 	relocation is against and a <<reloc_howto_type>> argument | 
 | 	which describes the relocation to perform.  These functions | 
 | 	are defined in <<reloc.c>>. | 
 |  | 
 | 	The a.out function which handles reading, relocating, and | 
 | 	writing section contents is <<aout_link_input_section>>.  The | 
 | 	actual relocation is done in <<aout_link_input_section_std>> | 
 | 	and <<aout_link_input_section_ext>>. | 
 |  | 
 | INODE | 
 | Writing the symbol table, , Relocating the section contents, Performing the Final Link | 
 | SUBSUBSECTION | 
 | 	Writing the symbol table | 
 |  | 
 | 	The <<_bfd_final_link>> function must gather all the symbols | 
 | 	in the input files and write them out.  It must also write out | 
 | 	all the symbols in the global hash table.  This must be | 
 | 	controlled by the <<strip>> and <<discard>> fields of the | 
 | 	<<bfd_link_info>> structure. | 
 |  | 
 | 	The local symbols of the input files will not have been | 
 | 	entered into the linker hash table.  The <<_bfd_final_link>> | 
 | 	routine must consider each input file and include the symbols | 
 | 	in the output file.  It may be convenient to do this when | 
 | 	looking through the <<link_order>> structures, or it may be | 
 | 	done by stepping through the <<input_bfds>> list. | 
 |  | 
 | 	The <<_bfd_final_link>> routine must also traverse the global | 
 | 	hash table to gather all the externally visible symbols.  It | 
 | 	is possible that most of the externally visible symbols may be | 
 | 	written out when considering the symbols of each input file, | 
 | 	but it is still necessary to traverse the hash table since the | 
 | 	linker script may have defined some symbols that are not in | 
 | 	any of the input files. | 
 |  | 
 | 	The <<strip>> field of the <<bfd_link_info>> structure | 
 | 	controls which symbols are written out.  The possible values | 
 | 	are listed in <<bfdlink.h>>.  If the value is <<strip_some>>, | 
 | 	then the <<keep_hash>> field of the <<bfd_link_info>> | 
 | 	structure is a hash table of symbols to keep; each symbol | 
 | 	should be looked up in this hash table, and only symbols which | 
 | 	are present should be included in the output file. | 
 |  | 
 | 	If the <<strip>> field of the <<bfd_link_info>> structure | 
 | 	permits local symbols to be written out, the <<discard>> field | 
 | 	is used to further controls which local symbols are included | 
 | 	in the output file.  If the value is <<discard_l>>, then all | 
 | 	local symbols which begin with a certain prefix are discarded; | 
 | 	this is controlled by the <<bfd_is_local_label_name>> entry point. | 
 |  | 
 | 	The a.out backend handles symbols by calling | 
 | 	<<aout_link_write_symbols>> on each input BFD and then | 
 | 	traversing the global hash table with the function | 
 | 	<<aout_link_write_other_symbol>>.  It builds a string table | 
 | 	while writing out the symbols, which is written to the output | 
 | 	file at the end of <<NAME(aout,final_link)>>. | 
 | */ | 
 |  | 
 | /* This structure is used to pass information to | 
 |    _bfd_generic_link_write_global_symbol, which may be called via | 
 |    _bfd_generic_link_hash_traverse.  */ | 
 |  | 
 | struct generic_write_global_symbol_info | 
 | { | 
 |   struct bfd_link_info *info; | 
 |   bfd *output_bfd; | 
 |   size_t *psymalloc; | 
 |   bool failed; | 
 | }; | 
 |  | 
 | static bool generic_link_add_object_symbols | 
 |   (bfd *, struct bfd_link_info *); | 
 | static bool generic_link_check_archive_element | 
 |   (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, const char *, | 
 |    bool *); | 
 | static bool generic_link_add_symbol_list | 
 |   (bfd *, struct bfd_link_info *, bfd_size_type count, asymbol **); | 
 | static bool generic_add_output_symbol | 
 |   (bfd *, size_t *psymalloc, asymbol *); | 
 | static bool default_data_link_order | 
 |   (bfd *, struct bfd_link_info *, asection *, struct bfd_link_order *); | 
 | static bool default_indirect_link_order | 
 |   (bfd *, struct bfd_link_info *, asection *, struct bfd_link_order *, | 
 |    bool); | 
 | static bool _bfd_generic_link_output_symbols | 
 |   (bfd *, bfd *, struct bfd_link_info *, size_t *); | 
 | static bool _bfd_generic_link_write_global_symbol | 
 |   (struct generic_link_hash_entry *, void *); | 
 |  | 
 | /* The link hash table structure is defined in bfdlink.h.  It provides | 
 |    a base hash table which the backend specific hash tables are built | 
 |    upon.  */ | 
 |  | 
 | /* Routine to create an entry in the link hash table.  */ | 
 |  | 
 | struct bfd_hash_entry * | 
 | _bfd_link_hash_newfunc (struct bfd_hash_entry *entry, | 
 | 			struct bfd_hash_table *table, | 
 | 			const char *string) | 
 | { | 
 |   /* Allocate the structure if it has not already been allocated by a | 
 |      subclass.  */ | 
 |   if (entry == NULL) | 
 |     { | 
 |       entry = (struct bfd_hash_entry *) | 
 | 	  bfd_hash_allocate (table, sizeof (struct bfd_link_hash_entry)); | 
 |       if (entry == NULL) | 
 | 	return entry; | 
 |     } | 
 |  | 
 |   /* Call the allocation method of the superclass.  */ | 
 |   entry = bfd_hash_newfunc (entry, table, string); | 
 |   if (entry) | 
 |     { | 
 |       struct bfd_link_hash_entry *h = (struct bfd_link_hash_entry *) entry; | 
 |  | 
 |       /* Initialize the local fields.  */ | 
 |       memset ((char *) &h->root + sizeof (h->root), 0, | 
 | 	      sizeof (*h) - sizeof (h->root)); | 
 |     } | 
 |  | 
 |   return entry; | 
 | } | 
 |  | 
 | /* Initialize a link hash table.  The BFD argument is the one | 
 |    responsible for creating this table.  */ | 
 |  | 
 | bool | 
 | _bfd_link_hash_table_init | 
 |   (struct bfd_link_hash_table *table, | 
 |    bfd *abfd ATTRIBUTE_UNUSED, | 
 |    struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *, | 
 | 				      struct bfd_hash_table *, | 
 | 				      const char *), | 
 |    unsigned int entsize) | 
 | { | 
 |   bool ret; | 
 |  | 
 |   BFD_ASSERT (!abfd->is_linker_output && !abfd->link.hash); | 
 |   table->undefs = NULL; | 
 |   table->undefs_tail = NULL; | 
 |   table->type = bfd_link_generic_hash_table; | 
 |  | 
 |   ret = bfd_hash_table_init (&table->table, newfunc, entsize); | 
 |   if (ret) | 
 |     { | 
 |       /* Arrange for destruction of this hash table on closing ABFD.  */ | 
 |       table->hash_table_free = _bfd_generic_link_hash_table_free; | 
 |       abfd->link.hash = table; | 
 |       abfd->is_linker_output = true; | 
 |     } | 
 |   return ret; | 
 | } | 
 |  | 
 | /* Look up a symbol in a link hash table.  If follow is TRUE, we | 
 |    follow bfd_link_hash_indirect and bfd_link_hash_warning links to | 
 |    the real symbol. | 
 |  | 
 | .{* Return TRUE if the symbol described by a linker hash entry H | 
 | .   is going to be absolute.  Linker-script defined symbols can be | 
 | .   converted from absolute to section-relative ones late in the | 
 | .   link.  Use this macro to correctly determine whether the symbol | 
 | .   will actually end up absolute in output.  *} | 
 | .#define bfd_is_abs_symbol(H) \ | 
 | .  (((H)->type == bfd_link_hash_defined \ | 
 | .    || (H)->type == bfd_link_hash_defweak) \ | 
 | .   && bfd_is_abs_section ((H)->u.def.section) \ | 
 | .   && !(H)->rel_from_abs) | 
 | . | 
 | */ | 
 |  | 
 | struct bfd_link_hash_entry * | 
 | bfd_link_hash_lookup (struct bfd_link_hash_table *table, | 
 | 		      const char *string, | 
 | 		      bool create, | 
 | 		      bool copy, | 
 | 		      bool follow) | 
 | { | 
 |   struct bfd_link_hash_entry *ret; | 
 |  | 
 |   if (table == NULL || string == NULL) | 
 |     return NULL; | 
 |  | 
 |   ret = ((struct bfd_link_hash_entry *) | 
 | 	 bfd_hash_lookup (&table->table, string, create, copy)); | 
 |  | 
 |   if (follow && ret != NULL) | 
 |     { | 
 |       while (ret->type == bfd_link_hash_indirect | 
 | 	     || ret->type == bfd_link_hash_warning) | 
 | 	ret = ret->u.i.link; | 
 |     } | 
 |  | 
 |   return ret; | 
 | } | 
 |  | 
 | /* Look up a symbol in the main linker hash table if the symbol might | 
 |    be wrapped.  This should only be used for references to an | 
 |    undefined symbol, not for definitions of a symbol.  */ | 
 |  | 
 | struct bfd_link_hash_entry * | 
 | bfd_wrapped_link_hash_lookup (bfd *abfd, | 
 | 			      struct bfd_link_info *info, | 
 | 			      const char *string, | 
 | 			      bool create, | 
 | 			      bool copy, | 
 | 			      bool follow) | 
 | { | 
 |   size_t amt; | 
 |  | 
 |   if (info->wrap_hash != NULL) | 
 |     { | 
 |       const char *l; | 
 |       char prefix = '\0'; | 
 |  | 
 |       l = string; | 
 |       if (*l | 
 | 	  && (*l == bfd_get_symbol_leading_char (abfd) | 
 | 	      || *l == info->wrap_char)) | 
 | 	{ | 
 | 	  prefix = *l; | 
 | 	  ++l; | 
 | 	} | 
 |  | 
 | #undef WRAP | 
 | #define WRAP "__wrap_" | 
 |  | 
 |       if (bfd_hash_lookup (info->wrap_hash, l, false, false) != NULL) | 
 | 	{ | 
 | 	  char *n; | 
 | 	  struct bfd_link_hash_entry *h; | 
 |  | 
 | 	  /* This symbol is being wrapped.  We want to replace all | 
 | 	     references to SYM with references to __wrap_SYM.  */ | 
 |  | 
 | 	  amt = strlen (l) + sizeof WRAP + 1; | 
 | 	  n = (char *) bfd_malloc (amt); | 
 | 	  if (n == NULL) | 
 | 	    return NULL; | 
 |  | 
 | 	  n[0] = prefix; | 
 | 	  n[1] = '\0'; | 
 | 	  strcat (n, WRAP); | 
 | 	  strcat (n, l); | 
 | 	  h = bfd_link_hash_lookup (info->hash, n, create, true, follow); | 
 | 	  if (h != NULL) | 
 | 	    h->wrapper_symbol = true; | 
 | 	  free (n); | 
 | 	  return h; | 
 | 	} | 
 |  | 
 | #undef  REAL | 
 | #define REAL "__real_" | 
 |  | 
 |       if (*l == '_' | 
 | 	  && startswith (l, REAL) | 
 | 	  && bfd_hash_lookup (info->wrap_hash, l + sizeof REAL - 1, | 
 | 			      false, false) != NULL) | 
 | 	{ | 
 | 	  char *n; | 
 | 	  struct bfd_link_hash_entry *h; | 
 |  | 
 | 	  /* This is a reference to __real_SYM, where SYM is being | 
 | 	     wrapped.  We want to replace all references to __real_SYM | 
 | 	     with references to SYM.  */ | 
 |  | 
 | 	  amt = strlen (l + sizeof REAL - 1) + 2; | 
 | 	  n = (char *) bfd_malloc (amt); | 
 | 	  if (n == NULL) | 
 | 	    return NULL; | 
 |  | 
 | 	  n[0] = prefix; | 
 | 	  n[1] = '\0'; | 
 | 	  strcat (n, l + sizeof REAL - 1); | 
 | 	  h = bfd_link_hash_lookup (info->hash, n, create, true, follow); | 
 | 	  if (h != NULL) | 
 | 	    h->ref_real = 1; | 
 | 	  free (n); | 
 | 	  return h; | 
 | 	} | 
 |  | 
 | #undef REAL | 
 |     } | 
 |  | 
 |   return bfd_link_hash_lookup (info->hash, string, create, copy, follow); | 
 | } | 
 |  | 
 | /* If H is a wrapped symbol, ie. the symbol name starts with "__wrap_" | 
 |    and the remainder is found in wrap_hash, return the real symbol.  */ | 
 |  | 
 | struct bfd_link_hash_entry * | 
 | unwrap_hash_lookup (struct bfd_link_info *info, | 
 | 		    bfd *input_bfd, | 
 | 		    struct bfd_link_hash_entry *h) | 
 | { | 
 |   const char *l = h->root.string; | 
 |  | 
 |   if (*l | 
 |       && (*l == bfd_get_symbol_leading_char (input_bfd) | 
 | 	  || *l == info->wrap_char)) | 
 |     ++l; | 
 |  | 
 |   if (startswith (l, WRAP)) | 
 |     { | 
 |       l += sizeof WRAP - 1; | 
 |  | 
 |       if (bfd_hash_lookup (info->wrap_hash, l, false, false) != NULL) | 
 | 	{ | 
 | 	  char save = 0; | 
 | 	  if (l - (sizeof WRAP - 1) != h->root.string) | 
 | 	    { | 
 | 	      --l; | 
 | 	      save = *l; | 
 | 	      *(char *) l = *h->root.string; | 
 | 	    } | 
 | 	  h = bfd_link_hash_lookup (info->hash, l, false, false, false); | 
 | 	  if (save) | 
 | 	    *(char *) l = save; | 
 | 	} | 
 |     } | 
 |   return h; | 
 | } | 
 | #undef WRAP | 
 |  | 
 | /* Traverse a generic link hash table.  Differs from bfd_hash_traverse | 
 |    in the treatment of warning symbols.  When warning symbols are | 
 |    created they replace the real symbol, so you don't get to see the | 
 |    real symbol in a bfd_hash_traverse.  This traversal calls func with | 
 |    the real symbol.  */ | 
 |  | 
 | void | 
 | bfd_link_hash_traverse | 
 |   (struct bfd_link_hash_table *htab, | 
 |    bool (*func) (struct bfd_link_hash_entry *, void *), | 
 |    void *info) | 
 | { | 
 |   unsigned int i; | 
 |  | 
 |   htab->table.frozen = 1; | 
 |   for (i = 0; i < htab->table.size; i++) | 
 |     { | 
 |       struct bfd_link_hash_entry *p; | 
 |  | 
 |       p = (struct bfd_link_hash_entry *) htab->table.table[i]; | 
 |       for (; p != NULL; p = (struct bfd_link_hash_entry *) p->root.next) | 
 | 	if (!(*func) (p->type == bfd_link_hash_warning ? p->u.i.link : p, info)) | 
 | 	  goto out; | 
 |     } | 
 |  out: | 
 |   htab->table.frozen = 0; | 
 | } | 
 |  | 
 | /* Add a symbol to the linker hash table undefs list.  */ | 
 |  | 
 | void | 
 | bfd_link_add_undef (struct bfd_link_hash_table *table, | 
 | 		    struct bfd_link_hash_entry *h) | 
 | { | 
 |   BFD_ASSERT (h->u.undef.next == NULL); | 
 |   if (table->undefs_tail != NULL) | 
 |     table->undefs_tail->u.undef.next = h; | 
 |   if (table->undefs == NULL) | 
 |     table->undefs = h; | 
 |   table->undefs_tail = h; | 
 | } | 
 |  | 
 | /* The undefs list was designed so that in normal use we don't need to | 
 |    remove entries.  However, if symbols on the list are changed from | 
 |    bfd_link_hash_undefined to either bfd_link_hash_undefweak or | 
 |    bfd_link_hash_new for some reason, then they must be removed from the | 
 |    list.  Failure to do so might result in the linker attempting to add | 
 |    the symbol to the list again at a later stage.  */ | 
 |  | 
 | void | 
 | bfd_link_repair_undef_list (struct bfd_link_hash_table *table) | 
 | { | 
 |   struct bfd_link_hash_entry **pun; | 
 |  | 
 |   pun = &table->undefs; | 
 |   while (*pun != NULL) | 
 |     { | 
 |       struct bfd_link_hash_entry *h = *pun; | 
 |  | 
 |       if (h->type == bfd_link_hash_new | 
 | 	  || h->type == bfd_link_hash_undefweak) | 
 | 	{ | 
 | 	  *pun = h->u.undef.next; | 
 | 	  h->u.undef.next = NULL; | 
 | 	  if (h == table->undefs_tail) | 
 | 	    { | 
 | 	      if (pun == &table->undefs) | 
 | 		table->undefs_tail = NULL; | 
 | 	      else | 
 | 		/* pun points at an u.undef.next field.  Go back to | 
 | 		   the start of the link_hash_entry.  */ | 
 | 		table->undefs_tail = (struct bfd_link_hash_entry *) | 
 | 		  ((char *) pun - ((char *) &h->u.undef.next - (char *) h)); | 
 | 	      break; | 
 | 	    } | 
 | 	} | 
 |       else | 
 | 	pun = &h->u.undef.next; | 
 |     } | 
 | } | 
 |  | 
 | /* Routine to create an entry in a generic link hash table.  */ | 
 |  | 
 | static struct bfd_hash_entry * | 
 | _bfd_generic_link_hash_newfunc (struct bfd_hash_entry *entry, | 
 | 				struct bfd_hash_table *table, | 
 | 				const char *string) | 
 | { | 
 |   /* Allocate the structure if it has not already been allocated by a | 
 |      subclass.  */ | 
 |   if (entry == NULL) | 
 |     { | 
 |       entry = (struct bfd_hash_entry *) | 
 | 	bfd_hash_allocate (table, sizeof (struct generic_link_hash_entry)); | 
 |       if (entry == NULL) | 
 | 	return entry; | 
 |     } | 
 |  | 
 |   /* Call the allocation method of the superclass.  */ | 
 |   entry = _bfd_link_hash_newfunc (entry, table, string); | 
 |   if (entry) | 
 |     { | 
 |       struct generic_link_hash_entry *ret; | 
 |  | 
 |       /* Set local fields.  */ | 
 |       ret = (struct generic_link_hash_entry *) entry; | 
 |       ret->written = false; | 
 |       ret->sym = NULL; | 
 |     } | 
 |  | 
 |   return entry; | 
 | } | 
 |  | 
 | /* Create a generic link hash table.  */ | 
 |  | 
 | struct bfd_link_hash_table * | 
 | _bfd_generic_link_hash_table_create (bfd *abfd) | 
 | { | 
 |   struct generic_link_hash_table *ret; | 
 |   size_t amt = sizeof (struct generic_link_hash_table); | 
 |  | 
 |   ret = (struct generic_link_hash_table *) bfd_malloc (amt); | 
 |   if (ret == NULL) | 
 |     return NULL; | 
 |   if (! _bfd_link_hash_table_init (&ret->root, abfd, | 
 | 				   _bfd_generic_link_hash_newfunc, | 
 | 				   sizeof (struct generic_link_hash_entry))) | 
 |     { | 
 |       free (ret); | 
 |       return NULL; | 
 |     } | 
 |   return &ret->root; | 
 | } | 
 |  | 
 | void | 
 | _bfd_generic_link_hash_table_free (bfd *obfd) | 
 | { | 
 |   struct generic_link_hash_table *ret; | 
 |  | 
 |   BFD_ASSERT (obfd->is_linker_output && obfd->link.hash); | 
 |   ret = (struct generic_link_hash_table *) obfd->link.hash; | 
 |   bfd_hash_table_free (&ret->root.table); | 
 |   free (ret); | 
 |   obfd->link.hash = NULL; | 
 |   obfd->is_linker_output = false; | 
 | } | 
 |  | 
 | /* Grab the symbols for an object file when doing a generic link.  We | 
 |    store the symbols in the outsymbols field.  We need to keep them | 
 |    around for the entire link to ensure that we only read them once. | 
 |    If we read them multiple times, we might wind up with relocs and | 
 |    the hash table pointing to different instances of the symbol | 
 |    structure.  */ | 
 |  | 
 | bool | 
 | bfd_generic_link_read_symbols (bfd *abfd) | 
 | { | 
 |   if (bfd_get_outsymbols (abfd) == NULL) | 
 |     { | 
 |       long symsize; | 
 |       long symcount; | 
 |  | 
 |       symsize = bfd_get_symtab_upper_bound (abfd); | 
 |       if (symsize < 0) | 
 | 	return false; | 
 |       abfd->outsymbols = bfd_alloc (abfd, symsize); | 
 |       if (bfd_get_outsymbols (abfd) == NULL && symsize != 0) | 
 | 	return false; | 
 |       symcount = bfd_canonicalize_symtab (abfd, bfd_get_outsymbols (abfd)); | 
 |       if (symcount < 0) | 
 | 	return false; | 
 |       abfd->symcount = symcount; | 
 |     } | 
 |  | 
 |   return true; | 
 | } | 
 |  | 
 | /* Indicate that we are only retrieving symbol values from this | 
 |    section.  We want the symbols to act as though the values in the | 
 |    file are absolute.  */ | 
 |  | 
 | void | 
 | _bfd_generic_link_just_syms (asection *sec, | 
 | 			     struct bfd_link_info *info ATTRIBUTE_UNUSED) | 
 | { | 
 |   sec->sec_info_type = SEC_INFO_TYPE_JUST_SYMS; | 
 |   sec->output_section = bfd_abs_section_ptr; | 
 |   sec->output_offset = sec->vma; | 
 | } | 
 |  | 
 | /* Copy the symbol type and other attributes for a linker script | 
 |    assignment from HSRC to HDEST. | 
 |    The default implementation does nothing.  */ | 
 | void | 
 | _bfd_generic_copy_link_hash_symbol_type (bfd *abfd ATTRIBUTE_UNUSED, | 
 |     struct bfd_link_hash_entry *hdest ATTRIBUTE_UNUSED, | 
 |     struct bfd_link_hash_entry *hsrc ATTRIBUTE_UNUSED) | 
 | { | 
 | } | 
 |  | 
 | /* Generic function to add symbols from an object file to the | 
 |    global hash table.  */ | 
 |  | 
 | bool | 
 | _bfd_generic_link_add_symbols (bfd *abfd, struct bfd_link_info *info) | 
 | { | 
 |   bool ret; | 
 |  | 
 |   switch (bfd_get_format (abfd)) | 
 |     { | 
 |     case bfd_object: | 
 |       ret = generic_link_add_object_symbols (abfd, info); | 
 |       break; | 
 |     case bfd_archive: | 
 |       ret = (_bfd_generic_link_add_archive_symbols | 
 | 	     (abfd, info, generic_link_check_archive_element)); | 
 |       break; | 
 |     default: | 
 |       bfd_set_error (bfd_error_wrong_format); | 
 |       ret = false; | 
 |     } | 
 |  | 
 |   return ret; | 
 | } | 
 |  | 
 | /* Add symbols from an object file to the global hash table.  */ | 
 |  | 
 | static bool | 
 | generic_link_add_object_symbols (bfd *abfd, | 
 | 				 struct bfd_link_info *info) | 
 | { | 
 |   bfd_size_type symcount; | 
 |   struct bfd_symbol **outsyms; | 
 |  | 
 |   if (!bfd_generic_link_read_symbols (abfd)) | 
 |     return false; | 
 |   symcount = _bfd_generic_link_get_symcount (abfd); | 
 |   outsyms = _bfd_generic_link_get_symbols (abfd); | 
 |   return generic_link_add_symbol_list (abfd, info, symcount, outsyms); | 
 | } | 
 |  | 
 | /* Generic function to add symbols from an archive file to the global | 
 |    hash file.  This function presumes that the archive symbol table | 
 |    has already been read in (this is normally done by the | 
 |    bfd_check_format entry point).  It looks through the archive symbol | 
 |    table for symbols that are undefined or common in the linker global | 
 |    symbol hash table.  When one is found, the CHECKFN argument is used | 
 |    to see if an object file should be included.  This allows targets | 
 |    to customize common symbol behaviour.  CHECKFN should set *PNEEDED | 
 |    to TRUE if the object file should be included, and must also call | 
 |    the bfd_link_info add_archive_element callback function and handle | 
 |    adding the symbols to the global hash table.  CHECKFN must notice | 
 |    if the callback indicates a substitute BFD, and arrange to add | 
 |    those symbols instead if it does so.  CHECKFN should only return | 
 |    FALSE if some sort of error occurs.  */ | 
 |  | 
 | bool | 
 | _bfd_generic_link_add_archive_symbols | 
 |   (bfd *abfd, | 
 |    struct bfd_link_info *info, | 
 |    bool (*checkfn) (bfd *, struct bfd_link_info *, | 
 | 		    struct bfd_link_hash_entry *, const char *, bool *)) | 
 | { | 
 |   bool loop; | 
 |   bfd_size_type amt; | 
 |   unsigned char *included; | 
 |  | 
 |   if (! bfd_has_map (abfd)) | 
 |     { | 
 |       /* An empty archive is a special case.  */ | 
 |       if (bfd_openr_next_archived_file (abfd, NULL) == NULL) | 
 | 	return true; | 
 |       bfd_set_error (bfd_error_no_armap); | 
 |       return false; | 
 |     } | 
 |  | 
 |   amt = bfd_ardata (abfd)->symdef_count; | 
 |   if (amt == 0) | 
 |     return true; | 
 |   amt *= sizeof (*included); | 
 |   included = (unsigned char *) bfd_zmalloc (amt); | 
 |   if (included == NULL) | 
 |     return false; | 
 |  | 
 |   do | 
 |     { | 
 |       carsym *arsyms; | 
 |       carsym *arsym_end; | 
 |       carsym *arsym; | 
 |       unsigned int indx; | 
 |       file_ptr last_ar_offset = -1; | 
 |       bool needed = false; | 
 |       bfd *element = NULL; | 
 |  | 
 |       loop = false; | 
 |       arsyms = bfd_ardata (abfd)->symdefs; | 
 |       arsym_end = arsyms + bfd_ardata (abfd)->symdef_count; | 
 |       for (arsym = arsyms, indx = 0; arsym < arsym_end; arsym++, indx++) | 
 | 	{ | 
 | 	  struct bfd_link_hash_entry *h; | 
 | 	  struct bfd_link_hash_entry *undefs_tail; | 
 |  | 
 | 	  if (included[indx]) | 
 | 	    continue; | 
 | 	  if (needed && arsym->file_offset == last_ar_offset) | 
 | 	    { | 
 | 	      included[indx] = 1; | 
 | 	      continue; | 
 | 	    } | 
 |  | 
 | 	  if (arsym->name == NULL) | 
 | 	    goto error_return; | 
 |  | 
 | 	  h = bfd_link_hash_lookup (info->hash, arsym->name, | 
 | 				    false, false, true); | 
 |  | 
 | 	  if (h == NULL | 
 | 	      && info->pei386_auto_import | 
 | 	      && startswith (arsym->name, "__imp_")) | 
 | 	    h = bfd_link_hash_lookup (info->hash, arsym->name + 6, | 
 | 				      false, false, true); | 
 | 	  if (h == NULL) | 
 | 	    continue; | 
 |  | 
 | 	  if (h->type != bfd_link_hash_undefined | 
 | 	      && h->type != bfd_link_hash_common) | 
 | 	    { | 
 | 	      if (h->type != bfd_link_hash_undefweak) | 
 | 		/* Symbol must be defined.  Don't check it again.  */ | 
 | 		included[indx] = 1; | 
 | 	      continue; | 
 | 	    } | 
 |  | 
 | 	  if (last_ar_offset != arsym->file_offset) | 
 | 	    { | 
 | 	      last_ar_offset = arsym->file_offset; | 
 | 	      element = _bfd_get_elt_at_filepos (abfd, last_ar_offset, | 
 | 						 info); | 
 | 	      if (element == NULL | 
 | 		  || !bfd_check_format (element, bfd_object)) | 
 | 		goto error_return; | 
 | 	    } | 
 |  | 
 | 	  undefs_tail = info->hash->undefs_tail; | 
 |  | 
 | 	  /* CHECKFN will see if this element should be included, and | 
 | 	     go ahead and include it if appropriate.  */ | 
 | 	  if (! (*checkfn) (element, info, h, arsym->name, &needed)) | 
 | 	    goto error_return; | 
 |  | 
 | 	  if (needed) | 
 | 	    { | 
 | 	      unsigned int mark; | 
 |  | 
 | 	      /* Look backward to mark all symbols from this object file | 
 | 		 which we have already seen in this pass.  */ | 
 | 	      mark = indx; | 
 | 	      do | 
 | 		{ | 
 | 		  included[mark] = 1; | 
 | 		  if (mark == 0) | 
 | 		    break; | 
 | 		  --mark; | 
 | 		} | 
 | 	      while (arsyms[mark].file_offset == last_ar_offset); | 
 |  | 
 | 	      if (undefs_tail != info->hash->undefs_tail) | 
 | 		loop = true; | 
 | 	    } | 
 | 	} | 
 |     } while (loop); | 
 |  | 
 |   free (included); | 
 |   return true; | 
 |  | 
 |  error_return: | 
 |   free (included); | 
 |   return false; | 
 | } | 
 |  | 
 | /* See if we should include an archive element.  */ | 
 |  | 
 | static bool | 
 | generic_link_check_archive_element (bfd *abfd, | 
 | 				    struct bfd_link_info *info, | 
 | 				    struct bfd_link_hash_entry *h, | 
 | 				    const char *name ATTRIBUTE_UNUSED, | 
 | 				    bool *pneeded) | 
 | { | 
 |   asymbol **pp, **ppend; | 
 |  | 
 |   *pneeded = false; | 
 |  | 
 |   if (!bfd_generic_link_read_symbols (abfd)) | 
 |     return false; | 
 |  | 
 |   pp = _bfd_generic_link_get_symbols (abfd); | 
 |   ppend = pp + _bfd_generic_link_get_symcount (abfd); | 
 |   for (; pp < ppend; pp++) | 
 |     { | 
 |       asymbol *p; | 
 |  | 
 |       p = *pp; | 
 |  | 
 |       /* We are only interested in globally visible symbols.  */ | 
 |       if (! bfd_is_com_section (p->section) | 
 | 	  && (p->flags & (BSF_GLOBAL | BSF_INDIRECT | BSF_WEAK)) == 0) | 
 | 	continue; | 
 |  | 
 |       /* We are only interested if we know something about this | 
 | 	 symbol, and it is undefined or common.  An undefined weak | 
 | 	 symbol (type bfd_link_hash_undefweak) is not considered to be | 
 | 	 a reference when pulling files out of an archive.  See the | 
 | 	 SVR4 ABI, p. 4-27.  */ | 
 |       h = bfd_link_hash_lookup (info->hash, bfd_asymbol_name (p), false, | 
 | 				false, true); | 
 |       if (h == NULL | 
 | 	  || (h->type != bfd_link_hash_undefined | 
 | 	      && h->type != bfd_link_hash_common)) | 
 | 	continue; | 
 |  | 
 |       /* P is a symbol we are looking for.  */ | 
 |  | 
 |       if (! bfd_is_com_section (p->section) | 
 | 	  || (h->type == bfd_link_hash_undefined | 
 | 	      && h->u.undef.abfd == NULL)) | 
 | 	{ | 
 | 	  /* P is not a common symbol, or an undefined reference was | 
 | 	     created from outside BFD such as from a linker -u option. | 
 | 	     This object file defines the symbol, so pull it in.  */ | 
 | 	  *pneeded = true; | 
 | 	  if (!(*info->callbacks | 
 | 		->add_archive_element) (info, abfd, bfd_asymbol_name (p), | 
 | 					&abfd)) | 
 | 	    return false; | 
 | 	  /* Potentially, the add_archive_element hook may have set a | 
 | 	     substitute BFD for us.  */ | 
 | 	  return bfd_link_add_symbols (abfd, info); | 
 | 	} | 
 |  | 
 |       /* P is a common symbol.  */ | 
 |  | 
 |       if (h->type == bfd_link_hash_undefined) | 
 | 	{ | 
 | 	  bfd *symbfd; | 
 | 	  bfd_vma size; | 
 | 	  unsigned int power; | 
 |  | 
 | 	  /* Turn the symbol into a common symbol but do not link in | 
 | 	     the object file.  This is how a.out works.  Object | 
 | 	     formats that require different semantics must implement | 
 | 	     this function differently.  This symbol is already on the | 
 | 	     undefs list.  We add the section to a common section | 
 | 	     attached to symbfd to ensure that it is in a BFD which | 
 | 	     will be linked in.  */ | 
 | 	  symbfd = h->u.undef.abfd; | 
 | 	  h->type = bfd_link_hash_common; | 
 | 	  h->u.c.p = (struct bfd_link_hash_common_entry *) | 
 | 	    bfd_hash_allocate (&info->hash->table, | 
 | 			       sizeof (struct bfd_link_hash_common_entry)); | 
 | 	  if (h->u.c.p == NULL) | 
 | 	    return false; | 
 |  | 
 | 	  size = bfd_asymbol_value (p); | 
 | 	  h->u.c.size = size; | 
 |  | 
 | 	  power = bfd_log2 (size); | 
 | 	  if (power > 4) | 
 | 	    power = 4; | 
 | 	  h->u.c.p->alignment_power = power; | 
 |  | 
 | 	  if (p->section == bfd_com_section_ptr) | 
 | 	    h->u.c.p->section = bfd_make_section_old_way (symbfd, "COMMON"); | 
 | 	  else | 
 | 	    h->u.c.p->section = bfd_make_section_old_way (symbfd, | 
 | 							  p->section->name); | 
 | 	  h->u.c.p->section->flags |= SEC_ALLOC; | 
 | 	} | 
 |       else | 
 | 	{ | 
 | 	  /* Adjust the size of the common symbol if necessary.  This | 
 | 	     is how a.out works.  Object formats that require | 
 | 	     different semantics must implement this function | 
 | 	     differently.  */ | 
 | 	  if (bfd_asymbol_value (p) > h->u.c.size) | 
 | 	    h->u.c.size = bfd_asymbol_value (p); | 
 | 	} | 
 |     } | 
 |  | 
 |   /* This archive element is not needed.  */ | 
 |   return true; | 
 | } | 
 |  | 
 | /* 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.  */ | 
 |  | 
 | static bool | 
 | generic_link_add_symbol_list (bfd *abfd, | 
 | 			      struct bfd_link_info *info, | 
 | 			      bfd_size_type symbol_count, | 
 | 			      asymbol **symbols) | 
 | { | 
 |   asymbol **pp, **ppend; | 
 |  | 
 |   pp = symbols; | 
 |   ppend = symbols + symbol_count; | 
 |   for (; pp < ppend; pp++) | 
 |     { | 
 |       asymbol *p; | 
 |  | 
 |       p = *pp; | 
 |  | 
 |       if ((p->flags & (BSF_INDIRECT | 
 | 		       | BSF_WARNING | 
 | 		       | BSF_GLOBAL | 
 | 		       | BSF_CONSTRUCTOR | 
 | 		       | BSF_WEAK)) != 0 | 
 | 	  || bfd_is_und_section (bfd_asymbol_section (p)) | 
 | 	  || bfd_is_com_section (bfd_asymbol_section (p)) | 
 | 	  || bfd_is_ind_section (bfd_asymbol_section (p))) | 
 | 	{ | 
 | 	  const char *name; | 
 | 	  const char *string; | 
 | 	  struct generic_link_hash_entry *h; | 
 | 	  struct bfd_link_hash_entry *bh; | 
 |  | 
 | 	  string = name = bfd_asymbol_name (p); | 
 | 	  if (((p->flags & BSF_INDIRECT) != 0 | 
 | 	       || bfd_is_ind_section (p->section)) | 
 | 	      && pp + 1 < ppend) | 
 | 	    { | 
 | 	      pp++; | 
 | 	      string = bfd_asymbol_name (*pp); | 
 | 	    } | 
 | 	  else if ((p->flags & BSF_WARNING) != 0 | 
 | 		   && pp + 1 < ppend) | 
 | 	    { | 
 | 	      /* The name of P is actually the warning string, and the | 
 | 		 next symbol is the one to warn about.  */ | 
 | 	      pp++; | 
 | 	      name = bfd_asymbol_name (*pp); | 
 | 	    } | 
 |  | 
 | 	  bh = NULL; | 
 | 	  if (! (_bfd_generic_link_add_one_symbol | 
 | 		 (info, abfd, name, p->flags, bfd_asymbol_section (p), | 
 | 		  p->value, string, false, false, &bh))) | 
 | 	    return false; | 
 | 	  h = (struct generic_link_hash_entry *) bh; | 
 |  | 
 | 	  /* If this is a constructor symbol, and the linker didn't do | 
 | 	     anything with it, then we want to just pass the symbol | 
 | 	     through to the output file.  This will happen when | 
 | 	     linking with -r.  */ | 
 | 	  if ((p->flags & BSF_CONSTRUCTOR) != 0 | 
 | 	      && (h == NULL || h->root.type == bfd_link_hash_new)) | 
 | 	    { | 
 | 	      p->udata.p = NULL; | 
 | 	      continue; | 
 | 	    } | 
 |  | 
 | 	  /* Save the BFD symbol so that we don't lose any backend | 
 | 	     specific information that may be attached to it.  We only | 
 | 	     want this one if it gives more information than the | 
 | 	     existing one; we don't want to replace a defined symbol | 
 | 	     with an undefined one.  This routine may be called with a | 
 | 	     hash table other than the generic hash table, so we only | 
 | 	     do this if we are certain that the hash table is a | 
 | 	     generic one.  */ | 
 | 	  if (info->output_bfd->xvec == abfd->xvec) | 
 | 	    { | 
 | 	      if (h->sym == NULL | 
 | 		  || (! bfd_is_und_section (bfd_asymbol_section (p)) | 
 | 		      && (! bfd_is_com_section (bfd_asymbol_section (p)) | 
 | 			  || bfd_is_und_section (bfd_asymbol_section (h->sym))))) | 
 | 		{ | 
 | 		  h->sym = p; | 
 | 		  /* BSF_OLD_COMMON is a hack to support COFF reloc | 
 | 		     reading, and it should go away when the COFF | 
 | 		     linker is switched to the new version.  */ | 
 | 		  if (bfd_is_com_section (bfd_asymbol_section (p))) | 
 | 		    p->flags |= BSF_OLD_COMMON; | 
 | 		} | 
 | 	    } | 
 |  | 
 | 	  /* Store a back pointer from the symbol to the hash | 
 | 	     table entry for the benefit of relaxation code until | 
 | 	     it gets rewritten to not use asymbol structures. | 
 | 	     Setting this is also used to check whether these | 
 | 	     symbols were set up by the generic linker.  */ | 
 | 	  p->udata.p = h; | 
 | 	} | 
 |     } | 
 |  | 
 |   return true; | 
 | } | 
 |  | 
 | /* We use a state table to deal with adding symbols from an object | 
 |    file.  The first index into the state table describes the symbol | 
 |    from the object file.  The second index into the state table is the | 
 |    type of the symbol in the hash table.  */ | 
 |  | 
 | /* The symbol from the object file is turned into one of these row | 
 |    values.  */ | 
 |  | 
 | enum link_row | 
 | { | 
 |   UNDEF_ROW,		/* Undefined.  */ | 
 |   UNDEFW_ROW,		/* Weak undefined.  */ | 
 |   DEF_ROW,		/* Defined.  */ | 
 |   DEFW_ROW,		/* Weak defined.  */ | 
 |   COMMON_ROW,		/* Common.  */ | 
 |   INDR_ROW,		/* Indirect.  */ | 
 |   WARN_ROW,		/* Warning.  */ | 
 |   SET_ROW		/* Member of set.  */ | 
 | }; | 
 |  | 
 | /* apparently needed for Hitachi 3050R(HI-UX/WE2)? */ | 
 | #undef FAIL | 
 |  | 
 | /* The actions to take in the state table.  */ | 
 |  | 
 | enum link_action | 
 | { | 
 |   FAIL,		/* Abort.  */ | 
 |   UND,		/* Mark symbol undefined.  */ | 
 |   WEAK,		/* Mark symbol weak undefined.  */ | 
 |   DEF,		/* Mark symbol defined.  */ | 
 |   DEFW,		/* Mark symbol weak defined.  */ | 
 |   COM,		/* Mark symbol common.  */ | 
 |   REF,		/* Mark defined symbol referenced.  */ | 
 |   CREF,		/* Possibly warn about common reference to defined symbol.  */ | 
 |   CDEF,		/* Define existing common symbol.  */ | 
 |   NOACT,	/* No action.  */ | 
 |   BIG,		/* Mark symbol common using largest size.  */ | 
 |   MDEF,		/* Multiple definition error.  */ | 
 |   MIND,		/* Multiple indirect symbols.  */ | 
 |   IND,		/* Make indirect symbol.  */ | 
 |   CIND,		/* Make indirect symbol from existing common symbol.  */ | 
 |   SET,		/* Add value to set.  */ | 
 |   MWARN,	/* Make warning symbol.  */ | 
 |   WARN,		/* Warn if referenced, else MWARN.  */ | 
 |   CYCLE,	/* Repeat with symbol pointed to.  */ | 
 |   REFC,		/* Mark indirect symbol referenced and then CYCLE.  */ | 
 |   WARNC		/* Issue warning and then CYCLE.  */ | 
 | }; | 
 |  | 
 | /* The state table itself.  The first index is a link_row and the | 
 |    second index is a bfd_link_hash_type.  */ | 
 |  | 
 | static const enum link_action link_action[8][8] = | 
 | { | 
 |   /* current\prev    new    undef  undefw def    defw   com    indr   warn  */ | 
 |   /* UNDEF_ROW	*/  {UND,   NOACT, UND,   REF,   REF,   NOACT, REFC,  WARNC }, | 
 |   /* UNDEFW_ROW	*/  {WEAK,  NOACT, NOACT, REF,   REF,   NOACT, REFC,  WARNC }, | 
 |   /* DEF_ROW	*/  {DEF,   DEF,   DEF,   MDEF,  DEF,   CDEF,  MIND,  CYCLE }, | 
 |   /* DEFW_ROW	*/  {DEFW,  DEFW,  DEFW,  NOACT, NOACT, NOACT, NOACT, CYCLE }, | 
 |   /* COMMON_ROW	*/  {COM,   COM,   COM,   CREF,  COM,   BIG,   REFC,  WARNC }, | 
 |   /* INDR_ROW	*/  {IND,   IND,   IND,   MDEF,  IND,   CIND,  MIND,  CYCLE }, | 
 |   /* WARN_ROW   */  {MWARN, WARN,  WARN,  WARN,  WARN,  WARN,  WARN,  NOACT }, | 
 |   /* SET_ROW	*/  {SET,   SET,   SET,   SET,   SET,   SET,   CYCLE, CYCLE } | 
 | }; | 
 |  | 
 | /* Most of the entries in the LINK_ACTION table are straightforward, | 
 |    but a few are somewhat subtle. | 
 |  | 
 |    A reference to an indirect symbol (UNDEF_ROW/indr or | 
 |    UNDEFW_ROW/indr) is counted as a reference both to the indirect | 
 |    symbol and to the symbol the indirect symbol points to. | 
 |  | 
 |    A reference to a warning symbol (UNDEF_ROW/warn or UNDEFW_ROW/warn) | 
 |    causes the warning to be issued. | 
 |  | 
 |    A common definition of an indirect symbol (COMMON_ROW/indr) is | 
 |    treated as a multiple definition error.  Likewise for an indirect | 
 |    definition of a common symbol (INDR_ROW/com). | 
 |  | 
 |    An indirect definition of a warning (INDR_ROW/warn) does not cause | 
 |    the warning to be issued. | 
 |  | 
 |    If a warning is created for an indirect symbol (WARN_ROW/indr) no | 
 |    warning is created for the symbol the indirect symbol points to. | 
 |  | 
 |    Adding an entry to a set does not count as a reference to a set, | 
 |    and no warning is issued (SET_ROW/warn).  */ | 
 |  | 
 | /* Return the BFD in which a hash entry has been defined, if known.  */ | 
 |  | 
 | static bfd * | 
 | hash_entry_bfd (struct bfd_link_hash_entry *h) | 
 | { | 
 |   while (h->type == bfd_link_hash_warning) | 
 |     h = h->u.i.link; | 
 |   switch (h->type) | 
 |     { | 
 |     default: | 
 |       return NULL; | 
 |     case bfd_link_hash_undefined: | 
 |     case bfd_link_hash_undefweak: | 
 |       return h->u.undef.abfd; | 
 |     case bfd_link_hash_defined: | 
 |     case bfd_link_hash_defweak: | 
 |       return h->u.def.section->owner; | 
 |     case bfd_link_hash_common: | 
 |       return h->u.c.p->section->owner; | 
 |     } | 
 |   /*NOTREACHED*/ | 
 | } | 
 |  | 
 | /* Add a symbol to the global hash table. | 
 |    ABFD is the BFD the symbol comes from. | 
 |    NAME is the name of the symbol. | 
 |    FLAGS is the BSF_* bits associated with the symbol. | 
 |    SECTION is the section in which the symbol is defined; this may be | 
 |      bfd_und_section_ptr or bfd_com_section_ptr. | 
 |    VALUE is the value of the symbol, relative to the section. | 
 |    STRING is used for either an indirect symbol, in which case it is | 
 |      the name of the symbol to indirect to, or a warning symbol, in | 
 |      which case it is the warning string. | 
 |    COPY is TRUE if NAME or STRING must be copied into locally | 
 |      allocated memory if they need to be saved. | 
 |    COLLECT is TRUE if we should automatically collect gcc constructor | 
 |      or destructor names as collect2 does. | 
 |    HASHP, if not NULL, is a place to store the created hash table | 
 |      entry; if *HASHP is not NULL, the caller has already looked up | 
 |      the hash table entry, and stored it in *HASHP.  */ | 
 |  | 
 | bool | 
 | _bfd_generic_link_add_one_symbol (struct bfd_link_info *info, | 
 | 				  bfd *abfd, | 
 | 				  const char *name, | 
 | 				  flagword flags, | 
 | 				  asection *section, | 
 | 				  bfd_vma value, | 
 | 				  const char *string, | 
 | 				  bool copy, | 
 | 				  bool collect, | 
 | 				  struct bfd_link_hash_entry **hashp) | 
 | { | 
 |   enum link_row row; | 
 |   struct bfd_link_hash_entry *h; | 
 |   struct bfd_link_hash_entry *inh = NULL; | 
 |   bool cycle; | 
 |  | 
 |   BFD_ASSERT (section != NULL); | 
 |  | 
 |   if (bfd_is_ind_section (section) | 
 |       || (flags & BSF_INDIRECT) != 0) | 
 |     { | 
 |       row = INDR_ROW; | 
 |       /* Create the indirect symbol here.  This is for the benefit of | 
 | 	 the plugin "notice" function. | 
 | 	 STRING is the name of the symbol we want to indirect to.  */ | 
 |       inh = bfd_wrapped_link_hash_lookup (abfd, info, string, true, | 
 | 					  copy, false); | 
 |       if (inh == NULL) | 
 | 	return false; | 
 |     } | 
 |   else if ((flags & BSF_WARNING) != 0) | 
 |     row = WARN_ROW; | 
 |   else if ((flags & BSF_CONSTRUCTOR) != 0) | 
 |     row = SET_ROW; | 
 |   else if (bfd_is_und_section (section)) | 
 |     { | 
 |       if ((flags & BSF_WEAK) != 0) | 
 | 	row = UNDEFW_ROW; | 
 |       else | 
 | 	row = UNDEF_ROW; | 
 |     } | 
 |   else if ((flags & BSF_WEAK) != 0) | 
 |     row = DEFW_ROW; | 
 |   else if (bfd_is_com_section (section)) | 
 |     { | 
 |       row = COMMON_ROW; | 
 |       if (!bfd_link_relocatable (info) | 
 | 	  && name != NULL | 
 | 	  && name[0] == '_' | 
 | 	  && name[1] == '_' | 
 | 	  && strcmp (name + (name[2] == '_'), "__gnu_lto_slim") == 0) | 
 | 	_bfd_error_handler | 
 | 	  (_("%pB: plugin needed to handle lto object"), abfd); | 
 |     } | 
 |   else | 
 |     row = DEF_ROW; | 
 |  | 
 |   if (hashp != NULL && *hashp != NULL) | 
 |     h = *hashp; | 
 |   else | 
 |     { | 
 |       if (row == UNDEF_ROW || row == UNDEFW_ROW) | 
 | 	h = bfd_wrapped_link_hash_lookup (abfd, info, name, true, copy, false); | 
 |       else | 
 | 	h = bfd_link_hash_lookup (info->hash, name, true, copy, false); | 
 |       if (h == NULL) | 
 | 	{ | 
 | 	  if (hashp != NULL) | 
 | 	    *hashp = NULL; | 
 | 	  return false; | 
 | 	} | 
 |     } | 
 |  | 
 |   if (info->notice_all | 
 |       || (info->notice_hash != NULL | 
 | 	  && bfd_hash_lookup (info->notice_hash, name, false, false) != NULL)) | 
 |     { | 
 |       if (! (*info->callbacks->notice) (info, h, inh, | 
 | 					abfd, section, value, flags)) | 
 | 	return false; | 
 |     } | 
 |  | 
 |   if (hashp != NULL) | 
 |     *hashp = h; | 
 |  | 
 |   do | 
 |     { | 
 |       enum link_action action; | 
 |       int prev; | 
 |  | 
 |       prev = h->type; | 
 |       /* Treat symbols defined by early linker script pass as undefined.  */ | 
 |       if (h->ldscript_def) | 
 | 	prev = bfd_link_hash_undefined; | 
 |       cycle = false; | 
 |       action = link_action[(int) row][prev]; | 
 |       switch (action) | 
 | 	{ | 
 | 	case FAIL: | 
 | 	  abort (); | 
 |  | 
 | 	case NOACT: | 
 | 	  /* Do nothing.  */ | 
 | 	  break; | 
 |  | 
 | 	case UND: | 
 | 	  /* Make a new undefined symbol.  */ | 
 | 	  h->type = bfd_link_hash_undefined; | 
 | 	  h->u.undef.abfd = abfd; | 
 | 	  bfd_link_add_undef (info->hash, h); | 
 | 	  break; | 
 |  | 
 | 	case WEAK: | 
 | 	  /* Make a new weak undefined symbol.  */ | 
 | 	  h->type = bfd_link_hash_undefweak; | 
 | 	  h->u.undef.abfd = abfd; | 
 | 	  break; | 
 |  | 
 | 	case CDEF: | 
 | 	  /* We have found a definition for a symbol which was | 
 | 	     previously common.  */ | 
 | 	  BFD_ASSERT (h->type == bfd_link_hash_common); | 
 | 	  (*info->callbacks->multiple_common) (info, h, abfd, | 
 | 					       bfd_link_hash_defined, 0); | 
 | 	  /* Fall through.  */ | 
 | 	case DEF: | 
 | 	case DEFW: | 
 | 	  { | 
 | 	    enum bfd_link_hash_type oldtype; | 
 |  | 
 | 	    /* Define a symbol.  */ | 
 | 	    oldtype = h->type; | 
 | 	    if (action == DEFW) | 
 | 	      h->type = bfd_link_hash_defweak; | 
 | 	    else | 
 | 	      h->type = bfd_link_hash_defined; | 
 | 	    h->u.def.section = section; | 
 | 	    h->u.def.value = value; | 
 | 	    h->linker_def = 0; | 
 | 	    h->ldscript_def = 0; | 
 |  | 
 | 	    /* If we have been asked to, we act like collect2 and | 
 | 	       identify all functions that might be global | 
 | 	       constructors and destructors and pass them up in a | 
 | 	       callback.  We only do this for certain object file | 
 | 	       types, since many object file types can handle this | 
 | 	       automatically.  */ | 
 | 	    if (collect && name[0] == '_') | 
 | 	      { | 
 | 		const char *s; | 
 |  | 
 | 		/* A constructor or destructor name starts like this: | 
 | 		   _+GLOBAL_[_.$][ID][_.$] where the first [_.$] and | 
 | 		   the second are the same character (we accept any | 
 | 		   character there, in case a new object file format | 
 | 		   comes along with even worse naming restrictions).  */ | 
 |  | 
 | #define CONS_PREFIX "GLOBAL_" | 
 | #define CONS_PREFIX_LEN (sizeof CONS_PREFIX - 1) | 
 |  | 
 | 		s = name + 1; | 
 | 		while (*s == '_') | 
 | 		  ++s; | 
 | 		if (s[0] == 'G' && startswith (s, CONS_PREFIX)) | 
 | 		  { | 
 | 		    char c; | 
 |  | 
 | 		    c = s[CONS_PREFIX_LEN + 1]; | 
 | 		    if ((c == 'I' || c == 'D') | 
 | 			&& s[CONS_PREFIX_LEN] == s[CONS_PREFIX_LEN + 2]) | 
 | 		      { | 
 | 			/* If this is a definition of a symbol which | 
 | 			   was previously weakly defined, we are in | 
 | 			   trouble.  We have already added a | 
 | 			   constructor entry for the weak defined | 
 | 			   symbol, and now we are trying to add one | 
 | 			   for the new symbol.  Fortunately, this case | 
 | 			   should never arise in practice.  */ | 
 | 			if (oldtype == bfd_link_hash_defweak) | 
 | 			  abort (); | 
 |  | 
 | 			(*info->callbacks->constructor) (info, c == 'I', | 
 | 							 h->root.string, abfd, | 
 | 							 section, value); | 
 | 		      } | 
 | 		  } | 
 | 	      } | 
 | 	  } | 
 |  | 
 | 	  break; | 
 |  | 
 | 	case COM: | 
 | 	  /* We have found a common definition for a symbol.  */ | 
 | 	  if (h->type == bfd_link_hash_new) | 
 | 	    bfd_link_add_undef (info->hash, h); | 
 | 	  h->type = bfd_link_hash_common; | 
 | 	  h->u.c.p = (struct bfd_link_hash_common_entry *) | 
 | 	    bfd_hash_allocate (&info->hash->table, | 
 | 			       sizeof (struct bfd_link_hash_common_entry)); | 
 | 	  if (h->u.c.p == NULL) | 
 | 	    return false; | 
 |  | 
 | 	  h->u.c.size = value; | 
 |  | 
 | 	  /* Select a default alignment based on the size.  This may | 
 | 	     be overridden by the caller.  */ | 
 | 	  { | 
 | 	    unsigned int power; | 
 |  | 
 | 	    power = bfd_log2 (value); | 
 | 	    if (power > 4) | 
 | 	      power = 4; | 
 | 	    h->u.c.p->alignment_power = power; | 
 | 	  } | 
 |  | 
 | 	  /* The section of a common symbol is only used if the common | 
 | 	     symbol is actually allocated.  It basically provides a | 
 | 	     hook for the linker script to decide which output section | 
 | 	     the common symbols should be put in.  In most cases, the | 
 | 	     section of a common symbol will be bfd_com_section_ptr, | 
 | 	     the code here will choose a common symbol section named | 
 | 	     "COMMON", and the linker script will contain *(COMMON) in | 
 | 	     the appropriate place.  A few targets use separate common | 
 | 	     sections for small symbols, and they require special | 
 | 	     handling.  */ | 
 | 	  if (section == bfd_com_section_ptr) | 
 | 	    { | 
 | 	      h->u.c.p->section = bfd_make_section_old_way (abfd, "COMMON"); | 
 | 	      h->u.c.p->section->flags |= SEC_ALLOC; | 
 | 	    } | 
 | 	  else if (section->owner != abfd) | 
 | 	    { | 
 | 	      h->u.c.p->section = bfd_make_section_old_way (abfd, | 
 | 							    section->name); | 
 | 	      h->u.c.p->section->flags |= SEC_ALLOC; | 
 | 	    } | 
 | 	  else | 
 | 	    h->u.c.p->section = section; | 
 | 	  h->linker_def = 0; | 
 | 	  h->ldscript_def = 0; | 
 | 	  break; | 
 |  | 
 | 	case REF: | 
 | 	  /* A reference to a defined symbol.  */ | 
 | 	  if (h->u.undef.next == NULL && info->hash->undefs_tail != h) | 
 | 	    h->u.undef.next = h; | 
 | 	  break; | 
 |  | 
 | 	case BIG: | 
 | 	  /* We have found a common definition for a symbol which | 
 | 	     already had a common definition.  Use the maximum of the | 
 | 	     two sizes, and use the section required by the larger symbol.  */ | 
 | 	  BFD_ASSERT (h->type == bfd_link_hash_common); | 
 | 	  (*info->callbacks->multiple_common) (info, h, abfd, | 
 | 					       bfd_link_hash_common, value); | 
 | 	  if (value > h->u.c.size) | 
 | 	    { | 
 | 	      unsigned int power; | 
 |  | 
 | 	      h->u.c.size = value; | 
 |  | 
 | 	      /* Select a default alignment based on the size.  This may | 
 | 		 be overridden by the caller.  */ | 
 | 	      power = bfd_log2 (value); | 
 | 	      if (power > 4) | 
 | 		power = 4; | 
 | 	      h->u.c.p->alignment_power = power; | 
 |  | 
 | 	      /* Some systems have special treatment for small commons, | 
 | 		 hence we want to select the section used by the larger | 
 | 		 symbol.  This makes sure the symbol does not go in a | 
 | 		 small common section if it is now too large.  */ | 
 | 	      if (section == bfd_com_section_ptr) | 
 | 		{ | 
 | 		  h->u.c.p->section | 
 | 		    = bfd_make_section_old_way (abfd, "COMMON"); | 
 | 		  h->u.c.p->section->flags |= SEC_ALLOC; | 
 | 		} | 
 | 	      else if (section->owner != abfd) | 
 | 		{ | 
 | 		  h->u.c.p->section | 
 | 		    = bfd_make_section_old_way (abfd, section->name); | 
 | 		  h->u.c.p->section->flags |= SEC_ALLOC; | 
 | 		} | 
 | 	      else | 
 | 		h->u.c.p->section = section; | 
 | 	    } | 
 | 	  break; | 
 |  | 
 | 	case CREF: | 
 | 	  /* We have found a common definition for a symbol which | 
 | 	     was already defined.  */ | 
 | 	  (*info->callbacks->multiple_common) (info, h, abfd, | 
 | 					       bfd_link_hash_common, value); | 
 | 	  break; | 
 |  | 
 | 	case MIND: | 
 | 	  /* Multiple indirect symbols.  This is OK if they both point | 
 | 	     to the same symbol.  */ | 
 | 	  if (h->u.i.link == inh) | 
 | 	    break; | 
 | 	  if (h->u.i.link->type == bfd_link_hash_defweak) | 
 | 	    { | 
 | 	      /* It is also OK to redefine a symbol that indirects to | 
 | 		 a weak definition.  So for sym@ver -> sym@@ver where | 
 | 		 sym@@ver is weak and we have a new strong sym@ver, | 
 | 		 redefine sym@@ver.  Of course if there exists | 
 | 		 sym -> sym@@ver then this also redefines sym.  */ | 
 | 	      h = h->u.i.link; | 
 | 	      cycle = true; | 
 | 	      break; | 
 | 	    } | 
 | 	  /* Fall through.  */ | 
 | 	case MDEF: | 
 | 	  /* Handle a multiple definition.  */ | 
 | 	  (*info->callbacks->multiple_definition) (info, h, | 
 | 						   abfd, section, value); | 
 | 	  break; | 
 |  | 
 | 	case CIND: | 
 | 	  /* Create an indirect symbol from an existing common symbol.  */ | 
 | 	  BFD_ASSERT (h->type == bfd_link_hash_common); | 
 | 	  (*info->callbacks->multiple_common) (info, h, abfd, | 
 | 					       bfd_link_hash_indirect, 0); | 
 | 	  /* Fall through.  */ | 
 | 	case IND: | 
 | 	  if (inh->type == bfd_link_hash_indirect | 
 | 	      && inh->u.i.link == h) | 
 | 	    { | 
 | 	      _bfd_error_handler | 
 | 		/* xgettext:c-format */ | 
 | 		(_("%pB: indirect symbol `%s' to `%s' is a loop"), | 
 | 		 abfd, name, string); | 
 | 	      bfd_set_error (bfd_error_invalid_operation); | 
 | 	      return false; | 
 | 	    } | 
 | 	  if (inh->type == bfd_link_hash_new) | 
 | 	    { | 
 | 	      inh->type = bfd_link_hash_undefined; | 
 | 	      inh->u.undef.abfd = abfd; | 
 | 	      bfd_link_add_undef (info->hash, inh); | 
 | 	    } | 
 |  | 
 | 	  /* If the indirect symbol has been referenced, we need to | 
 | 	     push the reference down to the symbol we are referencing.  */ | 
 | 	  if (h->type != bfd_link_hash_new) | 
 | 	    { | 
 | 	      /* ??? If inh->type == bfd_link_hash_undefweak this | 
 | 		 converts inh to bfd_link_hash_undefined.  */ | 
 | 	      row = UNDEF_ROW; | 
 | 	      cycle = true; | 
 | 	    } | 
 |  | 
 | 	  h->type = bfd_link_hash_indirect; | 
 | 	  h->u.i.link = inh; | 
 | 	  /* Not setting h = h->u.i.link here means that when cycle is | 
 | 	     set above we'll always go to REFC, and then cycle again | 
 | 	     to the indirected symbol.  This means that any successful | 
 | 	     change of an existing symbol to indirect counts as a | 
 | 	     reference.  ??? That may not be correct when the existing | 
 | 	     symbol was defweak.  */ | 
 | 	  break; | 
 |  | 
 | 	case SET: | 
 | 	  /* Add an entry to a set.  */ | 
 | 	  (*info->callbacks->add_to_set) (info, h, BFD_RELOC_CTOR, | 
 | 					  abfd, section, value); | 
 | 	  break; | 
 |  | 
 | 	case WARNC: | 
 | 	  /* Issue a warning and cycle, except when the reference is | 
 | 	     in LTO IR.  */ | 
 | 	  if (h->u.i.warning != NULL | 
 | 	      && (abfd->flags & BFD_PLUGIN) == 0) | 
 | 	    { | 
 | 	      (*info->callbacks->warning) (info, h->u.i.warning, | 
 | 					   h->root.string, abfd, NULL, 0); | 
 | 	      /* Only issue a warning once.  */ | 
 | 	      h->u.i.warning = NULL; | 
 | 	    } | 
 | 	  /* Fall through.  */ | 
 | 	case CYCLE: | 
 | 	  /* Try again with the referenced symbol.  */ | 
 | 	  h = h->u.i.link; | 
 | 	  cycle = true; | 
 | 	  break; | 
 |  | 
 | 	case REFC: | 
 | 	  /* A reference to an indirect symbol.  */ | 
 | 	  if (h->u.undef.next == NULL && info->hash->undefs_tail != h) | 
 | 	    h->u.undef.next = h; | 
 | 	  h = h->u.i.link; | 
 | 	  cycle = true; | 
 | 	  break; | 
 |  | 
 | 	case WARN: | 
 | 	  /* Warn if this symbol has been referenced already from non-IR, | 
 | 	     otherwise add a warning.  */ | 
 | 	  if ((!info->lto_plugin_active | 
 | 	       && (h->u.undef.next != NULL || info->hash->undefs_tail == h)) | 
 | 	      || h->non_ir_ref_regular | 
 | 	      || h->non_ir_ref_dynamic) | 
 | 	    { | 
 | 	      (*info->callbacks->warning) (info, string, h->root.string, | 
 | 					   hash_entry_bfd (h), NULL, 0); | 
 | 	      /* PR 31067: If garbage collection is enabled then the | 
 | 		 referenced symbol may actually be discarded later on. | 
 | 		 This could be very confusing to the user.  So give them | 
 | 		 a hint as to what might be happening.  */ | 
 | 	      if (info->gc_sections) | 
 | 		(*info->callbacks->info) | 
 | 		  (_("%P: %pB: note: the message above does not take linker garbage collection into account\n"), | 
 | 		   hash_entry_bfd (h)); | 
 | 	      break; | 
 | 	    } | 
 | 	  /* Fall through.  */ | 
 | 	case MWARN: | 
 | 	  /* Make a warning symbol.  */ | 
 | 	  { | 
 | 	    struct bfd_link_hash_entry *sub; | 
 |  | 
 | 	    /* STRING is the warning to give.  */ | 
 | 	    sub = ((struct bfd_link_hash_entry *) | 
 | 		   ((*info->hash->table.newfunc) | 
 | 		    (NULL, &info->hash->table, h->root.string))); | 
 | 	    if (sub == NULL) | 
 | 	      return false; | 
 | 	    *sub = *h; | 
 | 	    sub->type = bfd_link_hash_warning; | 
 | 	    sub->u.i.link = h; | 
 | 	    if (! copy) | 
 | 	      sub->u.i.warning = string; | 
 | 	    else | 
 | 	      { | 
 | 		char *w; | 
 | 		size_t len = strlen (string) + 1; | 
 |  | 
 | 		w = (char *) bfd_hash_allocate (&info->hash->table, len); | 
 | 		if (w == NULL) | 
 | 		  return false; | 
 | 		memcpy (w, string, len); | 
 | 		sub->u.i.warning = w; | 
 | 	      } | 
 |  | 
 | 	    bfd_hash_replace (&info->hash->table, | 
 | 			      (struct bfd_hash_entry *) h, | 
 | 			      (struct bfd_hash_entry *) sub); | 
 | 	    if (hashp != NULL) | 
 | 	      *hashp = sub; | 
 | 	  } | 
 | 	  break; | 
 | 	} | 
 |     } | 
 |   while (cycle); | 
 |  | 
 |   return true; | 
 | } | 
 |  | 
 | /* | 
 | FUNCTION | 
 | 	bfd_link_align_section | 
 |  | 
 | SYNOPSIS | 
 | 	bool bfd_link_align_section (asection *, unsigned int); | 
 |  | 
 | DESCRIPTION | 
 | 	Increase section alignment if the current section alignment is | 
 | 	less than the requested value.  Adjust output section | 
 | 	alignment too, so that linker layout adjusts for alignment on | 
 | 	the current lang_size_sections pass.  This is important for | 
 | 	lang_size_relro_segment.  If the output section alignment | 
 | 	isn't adjusted, the linker will place the output section at an | 
 | 	address depending on its current alignment.  When sizing the | 
 | 	output section, input sections attached transfer any increase | 
 | 	in alignment to the output section, which will affect layout | 
 | 	for the next sizing pass.  Which is all well and good except | 
 | 	that lang_size_relro_segment for the current sizing pass uses | 
 | 	that possibly increased alignment with a layout that doesn't | 
 | 	suit. | 
 | */ | 
 |  | 
 | bool | 
 | bfd_link_align_section (asection *sec, unsigned int align_p2) | 
 | { | 
 |   if (align_p2 > bfd_section_alignment (sec)) | 
 |     { | 
 |       if (!bfd_set_section_alignment (sec, align_p2)) | 
 | 	return false; | 
 |       asection *osec = sec->output_section; | 
 |       if (osec && align_p2 > bfd_section_alignment (osec)) | 
 | 	{ | 
 | 	  if (!bfd_set_section_alignment (osec, align_p2)) | 
 | 	    return false; | 
 | 	} | 
 |     } | 
 |   return true; | 
 | } | 
 |  | 
 | /* Generic final link routine.  */ | 
 |  | 
 | bool | 
 | _bfd_generic_final_link (bfd *abfd, struct bfd_link_info *info) | 
 | { | 
 |   bfd *sub; | 
 |   asection *o; | 
 |   struct bfd_link_order *p; | 
 |   size_t outsymalloc; | 
 |   struct generic_write_global_symbol_info wginfo; | 
 |  | 
 |   abfd->outsymbols = NULL; | 
 |   abfd->symcount = 0; | 
 |   outsymalloc = 0; | 
 |  | 
 |   /* Mark all sections which will be included in the output file.  */ | 
 |   for (o = abfd->sections; o != NULL; o = o->next) | 
 |     for (p = o->map_head.link_order; p != NULL; p = p->next) | 
 |       if (p->type == bfd_indirect_link_order) | 
 | 	p->u.indirect.section->linker_mark = true; | 
 |  | 
 |   /* Build the output symbol table.  */ | 
 |   for (sub = info->input_bfds; sub != NULL; sub = sub->link.next) | 
 |     if (! _bfd_generic_link_output_symbols (abfd, sub, info, &outsymalloc)) | 
 |       return false; | 
 |  | 
 |   /* Accumulate the global symbols.  */ | 
 |   wginfo.info = info; | 
 |   wginfo.output_bfd = abfd; | 
 |   wginfo.psymalloc = &outsymalloc; | 
 |   wginfo.failed = false; | 
 |   _bfd_generic_link_hash_traverse (_bfd_generic_hash_table (info), | 
 | 				   _bfd_generic_link_write_global_symbol, | 
 | 				   &wginfo); | 
 |   if (wginfo.failed) | 
 |     return false; | 
 |  | 
 |   /* Make sure we have a trailing NULL pointer on OUTSYMBOLS.  We | 
 |      shouldn't really need one, since we have SYMCOUNT, but some old | 
 |      code still expects one.  */ | 
 |   if (! generic_add_output_symbol (abfd, &outsymalloc, NULL)) | 
 |     return false; | 
 |  | 
 |   if (bfd_link_relocatable (info)) | 
 |     { | 
 |       /* Allocate space for the output relocs for each section.  */ | 
 |       for (o = abfd->sections; o != NULL; o = o->next) | 
 | 	{ | 
 | 	  o->reloc_count = 0; | 
 | 	  for (p = o->map_head.link_order; p != NULL; p = p->next) | 
 | 	    { | 
 | 	      if (p->type == bfd_section_reloc_link_order | 
 | 		  || p->type == bfd_symbol_reloc_link_order) | 
 | 		++o->reloc_count; | 
 | 	      else if (p->type == bfd_indirect_link_order) | 
 | 		{ | 
 | 		  asection *input_section; | 
 | 		  bfd *input_bfd; | 
 | 		  long relsize; | 
 | 		  arelent **relocs; | 
 | 		  asymbol **symbols; | 
 | 		  long reloc_count; | 
 |  | 
 | 		  input_section = p->u.indirect.section; | 
 | 		  input_bfd = input_section->owner; | 
 | 		  relsize = bfd_get_reloc_upper_bound (input_bfd, | 
 | 						       input_section); | 
 | 		  if (relsize < 0) | 
 | 		    return false; | 
 | 		  relocs = (arelent **) bfd_malloc (relsize); | 
 | 		  if (!relocs && relsize != 0) | 
 | 		    return false; | 
 | 		  symbols = _bfd_generic_link_get_symbols (input_bfd); | 
 | 		  reloc_count = bfd_canonicalize_reloc (input_bfd, | 
 | 							input_section, | 
 | 							relocs, | 
 | 							symbols); | 
 | 		  free (relocs); | 
 | 		  if (reloc_count < 0) | 
 | 		    return false; | 
 | 		  BFD_ASSERT ((unsigned long) reloc_count | 
 | 			      == input_section->reloc_count); | 
 | 		  o->reloc_count += reloc_count; | 
 | 		} | 
 | 	    } | 
 | 	  if (o->reloc_count > 0) | 
 | 	    { | 
 | 	      bfd_size_type amt; | 
 |  | 
 | 	      amt = o->reloc_count; | 
 | 	      amt *= sizeof (arelent *); | 
 | 	      o->orelocation = (struct reloc_cache_entry **) bfd_alloc (abfd, amt); | 
 | 	      if (!o->orelocation) | 
 | 		return false; | 
 | 	      o->flags |= SEC_RELOC; | 
 | 	      /* Reset the count so that it can be used as an index | 
 | 		 when putting in the output relocs.  */ | 
 | 	      o->reloc_count = 0; | 
 | 	    } | 
 | 	} | 
 |     } | 
 |  | 
 |   /* Handle all the link order information for the sections.  */ | 
 |   for (o = abfd->sections; o != NULL; o = o->next) | 
 |     { | 
 |       for (p = o->map_head.link_order; p != NULL; p = p->next) | 
 | 	{ | 
 | 	  switch (p->type) | 
 | 	    { | 
 | 	    case bfd_section_reloc_link_order: | 
 | 	    case bfd_symbol_reloc_link_order: | 
 | 	      if (! _bfd_generic_reloc_link_order (abfd, info, o, p)) | 
 | 		return false; | 
 | 	      break; | 
 | 	    case bfd_indirect_link_order: | 
 | 	      if (! default_indirect_link_order (abfd, info, o, p, true)) | 
 | 		return false; | 
 | 	      break; | 
 | 	    default: | 
 | 	      if (! _bfd_default_link_order (abfd, info, o, p)) | 
 | 		return false; | 
 | 	      break; | 
 | 	    } | 
 | 	} | 
 |     } | 
 |  | 
 |   return true; | 
 | } | 
 |  | 
 | /* Add an output symbol to the output BFD.  */ | 
 |  | 
 | static bool | 
 | generic_add_output_symbol (bfd *output_bfd, size_t *psymalloc, asymbol *sym) | 
 | { | 
 |   if (!(bfd_applicable_file_flags (output_bfd) & HAS_SYMS)) | 
 |     return true; | 
 |  | 
 |   if (bfd_get_symcount (output_bfd) >= *psymalloc) | 
 |     { | 
 |       asymbol **newsyms; | 
 |       bfd_size_type amt; | 
 |  | 
 |       if (*psymalloc == 0) | 
 | 	*psymalloc = 124; | 
 |       else | 
 | 	*psymalloc *= 2; | 
 |       amt = *psymalloc; | 
 |       amt *= sizeof (asymbol *); | 
 |       newsyms = (asymbol **) bfd_realloc (bfd_get_outsymbols (output_bfd), amt); | 
 |       if (newsyms == NULL) | 
 | 	return false; | 
 |       output_bfd->outsymbols = newsyms; | 
 |     } | 
 |  | 
 |   output_bfd->outsymbols[output_bfd->symcount] = sym; | 
 |   if (sym != NULL) | 
 |     ++output_bfd->symcount; | 
 |  | 
 |   return true; | 
 | } | 
 |  | 
 | /* Handle the symbols for an input BFD.  */ | 
 |  | 
 | static bool | 
 | _bfd_generic_link_output_symbols (bfd *output_bfd, | 
 | 				  bfd *input_bfd, | 
 | 				  struct bfd_link_info *info, | 
 | 				  size_t *psymalloc) | 
 | { | 
 |   asymbol **sym_ptr; | 
 |   asymbol **sym_end; | 
 |  | 
 |   if (!bfd_generic_link_read_symbols (input_bfd)) | 
 |     return false; | 
 |  | 
 |   /* Create a filename symbol if we are supposed to.  */ | 
 |   if (info->create_object_symbols_section != NULL) | 
 |     { | 
 |       asection *sec; | 
 |  | 
 |       for (sec = input_bfd->sections; sec != NULL; sec = sec->next) | 
 | 	{ | 
 | 	  if (sec->output_section == info->create_object_symbols_section) | 
 | 	    { | 
 | 	      asymbol *newsym; | 
 |  | 
 | 	      newsym = bfd_make_empty_symbol (input_bfd); | 
 | 	      if (!newsym) | 
 | 		return false; | 
 | 	      newsym->name = bfd_get_filename (input_bfd); | 
 | 	      newsym->value = 0; | 
 | 	      newsym->flags = BSF_LOCAL | BSF_FILE; | 
 | 	      newsym->section = sec; | 
 |  | 
 | 	      if (! generic_add_output_symbol (output_bfd, psymalloc, | 
 | 					       newsym)) | 
 | 		return false; | 
 |  | 
 | 	      break; | 
 | 	    } | 
 | 	} | 
 |     } | 
 |  | 
 |   /* Adjust the values of the globally visible symbols, and write out | 
 |      local symbols.  */ | 
 |   sym_ptr = _bfd_generic_link_get_symbols (input_bfd); | 
 |   sym_end = sym_ptr + _bfd_generic_link_get_symcount (input_bfd); | 
 |   for (; sym_ptr < sym_end; sym_ptr++) | 
 |     { | 
 |       asymbol *sym; | 
 |       struct generic_link_hash_entry *h; | 
 |  | 
 |       h = NULL; | 
 |       sym = *sym_ptr; | 
 |       if ((sym->flags & (BSF_INDIRECT | 
 | 			 | BSF_WARNING | 
 | 			 | BSF_GLOBAL | 
 | 			 | BSF_CONSTRUCTOR | 
 | 			 | BSF_WEAK)) != 0 | 
 | 	  || bfd_is_und_section (bfd_asymbol_section (sym)) | 
 | 	  || bfd_is_com_section (bfd_asymbol_section (sym)) | 
 | 	  || bfd_is_ind_section (bfd_asymbol_section (sym))) | 
 | 	{ | 
 | 	  if (sym->udata.p != NULL) | 
 | 	    h = (struct generic_link_hash_entry *) sym->udata.p; | 
 | 	  else if ((sym->flags & BSF_CONSTRUCTOR) != 0) | 
 | 	    { | 
 | 	      /* This case normally means that the main linker code | 
 | 		 deliberately ignored this constructor symbol.  We | 
 | 		 should just pass it through.  This will screw up if | 
 | 		 the constructor symbol is from a different, | 
 | 		 non-generic, object file format, but the case will | 
 | 		 only arise when linking with -r, which will probably | 
 | 		 fail anyhow, since there will be no way to represent | 
 | 		 the relocs in the output format being used.  */ | 
 | 	      h = NULL; | 
 | 	    } | 
 | 	  else if (bfd_is_und_section (bfd_asymbol_section (sym))) | 
 | 	    h = ((struct generic_link_hash_entry *) | 
 | 		 bfd_wrapped_link_hash_lookup (output_bfd, info, | 
 | 					       bfd_asymbol_name (sym), | 
 | 					       false, false, true)); | 
 | 	  else | 
 | 	    h = _bfd_generic_link_hash_lookup (_bfd_generic_hash_table (info), | 
 | 					       bfd_asymbol_name (sym), | 
 | 					       false, false, true); | 
 |  | 
 | 	  if (h != NULL) | 
 | 	    { | 
 | 	      /* Force all references to this symbol to point to | 
 | 		 the same area in memory.  It is possible that | 
 | 		 this routine will be called with a hash table | 
 | 		 other than a generic hash table, so we double | 
 | 		 check that.  */ | 
 | 	      if (info->output_bfd->xvec == input_bfd->xvec) | 
 | 		{ | 
 | 		  if (h->sym != NULL) | 
 | 		    *sym_ptr = sym = h->sym; | 
 | 		} | 
 |  | 
 | 	      switch (h->root.type) | 
 | 		{ | 
 | 		default: | 
 | 		case bfd_link_hash_new: | 
 | 		  abort (); | 
 | 		case bfd_link_hash_undefined: | 
 | 		  break; | 
 | 		case bfd_link_hash_undefweak: | 
 | 		  sym->flags |= BSF_WEAK; | 
 | 		  break; | 
 | 		case bfd_link_hash_indirect: | 
 | 		  h = (struct generic_link_hash_entry *) h->root.u.i.link; | 
 | 		  /* fall through */ | 
 | 		case bfd_link_hash_defined: | 
 | 		  sym->flags |= BSF_GLOBAL; | 
 | 		  sym->flags &=~ (BSF_WEAK | BSF_CONSTRUCTOR); | 
 | 		  sym->value = h->root.u.def.value; | 
 | 		  sym->section = h->root.u.def.section; | 
 | 		  break; | 
 | 		case bfd_link_hash_defweak: | 
 | 		  sym->flags |= BSF_WEAK; | 
 | 		  sym->flags &=~ BSF_CONSTRUCTOR; | 
 | 		  sym->value = h->root.u.def.value; | 
 | 		  sym->section = h->root.u.def.section; | 
 | 		  break; | 
 | 		case bfd_link_hash_common: | 
 | 		  sym->value = h->root.u.c.size; | 
 | 		  sym->flags |= BSF_GLOBAL; | 
 | 		  if (! bfd_is_com_section (sym->section)) | 
 | 		    { | 
 | 		      BFD_ASSERT (bfd_is_und_section (sym->section)); | 
 | 		      sym->section = bfd_com_section_ptr; | 
 | 		    } | 
 | 		  /* We do not set the section of the symbol to | 
 | 		     h->root.u.c.p->section.  That value was saved so | 
 | 		     that we would know where to allocate the symbol | 
 | 		     if it was defined.  In this case the type is | 
 | 		     still bfd_link_hash_common, so we did not define | 
 | 		     it, so we do not want to use that section.  */ | 
 | 		  break; | 
 | 		} | 
 | 	    } | 
 | 	} | 
 |  | 
 |       bool output = false; | 
 |       if ((sym->flags & BSF_KEEP) == 0 | 
 | 	  && (info->strip == strip_all | 
 | 	      || (info->strip == strip_some | 
 | 		  && bfd_hash_lookup (info->keep_hash, bfd_asymbol_name (sym), | 
 | 				      false, false) == NULL))) | 
 | 	; | 
 |       /* If this symbol is in a section which is not being included | 
 | 	 in the output file, then we don't want to output the | 
 | 	 symbol.  */ | 
 |       else if (!bfd_is_abs_section (sym->section) | 
 | 	       && bfd_section_removed_from_list (output_bfd, | 
 | 						 sym->section->output_section)) | 
 | 	; | 
 |       else if ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0) | 
 | 	{ | 
 | 	  /* If this symbol is marked as occurring now, rather | 
 | 	     than at the end, output it now.  This is used for | 
 | 	     COFF C_EXT FCN symbols.  FIXME: There must be a | 
 | 	     better way.  */ | 
 | 	  if (bfd_asymbol_bfd (sym) == input_bfd | 
 | 	      && (sym->flags & BSF_NOT_AT_END) != 0) | 
 | 	    output = true; | 
 | 	} | 
 |       else if ((sym->flags & BSF_KEEP) != 0) | 
 | 	output = true; | 
 |       else if (bfd_is_ind_section (sym->section)) | 
 | 	; | 
 |       else if ((sym->flags & BSF_DEBUGGING) != 0) | 
 | 	{ | 
 | 	  if (info->strip == strip_none) | 
 | 	    output = true; | 
 | 	} | 
 |       else if (bfd_is_und_section (sym->section) | 
 | 	       || bfd_is_com_section (sym->section)) | 
 | 	; | 
 |       else if ((sym->flags & BSF_LOCAL) != 0) | 
 | 	{ | 
 | 	  if ((sym->flags & BSF_WARNING) == 0) | 
 | 	    { | 
 | 	      switch (info->discard) | 
 | 		{ | 
 | 		default: | 
 | 		case discard_all: | 
 | 		  break; | 
 | 		case discard_sec_merge: | 
 | 		  output = true; | 
 | 		  if (bfd_link_relocatable (info) | 
 | 		      || ! (sym->section->flags & SEC_MERGE)) | 
 | 		    break; | 
 | 		  /* FALLTHROUGH */ | 
 | 		case discard_l: | 
 | 		  if (!bfd_is_local_label (input_bfd, sym)) | 
 | 		    output = true; | 
 | 		  break; | 
 | 		case discard_none: | 
 | 		  output = true; | 
 | 		  break; | 
 | 		} | 
 | 	    } | 
 | 	} | 
 |       else if ((sym->flags & BSF_CONSTRUCTOR)) | 
 | 	{ | 
 | 	  if (info->strip != strip_all) | 
 | 	    output = true; | 
 | 	} | 
 |       else if (sym->flags == 0) | 
 | 	/* LTO doesn't set symbol information.  We get here with the | 
 | 	   generic linker for a symbol that was "common" but no longer | 
 | 	   needs to be global.  We also get here on fuzzed ELF objects | 
 | 	   with bogus symbol type and binding.  */ | 
 | 	; | 
 |       else | 
 | 	BFD_FAIL (); | 
 |  | 
 |       if (output) | 
 | 	{ | 
 | 	  if (! generic_add_output_symbol (output_bfd, psymalloc, sym)) | 
 | 	    return false; | 
 | 	  if (h != NULL) | 
 | 	    h->written = true; | 
 | 	} | 
 |     } | 
 |  | 
 |   return true; | 
 | } | 
 |  | 
 | /* Set the section and value of a generic BFD symbol based on a linker | 
 |    hash table entry.  */ | 
 |  | 
 | static void | 
 | set_symbol_from_hash (asymbol *sym, struct bfd_link_hash_entry *h) | 
 | { | 
 |   switch (h->type) | 
 |     { | 
 |     default: | 
 |       abort (); | 
 |       break; | 
 |     case bfd_link_hash_new: | 
 |       /* This can happen when a constructor symbol is seen but we are | 
 | 	 not building constructors.  */ | 
 |       if (sym->section != NULL) | 
 | 	{ | 
 | 	  BFD_ASSERT ((sym->flags & BSF_CONSTRUCTOR) != 0); | 
 | 	} | 
 |       else | 
 | 	{ | 
 | 	  sym->flags |= BSF_CONSTRUCTOR; | 
 | 	  sym->section = bfd_abs_section_ptr; | 
 | 	  sym->value = 0; | 
 | 	} | 
 |       break; | 
 |     case bfd_link_hash_undefined: | 
 |       sym->section = bfd_und_section_ptr; | 
 |       sym->value = 0; | 
 |       break; | 
 |     case bfd_link_hash_undefweak: | 
 |       sym->section = bfd_und_section_ptr; | 
 |       sym->value = 0; | 
 |       sym->flags |= BSF_WEAK; | 
 |       break; | 
 |     case bfd_link_hash_defined: | 
 |       sym->section = h->u.def.section; | 
 |       sym->value = h->u.def.value; | 
 |       break; | 
 |     case bfd_link_hash_defweak: | 
 |       sym->flags |= BSF_WEAK; | 
 |       sym->section = h->u.def.section; | 
 |       sym->value = h->u.def.value; | 
 |       break; | 
 |     case bfd_link_hash_common: | 
 |       sym->value = h->u.c.size; | 
 |       if (sym->section == NULL) | 
 | 	sym->section = bfd_com_section_ptr; | 
 |       else if (! bfd_is_com_section (sym->section)) | 
 | 	{ | 
 | 	  BFD_ASSERT (bfd_is_und_section (sym->section)); | 
 | 	  sym->section = bfd_com_section_ptr; | 
 | 	} | 
 |       /* Do not set the section; see _bfd_generic_link_output_symbols.  */ | 
 |       break; | 
 |     case bfd_link_hash_indirect: | 
 |     case bfd_link_hash_warning: | 
 |       /* FIXME: What should we do here?  */ | 
 |       break; | 
 |     } | 
 | } | 
 |  | 
 | /* Write out a global symbol, if it hasn't already been written out. | 
 |    This is called for each symbol in the hash table.  */ | 
 |  | 
 | static bool | 
 | _bfd_generic_link_write_global_symbol (struct generic_link_hash_entry *h, | 
 | 				       void *data) | 
 | { | 
 |   struct generic_write_global_symbol_info *wginfo = data; | 
 |   asymbol *sym; | 
 |  | 
 |   if (h->written) | 
 |     return true; | 
 |  | 
 |   h->written = true; | 
 |  | 
 |   if (wginfo->info->strip == strip_all | 
 |       || (wginfo->info->strip == strip_some | 
 | 	  && bfd_hash_lookup (wginfo->info->keep_hash, h->root.root.string, | 
 | 			      false, false) == NULL)) | 
 |     return true; | 
 |  | 
 |   if (h->sym != NULL) | 
 |     sym = h->sym; | 
 |   else | 
 |     { | 
 |       sym = bfd_make_empty_symbol (wginfo->output_bfd); | 
 |       if (!sym) | 
 | 	{ | 
 | 	  wginfo->failed = true; | 
 | 	  return false; | 
 | 	} | 
 |       sym->name = h->root.root.string; | 
 |       sym->flags = 0; | 
 |     } | 
 |  | 
 |   set_symbol_from_hash (sym, &h->root); | 
 |  | 
 |   sym->flags |= BSF_GLOBAL; | 
 |  | 
 |   if (! generic_add_output_symbol (wginfo->output_bfd, wginfo->psymalloc, | 
 | 				   sym)) | 
 |     { | 
 |       wginfo->failed = true; | 
 |       return false; | 
 |     } | 
 |  | 
 |   return true; | 
 | } | 
 |  | 
 | /* Create a relocation.  */ | 
 |  | 
 | bool | 
 | _bfd_generic_reloc_link_order (bfd *abfd, | 
 | 			       struct bfd_link_info *info, | 
 | 			       asection *sec, | 
 | 			       struct bfd_link_order *link_order) | 
 | { | 
 |   arelent *r; | 
 |  | 
 |   if (! bfd_link_relocatable (info)) | 
 |     abort (); | 
 |   if (sec->orelocation == NULL) | 
 |     abort (); | 
 |  | 
 |   r = (arelent *) bfd_alloc (abfd, sizeof (arelent)); | 
 |   if (r == NULL) | 
 |     return false; | 
 |  | 
 |   r->address = link_order->offset; | 
 |   r->howto = bfd_reloc_type_lookup (abfd, link_order->u.reloc.p->reloc); | 
 |   if (r->howto == 0) | 
 |     { | 
 |       bfd_set_error (bfd_error_bad_value); | 
 |       return false; | 
 |     } | 
 |  | 
 |   /* Get the symbol to use for the relocation.  */ | 
 |   if (link_order->type == bfd_section_reloc_link_order) | 
 |     r->sym_ptr_ptr = &link_order->u.reloc.p->u.section->symbol; | 
 |   else | 
 |     { | 
 |       struct generic_link_hash_entry *h; | 
 |  | 
 |       h = ((struct generic_link_hash_entry *) | 
 | 	   bfd_wrapped_link_hash_lookup (abfd, info, | 
 | 					 link_order->u.reloc.p->u.name, | 
 | 					 false, false, true)); | 
 |       if (h == NULL | 
 | 	  || ! h->written) | 
 | 	{ | 
 | 	  (*info->callbacks->unattached_reloc) | 
 | 	    (info, link_order->u.reloc.p->u.name, NULL, NULL, 0); | 
 | 	  bfd_set_error (bfd_error_bad_value); | 
 | 	  return false; | 
 | 	} | 
 |       r->sym_ptr_ptr = &h->sym; | 
 |     } | 
 |  | 
 |   /* If this is an inplace reloc, write the addend to the object file. | 
 |      Otherwise, store it in the reloc addend.  */ | 
 |   if (! r->howto->partial_inplace) | 
 |     r->addend = link_order->u.reloc.p->addend; | 
 |   else | 
 |     { | 
 |       bfd_size_type size; | 
 |       bfd_reloc_status_type rstat; | 
 |       bfd_byte *buf; | 
 |       bool ok; | 
 |       file_ptr loc; | 
 |  | 
 |       size = bfd_get_reloc_size (r->howto); | 
 |       buf = (bfd_byte *) bfd_zmalloc (size); | 
 |       if (buf == NULL && size != 0) | 
 | 	return false; | 
 |       rstat = _bfd_relocate_contents (r->howto, abfd, | 
 | 				      (bfd_vma) link_order->u.reloc.p->addend, | 
 | 				      buf); | 
 |       switch (rstat) | 
 | 	{ | 
 | 	case bfd_reloc_ok: | 
 | 	  break; | 
 | 	default: | 
 | 	case bfd_reloc_outofrange: | 
 | 	  abort (); | 
 | 	case bfd_reloc_overflow: | 
 | 	  (*info->callbacks->reloc_overflow) | 
 | 	    (info, NULL, | 
 | 	     (link_order->type == bfd_section_reloc_link_order | 
 | 	      ? bfd_section_name (link_order->u.reloc.p->u.section) | 
 | 	      : link_order->u.reloc.p->u.name), | 
 | 	     r->howto->name, link_order->u.reloc.p->addend, | 
 | 	     NULL, NULL, 0); | 
 | 	  break; | 
 | 	} | 
 |       loc = link_order->offset * bfd_octets_per_byte (abfd, sec); | 
 |       ok = bfd_set_section_contents (abfd, sec, buf, loc, size); | 
 |       free (buf); | 
 |       if (! ok) | 
 | 	return false; | 
 |  | 
 |       r->addend = 0; | 
 |     } | 
 |  | 
 |   sec->orelocation[sec->reloc_count] = r; | 
 |   ++sec->reloc_count; | 
 |  | 
 |   return true; | 
 | } | 
 |  | 
 | /* Allocate a new link_order for a section.  */ | 
 |  | 
 | struct bfd_link_order * | 
 | bfd_new_link_order (bfd *abfd, asection *section) | 
 | { | 
 |   size_t amt = sizeof (struct bfd_link_order); | 
 |   struct bfd_link_order *new_lo; | 
 |  | 
 |   new_lo = (struct bfd_link_order *) bfd_zalloc (abfd, amt); | 
 |   if (!new_lo) | 
 |     return NULL; | 
 |  | 
 |   new_lo->type = bfd_undefined_link_order; | 
 |  | 
 |   if (section->map_tail.link_order != NULL) | 
 |     section->map_tail.link_order->next = new_lo; | 
 |   else | 
 |     section->map_head.link_order = new_lo; | 
 |   section->map_tail.link_order = new_lo; | 
 |  | 
 |   return new_lo; | 
 | } | 
 |  | 
 | /* Default link order processing routine.  Note that we can not handle | 
 |    the reloc_link_order types here, since they depend upon the details | 
 |    of how the particular backends generates relocs.  */ | 
 |  | 
 | bool | 
 | _bfd_default_link_order (bfd *abfd, | 
 | 			 struct bfd_link_info *info, | 
 | 			 asection *sec, | 
 | 			 struct bfd_link_order *link_order) | 
 | { | 
 |   switch (link_order->type) | 
 |     { | 
 |     case bfd_undefined_link_order: | 
 |     case bfd_section_reloc_link_order: | 
 |     case bfd_symbol_reloc_link_order: | 
 |     default: | 
 |       abort (); | 
 |     case bfd_indirect_link_order: | 
 |       return default_indirect_link_order (abfd, info, sec, link_order, | 
 | 					  false); | 
 |     case bfd_data_link_order: | 
 |       return default_data_link_order (abfd, info, sec, link_order); | 
 |     } | 
 | } | 
 |  | 
 | /* Default routine to handle a bfd_data_link_order.  */ | 
 |  | 
 | static bool | 
 | default_data_link_order (bfd *abfd, | 
 | 			 struct bfd_link_info *info, | 
 | 			 asection *sec, | 
 | 			 struct bfd_link_order *link_order) | 
 | { | 
 |   bfd_size_type size; | 
 |   size_t fill_size; | 
 |   bfd_byte *fill; | 
 |   file_ptr loc; | 
 |   bool result; | 
 |  | 
 |   BFD_ASSERT ((sec->flags & SEC_HAS_CONTENTS) != 0); | 
 |  | 
 |   size = link_order->size; | 
 |   if (size == 0) | 
 |     return true; | 
 |  | 
 |   fill = link_order->u.data.contents; | 
 |   fill_size = link_order->u.data.size; | 
 |   if (fill_size == 0) | 
 |     { | 
 |       fill = abfd->arch_info->fill (size, info->big_endian, | 
 | 				    (sec->flags & SEC_CODE) != 0); | 
 |       if (fill == NULL) | 
 | 	return false; | 
 |     } | 
 |   else if (fill_size < size) | 
 |     { | 
 |       bfd_byte *p; | 
 |       fill = (bfd_byte *) bfd_malloc (size); | 
 |       if (fill == NULL) | 
 | 	return false; | 
 |       p = fill; | 
 |       if (fill_size == 1) | 
 | 	memset (p, (int) link_order->u.data.contents[0], (size_t) size); | 
 |       else | 
 | 	{ | 
 | 	  do | 
 | 	    { | 
 | 	      memcpy (p, link_order->u.data.contents, fill_size); | 
 | 	      p += fill_size; | 
 | 	      size -= fill_size; | 
 | 	    } | 
 | 	  while (size >= fill_size); | 
 | 	  if (size != 0) | 
 | 	    memcpy (p, link_order->u.data.contents, (size_t) size); | 
 | 	  size = link_order->size; | 
 | 	} | 
 |     } | 
 |  | 
 |   loc = link_order->offset * bfd_octets_per_byte (abfd, sec); | 
 |   result = bfd_set_section_contents (abfd, sec, fill, loc, size); | 
 |  | 
 |   if (fill != link_order->u.data.contents) | 
 |     free (fill); | 
 |   return result; | 
 | } | 
 |  | 
 | /* Default routine to handle a bfd_indirect_link_order.  */ | 
 |  | 
 | static bool | 
 | default_indirect_link_order (bfd *output_bfd, | 
 | 			     struct bfd_link_info *info, | 
 | 			     asection *output_section, | 
 | 			     struct bfd_link_order *link_order, | 
 | 			     bool generic_linker) | 
 | { | 
 |   asection *input_section; | 
 |   bfd *input_bfd; | 
 |   bfd_byte *alloced = NULL; | 
 |   bfd_byte *new_contents; | 
 |   file_ptr loc; | 
 |  | 
 |   BFD_ASSERT ((output_section->flags & SEC_HAS_CONTENTS) != 0); | 
 |  | 
 |   input_section = link_order->u.indirect.section; | 
 |   input_bfd = input_section->owner; | 
 |   if (input_section->size == 0) | 
 |     return true; | 
 |  | 
 |   BFD_ASSERT (input_section->output_section == output_section); | 
 |   BFD_ASSERT (input_section->output_offset == link_order->offset); | 
 |   BFD_ASSERT (input_section->size == link_order->size); | 
 |  | 
 |   if (bfd_link_relocatable (info) | 
 |       && input_section->reloc_count > 0 | 
 |       && output_section->orelocation == NULL) | 
 |     { | 
 |       /* Space has not been allocated for the output relocations. | 
 | 	 This can happen when we are called by a specific backend | 
 | 	 because somebody is attempting to link together different | 
 | 	 types of object files.  Handling this case correctly is | 
 | 	 difficult, and sometimes impossible.  */ | 
 |       _bfd_error_handler | 
 | 	/* xgettext:c-format */ | 
 | 	(_("attempt to do relocatable link with %s input and %s output"), | 
 | 	 bfd_get_target (input_bfd), bfd_get_target (output_bfd)); | 
 |       bfd_set_error (bfd_error_wrong_format); | 
 |       return false; | 
 |     } | 
 |  | 
 |   if (! generic_linker) | 
 |     { | 
 |       asymbol **sympp; | 
 |       asymbol **symppend; | 
 |  | 
 |       /* Get the canonical symbols.  The generic linker will always | 
 | 	 have retrieved them by this point, but we are being called by | 
 | 	 a specific linker, presumably because we are linking | 
 | 	 different types of object files together.  */ | 
 |       if (!bfd_generic_link_read_symbols (input_bfd)) | 
 | 	return false; | 
 |  | 
 |       /* Since we have been called by a specific linker, rather than | 
 | 	 the generic linker, the values of the symbols will not be | 
 | 	 right.  They will be the values as seen in the input file, | 
 | 	 not the values of the final link.  We need to fix them up | 
 | 	 before we can relocate the section.  */ | 
 |       sympp = _bfd_generic_link_get_symbols (input_bfd); | 
 |       symppend = sympp + _bfd_generic_link_get_symcount (input_bfd); | 
 |       for (; sympp < symppend; sympp++) | 
 | 	{ | 
 | 	  asymbol *sym; | 
 | 	  struct bfd_link_hash_entry *h; | 
 |  | 
 | 	  sym = *sympp; | 
 |  | 
 | 	  if ((sym->flags & (BSF_INDIRECT | 
 | 			     | BSF_WARNING | 
 | 			     | BSF_GLOBAL | 
 | 			     | BSF_CONSTRUCTOR | 
 | 			     | BSF_WEAK)) != 0 | 
 | 	      || bfd_is_und_section (bfd_asymbol_section (sym)) | 
 | 	      || bfd_is_com_section (bfd_asymbol_section (sym)) | 
 | 	      || bfd_is_ind_section (bfd_asymbol_section (sym))) | 
 | 	    { | 
 | 	      /* sym->udata may have been set by | 
 | 		 generic_link_add_symbol_list.  */ | 
 | 	      if (sym->udata.p != NULL) | 
 | 		h = (struct bfd_link_hash_entry *) sym->udata.p; | 
 | 	      else if (bfd_is_und_section (bfd_asymbol_section (sym))) | 
 | 		h = bfd_wrapped_link_hash_lookup (output_bfd, info, | 
 | 						  bfd_asymbol_name (sym), | 
 | 						  false, false, true); | 
 | 	      else | 
 | 		h = bfd_link_hash_lookup (info->hash, | 
 | 					  bfd_asymbol_name (sym), | 
 | 					  false, false, true); | 
 | 	      if (h != NULL) | 
 | 		set_symbol_from_hash (sym, h); | 
 | 	    } | 
 | 	} | 
 |     } | 
 |  | 
 |   if ((output_section->flags & (SEC_GROUP | SEC_LINKER_CREATED)) == SEC_GROUP | 
 |       && input_section->size != 0) | 
 |     { | 
 |       /* Group section contents are set by bfd_elf_set_group_contents.  */ | 
 |       if (!output_bfd->output_has_begun) | 
 | 	{ | 
 | 	  /* FIXME: This hack ensures bfd_elf_set_group_contents is called.  */ | 
 | 	  if (!bfd_set_section_contents (output_bfd, output_section, "", 0, 1)) | 
 | 	    goto error_return; | 
 | 	} | 
 |       new_contents = output_section->contents; | 
 |       BFD_ASSERT (new_contents != NULL); | 
 |       BFD_ASSERT (input_section->output_offset == 0); | 
 |     } | 
 |   else | 
 |     { | 
 |       /* Get and relocate the section contents.  */ | 
 |       new_contents = (bfd_get_relocated_section_contents | 
 | 		      (output_bfd, info, link_order, NULL, | 
 | 		       bfd_link_relocatable (info), | 
 | 		       _bfd_generic_link_get_symbols (input_bfd))); | 
 |       alloced = new_contents; | 
 |       if (!new_contents) | 
 | 	goto error_return; | 
 |     } | 
 |  | 
 |   /* Output the section contents.  */ | 
 |   loc = (input_section->output_offset | 
 | 	 * bfd_octets_per_byte (output_bfd, output_section)); | 
 |   if (! bfd_set_section_contents (output_bfd, output_section, | 
 | 				  new_contents, loc, input_section->size)) | 
 |     goto error_return; | 
 |  | 
 |   free (alloced); | 
 |   return true; | 
 |  | 
 |  error_return: | 
 |   free (alloced); | 
 |   return false; | 
 | } | 
 |  | 
 | /* A little routine to count the number of relocs in a link_order | 
 |    list.  */ | 
 |  | 
 | unsigned int | 
 | _bfd_count_link_order_relocs (struct bfd_link_order *link_order) | 
 | { | 
 |   register unsigned int c; | 
 |   register struct bfd_link_order *l; | 
 |  | 
 |   c = 0; | 
 |   for (l = link_order; l != NULL; l = l->next) | 
 |     { | 
 |       if (l->type == bfd_section_reloc_link_order | 
 | 	  || l->type == bfd_symbol_reloc_link_order) | 
 | 	++c; | 
 |     } | 
 |  | 
 |   return c; | 
 | } | 
 |  | 
 | /* | 
 | FUNCTION | 
 | 	bfd_link_split_section | 
 |  | 
 | SYNOPSIS | 
 | 	bool bfd_link_split_section (bfd *abfd, asection *sec); | 
 |  | 
 | DESCRIPTION | 
 | 	Return nonzero if @var{sec} should be split during a | 
 | 	reloceatable or final link. | 
 |  | 
 | .#define bfd_link_split_section(abfd, sec) \ | 
 | .	BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec)) | 
 | . | 
 |  | 
 | */ | 
 |  | 
 | bool | 
 | _bfd_generic_link_split_section (bfd *abfd ATTRIBUTE_UNUSED, | 
 | 				 asection *sec ATTRIBUTE_UNUSED) | 
 | { | 
 |   return false; | 
 | } | 
 |  | 
 | /* | 
 | FUNCTION | 
 | 	bfd_section_already_linked | 
 |  | 
 | SYNOPSIS | 
 | 	bool bfd_section_already_linked (bfd *abfd, | 
 | 					 asection *sec, | 
 | 					 struct bfd_link_info *info); | 
 |  | 
 | DESCRIPTION | 
 | 	Check if @var{data} has been already linked during a reloceatable | 
 | 	or final link.  Return TRUE if it has. | 
 |  | 
 | .#define bfd_section_already_linked(abfd, sec, info) \ | 
 | .	BFD_SEND (abfd, _section_already_linked, (abfd, sec, info)) | 
 | . | 
 |  | 
 | */ | 
 |  | 
 | /* Sections marked with the SEC_LINK_ONCE flag should only be linked | 
 |    once into the output.  This routine checks each section, and | 
 |    arrange to discard it if a section of the same name has already | 
 |    been linked.  This code assumes that all relevant sections have the | 
 |    SEC_LINK_ONCE flag set; that is, it does not depend solely upon the | 
 |    section name.  bfd_section_already_linked is called via | 
 |    bfd_map_over_sections.  */ | 
 |  | 
 | /* The hash table.  */ | 
 |  | 
 | static struct bfd_hash_table _bfd_section_already_linked_table; | 
 |  | 
 | /* Support routines for the hash table used by section_already_linked, | 
 |    initialize the table, traverse, lookup, fill in an entry and remove | 
 |    the table.  */ | 
 |  | 
 | void | 
 | bfd_section_already_linked_table_traverse | 
 |   (bool (*func) (struct bfd_section_already_linked_hash_entry *, void *), | 
 |    void *info) | 
 | { | 
 |   bfd_hash_traverse (&_bfd_section_already_linked_table, | 
 | 		     (bool (*) (struct bfd_hash_entry *, void *)) func, | 
 | 		     info); | 
 | } | 
 |  | 
 | struct bfd_section_already_linked_hash_entry * | 
 | bfd_section_already_linked_table_lookup (const char *name) | 
 | { | 
 |   return ((struct bfd_section_already_linked_hash_entry *) | 
 | 	  bfd_hash_lookup (&_bfd_section_already_linked_table, name, | 
 | 			   true, false)); | 
 | } | 
 |  | 
 | bool | 
 | bfd_section_already_linked_table_insert | 
 |   (struct bfd_section_already_linked_hash_entry *already_linked_list, | 
 |    asection *sec) | 
 | { | 
 |   struct bfd_section_already_linked *l; | 
 |  | 
 |   /* Allocate the memory from the same obstack as the hash table is | 
 |      kept in.  */ | 
 |   l = (struct bfd_section_already_linked *) | 
 |       bfd_hash_allocate (&_bfd_section_already_linked_table, sizeof *l); | 
 |   if (l == NULL) | 
 |     return false; | 
 |   l->sec = sec; | 
 |   l->next = already_linked_list->entry; | 
 |   already_linked_list->entry = l; | 
 |   return true; | 
 | } | 
 |  | 
 | static struct bfd_hash_entry * | 
 | already_linked_newfunc (struct bfd_hash_entry *entry ATTRIBUTE_UNUSED, | 
 | 			struct bfd_hash_table *table, | 
 | 			const char *string ATTRIBUTE_UNUSED) | 
 | { | 
 |   struct bfd_section_already_linked_hash_entry *ret = | 
 |     (struct bfd_section_already_linked_hash_entry *) | 
 |       bfd_hash_allocate (table, sizeof *ret); | 
 |  | 
 |   if (ret == NULL) | 
 |     return NULL; | 
 |  | 
 |   ret->entry = NULL; | 
 |  | 
 |   return &ret->root; | 
 | } | 
 |  | 
 | bool | 
 | bfd_section_already_linked_table_init (void) | 
 | { | 
 |   return bfd_hash_table_init_n (&_bfd_section_already_linked_table, | 
 | 				already_linked_newfunc, | 
 | 				sizeof (struct bfd_section_already_linked_hash_entry), | 
 | 				42); | 
 | } | 
 |  | 
 | void | 
 | bfd_section_already_linked_table_free (void) | 
 | { | 
 |   bfd_hash_table_free (&_bfd_section_already_linked_table); | 
 | } | 
 |  | 
 | /* Report warnings as appropriate for duplicate section SEC. | 
 |    Return FALSE if we decide to keep SEC after all.  */ | 
 |  | 
 | bool | 
 | _bfd_handle_already_linked (asection *sec, | 
 | 			    struct bfd_section_already_linked *l, | 
 | 			    struct bfd_link_info *info) | 
 | { | 
 |   switch (sec->flags & SEC_LINK_DUPLICATES) | 
 |     { | 
 |     default: | 
 |       abort (); | 
 |  | 
 |     case SEC_LINK_DUPLICATES_DISCARD: | 
 |       /* If we found an LTO IR match for this comdat group on | 
 | 	 the first pass, replace it with the LTO output on the | 
 | 	 second pass.  We can't simply choose real object | 
 | 	 files over IR because the first pass may contain a | 
 | 	 mix of LTO and normal objects and we must keep the | 
 | 	 first match, be it IR or real.  */ | 
 |       if (sec->owner->lto_output | 
 | 	  && (l->sec->owner->flags & BFD_PLUGIN) != 0) | 
 | 	{ | 
 | 	  l->sec = sec; | 
 | 	  return false; | 
 | 	} | 
 |       break; | 
 |  | 
 |     case SEC_LINK_DUPLICATES_ONE_ONLY: | 
 |       info->callbacks->einfo | 
 | 	/* xgettext:c-format */ | 
 | 	(_("%pB: ignoring duplicate section `%pA'\n"), | 
 | 	 sec->owner, sec); | 
 |       break; | 
 |  | 
 |     case SEC_LINK_DUPLICATES_SAME_SIZE: | 
 |       if ((l->sec->owner->flags & BFD_PLUGIN) != 0) | 
 | 	; | 
 |       else if (sec->size != l->sec->size) | 
 | 	info->callbacks->einfo | 
 | 	  /* xgettext:c-format */ | 
 | 	  (_("%pB: duplicate section `%pA' has different size\n"), | 
 | 	   sec->owner, sec); | 
 |       break; | 
 |  | 
 |     case SEC_LINK_DUPLICATES_SAME_CONTENTS: | 
 |       if ((l->sec->owner->flags & BFD_PLUGIN) != 0) | 
 | 	; | 
 |       else if (sec->size != l->sec->size) | 
 | 	info->callbacks->einfo | 
 | 	  /* xgettext:c-format */ | 
 | 	  (_("%pB: duplicate section `%pA' has different size\n"), | 
 | 	   sec->owner, sec); | 
 |       else if (sec->size != 0) | 
 | 	{ | 
 | 	  bfd_byte *sec_contents, *l_sec_contents; | 
 |  | 
 | 	  if ((sec->flags & SEC_HAS_CONTENTS) == 0 | 
 | 	      && (l->sec->flags & SEC_HAS_CONTENTS) == 0) | 
 | 	    ; | 
 | 	  else if ((sec->flags & SEC_HAS_CONTENTS) == 0 | 
 | 		   || !bfd_malloc_and_get_section (sec->owner, sec, | 
 | 						   &sec_contents)) | 
 | 	    info->callbacks->einfo | 
 | 	      /* xgettext:c-format */ | 
 | 	      (_("%pB: could not read contents of section `%pA'\n"), | 
 | 	       sec->owner, sec); | 
 | 	  else if ((l->sec->flags & SEC_HAS_CONTENTS) == 0 | 
 | 		   || !bfd_malloc_and_get_section (l->sec->owner, l->sec, | 
 | 						   &l_sec_contents)) | 
 | 	    { | 
 | 	      info->callbacks->einfo | 
 | 		/* xgettext:c-format */ | 
 | 		(_("%pB: could not read contents of section `%pA'\n"), | 
 | 		 l->sec->owner, l->sec); | 
 | 	      free (sec_contents); | 
 | 	    } | 
 | 	  else | 
 | 	    { | 
 | 	      if (memcmp (sec_contents, l_sec_contents, sec->size) != 0) | 
 | 		info->callbacks->einfo | 
 | 		  /* xgettext:c-format */ | 
 | 		  (_("%pB: duplicate section `%pA' has different contents\n"), | 
 | 		   sec->owner, sec); | 
 | 	      free (l_sec_contents); | 
 | 	      free (sec_contents); | 
 | 	    } | 
 | 	} | 
 |       break; | 
 |     } | 
 |  | 
 |   /* Set the output_section field so that lang_add_section | 
 |      does not create a lang_input_section structure for this | 
 |      section.  Since there might be a symbol in the section | 
 |      being discarded, we must retain a pointer to the section | 
 |      which we are really going to use.  */ | 
 |   sec->output_section = bfd_abs_section_ptr; | 
 |   sec->kept_section = l->sec; | 
 |   return true; | 
 | } | 
 |  | 
 | /* This is used on non-ELF inputs.  */ | 
 |  | 
 | bool | 
 | _bfd_generic_section_already_linked (bfd *abfd ATTRIBUTE_UNUSED, | 
 | 				     asection *sec, | 
 | 				     struct bfd_link_info *info) | 
 | { | 
 |   const char *name; | 
 |   struct bfd_section_already_linked *l; | 
 |   struct bfd_section_already_linked_hash_entry *already_linked_list; | 
 |  | 
 |   if ((sec->flags & SEC_LINK_ONCE) == 0) | 
 |     return false; | 
 |  | 
 |   /* The generic linker doesn't handle section groups.  */ | 
 |   if ((sec->flags & SEC_GROUP) != 0) | 
 |     return false; | 
 |  | 
 |   /* FIXME: When doing a relocatable link, we may have trouble | 
 |      copying relocations in other sections that refer to local symbols | 
 |      in the section being discarded.  Those relocations will have to | 
 |      be converted somehow; as of this writing I'm not sure that any of | 
 |      the backends handle that correctly. | 
 |  | 
 |      It is tempting to instead not discard link once sections when | 
 |      doing a relocatable link (technically, they should be discarded | 
 |      whenever we are building constructors).  However, that fails, | 
 |      because the linker winds up combining all the link once sections | 
 |      into a single large link once section, which defeats the purpose | 
 |      of having link once sections in the first place.  */ | 
 |  | 
 |   name = bfd_section_name (sec); | 
 |  | 
 |   already_linked_list = bfd_section_already_linked_table_lookup (name); | 
 |   if (!already_linked_list) | 
 |     goto bad; | 
 |  | 
 |   l = already_linked_list->entry; | 
 |   if (l != NULL) | 
 |     { | 
 |       /* The section has already been linked.  See if we should | 
 | 	 issue a warning.  */ | 
 |       return _bfd_handle_already_linked (sec, l, info); | 
 |     } | 
 |  | 
 |   /* This is the first section with this name.  Record it.  */ | 
 |   if (!bfd_section_already_linked_table_insert (already_linked_list, sec)) | 
 |     { | 
 |     bad: | 
 |       info->callbacks->fatal (_("%P: already_linked_table: %E\n")); | 
 |     } | 
 |   return false; | 
 | } | 
 |  | 
 | /* Choose a neighbouring section to S in OBFD that will be output, or | 
 |    the absolute section if ADDR is out of bounds of the neighbours.  */ | 
 |  | 
 | asection * | 
 | _bfd_nearby_section (bfd *obfd, asection *s, bfd_vma addr) | 
 | { | 
 |   asection *next, *prev, *best; | 
 |  | 
 |   /* Find preceding kept section.  */ | 
 |   for (prev = s->prev; prev != NULL; prev = prev->prev) | 
 |     if ((prev->flags & SEC_EXCLUDE) == 0 | 
 | 	&& !bfd_section_removed_from_list (obfd, prev)) | 
 |       break; | 
 |  | 
 |   /* Find following kept section.  Start at prev->next because | 
 |      other sections may have been added after S was removed.  */ | 
 |   if (s->prev != NULL) | 
 |     next = s->prev->next; | 
 |   else | 
 |     next = s->owner->sections; | 
 |   for (; next != NULL; next = next->next) | 
 |     if ((next->flags & SEC_EXCLUDE) == 0 | 
 | 	&& !bfd_section_removed_from_list (obfd, next)) | 
 |       break; | 
 |  | 
 |   /* Choose better of two sections, based on flags.  The idea | 
 |      is to choose a section that will be in the same segment | 
 |      as S would have been if it was kept.  */ | 
 |   best = next; | 
 |   if (prev == NULL) | 
 |     { | 
 |       if (next == NULL) | 
 | 	best = bfd_abs_section_ptr; | 
 |     } | 
 |   else if (next == NULL) | 
 |     best = prev; | 
 |   else if (((prev->flags ^ next->flags) | 
 | 	    & (SEC_ALLOC | SEC_THREAD_LOCAL | SEC_LOAD)) != 0) | 
 |     { | 
 |       if (((next->flags ^ s->flags) | 
 | 	   & (SEC_ALLOC | SEC_THREAD_LOCAL)) != 0 | 
 | 	  /* We prefer to choose a loaded section.  Section S | 
 | 	     doesn't have SEC_LOAD set (it being excluded, that | 
 | 	     part of the flag processing didn't happen) so we | 
 | 	     can't compare that flag to those of NEXT and PREV.  */ | 
 | 	  || ((prev->flags & SEC_LOAD) != 0 | 
 | 	      && (next->flags & SEC_LOAD) == 0)) | 
 | 	best = prev; | 
 |     } | 
 |   else if (((prev->flags ^ next->flags) & SEC_READONLY) != 0) | 
 |     { | 
 |       if (((next->flags ^ s->flags) & SEC_READONLY) != 0) | 
 | 	best = prev; | 
 |     } | 
 |   else if (((prev->flags ^ next->flags) & SEC_CODE) != 0) | 
 |     { | 
 |       if (((next->flags ^ s->flags) & SEC_CODE) != 0) | 
 | 	best = prev; | 
 |     } | 
 |   else | 
 |     { | 
 |       /* Flags we care about are the same.  Prefer the following | 
 | 	 section if that will result in a positive valued sym.  */ | 
 |       if (addr < next->vma) | 
 | 	best = prev; | 
 |     } | 
 |  | 
 |   return best; | 
 | } | 
 |  | 
 | /* Convert symbols in excluded output sections to use a kept section.  */ | 
 |  | 
 | static bool | 
 | fix_syms (struct bfd_link_hash_entry *h, void *data) | 
 | { | 
 |   bfd *obfd = (bfd *) data; | 
 |  | 
 |   if (h->type == bfd_link_hash_defined | 
 |       || h->type == bfd_link_hash_defweak) | 
 |     { | 
 |       asection *s = h->u.def.section; | 
 |       if (s != NULL | 
 | 	  && s->output_section != NULL | 
 | 	  && (s->output_section->flags & SEC_EXCLUDE) != 0 | 
 | 	  && bfd_section_removed_from_list (obfd, s->output_section)) | 
 | 	{ | 
 | 	  asection *op; | 
 |  | 
 | 	  h->u.def.value += s->output_offset + s->output_section->vma; | 
 | 	  op = _bfd_nearby_section (obfd, s->output_section, h->u.def.value); | 
 | 	  h->u.def.value -= op->vma; | 
 | 	  h->u.def.section = op; | 
 | 	} | 
 |     } | 
 |  | 
 |   return true; | 
 | } | 
 |  | 
 | void | 
 | _bfd_fix_excluded_sec_syms (bfd *obfd, struct bfd_link_info *info) | 
 | { | 
 |   bfd_link_hash_traverse (info->hash, fix_syms, obfd); | 
 | } | 
 |  | 
 | /* | 
 | FUNCTION | 
 | 	bfd_generic_define_common_symbol | 
 |  | 
 | SYNOPSIS | 
 | 	bool bfd_generic_define_common_symbol | 
 | 	  (bfd *output_bfd, struct bfd_link_info *info, | 
 | 	   struct bfd_link_hash_entry *h); | 
 |  | 
 | DESCRIPTION | 
 | 	Convert common symbol @var{h} into a defined symbol. | 
 | 	Return TRUE on success and FALSE on failure. | 
 |  | 
 | .#define bfd_define_common_symbol(output_bfd, info, h) \ | 
 | .	BFD_SEND (output_bfd, _bfd_define_common_symbol, (output_bfd, info, h)) | 
 | . | 
 | */ | 
 |  | 
 | bool | 
 | bfd_generic_define_common_symbol (bfd *output_bfd, | 
 | 				  struct bfd_link_info *info ATTRIBUTE_UNUSED, | 
 | 				  struct bfd_link_hash_entry *h) | 
 | { | 
 |   unsigned int power_of_two; | 
 |   bfd_vma alignment, size; | 
 |   asection *section; | 
 |  | 
 |   BFD_ASSERT (h != NULL && h->type == bfd_link_hash_common); | 
 |  | 
 |   size = h->u.c.size; | 
 |   power_of_two = h->u.c.p->alignment_power; | 
 |   section = h->u.c.p->section; | 
 |  | 
 |   /* Increase the size of the section to align the common symbol. | 
 |      The alignment must be a power of two.  But if the section does | 
 |      not have any alignment requirement then do not increase the | 
 |      alignment unnecessarily.  */ | 
 |   if (power_of_two) | 
 |     alignment = bfd_octets_per_byte (output_bfd, section) << power_of_two; | 
 |   else | 
 |     alignment = 1; | 
 |   BFD_ASSERT (alignment != 0 && (alignment & -alignment) == alignment); | 
 |   section->size += alignment - 1; | 
 |   section->size &= -alignment; | 
 |  | 
 |   /* Adjust the section's overall alignment if necessary.  */ | 
 |   if (power_of_two > section->alignment_power) | 
 |     section->alignment_power = power_of_two; | 
 |  | 
 |   /* Change the symbol from common to defined.  */ | 
 |   h->type = bfd_link_hash_defined; | 
 |   h->u.def.section = section; | 
 |   h->u.def.value = section->size; | 
 |  | 
 |   /* Increase the size of the section.  */ | 
 |   section->size += size; | 
 |  | 
 |   /* Make sure the section is allocated in memory, and make sure that | 
 |      it is no longer a common section.  */ | 
 |   section->flags |= SEC_ALLOC; | 
 |   section->flags &= ~(SEC_IS_COMMON | SEC_HAS_CONTENTS); | 
 |   return true; | 
 | } | 
 |  | 
 | /* | 
 | FUNCTION | 
 | 	_bfd_generic_link_hide_symbol | 
 |  | 
 | SYNOPSIS | 
 | 	void _bfd_generic_link_hide_symbol | 
 | 	  (bfd *output_bfd, struct bfd_link_info *info, | 
 | 	   struct bfd_link_hash_entry *h); | 
 |  | 
 | DESCRIPTION | 
 | 	Hide symbol @var{h}. | 
 | 	This is an internal function.  It should not be called from | 
 | 	outside the BFD library. | 
 |  | 
 | .#define bfd_link_hide_symbol(output_bfd, info, h) \ | 
 | .	BFD_SEND (output_bfd, _bfd_link_hide_symbol, (output_bfd, info, h)) | 
 | . | 
 | */ | 
 |  | 
 | void | 
 | _bfd_generic_link_hide_symbol (bfd *output_bfd ATTRIBUTE_UNUSED, | 
 | 			       struct bfd_link_info *info ATTRIBUTE_UNUSED, | 
 | 			       struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED) | 
 | { | 
 | } | 
 |  | 
 | /* | 
 | FUNCTION | 
 | 	bfd_generic_define_start_stop | 
 |  | 
 | SYNOPSIS | 
 | 	struct bfd_link_hash_entry *bfd_generic_define_start_stop | 
 | 	  (struct bfd_link_info *info, | 
 | 	   const char *symbol, asection *sec); | 
 |  | 
 | DESCRIPTION | 
 | 	Define a __start, __stop, .startof. or .sizeof. symbol. | 
 | 	Return the symbol or NULL if no such undefined symbol exists. | 
 |  | 
 | .#define bfd_define_start_stop(output_bfd, info, symbol, sec) \ | 
 | .	BFD_SEND (output_bfd, _bfd_define_start_stop, (info, symbol, sec)) | 
 | . | 
 | */ | 
 |  | 
 | struct bfd_link_hash_entry * | 
 | bfd_generic_define_start_stop (struct bfd_link_info *info, | 
 | 			       const char *symbol, asection *sec) | 
 | { | 
 |   struct bfd_link_hash_entry *h; | 
 |  | 
 |   h = bfd_link_hash_lookup (info->hash, symbol, false, false, true); | 
 |   if (h != NULL | 
 |       && !h->ldscript_def | 
 |       && (h->type == bfd_link_hash_undefined | 
 | 	  || h->type == bfd_link_hash_undefweak)) | 
 |     { | 
 |       h->type = bfd_link_hash_defined; | 
 |       h->u.def.section = sec; | 
 |       h->u.def.value = 0; | 
 |       return h; | 
 |     } | 
 |   return NULL; | 
 | } | 
 |  | 
 | /* | 
 | FUNCTION | 
 | 	bfd_find_version_for_sym | 
 |  | 
 | SYNOPSIS | 
 | 	struct bfd_elf_version_tree * bfd_find_version_for_sym | 
 | 	  (struct bfd_elf_version_tree *verdefs, | 
 | 	   const char *sym_name, bool *hide); | 
 |  | 
 | DESCRIPTION | 
 | 	Search an elf version script tree for symbol versioning | 
 | 	info and export / don't-export status for a given symbol. | 
 | 	Return non-NULL on success and NULL on failure; also sets | 
 | 	the output @samp{hide} boolean parameter. | 
 |  | 
 | */ | 
 |  | 
 | struct bfd_elf_version_tree * | 
 | bfd_find_version_for_sym (struct bfd_elf_version_tree *verdefs, | 
 | 			  const char *sym_name, | 
 | 			  bool *hide) | 
 | { | 
 |   struct bfd_elf_version_tree *t; | 
 |   struct bfd_elf_version_tree *local_ver, *global_ver, *exist_ver; | 
 |   struct bfd_elf_version_tree *star_local_ver, *star_global_ver; | 
 |  | 
 |   local_ver = NULL; | 
 |   global_ver = NULL; | 
 |   star_local_ver = NULL; | 
 |   star_global_ver = NULL; | 
 |   exist_ver = NULL; | 
 |   for (t = verdefs; t != NULL; t = t->next) | 
 |     { | 
 |       if (t->globals.list != NULL) | 
 | 	{ | 
 | 	  struct bfd_elf_version_expr *d = NULL; | 
 |  | 
 | 	  while ((d = (*t->match) (&t->globals, d, sym_name)) != NULL) | 
 | 	    { | 
 | 	      if (d->literal || strcmp (d->pattern, "*") != 0) | 
 | 		global_ver = t; | 
 | 	      else | 
 | 		star_global_ver = t; | 
 | 	      if (d->symver) | 
 | 		exist_ver = t; | 
 | 	      d->script = 1; | 
 | 	      /* If the match is a wildcard pattern, keep looking for | 
 | 		 a more explicit, perhaps even local, match.  */ | 
 | 	      if (d->literal) | 
 | 		break; | 
 | 	    } | 
 |  | 
 | 	  if (d != NULL) | 
 | 	    break; | 
 | 	} | 
 |  | 
 |       if (t->locals.list != NULL) | 
 | 	{ | 
 | 	  struct bfd_elf_version_expr *d = NULL; | 
 |  | 
 | 	  while ((d = (*t->match) (&t->locals, d, sym_name)) != NULL) | 
 | 	    { | 
 | 	      if (d->literal || strcmp (d->pattern, "*") != 0) | 
 | 		local_ver = t; | 
 | 	      else | 
 | 		star_local_ver = t; | 
 | 	      /* If the match is a wildcard pattern, keep looking for | 
 | 		 a more explicit, perhaps even global, match.  */ | 
 | 	      if (d->literal) | 
 | 		{ | 
 | 		  /* An exact match overrides a global wildcard.  */ | 
 | 		  global_ver = NULL; | 
 | 		  star_global_ver = NULL; | 
 | 		  break; | 
 | 		} | 
 | 	    } | 
 |  | 
 | 	  if (d != NULL) | 
 | 	    break; | 
 | 	} | 
 |     } | 
 |  | 
 |   if (global_ver == NULL && local_ver == NULL) | 
 |     global_ver = star_global_ver; | 
 |  | 
 |   if (global_ver != NULL) | 
 |     { | 
 |       /* If we already have a versioned symbol that matches the | 
 | 	 node for this symbol, then we don't want to create a | 
 | 	 duplicate from the unversioned symbol.  Instead hide the | 
 | 	 unversioned symbol.  */ | 
 |       *hide = exist_ver == global_ver; | 
 |       return global_ver; | 
 |     } | 
 |  | 
 |   if (local_ver == NULL) | 
 |     local_ver = star_local_ver; | 
 |  | 
 |   if (local_ver != NULL) | 
 |     { | 
 |       *hide = true; | 
 |       return local_ver; | 
 |     } | 
 |  | 
 |   return NULL; | 
 | } | 
 |  | 
 | /* | 
 | FUNCTION | 
 | 	bfd_hide_sym_by_version | 
 |  | 
 | SYNOPSIS | 
 | 	bool bfd_hide_sym_by_version | 
 | 	  (struct bfd_elf_version_tree *verdefs, const char *sym_name); | 
 |  | 
 | DESCRIPTION | 
 | 	Search an elf version script tree for symbol versioning | 
 | 	info for a given symbol.  Return TRUE if the symbol is hidden. | 
 |  | 
 | */ | 
 |  | 
 | bool | 
 | bfd_hide_sym_by_version (struct bfd_elf_version_tree *verdefs, | 
 | 			 const char *sym_name) | 
 | { | 
 |   bool hidden = false; | 
 |   bfd_find_version_for_sym (verdefs, sym_name, &hidden); | 
 |   return hidden; | 
 | } | 
 |  | 
 | /* | 
 | FUNCTION | 
 | 	bfd_link_check_relocs | 
 |  | 
 | SYNOPSIS | 
 | 	bool bfd_link_check_relocs | 
 | 	  (bfd *abfd, struct bfd_link_info *info); | 
 |  | 
 | DESCRIPTION | 
 | 	Checks the relocs in ABFD for validity. | 
 | 	Does not execute the relocs. | 
 | 	Return TRUE if everything is OK, FALSE otherwise. | 
 | 	This is the external entry point to this code. | 
 | */ | 
 |  | 
 | bool | 
 | bfd_link_check_relocs (bfd *abfd, struct bfd_link_info *info) | 
 | { | 
 |   return BFD_SEND (abfd, _bfd_link_check_relocs, (abfd, info)); | 
 | } | 
 |  | 
 | /* | 
 | FUNCTION | 
 | 	_bfd_generic_link_check_relocs | 
 |  | 
 | SYNOPSIS | 
 | 	bool _bfd_generic_link_check_relocs | 
 | 	  (bfd *abfd, struct bfd_link_info *info); | 
 |  | 
 | DESCRIPTION | 
 | 	Stub function for targets that do not implement reloc checking. | 
 | 	Return TRUE. | 
 | 	This is an internal function.  It should not be called from | 
 | 	outside the BFD library. | 
 | */ | 
 |  | 
 | bool | 
 | _bfd_generic_link_check_relocs (bfd *abfd ATTRIBUTE_UNUSED, | 
 | 				struct bfd_link_info *info ATTRIBUTE_UNUSED) | 
 | { | 
 |   return true; | 
 | } | 
 |  | 
 | /* | 
 | FUNCTION | 
 | 	bfd_merge_private_bfd_data | 
 |  | 
 | SYNOPSIS | 
 | 	bool bfd_merge_private_bfd_data | 
 | 	  (bfd *ibfd, struct bfd_link_info *info); | 
 |  | 
 | DESCRIPTION | 
 | 	Merge private BFD information from the BFD @var{ibfd} to the | 
 | 	the output file BFD when linking.  Return <<TRUE>> on success, | 
 | 	<<FALSE>> on error.  Possible error returns are: | 
 |  | 
 | 	o <<bfd_error_no_memory>> - | 
 | 	Not enough memory exists to create private data for @var{obfd}. | 
 |  | 
 | .#define bfd_merge_private_bfd_data(ibfd, info) \ | 
 | .	BFD_SEND ((info)->output_bfd, _bfd_merge_private_bfd_data, \ | 
 | .		  (ibfd, info)) | 
 | . | 
 | */ | 
 |  | 
 | /* | 
 | INTERNAL_FUNCTION | 
 | 	_bfd_generic_verify_endian_match | 
 |  | 
 | SYNOPSIS | 
 | 	bool _bfd_generic_verify_endian_match | 
 | 	  (bfd *ibfd, struct bfd_link_info *info); | 
 |  | 
 | DESCRIPTION | 
 | 	Can be used from / for bfd_merge_private_bfd_data to check that | 
 | 	endianness matches between input and output file.  Returns | 
 | 	TRUE for a match, otherwise returns FALSE and emits an error. | 
 | */ | 
 |  | 
 | bool | 
 | _bfd_generic_verify_endian_match (bfd *ibfd, struct bfd_link_info *info) | 
 | { | 
 |   bfd *obfd = info->output_bfd; | 
 |  | 
 |   if (ibfd->xvec->byteorder != obfd->xvec->byteorder | 
 |       && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN | 
 |       && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN) | 
 |     { | 
 |       if (bfd_big_endian (ibfd)) | 
 | 	_bfd_error_handler (_("%pB: compiled for a big endian system " | 
 | 			      "and target is little endian"), ibfd); | 
 |       else | 
 | 	_bfd_error_handler (_("%pB: compiled for a little endian system " | 
 | 			      "and target is big endian"), ibfd); | 
 |       bfd_set_error (bfd_error_wrong_format); | 
 |       return false; | 
 |     } | 
 |  | 
 |   return true; | 
 | } | 
 |  | 
 | int | 
 | _bfd_nolink_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED, | 
 | 			    struct bfd_link_info *info ATTRIBUTE_UNUSED) | 
 | { | 
 |   return 0; | 
 | } | 
 |  | 
 | bool | 
 | _bfd_nolink_bfd_relax_section (bfd *abfd, | 
 | 			       asection *section ATTRIBUTE_UNUSED, | 
 | 			       struct bfd_link_info *link_info ATTRIBUTE_UNUSED, | 
 | 			       bool *again ATTRIBUTE_UNUSED) | 
 | { | 
 |   return _bfd_bool_bfd_false_error (abfd); | 
 | } | 
 |  | 
 | bfd_byte * | 
 | _bfd_nolink_bfd_get_relocated_section_contents | 
 |     (bfd *abfd, | 
 |      struct bfd_link_info *link_info ATTRIBUTE_UNUSED, | 
 |      struct bfd_link_order *link_order ATTRIBUTE_UNUSED, | 
 |      bfd_byte *data ATTRIBUTE_UNUSED, | 
 |      bool relocatable ATTRIBUTE_UNUSED, | 
 |      asymbol **symbols ATTRIBUTE_UNUSED) | 
 | { | 
 |   return (bfd_byte *) _bfd_ptr_bfd_null_error (abfd); | 
 | } | 
 |  | 
 | bool | 
 | _bfd_nolink_bfd_lookup_section_flags | 
 |     (struct bfd_link_info *info ATTRIBUTE_UNUSED, | 
 |      struct flag_info *flaginfo ATTRIBUTE_UNUSED, | 
 |      asection *section) | 
 | { | 
 |   return _bfd_bool_bfd_false_error (section->owner); | 
 | } | 
 |  | 
 | bool | 
 | _bfd_nolink_bfd_is_group_section (bfd *abfd, | 
 | 				  const asection *sec ATTRIBUTE_UNUSED) | 
 | { | 
 |   return _bfd_bool_bfd_false_error (abfd); | 
 | } | 
 |  | 
 | const char * | 
 | _bfd_nolink_bfd_group_name (bfd *abfd, | 
 | 			    const asection *sec ATTRIBUTE_UNUSED) | 
 | { | 
 |   return _bfd_ptr_bfd_null_error (abfd); | 
 | } | 
 |  | 
 | bool | 
 | _bfd_nolink_bfd_discard_group (bfd *abfd, asection *sec ATTRIBUTE_UNUSED) | 
 | { | 
 |   return _bfd_bool_bfd_false_error (abfd); | 
 | } | 
 |  | 
 | struct bfd_link_hash_table * | 
 | _bfd_nolink_bfd_link_hash_table_create (bfd *abfd) | 
 | { | 
 |   return (struct bfd_link_hash_table *) _bfd_ptr_bfd_null_error (abfd); | 
 | } | 
 |  | 
 | void | 
 | _bfd_nolink_bfd_link_just_syms (asection *sec ATTRIBUTE_UNUSED, | 
 | 				struct bfd_link_info *info ATTRIBUTE_UNUSED) | 
 | { | 
 | } | 
 |  | 
 | void | 
 | _bfd_nolink_bfd_copy_link_hash_symbol_type | 
 |     (bfd *abfd ATTRIBUTE_UNUSED, | 
 |      struct bfd_link_hash_entry *from ATTRIBUTE_UNUSED, | 
 |      struct bfd_link_hash_entry *to ATTRIBUTE_UNUSED) | 
 | { | 
 | } | 
 |  | 
 | bool | 
 | _bfd_nolink_bfd_link_split_section (bfd *abfd, asection *sec ATTRIBUTE_UNUSED) | 
 | { | 
 |   return _bfd_bool_bfd_false_error (abfd); | 
 | } | 
 |  | 
 | bool | 
 | _bfd_nolink_section_already_linked (bfd *abfd, | 
 | 				    asection *sec ATTRIBUTE_UNUSED, | 
 | 				    struct bfd_link_info *info ATTRIBUTE_UNUSED) | 
 | { | 
 |   return _bfd_bool_bfd_false_error (abfd); | 
 | } | 
 |  | 
 | bool | 
 | _bfd_nolink_bfd_define_common_symbol | 
 |     (bfd *abfd, | 
 |      struct bfd_link_info *info ATTRIBUTE_UNUSED, | 
 |      struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED) | 
 | { | 
 |   return _bfd_bool_bfd_false_error (abfd); | 
 | } | 
 |  | 
 | struct bfd_link_hash_entry * | 
 | _bfd_nolink_bfd_define_start_stop (struct bfd_link_info *info ATTRIBUTE_UNUSED, | 
 | 				   const char *name ATTRIBUTE_UNUSED, | 
 | 				   asection *sec) | 
 | { | 
 |   return (struct bfd_link_hash_entry *) _bfd_ptr_bfd_null_error (sec->owner); | 
 | } |