133965Sjdp/* Support for the generic parts of most COFF variants, for BFD.
278828Sobrien   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3218822Sdim   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
438889Sjdp   Free Software Foundation, Inc.
533965Sjdp   Written by Cygnus Support.
633965Sjdp
7130561Sobrien   This file is part of BFD, the Binary File Descriptor library.
833965Sjdp
9130561Sobrien   This program is free software; you can redistribute it and/or modify
10130561Sobrien   it under the terms of the GNU General Public License as published by
11130561Sobrien   the Free Software Foundation; either version 2 of the License, or
12130561Sobrien   (at your option) any later version.
1333965Sjdp
14130561Sobrien   This program is distributed in the hope that it will be useful,
15130561Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
16130561Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17130561Sobrien   GNU General Public License for more details.
1833965Sjdp
19130561Sobrien   You should have received a copy of the GNU General Public License
20130561Sobrien   along with this program; if not, write to the Free Software
21218822Sdim   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
2233965Sjdp
23218822Sdim/* Most of this hacked by  Steve Chamberlain,
24218822Sdim			sac@cygnus.com.  */
2533965Sjdp/*
2633965SjdpSECTION
2733965Sjdp	coff backends
2833965Sjdp
2933965Sjdp	BFD supports a number of different flavours of coff format.
3033965Sjdp	The major differences between formats are the sizes and
3133965Sjdp	alignments of fields in structures on disk, and the occasional
3233965Sjdp	extra field.
3333965Sjdp
3433965Sjdp	Coff in all its varieties is implemented with a few common
3533965Sjdp	files and a number of implementation specific files. For
3633965Sjdp	example, The 88k bcs coff format is implemented in the file
3733965Sjdp	@file{coff-m88k.c}. This file @code{#include}s
3833965Sjdp	@file{coff/m88k.h} which defines the external structure of the
3933965Sjdp	coff format for the 88k, and @file{coff/internal.h} which
4033965Sjdp	defines the internal structure. @file{coff-m88k.c} also
4133965Sjdp	defines the relocations used by the 88k format
4233965Sjdp	@xref{Relocations}.
4333965Sjdp
4433965Sjdp	The Intel i960 processor version of coff is implemented in
4533965Sjdp	@file{coff-i960.c}. This file has the same structure as
4633965Sjdp	@file{coff-m88k.c}, except that it includes @file{coff/i960.h}
4733965Sjdp	rather than @file{coff-m88k.h}.
4833965Sjdp
4933965SjdpSUBSECTION
5033965Sjdp	Porting to a new version of coff
5133965Sjdp
5233965Sjdp	The recommended method is to select from the existing
5333965Sjdp	implementations the version of coff which is most like the one
5433965Sjdp	you want to use.  For example, we'll say that i386 coff is
5533965Sjdp	the one you select, and that your coff flavour is called foo.
5633965Sjdp	Copy @file{i386coff.c} to @file{foocoff.c}, copy
5733965Sjdp	@file{../include/coff/i386.h} to @file{../include/coff/foo.h},
5833965Sjdp	and add the lines to @file{targets.c} and @file{Makefile.in}
5933965Sjdp	so that your new back end is used. Alter the shapes of the
6033965Sjdp	structures in @file{../include/coff/foo.h} so that they match
6133965Sjdp	what you need. You will probably also have to add
6233965Sjdp	@code{#ifdef}s to the code in @file{coff/internal.h} and
6333965Sjdp	@file{coffcode.h} if your version of coff is too wild.
6433965Sjdp
6533965Sjdp	You can verify that your new BFD backend works quite simply by
6633965Sjdp	building @file{objdump} from the @file{binutils} directory,
6733965Sjdp	and making sure that its version of what's going on and your
6833965Sjdp	host system's idea (assuming it has the pretty standard coff
6933965Sjdp	dump utility, usually called @code{att-dump} or just
7033965Sjdp	@code{dump}) are the same.  Then clean up your code, and send
7133965Sjdp	what you've done to Cygnus. Then your stuff will be in the
7233965Sjdp	next release, and you won't have to keep integrating it.
7333965Sjdp
7433965SjdpSUBSECTION
7533965Sjdp	How the coff backend works
7633965Sjdp
7733965SjdpSUBSUBSECTION
7833965Sjdp	File layout
7933965Sjdp
8033965Sjdp	The Coff backend is split into generic routines that are
8133965Sjdp	applicable to any Coff target and routines that are specific
8233965Sjdp	to a particular target.  The target-specific routines are
8333965Sjdp	further split into ones which are basically the same for all
8433965Sjdp	Coff targets except that they use the external symbol format
8533965Sjdp	or use different values for certain constants.
8633965Sjdp
8733965Sjdp	The generic routines are in @file{coffgen.c}.  These routines
8833965Sjdp	work for any Coff target.  They use some hooks into the target
8933965Sjdp	specific code; the hooks are in a @code{bfd_coff_backend_data}
9033965Sjdp	structure, one of which exists for each target.
9133965Sjdp
9233965Sjdp	The essentially similar target-specific routines are in
9333965Sjdp	@file{coffcode.h}.  This header file includes executable C code.
9433965Sjdp	The various Coff targets first include the appropriate Coff
9533965Sjdp	header file, make any special defines that are needed, and
9633965Sjdp	then include @file{coffcode.h}.
9733965Sjdp
9833965Sjdp	Some of the Coff targets then also have additional routines in
9933965Sjdp	the target source file itself.
10033965Sjdp
10133965Sjdp	For example, @file{coff-i960.c} includes
10233965Sjdp	@file{coff/internal.h} and @file{coff/i960.h}.  It then
10333965Sjdp	defines a few constants, such as @code{I960}, and includes
10433965Sjdp	@file{coffcode.h}.  Since the i960 has complex relocation
10533965Sjdp	types, @file{coff-i960.c} also includes some code to
10633965Sjdp	manipulate the i960 relocs.  This code is not in
10733965Sjdp	@file{coffcode.h} because it would not be used by any other
10833965Sjdp	target.
10933965Sjdp
11033965SjdpSUBSUBSECTION
11133965Sjdp	Bit twiddling
11233965Sjdp
11333965Sjdp	Each flavour of coff supported in BFD has its own header file
11433965Sjdp	describing the external layout of the structures. There is also
11533965Sjdp	an internal description of the coff layout, in
11633965Sjdp	@file{coff/internal.h}. A major function of the
11733965Sjdp	coff backend is swapping the bytes and twiddling the bits to
11833965Sjdp	translate the external form of the structures into the normal
11933965Sjdp	internal form. This is all performed in the
12033965Sjdp	@code{bfd_swap}_@i{thing}_@i{direction} routines. Some
12133965Sjdp	elements are different sizes between different versions of
12233965Sjdp	coff; it is the duty of the coff version specific include file
12333965Sjdp	to override the definitions of various packing routines in
12433965Sjdp	@file{coffcode.h}. E.g., the size of line number entry in coff is
12533965Sjdp	sometimes 16 bits, and sometimes 32 bits. @code{#define}ing
12633965Sjdp	@code{PUT_LNSZ_LNNO} and @code{GET_LNSZ_LNNO} will select the
12733965Sjdp	correct one. No doubt, some day someone will find a version of
12833965Sjdp	coff which has a varying field size not catered to at the
12933965Sjdp	moment. To port BFD, that person will have to add more @code{#defines}.
13033965Sjdp	Three of the bit twiddling routines are exported to
13133965Sjdp	@code{gdb}; @code{coff_swap_aux_in}, @code{coff_swap_sym_in}
13260484Sobrien	and @code{coff_swap_lineno_in}. @code{GDB} reads the symbol
13333965Sjdp	table on its own, but uses BFD to fix things up.  More of the
13433965Sjdp	bit twiddlers are exported for @code{gas};
13533965Sjdp	@code{coff_swap_aux_out}, @code{coff_swap_sym_out},
13633965Sjdp	@code{coff_swap_lineno_out}, @code{coff_swap_reloc_out},
13733965Sjdp	@code{coff_swap_filehdr_out}, @code{coff_swap_aouthdr_out},
13833965Sjdp	@code{coff_swap_scnhdr_out}. @code{Gas} currently keeps track
13933965Sjdp	of all the symbol table and reloc drudgery itself, thereby
14033965Sjdp	saving the internal BFD overhead, but uses BFD to swap things
14133965Sjdp	on the way out, making cross ports much safer.  Doing so also
14233965Sjdp	allows BFD (and thus the linker) to use the same header files
14333965Sjdp	as @code{gas}, which makes one avenue to disaster disappear.
14433965Sjdp
14533965SjdpSUBSUBSECTION
14633965Sjdp	Symbol reading
14733965Sjdp
14833965Sjdp	The simple canonical form for symbols used by BFD is not rich
14933965Sjdp	enough to keep all the information available in a coff symbol
15033965Sjdp	table. The back end gets around this problem by keeping the original
15133965Sjdp	symbol table around, "behind the scenes".
15233965Sjdp
15333965Sjdp	When a symbol table is requested (through a call to
15433965Sjdp	@code{bfd_canonicalize_symtab}), a request gets through to
15533965Sjdp	@code{coff_get_normalized_symtab}. This reads the symbol table from
15633965Sjdp	the coff file and swaps all the structures inside into the
15733965Sjdp	internal form. It also fixes up all the pointers in the table
15833965Sjdp	(represented in the file by offsets from the first symbol in
15933965Sjdp	the table) into physical pointers to elements in the new
16033965Sjdp	internal table. This involves some work since the meanings of
16133965Sjdp	fields change depending upon context: a field that is a
16233965Sjdp	pointer to another structure in the symbol table at one moment
16333965Sjdp	may be the size in bytes of a structure at the next.  Another
16433965Sjdp	pass is made over the table. All symbols which mark file names
16533965Sjdp	(<<C_FILE>> symbols) are modified so that the internal
16633965Sjdp	string points to the value in the auxent (the real filename)
16733965Sjdp	rather than the normal text associated with the symbol
16833965Sjdp	(@code{".file"}).
16933965Sjdp
17033965Sjdp	At this time the symbol names are moved around. Coff stores
17133965Sjdp	all symbols less than nine characters long physically
17233965Sjdp	within the symbol table; longer strings are kept at the end of
17333965Sjdp	the file in the string 	table. This pass moves all strings
17433965Sjdp	into memory and replaces them with pointers to the strings.
17533965Sjdp
17633965Sjdp	The symbol table is massaged once again, this time to create
17733965Sjdp	the canonical table used by the BFD application. Each symbol
17833965Sjdp	is inspected in turn, and a decision made (using the
17933965Sjdp	@code{sclass} field) about the various flags to set in the
18033965Sjdp	@code{asymbol}.  @xref{Symbols}. The generated canonical table
18133965Sjdp	shares strings with the hidden internal symbol table.
18233965Sjdp
18333965Sjdp	Any linenumbers are read from the coff file too, and attached
18433965Sjdp	to the symbols which own the functions the linenumbers belong to.
18533965Sjdp
18633965SjdpSUBSUBSECTION
18733965Sjdp	Symbol writing
18833965Sjdp
18933965Sjdp	Writing a symbol to a coff file which didn't come from a coff
19033965Sjdp	file will lose any debugging information. The @code{asymbol}
19133965Sjdp	structure remembers the BFD from which the symbol was taken, and on
19233965Sjdp	output the back end makes sure that the same destination target as
19333965Sjdp	source target is present.
19433965Sjdp
19533965Sjdp	When the symbols have come from a coff file then all the
19633965Sjdp	debugging information is preserved.
19733965Sjdp
19833965Sjdp	Symbol tables are provided for writing to the back end in a
19933965Sjdp	vector of pointers to pointers. This allows applications like
20033965Sjdp	the linker to accumulate and output large symbol tables
20133965Sjdp	without having to do too much byte copying.
20233965Sjdp
20333965Sjdp	This function runs through the provided symbol table and
20433965Sjdp	patches each symbol marked as a file place holder
20533965Sjdp	(@code{C_FILE}) to point to the next file place holder in the
20633965Sjdp	list. It also marks each @code{offset} field in the list with
20733965Sjdp	the offset from the first symbol of the current symbol.
20833965Sjdp
20933965Sjdp	Another function of this procedure is to turn the canonical
21033965Sjdp	value form of BFD into the form used by coff. Internally, BFD
21133965Sjdp	expects symbol values to be offsets from a section base; so a
21233965Sjdp	symbol physically at 0x120, but in a section starting at
21333965Sjdp	0x100, would have the value 0x20. Coff expects symbols to
21433965Sjdp	contain their final value, so symbols have their values
21533965Sjdp	changed at this point to reflect their sum with their owning
21633965Sjdp	section.  This transformation uses the
21733965Sjdp	<<output_section>> field of the @code{asymbol}'s
21833965Sjdp	@code{asection} @xref{Sections}.
21933965Sjdp
22033965Sjdp	o <<coff_mangle_symbols>>
22133965Sjdp
22233965Sjdp	This routine runs though the provided symbol table and uses
22333965Sjdp	the offsets generated by the previous pass and the pointers
22433965Sjdp	generated when the symbol table was read in to create the
225130561Sobrien	structured hierarchy required by coff. It changes each pointer
22633965Sjdp	to a symbol into the index into the symbol table of the asymbol.
22733965Sjdp
22833965Sjdp	o <<coff_write_symbols>>
22933965Sjdp
23033965Sjdp	This routine runs through the symbol table and patches up the
23133965Sjdp	symbols from their internal form into the coff way, calls the
23233965Sjdp	bit twiddlers, and writes out the table to the file.
23333965Sjdp
23433965Sjdp*/
23533965Sjdp
23633965Sjdp/*
23733965SjdpINTERNAL_DEFINITION
23833965Sjdp	coff_symbol_type
23933965Sjdp
24033965SjdpDESCRIPTION
24133965Sjdp	The hidden information for an <<asymbol>> is described in a
24233965Sjdp	<<combined_entry_type>>:
24333965Sjdp
24433965SjdpCODE_FRAGMENT
24533965Sjdp.
24633965Sjdp.typedef struct coff_ptr_struct
24733965Sjdp.{
24889857Sobrien.  {* Remembers the offset from the first symbol in the file for
24989857Sobrien.     this symbol. Generated by coff_renumber_symbols. *}
25089857Sobrien.  unsigned int offset;
25133965Sjdp.
25289857Sobrien.  {* Should the value of this symbol be renumbered.  Used for
25389857Sobrien.     XCOFF C_BSTAT symbols.  Set by coff_slurp_symbol_table.  *}
25489857Sobrien.  unsigned int fix_value : 1;
25533965Sjdp.
25689857Sobrien.  {* Should the tag field of this symbol be renumbered.
25789857Sobrien.     Created by coff_pointerize_aux. *}
25889857Sobrien.  unsigned int fix_tag : 1;
25933965Sjdp.
26089857Sobrien.  {* Should the endidx field of this symbol be renumbered.
26189857Sobrien.     Created by coff_pointerize_aux. *}
26289857Sobrien.  unsigned int fix_end : 1;
26333965Sjdp.
26489857Sobrien.  {* Should the x_csect.x_scnlen field be renumbered.
26589857Sobrien.     Created by coff_pointerize_aux. *}
26689857Sobrien.  unsigned int fix_scnlen : 1;
26733965Sjdp.
26889857Sobrien.  {* Fix up an XCOFF C_BINCL/C_EINCL symbol.  The value is the
26989857Sobrien.     index into the line number entries.  Set by coff_slurp_symbol_table.  *}
27089857Sobrien.  unsigned int fix_line : 1;
27133965Sjdp.
27289857Sobrien.  {* The container for the symbol structure as read and translated
27389857Sobrien.     from the file. *}
27489857Sobrien.  union
27589857Sobrien.  {
27689857Sobrien.    union internal_auxent auxent;
27789857Sobrien.    struct internal_syment syment;
27889857Sobrien.  } u;
27933965Sjdp.} combined_entry_type;
28033965Sjdp.
28133965Sjdp.
28233965Sjdp.{* Each canonical asymbol really looks like this: *}
28333965Sjdp.
28433965Sjdp.typedef struct coff_symbol_struct
28533965Sjdp.{
28689857Sobrien.  {* The actual symbol which the rest of BFD works with *}
28789857Sobrien.  asymbol symbol;
28833965Sjdp.
28989857Sobrien.  {* A pointer to the hidden information for this symbol *}
29089857Sobrien.  combined_entry_type *native;
29133965Sjdp.
29289857Sobrien.  {* A pointer to the linenumber information for this symbol *}
29389857Sobrien.  struct lineno_cache_entry *lineno;
29433965Sjdp.
29589857Sobrien.  {* Have the line numbers been relocated yet ? *}
296130561Sobrien.  bfd_boolean done_lineno;
29733965Sjdp.} coff_symbol_type;
29833965Sjdp
29933965Sjdp*/
30033965Sjdp
30133965Sjdp#ifdef COFF_WITH_PE
30233965Sjdp#include "peicode.h"
30333965Sjdp#else
30433965Sjdp#include "coffswap.h"
30533965Sjdp#endif
30633965Sjdp
307218822Sdim#define STRING_SIZE_SIZE 4
30833965Sjdp
309218822Sdim#define DOT_DEBUG	".debug"
310218822Sdim#define GNU_LINKONCE_WI ".gnu.linkonce.wi."
311218822Sdim
312130561Sobrienstatic long sec_to_styp_flags
313218822Sdim  (const char *, flagword);
314130561Sobrienstatic bfd_boolean styp_to_sec_flags
315218822Sdim  (bfd *, void *, const char *, asection *, flagword *);
316130561Sobrienstatic bfd_boolean coff_bad_format_hook
317218822Sdim  (bfd *, void *);
31860484Sobrienstatic void coff_set_custom_section_alignment
319218822Sdim  (bfd *, asection *, const struct coff_section_alignment_entry *,
320218822Sdim   const unsigned int);
321130561Sobrienstatic bfd_boolean coff_new_section_hook
322218822Sdim  (bfd *, asection *);
323130561Sobrienstatic bfd_boolean coff_set_arch_mach_hook
324218822Sdim  (bfd *, void *);
325130561Sobrienstatic bfd_boolean coff_write_relocs
326218822Sdim  (bfd *, int);
327130561Sobrienstatic bfd_boolean coff_set_flags
328218822Sdim  (bfd *, unsigned int *, unsigned short *);
329130561Sobrienstatic bfd_boolean coff_set_arch_mach
330218822Sdim  (bfd *, enum bfd_architecture, unsigned long) ATTRIBUTE_UNUSED;
331130561Sobrienstatic bfd_boolean coff_compute_section_file_positions
332218822Sdim  (bfd *);
333130561Sobrienstatic bfd_boolean coff_write_object_contents
334218822Sdim  (bfd *) ATTRIBUTE_UNUSED;
335130561Sobrienstatic bfd_boolean coff_set_section_contents
336218822Sdim  (bfd *, asection *, const void *, file_ptr, bfd_size_type);
337218822Sdimstatic void * buy_and_read
338218822Sdim  (bfd *, file_ptr, bfd_size_type);
339130561Sobrienstatic bfd_boolean coff_slurp_line_table
340218822Sdim  (bfd *, asection *);
341130561Sobrienstatic bfd_boolean coff_slurp_symbol_table
342218822Sdim  (bfd *);
34360484Sobrienstatic enum coff_symbol_classification coff_classify_symbol
344218822Sdim  (bfd *, struct internal_syment *);
345130561Sobrienstatic bfd_boolean coff_slurp_reloc_table
346218822Sdim  (bfd *, asection *, asymbol **);
34733965Sjdpstatic long coff_canonicalize_reloc
348218822Sdim  (bfd *, asection *, arelent **, asymbol **);
34933965Sjdp#ifndef coff_mkobject_hook
350218822Sdimstatic void * coff_mkobject_hook
351218822Sdim  (bfd *, void *,  void *);
35233965Sjdp#endif
35378828Sobrien#ifdef COFF_WITH_PE
354130561Sobrienstatic flagword handle_COMDAT
355218822Sdim  (bfd *, flagword, void *, const char *, asection *);
35678828Sobrien#endif
357104834Sobrien#ifdef COFF_IMAGE_WITH_PE
358130561Sobrienstatic bfd_boolean coff_read_word
359218822Sdim  (bfd *, unsigned int *);
360130561Sobrienstatic unsigned int coff_compute_checksum
361218822Sdim  (bfd *);
362130561Sobrienstatic bfd_boolean coff_apply_checksum
363218822Sdim  (bfd *);
364104834Sobrien#endif
365130561Sobrien#ifdef TICOFF
366130561Sobrienstatic bfd_boolean ticoff0_bad_format_hook
367218822Sdim  (bfd *, void * );
368130561Sobrienstatic bfd_boolean ticoff1_bad_format_hook
369218822Sdim  (bfd *, void * );
370130561Sobrien#endif
37133965Sjdp
37233965Sjdp/* void warning(); */
37333965Sjdp
37460484Sobrien/* Return a word with STYP_* (scnhdr.s_flags) flags set to represent
37560484Sobrien   the incoming SEC_* flags.  The inverse of this function is
37660484Sobrien   styp_to_sec_flags().  NOTE: If you add to/change this routine, you
37760484Sobrien   should probably mirror the changes in styp_to_sec_flags().  */
37860484Sobrien
37960484Sobrien#ifndef COFF_WITH_PE
38060484Sobrien
38177298Sobrien/* Macros for setting debugging flags.  */
382218822Sdim
38377298Sobrien#ifdef STYP_DEBUG
38477298Sobrien#define STYP_XCOFF_DEBUG STYP_DEBUG
38577298Sobrien#else
38677298Sobrien#define STYP_XCOFF_DEBUG STYP_INFO
38777298Sobrien#endif
38877298Sobrien
38977298Sobrien#ifdef COFF_ALIGN_IN_S_FLAGS
39077298Sobrien#define STYP_DEBUG_INFO STYP_DSECT
39177298Sobrien#else
39277298Sobrien#define STYP_DEBUG_INFO STYP_INFO
39377298Sobrien#endif
39477298Sobrien
39533965Sjdpstatic long
396218822Sdimsec_to_styp_flags (const char *sec_name, flagword sec_flags)
39733965Sjdp{
39833965Sjdp  long styp_flags = 0;
39933965Sjdp
40033965Sjdp  if (!strcmp (sec_name, _TEXT))
40133965Sjdp    {
40233965Sjdp      styp_flags = STYP_TEXT;
40333965Sjdp    }
40433965Sjdp  else if (!strcmp (sec_name, _DATA))
40533965Sjdp    {
40633965Sjdp      styp_flags = STYP_DATA;
40733965Sjdp    }
40833965Sjdp  else if (!strcmp (sec_name, _BSS))
40933965Sjdp    {
41033965Sjdp      styp_flags = STYP_BSS;
41133965Sjdp#ifdef _COMMENT
41233965Sjdp    }
41333965Sjdp  else if (!strcmp (sec_name, _COMMENT))
41433965Sjdp    {
41533965Sjdp      styp_flags = STYP_INFO;
41633965Sjdp#endif /* _COMMENT */
41733965Sjdp#ifdef _LIB
41833965Sjdp    }
41933965Sjdp  else if (!strcmp (sec_name, _LIB))
42033965Sjdp    {
42133965Sjdp      styp_flags = STYP_LIB;
42233965Sjdp#endif /* _LIB */
42333965Sjdp#ifdef _LIT
42433965Sjdp    }
42533965Sjdp  else if (!strcmp (sec_name, _LIT))
42633965Sjdp    {
42733965Sjdp      styp_flags = STYP_LIT;
42833965Sjdp#endif /* _LIT */
42933965Sjdp    }
430218822Sdim  else if (CONST_STRNEQ (sec_name, DOT_DEBUG))
43133965Sjdp    {
43277298Sobrien      /* Handle the XCOFF debug section and DWARF2 debug sections.  */
43377298Sobrien      if (!sec_name[6])
43477298Sobrien        styp_flags = STYP_XCOFF_DEBUG;
43577298Sobrien      else
43677298Sobrien        styp_flags = STYP_DEBUG_INFO;
43733965Sjdp    }
438218822Sdim  else if (CONST_STRNEQ (sec_name, ".stab"))
43933965Sjdp    {
44077298Sobrien      styp_flags = STYP_DEBUG_INFO;
44133965Sjdp    }
44277298Sobrien#ifdef COFF_LONG_SECTION_NAMES
443218822Sdim  else if (CONST_STRNEQ (sec_name, GNU_LINKONCE_WI))
44477298Sobrien    {
44577298Sobrien      styp_flags = STYP_DEBUG_INFO;
44677298Sobrien    }
44777298Sobrien#endif
44833965Sjdp#ifdef RS6000COFF_C
44933965Sjdp  else if (!strcmp (sec_name, _PAD))
45033965Sjdp    {
45133965Sjdp      styp_flags = STYP_PAD;
45233965Sjdp    }
45333965Sjdp  else if (!strcmp (sec_name, _LOADER))
45433965Sjdp    {
45533965Sjdp      styp_flags = STYP_LOADER;
45633965Sjdp    }
45789857Sobrien  else if (!strcmp (sec_name, _EXCEPT))
45889857Sobrien    {
45989857Sobrien      styp_flags = STYP_EXCEPT;
46089857Sobrien    }
46189857Sobrien  else if (!strcmp (sec_name, _TYPCHK))
46289857Sobrien    {
46389857Sobrien      styp_flags = STYP_TYPCHK;
46489857Sobrien    }
46533965Sjdp#endif
46633965Sjdp  /* Try and figure out what it should be */
46733965Sjdp  else if (sec_flags & SEC_CODE)
46833965Sjdp    {
46933965Sjdp      styp_flags = STYP_TEXT;
47033965Sjdp    }
47133965Sjdp  else if (sec_flags & SEC_DATA)
47233965Sjdp    {
47333965Sjdp      styp_flags = STYP_DATA;
47433965Sjdp    }
47533965Sjdp  else if (sec_flags & SEC_READONLY)
47633965Sjdp    {
47733965Sjdp#ifdef STYP_LIT			/* 29k readonly text/data section */
47833965Sjdp      styp_flags = STYP_LIT;
47933965Sjdp#else
48033965Sjdp      styp_flags = STYP_TEXT;
48133965Sjdp#endif /* STYP_LIT */
48233965Sjdp    }
48333965Sjdp  else if (sec_flags & SEC_LOAD)
48433965Sjdp    {
48533965Sjdp      styp_flags = STYP_TEXT;
48633965Sjdp    }
48733965Sjdp  else if (sec_flags & SEC_ALLOC)
48833965Sjdp    {
48933965Sjdp      styp_flags = STYP_BSS;
49033965Sjdp    }
49133965Sjdp
49277298Sobrien#ifdef STYP_CLINK
493218822Sdim  if (sec_flags & SEC_TIC54X_CLINK)
49477298Sobrien    styp_flags |= STYP_CLINK;
49577298Sobrien#endif
49677298Sobrien
49777298Sobrien#ifdef STYP_BLOCK
498218822Sdim  if (sec_flags & SEC_TIC54X_BLOCK)
49977298Sobrien    styp_flags |= STYP_BLOCK;
50077298Sobrien#endif
50177298Sobrien
50233965Sjdp#ifdef STYP_NOLOAD
50333965Sjdp  if ((sec_flags & (SEC_NEVER_LOAD | SEC_COFF_SHARED_LIBRARY)) != 0)
50433965Sjdp    styp_flags |= STYP_NOLOAD;
50533965Sjdp#endif
50633965Sjdp
50760484Sobrien  return styp_flags;
50860484Sobrien}
50960484Sobrien
51060484Sobrien#else /* COFF_WITH_PE */
51160484Sobrien
51260484Sobrien/* The PE version; see above for the general comments.  The non-PE
51360484Sobrien   case seems to be more guessing, and breaks PE format; specifically,
51460484Sobrien   .rdata is readonly, but it sure ain't text.  Really, all this
51560484Sobrien   should be set up properly in gas (or whatever assembler is in use),
51660484Sobrien   and honor whatever objcopy/strip, etc. sent us as input.  */
51760484Sobrien
51860484Sobrienstatic long
519218822Sdimsec_to_styp_flags (const char *sec_name, flagword sec_flags)
52060484Sobrien{
52160484Sobrien  long styp_flags = 0;
52260484Sobrien
52360484Sobrien  /* caution: there are at least three groups of symbols that have
52460484Sobrien     very similar bits and meanings: IMAGE_SCN*, SEC_*, and STYP_*.
52560484Sobrien     SEC_* are the BFD internal flags, used for generic BFD
52660484Sobrien     information.  STYP_* are the COFF section flags which appear in
52760484Sobrien     COFF files.  IMAGE_SCN_* are the PE section flags which appear in
52860484Sobrien     PE files.  The STYP_* flags and the IMAGE_SCN_* flags overlap,
52960484Sobrien     but there are more IMAGE_SCN_* flags.  */
53060484Sobrien
531218822Sdim  /* FIXME: There is no gas syntax to specify the debug section flag.  */
532218822Sdim  if (CONST_STRNEQ (sec_name, DOT_DEBUG)
533218822Sdim      || CONST_STRNEQ (sec_name, GNU_LINKONCE_WI))
534218822Sdim    sec_flags = SEC_DEBUGGING;
535218822Sdim
53660484Sobrien  /* skip LOAD */
53760484Sobrien  /* READONLY later */
53860484Sobrien  /* skip RELOC */
53960484Sobrien  if ((sec_flags & SEC_CODE) != 0)
54060484Sobrien    styp_flags |= IMAGE_SCN_CNT_CODE;
54160484Sobrien  if ((sec_flags & SEC_DATA) != 0)
54260484Sobrien    styp_flags |= IMAGE_SCN_CNT_INITIALIZED_DATA;
54360484Sobrien  if ((sec_flags & SEC_ALLOC) != 0 && (sec_flags & SEC_LOAD) == 0)
54460484Sobrien    styp_flags |= IMAGE_SCN_CNT_UNINITIALIZED_DATA;  /* ==STYP_BSS */
54560484Sobrien  /* skip ROM */
54689857Sobrien  /* skip constRUCTOR */
54760484Sobrien  /* skip CONTENTS */
54860484Sobrien  if ((sec_flags & SEC_IS_COMMON) != 0)
54933965Sjdp    styp_flags |= IMAGE_SCN_LNK_COMDAT;
55060484Sobrien  if ((sec_flags & SEC_DEBUGGING) != 0)
55160484Sobrien    styp_flags |= IMAGE_SCN_MEM_DISCARDABLE;
55260484Sobrien  if ((sec_flags & SEC_EXCLUDE) != 0)
55360484Sobrien    styp_flags |= IMAGE_SCN_LNK_REMOVE;
55460484Sobrien  if ((sec_flags & SEC_NEVER_LOAD) != 0)
55560484Sobrien    styp_flags |= IMAGE_SCN_LNK_REMOVE;
55660484Sobrien  /* skip IN_MEMORY */
55760484Sobrien  /* skip SORT */
55877298Sobrien  if (sec_flags & SEC_LINK_ONCE)
55977298Sobrien    styp_flags |= IMAGE_SCN_LNK_COMDAT;
56060484Sobrien  /* skip LINK_DUPLICATES */
56160484Sobrien  /* skip LINKER_CREATED */
56233965Sjdp
563218822Sdim  if (sec_flags & (SEC_ALLOC | SEC_LOAD))
564218822Sdim    {
565218822Sdim      /* For now, the read/write bits are mapped onto SEC_READONLY, even
566218822Sdim	 though the semantics don't quite match.  The bits from the input
567218822Sdim	 are retained in pei_section_data(abfd, section)->pe_flags.  */
568218822Sdim      styp_flags |= IMAGE_SCN_MEM_READ;       /* Always readable.  */
569218822Sdim      if ((sec_flags & SEC_READONLY) == 0)
570218822Sdim	styp_flags |= IMAGE_SCN_MEM_WRITE;    /* Invert READONLY for write.  */
571218822Sdim      if (sec_flags & SEC_CODE)
572218822Sdim	styp_flags |= IMAGE_SCN_MEM_EXECUTE;  /* CODE->EXECUTE.  */
573218822Sdim      if (sec_flags & SEC_COFF_SHARED)
574218822Sdim	styp_flags |= IMAGE_SCN_MEM_SHARED;   /* Shared remains meaningful.  */
575218822Sdim    }
57660484Sobrien
57777298Sobrien  return styp_flags;
57833965Sjdp}
57960484Sobrien
58060484Sobrien#endif /* COFF_WITH_PE */
58160484Sobrien
58260484Sobrien/* Return a word with SEC_* flags set to represent the incoming STYP_*
58360484Sobrien   flags (from scnhdr.s_flags).  The inverse of this function is
58460484Sobrien   sec_to_styp_flags().  NOTE: If you add to/change this routine, you
58560484Sobrien   should probably mirror the changes in sec_to_styp_flags().  */
58660484Sobrien
58760484Sobrien#ifndef COFF_WITH_PE
58860484Sobrien
589130561Sobrienstatic bfd_boolean
590218822Sdimstyp_to_sec_flags (bfd *abfd ATTRIBUTE_UNUSED,
591218822Sdim		   void * hdr,
592218822Sdim		   const char *name,
593218822Sdim		   asection *section ATTRIBUTE_UNUSED,
594218822Sdim		   flagword *flags_ptr)
59533965Sjdp{
59633965Sjdp  struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
59733965Sjdp  long styp_flags = internal_s->s_flags;
59833965Sjdp  flagword sec_flags = 0;
59933965Sjdp
60077298Sobrien#ifdef STYP_BLOCK
60177298Sobrien  if (styp_flags & STYP_BLOCK)
602218822Sdim    sec_flags |= SEC_TIC54X_BLOCK;
60377298Sobrien#endif
60477298Sobrien
60577298Sobrien#ifdef STYP_CLINK
60677298Sobrien  if (styp_flags & STYP_CLINK)
607218822Sdim    sec_flags |= SEC_TIC54X_CLINK;
60877298Sobrien#endif
60977298Sobrien
61033965Sjdp#ifdef STYP_NOLOAD
61133965Sjdp  if (styp_flags & STYP_NOLOAD)
61289857Sobrien    sec_flags |= SEC_NEVER_LOAD;
61333965Sjdp#endif /* STYP_NOLOAD */
61433965Sjdp
61533965Sjdp  /* For 386 COFF, at least, an unloadable text or data section is
61633965Sjdp     actually a shared library section.  */
61733965Sjdp  if (styp_flags & STYP_TEXT)
61833965Sjdp    {
61933965Sjdp      if (sec_flags & SEC_NEVER_LOAD)
62033965Sjdp	sec_flags |= SEC_CODE | SEC_COFF_SHARED_LIBRARY;
62133965Sjdp      else
62233965Sjdp	sec_flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC;
62333965Sjdp    }
62433965Sjdp  else if (styp_flags & STYP_DATA)
62533965Sjdp    {
62633965Sjdp      if (sec_flags & SEC_NEVER_LOAD)
62733965Sjdp	sec_flags |= SEC_DATA | SEC_COFF_SHARED_LIBRARY;
62833965Sjdp      else
62933965Sjdp	sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC;
63033965Sjdp    }
63133965Sjdp  else if (styp_flags & STYP_BSS)
63233965Sjdp    {
63333965Sjdp#ifdef BSS_NOLOAD_IS_SHARED_LIBRARY
63433965Sjdp      if (sec_flags & SEC_NEVER_LOAD)
63533965Sjdp	sec_flags |= SEC_ALLOC | SEC_COFF_SHARED_LIBRARY;
63633965Sjdp      else
63733965Sjdp#endif
63833965Sjdp	sec_flags |= SEC_ALLOC;
63933965Sjdp    }
64033965Sjdp  else if (styp_flags & STYP_INFO)
64133965Sjdp    {
64233965Sjdp      /* We mark these as SEC_DEBUGGING, but only if COFF_PAGE_SIZE is
64333965Sjdp	 defined.  coff_compute_section_file_positions uses
64433965Sjdp	 COFF_PAGE_SIZE to ensure that the low order bits of the
64533965Sjdp	 section VMA and the file offset match.  If we don't know
64633965Sjdp	 COFF_PAGE_SIZE, we can't ensure the correct correspondence,
64733965Sjdp	 and demand page loading of the file will fail.  */
64838889Sjdp#if defined (COFF_PAGE_SIZE) && !defined (COFF_ALIGN_IN_S_FLAGS)
64933965Sjdp      sec_flags |= SEC_DEBUGGING;
65033965Sjdp#endif
65133965Sjdp    }
65233965Sjdp  else if (styp_flags & STYP_PAD)
65389857Sobrien    sec_flags = 0;
65433965Sjdp  else if (strcmp (name, _TEXT) == 0)
65533965Sjdp    {
65633965Sjdp      if (sec_flags & SEC_NEVER_LOAD)
65733965Sjdp	sec_flags |= SEC_CODE | SEC_COFF_SHARED_LIBRARY;
65833965Sjdp      else
65933965Sjdp	sec_flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC;
66033965Sjdp    }
66133965Sjdp  else if (strcmp (name, _DATA) == 0)
66233965Sjdp    {
66333965Sjdp      if (sec_flags & SEC_NEVER_LOAD)
66433965Sjdp	sec_flags |= SEC_DATA | SEC_COFF_SHARED_LIBRARY;
66533965Sjdp      else
66633965Sjdp	sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC;
66733965Sjdp    }
66833965Sjdp  else if (strcmp (name, _BSS) == 0)
66933965Sjdp    {
67033965Sjdp#ifdef BSS_NOLOAD_IS_SHARED_LIBRARY
67133965Sjdp      if (sec_flags & SEC_NEVER_LOAD)
67233965Sjdp	sec_flags |= SEC_ALLOC | SEC_COFF_SHARED_LIBRARY;
67333965Sjdp      else
67433965Sjdp#endif
67533965Sjdp	sec_flags |= SEC_ALLOC;
67633965Sjdp    }
677218822Sdim  else if (CONST_STRNEQ (name, DOT_DEBUG)
67833965Sjdp#ifdef _COMMENT
67933965Sjdp	   || strcmp (name, _COMMENT) == 0
68033965Sjdp#endif
68177298Sobrien#ifdef COFF_LONG_SECTION_NAMES
682218822Sdim	   || CONST_STRNEQ (name, GNU_LINKONCE_WI)
68377298Sobrien#endif
684218822Sdim	   || CONST_STRNEQ (name, ".stab"))
68533965Sjdp    {
68633965Sjdp#ifdef COFF_PAGE_SIZE
68733965Sjdp      sec_flags |= SEC_DEBUGGING;
68833965Sjdp#endif
68933965Sjdp    }
69033965Sjdp#ifdef _LIB
69133965Sjdp  else if (strcmp (name, _LIB) == 0)
69233965Sjdp    ;
69333965Sjdp#endif
69433965Sjdp#ifdef _LIT
69533965Sjdp  else if (strcmp (name, _LIT) == 0)
69689857Sobrien    sec_flags = SEC_LOAD | SEC_ALLOC | SEC_READONLY;
69733965Sjdp#endif
69833965Sjdp  else
69989857Sobrien    sec_flags |= SEC_ALLOC | SEC_LOAD;
70033965Sjdp
701130561Sobrien#ifdef STYP_LIT			/* A29k readonly text/data section type.  */
70233965Sjdp  if ((styp_flags & STYP_LIT) == STYP_LIT)
70389857Sobrien    sec_flags = (SEC_LOAD | SEC_ALLOC | SEC_READONLY);
70433965Sjdp#endif /* STYP_LIT */
70589857Sobrien
706130561Sobrien#ifdef STYP_OTHER_LOAD		/* Other loaded sections.  */
70733965Sjdp  if (styp_flags & STYP_OTHER_LOAD)
70889857Sobrien    sec_flags = (SEC_LOAD | SEC_ALLOC);
70933965Sjdp#endif /* STYP_SDATA */
71033965Sjdp
71160484Sobrien#if defined (COFF_LONG_SECTION_NAMES) && defined (COFF_SUPPORT_GNU_LINKONCE)
71260484Sobrien  /* As a GNU extension, if the name begins with .gnu.linkonce, we
71360484Sobrien     only link a single copy of the section.  This is used to support
71460484Sobrien     g++.  g++ will emit each template expansion in its own section.
71560484Sobrien     The symbols will be defined as weak, so that multiple definitions
71660484Sobrien     are permitted.  The GNU linker extension is to actually discard
71760484Sobrien     all but one of the sections.  */
718218822Sdim  if (CONST_STRNEQ (name, ".gnu.linkonce"))
71960484Sobrien    sec_flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
72060484Sobrien#endif
72160484Sobrien
72289857Sobrien  if (flags_ptr == NULL)
723130561Sobrien    return FALSE;
72489857Sobrien
72589857Sobrien  * flags_ptr = sec_flags;
726130561Sobrien  return TRUE;
72760484Sobrien}
72860484Sobrien
72960484Sobrien#else /* COFF_WITH_PE */
73060484Sobrien
73160484Sobrienstatic flagword
732218822Sdimhandle_COMDAT (bfd * abfd,
733218822Sdim	       flagword sec_flags,
734218822Sdim	       void * hdr,
735218822Sdim	       const char *name,
736218822Sdim	       asection *section)
73760484Sobrien{
73860484Sobrien  struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
73978828Sobrien  bfd_byte *esymstart, *esym, *esymend;
74078828Sobrien  int seen_state = 0;
74178828Sobrien  char *target_name = NULL;
74260484Sobrien
74378828Sobrien  sec_flags |= SEC_LINK_ONCE;
74433965Sjdp
74578828Sobrien  /* Unfortunately, the PE format stores essential information in
74678828Sobrien     the symbol table, of all places.  We need to extract that
74778828Sobrien     information now, so that objdump and the linker will know how
74878828Sobrien     to handle the section without worrying about the symbols.  We
74978828Sobrien     can't call slurp_symtab, because the linker doesn't want the
75078828Sobrien     swapped symbols.  */
75160484Sobrien
75278828Sobrien  /* COMDAT sections are special.  The first symbol is the section
75378828Sobrien     symbol, which tells what kind of COMDAT section it is.  The
75478828Sobrien     second symbol is the "comdat symbol" - the one with the
75578828Sobrien     unique name.  GNU uses the section symbol for the unique
75678828Sobrien     name; MS uses ".text" for every comdat section.  Sigh.  - DJ */
75760484Sobrien
75878828Sobrien  /* This is not mirrored in sec_to_styp_flags(), but there
75978828Sobrien     doesn't seem to be a need to, either, and it would at best be
76078828Sobrien     rather messy.  */
76160484Sobrien
76278828Sobrien  if (! _bfd_coff_get_external_symbols (abfd))
76378828Sobrien    return sec_flags;
76489857Sobrien
76578828Sobrien  esymstart = esym = (bfd_byte *) obj_coff_external_syms (abfd);
76678828Sobrien  esymend = esym + obj_raw_syment_count (abfd) * bfd_coff_symesz (abfd);
76778828Sobrien
76878828Sobrien  while (esym < esymend)
76933965Sjdp    {
77078828Sobrien      struct internal_syment isym;
77178828Sobrien      char buf[SYMNMLEN + 1];
77278828Sobrien      const char *symname;
77333965Sjdp
774218822Sdim      bfd_coff_swap_sym_in (abfd, esym, & isym);
77533965Sjdp
77678828Sobrien      if (sizeof (internal_s->s_name) > SYMNMLEN)
77778828Sobrien	{
77878828Sobrien	  /* This case implies that the matching
77978828Sobrien	     symbol name will be in the string table.  */
78078828Sobrien	  abort ();
78178828Sobrien	}
78260484Sobrien
78378828Sobrien      if (isym.n_scnum == section->target_index)
78433965Sjdp	{
78578828Sobrien	  /* According to the MSVC documentation, the first
78678828Sobrien	     TWO entries with the section # are both of
78778828Sobrien	     interest to us.  The first one is the "section
78878828Sobrien	     symbol" (section name).  The second is the comdat
78978828Sobrien	     symbol name.  Here, we've found the first
79078828Sobrien	     qualifying entry; we distinguish it from the
79178828Sobrien	     second with a state flag.
79233965Sjdp
79378828Sobrien	     In the case of gas-generated (at least until that
79478828Sobrien	     is fixed) .o files, it isn't necessarily the
79578828Sobrien	     second one.  It may be some other later symbol.
79633965Sjdp
79778828Sobrien	     Since gas also doesn't follow MS conventions and
79878828Sobrien	     emits the section similar to .text$<name>, where
79978828Sobrien	     <something> is the name we're looking for, we
80078828Sobrien	     distinguish the two as follows:
80133965Sjdp
80278828Sobrien	     If the section name is simply a section name (no
80378828Sobrien	     $) we presume it's MS-generated, and look at
80478828Sobrien	     precisely the second symbol for the comdat name.
80578828Sobrien	     If the section name has a $, we assume it's
80678828Sobrien	     gas-generated, and look for <something> (whatever
80778828Sobrien	     follows the $) as the comdat symbol.  */
80833965Sjdp
809130561Sobrien	  /* All 3 branches use this.  */
81078828Sobrien	  symname = _bfd_coff_internal_syment_name (abfd, &isym, buf);
81133965Sjdp
81278828Sobrien	  if (symname == NULL)
81378828Sobrien	    abort ();
81433965Sjdp
81578828Sobrien	  switch (seen_state)
81678828Sobrien	    {
81778828Sobrien	    case 0:
81878828Sobrien	      {
81978828Sobrien		/* The first time we've seen the symbol.  */
82078828Sobrien		union internal_auxent aux;
82160484Sobrien
82278828Sobrien		/* If it isn't the stuff we're expecting, die;
82378828Sobrien		   The MS documentation is vague, but it
82478828Sobrien		   appears that the second entry serves BOTH
82578828Sobrien		   as the comdat symbol and the defining
82678828Sobrien		   symbol record (either C_STAT or C_EXT,
82778828Sobrien		   possibly with an aux entry with debug
82878828Sobrien		   information if it's a function.)  It
82978828Sobrien		   appears the only way to find the second one
83078828Sobrien		   is to count.  (On Intel, they appear to be
83178828Sobrien		   adjacent, but on Alpha, they have been
83278828Sobrien		   found separated.)
83360484Sobrien
83478828Sobrien		   Here, we think we've found the first one,
83578828Sobrien		   but there's some checking we can do to be
83678828Sobrien		   sure.  */
83760484Sobrien
83878828Sobrien		if (! (isym.n_sclass == C_STAT
83978828Sobrien		       && isym.n_type == T_NULL
84078828Sobrien		       && isym.n_value == 0))
84178828Sobrien		  abort ();
84233965Sjdp
84378828Sobrien		/* FIXME LATER: MSVC generates section names
84478828Sobrien		   like .text for comdats.  Gas generates
84578828Sobrien		   names like .text$foo__Fv (in the case of a
84678828Sobrien		   function).  See comment above for more.  */
84733965Sjdp
84878828Sobrien		if (strcmp (name, symname) != 0)
849218822Sdim		  _bfd_error_handler (_("%B: warning: COMDAT symbol '%s' does not match section name '%s'"),
850218822Sdim				      abfd, symname, name);
85133965Sjdp
852218822Sdim		seen_state = 1;
853218822Sdim
85478828Sobrien		/* This is the section symbol.  */
855218822Sdim		bfd_coff_swap_aux_in (abfd, (esym + bfd_coff_symesz (abfd)),
85678828Sobrien				      isym.n_type, isym.n_sclass,
857218822Sdim				      0, isym.n_numaux, & aux);
85833965Sjdp
85978828Sobrien		target_name = strchr (name, '$');
86078828Sobrien		if (target_name != NULL)
86178828Sobrien		  {
86278828Sobrien		    /* Gas mode.  */
86378828Sobrien		    seen_state = 2;
86478828Sobrien		    /* Skip the `$'.  */
86578828Sobrien		    target_name += 1;
86678828Sobrien		  }
86733965Sjdp
86878828Sobrien		/* FIXME: Microsoft uses NODUPLICATES and
86978828Sobrien		   ASSOCIATIVE, but gnu uses ANY and
87078828Sobrien		   SAME_SIZE.  Unfortunately, gnu doesn't do
87178828Sobrien		   the comdat symbols right.  So, until we can
87278828Sobrien		   fix it to do the right thing, we are
87378828Sobrien		   temporarily disabling comdats for the MS
87478828Sobrien		   types (they're used in DLLs and C++, but we
87578828Sobrien		   don't support *their* C++ libraries anyway
87678828Sobrien		   - DJ.  */
87733965Sjdp
87878828Sobrien		/* Cygwin does not follow the MS style, and
87978828Sobrien		   uses ANY and SAME_SIZE where NODUPLICATES
88078828Sobrien		   and ASSOCIATIVE should be used.  For
88178828Sobrien		   Interix, we just do the right thing up
88278828Sobrien		   front.  */
88333965Sjdp
88478828Sobrien		switch (aux.x_scn.x_comdat)
88578828Sobrien		  {
88678828Sobrien		  case IMAGE_COMDAT_SELECT_NODUPLICATES:
88777298Sobrien#ifdef STRICT_PE_FORMAT
88878828Sobrien		    sec_flags |= SEC_LINK_DUPLICATES_ONE_ONLY;
88960484Sobrien#else
89078828Sobrien		    sec_flags &= ~SEC_LINK_ONCE;
89160484Sobrien#endif
89278828Sobrien		    break;
89360484Sobrien
89478828Sobrien		  case IMAGE_COMDAT_SELECT_ANY:
89578828Sobrien		    sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
89678828Sobrien		    break;
89760484Sobrien
89878828Sobrien		  case IMAGE_COMDAT_SELECT_SAME_SIZE:
89978828Sobrien		    sec_flags |= SEC_LINK_DUPLICATES_SAME_SIZE;
90078828Sobrien		    break;
90160484Sobrien
90278828Sobrien		  case IMAGE_COMDAT_SELECT_EXACT_MATCH:
90378828Sobrien		    /* Not yet fully implemented ??? */
90478828Sobrien		    sec_flags |= SEC_LINK_DUPLICATES_SAME_CONTENTS;
90578828Sobrien		    break;
90660484Sobrien
90778828Sobrien		    /* debug$S gets this case; other
90878828Sobrien		       implications ??? */
90960484Sobrien
91078828Sobrien		    /* There may be no symbol... we'll search
91178828Sobrien		       the whole table... Is this the right
91278828Sobrien		       place to play this game? Or should we do
91378828Sobrien		       it when reading it in.  */
91478828Sobrien		  case IMAGE_COMDAT_SELECT_ASSOCIATIVE:
91560484Sobrien#ifdef STRICT_PE_FORMAT
91678828Sobrien		    /* FIXME: This is not currently implemented.  */
91778828Sobrien		    sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
91860484Sobrien#else
91978828Sobrien		    sec_flags &= ~SEC_LINK_ONCE;
92060484Sobrien#endif
92178828Sobrien		    break;
92260484Sobrien
92378828Sobrien		  default:  /* 0 means "no symbol" */
92478828Sobrien		    /* debug$F gets this case; other
92578828Sobrien		       implications ??? */
92678828Sobrien		    sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
92778828Sobrien		    break;
92878828Sobrien		  }
92978828Sobrien	      }
93078828Sobrien	      break;
93160484Sobrien
93278828Sobrien	    case 2:
93378828Sobrien	      /* Gas mode: the first matching on partial name.  */
93460484Sobrien
93560484Sobrien#ifndef TARGET_UNDERSCORE
93660484Sobrien#define TARGET_UNDERSCORE 0
93760484Sobrien#endif
938130561Sobrien	      /* Is this the name we're looking for ?  */
93978828Sobrien	      if (strcmp (target_name,
94078828Sobrien			  symname + (TARGET_UNDERSCORE ? 1 : 0)) != 0)
94178828Sobrien		{
94278828Sobrien		  /* Not the name we're looking for */
94378828Sobrien		  esym += (isym.n_numaux + 1) * bfd_coff_symesz (abfd);
94478828Sobrien		  continue;
94578828Sobrien		}
94678828Sobrien	      /* Fall through.  */
94778828Sobrien	    case 1:
94878828Sobrien	      /* MSVC mode: the lexically second symbol (or
94978828Sobrien		 drop through from the above).  */
95078828Sobrien	      {
95178828Sobrien		char *newname;
95289857Sobrien		bfd_size_type amt;
95333965Sjdp
95489857Sobrien		/* This must the second symbol with the
95578828Sobrien		   section #.  It is the actual symbol name.
95678828Sobrien		   Intel puts the two adjacent, but Alpha (at
95778828Sobrien		   least) spreads them out.  */
95860484Sobrien
959218822Sdim		amt = sizeof (struct coff_comdat_info);
960218822Sdim		coff_section_data (abfd, section)->comdat
961218822Sdim		  = bfd_alloc (abfd, amt);
962218822Sdim		if (coff_section_data (abfd, section)->comdat == NULL)
96378828Sobrien		  abort ();
96460484Sobrien
965218822Sdim		coff_section_data (abfd, section)->comdat->symbol =
96678828Sobrien		  (esym - esymstart) / bfd_coff_symesz (abfd);
96760484Sobrien
96889857Sobrien		amt = strlen (symname) + 1;
96989857Sobrien		newname = bfd_alloc (abfd, amt);
97078828Sobrien		if (newname == NULL)
97178828Sobrien		  abort ();
97260484Sobrien
97378828Sobrien		strcpy (newname, symname);
974218822Sdim		coff_section_data (abfd, section)->comdat->name
975218822Sdim		  = newname;
97678828Sobrien	      }
97760484Sobrien
97878828Sobrien	      goto breakloop;
97933965Sjdp	    }
98033965Sjdp	}
98178828Sobrien
98278828Sobrien      esym += (isym.n_numaux + 1) * bfd_coff_symesz (abfd);
98333965Sjdp    }
98460484Sobrien
98578828Sobrien breakloop:
98678828Sobrien  return sec_flags;
98778828Sobrien}
98878828Sobrien
98978828Sobrien
99078828Sobrien/* The PE version; see above for the general comments.
99178828Sobrien
99278828Sobrien   Since to set the SEC_LINK_ONCE and associated flags, we have to
99378828Sobrien   look at the symbol table anyway, we return the symbol table index
99478828Sobrien   of the symbol being used as the COMDAT symbol.  This is admittedly
99578828Sobrien   ugly, but there's really nowhere else that we have access to the
99678828Sobrien   required information.  FIXME: Is the COMDAT symbol index used for
99778828Sobrien   any purpose other than objdump?  */
99878828Sobrien
999130561Sobrienstatic bfd_boolean
1000218822Sdimstyp_to_sec_flags (bfd *abfd,
1001218822Sdim		   void * hdr,
1002218822Sdim		   const char *name,
1003218822Sdim		   asection *section,
1004218822Sdim		   flagword *flags_ptr)
100578828Sobrien{
100678828Sobrien  struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
100778828Sobrien  long styp_flags = internal_s->s_flags;
100878828Sobrien  flagword sec_flags;
1009130561Sobrien  bfd_boolean result = TRUE;
101078828Sobrien
101178828Sobrien  /* Assume read only unless IMAGE_SCN_MEM_WRITE is specified.  */
101278828Sobrien  sec_flags = SEC_READONLY;
101378828Sobrien
101478828Sobrien  /* Process each flag bit in styp_flags in turn.  */
101578828Sobrien  while (styp_flags)
101678828Sobrien    {
101778828Sobrien      long flag = styp_flags & - styp_flags;
101878828Sobrien      char * unhandled = NULL;
101989857Sobrien
102078828Sobrien      styp_flags &= ~ flag;
102178828Sobrien
102278828Sobrien      /* We infer from the distinct read/write/execute bits the settings
102378828Sobrien	 of some of the bfd flags; the actual values, should we need them,
102478828Sobrien	 are also in pei_section_data (abfd, section)->pe_flags.  */
102578828Sobrien
102678828Sobrien      switch (flag)
102778828Sobrien	{
102878828Sobrien	case STYP_DSECT:
102978828Sobrien	  unhandled = "STYP_DSECT";
103078828Sobrien	  break;
103178828Sobrien	case STYP_GROUP:
103278828Sobrien	  unhandled = "STYP_GROUP";
103378828Sobrien	  break;
103478828Sobrien	case STYP_COPY:
103578828Sobrien	  unhandled = "STYP_COPY";
103678828Sobrien	  break;
103778828Sobrien	case STYP_OVER:
103878828Sobrien	  unhandled = "STYP_OVER";
103978828Sobrien	  break;
104078828Sobrien#ifdef SEC_NEVER_LOAD
104178828Sobrien	case STYP_NOLOAD:
104278828Sobrien	  sec_flags |= SEC_NEVER_LOAD;
104378828Sobrien	  break;
104489857Sobrien#endif
104578828Sobrien	case IMAGE_SCN_MEM_READ:
104678828Sobrien	  /* Ignored, assume it always to be true.  */
104778828Sobrien	  break;
104878828Sobrien	case IMAGE_SCN_TYPE_NO_PAD:
104978828Sobrien	  /* Skip.  */
105078828Sobrien	  break;
105178828Sobrien	case IMAGE_SCN_LNK_OTHER:
105278828Sobrien	  unhandled = "IMAGE_SCN_LNK_OTHER";
105378828Sobrien	  break;
105478828Sobrien	case IMAGE_SCN_MEM_NOT_CACHED:
105578828Sobrien	  unhandled = "IMAGE_SCN_MEM_NOT_CACHED";
105678828Sobrien	  break;
105778828Sobrien	case IMAGE_SCN_MEM_NOT_PAGED:
1058218822Sdim	  /* Generate a warning message rather using the 'unhandled'
1059218822Sdim	     variable as this will allow some .sys files generate by
1060218822Sdim	     other toolchains to be processed.  See bugzilla issue 196.  */
1061218822Sdim	  _bfd_error_handler (_("%B: Warning: Ignoring section flag IMAGE_SCN_MEM_NOT_PAGED in section %s"),
1062218822Sdim			      abfd, name);
106378828Sobrien	  break;
106478828Sobrien	case IMAGE_SCN_MEM_EXECUTE:
106578828Sobrien	  sec_flags |= SEC_CODE;
106678828Sobrien	  break;
106778828Sobrien	case IMAGE_SCN_MEM_WRITE:
106878828Sobrien	  sec_flags &= ~ SEC_READONLY;
106978828Sobrien	  break;
107078828Sobrien	case IMAGE_SCN_MEM_DISCARDABLE:
1071130561Sobrien	  /* The MS PE spec sets the DISCARDABLE flag on .reloc sections
1072130561Sobrien	     but we do not want them to be labelled as debug section, since
1073130561Sobrien	     then strip would remove them.  */
1074218822Sdim	  if (! CONST_STRNEQ (name, ".reloc"))
1075130561Sobrien	    sec_flags |= SEC_DEBUGGING;
107678828Sobrien	  break;
107778828Sobrien	case IMAGE_SCN_MEM_SHARED:
1078218822Sdim	  sec_flags |= SEC_COFF_SHARED;
107978828Sobrien	  break;
108078828Sobrien	case IMAGE_SCN_LNK_REMOVE:
108178828Sobrien	  sec_flags |= SEC_EXCLUDE;
108278828Sobrien	  break;
108378828Sobrien	case IMAGE_SCN_CNT_CODE:
108478828Sobrien	  sec_flags |= SEC_CODE | SEC_ALLOC | SEC_LOAD;
108578828Sobrien	  break;
108678828Sobrien	case IMAGE_SCN_CNT_INITIALIZED_DATA:
108778828Sobrien	  sec_flags |= SEC_DATA | SEC_ALLOC | SEC_LOAD;
108878828Sobrien	  break;
108978828Sobrien	case IMAGE_SCN_CNT_UNINITIALIZED_DATA:
109078828Sobrien	  sec_flags |= SEC_ALLOC;
109178828Sobrien	  break;
109278828Sobrien	case IMAGE_SCN_LNK_INFO:
109378828Sobrien	  /* We mark these as SEC_DEBUGGING, but only if COFF_PAGE_SIZE is
109478828Sobrien	     defined.  coff_compute_section_file_positions uses
109578828Sobrien	     COFF_PAGE_SIZE to ensure that the low order bits of the
109678828Sobrien	     section VMA and the file offset match.  If we don't know
109778828Sobrien	     COFF_PAGE_SIZE, we can't ensure the correct correspondence,
109878828Sobrien	     and demand page loading of the file will fail.  */
109978828Sobrien#ifdef COFF_PAGE_SIZE
110078828Sobrien	  sec_flags |= SEC_DEBUGGING;
110178828Sobrien#endif
110278828Sobrien	  break;
110378828Sobrien	case IMAGE_SCN_LNK_COMDAT:
110478828Sobrien	  /* COMDAT gets very special treatment.  */
110578828Sobrien	  sec_flags = handle_COMDAT (abfd, sec_flags, hdr, name, section);
110678828Sobrien	  break;
110778828Sobrien	default:
110878828Sobrien	  /* Silently ignore for now.  */
110989857Sobrien	  break;
111078828Sobrien	}
111178828Sobrien
111289857Sobrien      /* If the section flag was not handled, report it here.  */
111378828Sobrien      if (unhandled != NULL)
111489857Sobrien	{
111589857Sobrien	  (*_bfd_error_handler)
1116218822Sdim	    (_("%B (%s): Section flag %s (0x%x) ignored"),
1117218822Sdim	     abfd, name, unhandled, flag);
1118130561Sobrien	  result = FALSE;
111989857Sobrien	}
112078828Sobrien    }
112178828Sobrien
112260484Sobrien#if defined (COFF_LONG_SECTION_NAMES) && defined (COFF_SUPPORT_GNU_LINKONCE)
112360484Sobrien  /* As a GNU extension, if the name begins with .gnu.linkonce, we
112460484Sobrien     only link a single copy of the section.  This is used to support
112560484Sobrien     g++.  g++ will emit each template expansion in its own section.
112660484Sobrien     The symbols will be defined as weak, so that multiple definitions
112760484Sobrien     are permitted.  The GNU linker extension is to actually discard
112860484Sobrien     all but one of the sections.  */
1129218822Sdim  if (CONST_STRNEQ (name, ".gnu.linkonce"))
113060484Sobrien    sec_flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
113133965Sjdp#endif
113233965Sjdp
113389857Sobrien  if (flags_ptr)
113489857Sobrien    * flags_ptr = sec_flags;
113589857Sobrien
113689857Sobrien  return result;
113733965Sjdp}
113833965Sjdp
113960484Sobrien#endif /* COFF_WITH_PE */
114060484Sobrien
114133965Sjdp#define	get_index(symbol)	((symbol)->udata.i)
114233965Sjdp
114333965Sjdp/*
114433965SjdpINTERNAL_DEFINITION
114533965Sjdp	bfd_coff_backend_data
114633965Sjdp
114733965SjdpCODE_FRAGMENT
114833965Sjdp
114960484Sobrien.{* COFF symbol classifications.  *}
115060484Sobrien.
115160484Sobrien.enum coff_symbol_classification
115260484Sobrien.{
115360484Sobrien.  {* Global symbol.  *}
115460484Sobrien.  COFF_SYMBOL_GLOBAL,
115560484Sobrien.  {* Common symbol.  *}
115660484Sobrien.  COFF_SYMBOL_COMMON,
115760484Sobrien.  {* Undefined symbol.  *}
115860484Sobrien.  COFF_SYMBOL_UNDEFINED,
115960484Sobrien.  {* Local symbol.  *}
116060484Sobrien.  COFF_SYMBOL_LOCAL,
116160484Sobrien.  {* PE section symbol.  *}
116260484Sobrien.  COFF_SYMBOL_PE_SECTION
116360484Sobrien.};
116460484Sobrien.
116533965SjdpSpecial entry points for gdb to swap in coff symbol table parts:
116633965Sjdp.typedef struct
116733965Sjdp.{
116889857Sobrien.  void (*_bfd_coff_swap_aux_in)
1169218822Sdim.    (bfd *, void *, int, int, int, int, void *);
117033965Sjdp.
117189857Sobrien.  void (*_bfd_coff_swap_sym_in)
1172218822Sdim.    (bfd *, void *, void *);
117333965Sjdp.
117489857Sobrien.  void (*_bfd_coff_swap_lineno_in)
1175218822Sdim.    (bfd *, void *, void *);
117633965Sjdp.
117789857Sobrien.  unsigned int (*_bfd_coff_swap_aux_out)
1178218822Sdim.    (bfd *, void *, int, int, int, int, void *);
117933965Sjdp.
118089857Sobrien.  unsigned int (*_bfd_coff_swap_sym_out)
1181218822Sdim.    (bfd *, void *, void *);
118233965Sjdp.
118389857Sobrien.  unsigned int (*_bfd_coff_swap_lineno_out)
1184218822Sdim.    (bfd *, void *, void *);
118533965Sjdp.
118689857Sobrien.  unsigned int (*_bfd_coff_swap_reloc_out)
1187218822Sdim.    (bfd *, void *, void *);
118833965Sjdp.
118989857Sobrien.  unsigned int (*_bfd_coff_swap_filehdr_out)
1190218822Sdim.    (bfd *, void *, void *);
119133965Sjdp.
119289857Sobrien.  unsigned int (*_bfd_coff_swap_aouthdr_out)
1193218822Sdim.    (bfd *, void *, void *);
119433965Sjdp.
119589857Sobrien.  unsigned int (*_bfd_coff_swap_scnhdr_out)
1196218822Sdim.    (bfd *, void *, void *);
119733965Sjdp.
119889857Sobrien.  unsigned int _bfd_filhsz;
119989857Sobrien.  unsigned int _bfd_aoutsz;
120089857Sobrien.  unsigned int _bfd_scnhsz;
120189857Sobrien.  unsigned int _bfd_symesz;
120289857Sobrien.  unsigned int _bfd_auxesz;
120389857Sobrien.  unsigned int _bfd_relsz;
120489857Sobrien.  unsigned int _bfd_linesz;
120589857Sobrien.  unsigned int _bfd_filnmlen;
1206130561Sobrien.  bfd_boolean _bfd_coff_long_filenames;
1207130561Sobrien.  bfd_boolean _bfd_coff_long_section_names;
120889857Sobrien.  unsigned int _bfd_coff_default_section_alignment_power;
1209130561Sobrien.  bfd_boolean _bfd_coff_force_symnames_in_strings;
121089857Sobrien.  unsigned int _bfd_coff_debug_string_prefix_length;
121133965Sjdp.
121289857Sobrien.  void (*_bfd_coff_swap_filehdr_in)
1213218822Sdim.    (bfd *, void *, void *);
121438889Sjdp.
121589857Sobrien.  void (*_bfd_coff_swap_aouthdr_in)
1216218822Sdim.    (bfd *, void *, void *);
121789857Sobrien.
121889857Sobrien.  void (*_bfd_coff_swap_scnhdr_in)
1219218822Sdim.    (bfd *, void *, void *);
122089857Sobrien.
122189857Sobrien.  void (*_bfd_coff_swap_reloc_in)
1222218822Sdim.    (bfd *abfd, void *, void *);
122389857Sobrien.
1224130561Sobrien.  bfd_boolean (*_bfd_coff_bad_format_hook)
1225218822Sdim.    (bfd *, void *);
122689857Sobrien.
1227130561Sobrien.  bfd_boolean (*_bfd_coff_set_arch_mach_hook)
1228218822Sdim.    (bfd *, void *);
122989857Sobrien.
1230218822Sdim.  void * (*_bfd_coff_mkobject_hook)
1231218822Sdim.    (bfd *, void *, void *);
123289857Sobrien.
1233130561Sobrien.  bfd_boolean (*_bfd_styp_to_sec_flags_hook)
1234218822Sdim.    (bfd *, void *, const char *, asection *, flagword *);
123589857Sobrien.
123689857Sobrien.  void (*_bfd_set_alignment_hook)
1237218822Sdim.    (bfd *, asection *, void *);
123889857Sobrien.
1239130561Sobrien.  bfd_boolean (*_bfd_coff_slurp_symbol_table)
1240218822Sdim.    (bfd *);
124189857Sobrien.
1242130561Sobrien.  bfd_boolean (*_bfd_coff_symname_in_debug)
1243218822Sdim.    (bfd *, struct internal_syment *);
124489857Sobrien.
1245130561Sobrien.  bfd_boolean (*_bfd_coff_pointerize_aux_hook)
1246218822Sdim.    (bfd *, combined_entry_type *, combined_entry_type *,
1247218822Sdim.	     unsigned int, combined_entry_type *);
124889857Sobrien.
1249130561Sobrien.  bfd_boolean (*_bfd_coff_print_aux)
1250218822Sdim.    (bfd *, FILE *, combined_entry_type *, combined_entry_type *,
1251218822Sdim.	     combined_entry_type *, unsigned int);
125289857Sobrien.
125389857Sobrien.  void (*_bfd_coff_reloc16_extra_cases)
1254218822Sdim.    (bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *,
1255218822Sdim.	    bfd_byte *, unsigned int *, unsigned int *);
125689857Sobrien.
125789857Sobrien.  int (*_bfd_coff_reloc16_estimate)
1258218822Sdim.    (bfd *, asection *, arelent *, unsigned int,
1259218822Sdim.	     struct bfd_link_info *);
126089857Sobrien.
126189857Sobrien.  enum coff_symbol_classification (*_bfd_coff_classify_symbol)
1262218822Sdim.    (bfd *, struct internal_syment *);
126389857Sobrien.
1264130561Sobrien.  bfd_boolean (*_bfd_coff_compute_section_file_positions)
1265218822Sdim.    (bfd *);
126689857Sobrien.
1267130561Sobrien.  bfd_boolean (*_bfd_coff_start_final_link)
1268218822Sdim.    (bfd *, struct bfd_link_info *);
126989857Sobrien.
1270130561Sobrien.  bfd_boolean (*_bfd_coff_relocate_section)
1271218822Sdim.    (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
1272218822Sdim.	     struct internal_reloc *, struct internal_syment *, asection **);
127389857Sobrien.
127489857Sobrien.  reloc_howto_type *(*_bfd_coff_rtype_to_howto)
1275218822Sdim.    (bfd *, asection *, struct internal_reloc *,
127689857Sobrien.	     struct coff_link_hash_entry *, struct internal_syment *,
1277218822Sdim.	     bfd_vma *);
127889857Sobrien.
1279130561Sobrien.  bfd_boolean (*_bfd_coff_adjust_symndx)
1280218822Sdim.    (bfd *, struct bfd_link_info *, bfd *, asection *,
1281218822Sdim.	     struct internal_reloc *, bfd_boolean *);
128289857Sobrien.
1283130561Sobrien.  bfd_boolean (*_bfd_coff_link_add_one_symbol)
1284218822Sdim.    (struct bfd_link_info *, bfd *, const char *, flagword,
1285130561Sobrien.	     asection *, bfd_vma, const char *, bfd_boolean, bfd_boolean,
1286218822Sdim.	     struct bfd_link_hash_entry **);
128789857Sobrien.
1288130561Sobrien.  bfd_boolean (*_bfd_coff_link_output_has_begun)
1289218822Sdim.    (bfd *, struct coff_final_link_info *);
129089857Sobrien.
1291130561Sobrien.  bfd_boolean (*_bfd_coff_final_link_postscript)
1292218822Sdim.    (bfd *, struct coff_final_link_info *);
129389857Sobrien.
129433965Sjdp.} bfd_coff_backend_data;
129533965Sjdp.
129689857Sobrien.#define coff_backend_info(abfd) \
129789857Sobrien.  ((bfd_coff_backend_data *) (abfd)->xvec->backend_data)
129833965Sjdp.
129933965Sjdp.#define bfd_coff_swap_aux_in(a,e,t,c,ind,num,i) \
130089857Sobrien.  ((coff_backend_info (a)->_bfd_coff_swap_aux_in) (a,e,t,c,ind,num,i))
130133965Sjdp.
130233965Sjdp.#define bfd_coff_swap_sym_in(a,e,i) \
130389857Sobrien.  ((coff_backend_info (a)->_bfd_coff_swap_sym_in) (a,e,i))
130433965Sjdp.
130533965Sjdp.#define bfd_coff_swap_lineno_in(a,e,i) \
130689857Sobrien.  ((coff_backend_info ( a)->_bfd_coff_swap_lineno_in) (a,e,i))
130733965Sjdp.
130833965Sjdp.#define bfd_coff_swap_reloc_out(abfd, i, o) \
130989857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_out) (abfd, i, o))
131033965Sjdp.
131133965Sjdp.#define bfd_coff_swap_lineno_out(abfd, i, o) \
131289857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_swap_lineno_out) (abfd, i, o))
131333965Sjdp.
131433965Sjdp.#define bfd_coff_swap_aux_out(a,i,t,c,ind,num,o) \
131589857Sobrien.  ((coff_backend_info (a)->_bfd_coff_swap_aux_out) (a,i,t,c,ind,num,o))
131633965Sjdp.
131733965Sjdp.#define bfd_coff_swap_sym_out(abfd, i,o) \
131889857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_swap_sym_out) (abfd, i, o))
131933965Sjdp.
132033965Sjdp.#define bfd_coff_swap_scnhdr_out(abfd, i,o) \
132189857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_out) (abfd, i, o))
132233965Sjdp.
132333965Sjdp.#define bfd_coff_swap_filehdr_out(abfd, i,o) \
132489857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_out) (abfd, i, o))
132533965Sjdp.
132633965Sjdp.#define bfd_coff_swap_aouthdr_out(abfd, i,o) \
132789857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_out) (abfd, i, o))
132833965Sjdp.
132933965Sjdp.#define bfd_coff_filhsz(abfd) (coff_backend_info (abfd)->_bfd_filhsz)
133033965Sjdp.#define bfd_coff_aoutsz(abfd) (coff_backend_info (abfd)->_bfd_aoutsz)
133133965Sjdp.#define bfd_coff_scnhsz(abfd) (coff_backend_info (abfd)->_bfd_scnhsz)
133233965Sjdp.#define bfd_coff_symesz(abfd) (coff_backend_info (abfd)->_bfd_symesz)
133333965Sjdp.#define bfd_coff_auxesz(abfd) (coff_backend_info (abfd)->_bfd_auxesz)
133433965Sjdp.#define bfd_coff_relsz(abfd)  (coff_backend_info (abfd)->_bfd_relsz)
133533965Sjdp.#define bfd_coff_linesz(abfd) (coff_backend_info (abfd)->_bfd_linesz)
133660484Sobrien.#define bfd_coff_filnmlen(abfd) (coff_backend_info (abfd)->_bfd_filnmlen)
133789857Sobrien.#define bfd_coff_long_filenames(abfd) \
133889857Sobrien.  (coff_backend_info (abfd)->_bfd_coff_long_filenames)
133933965Sjdp.#define bfd_coff_long_section_names(abfd) \
134089857Sobrien.  (coff_backend_info (abfd)->_bfd_coff_long_section_names)
134133965Sjdp.#define bfd_coff_default_section_alignment_power(abfd) \
134289857Sobrien.  (coff_backend_info (abfd)->_bfd_coff_default_section_alignment_power)
134333965Sjdp.#define bfd_coff_swap_filehdr_in(abfd, i,o) \
134489857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_in) (abfd, i, o))
134533965Sjdp.
134633965Sjdp.#define bfd_coff_swap_aouthdr_in(abfd, i,o) \
134789857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_in) (abfd, i, o))
134833965Sjdp.
134933965Sjdp.#define bfd_coff_swap_scnhdr_in(abfd, i,o) \
135089857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_in) (abfd, i, o))
135133965Sjdp.
135233965Sjdp.#define bfd_coff_swap_reloc_in(abfd, i, o) \
135389857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_in) (abfd, i, o))
135433965Sjdp.
135533965Sjdp.#define bfd_coff_bad_format_hook(abfd, filehdr) \
135689857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_bad_format_hook) (abfd, filehdr))
135733965Sjdp.
135833965Sjdp.#define bfd_coff_set_arch_mach_hook(abfd, filehdr)\
135989857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_set_arch_mach_hook) (abfd, filehdr))
136033965Sjdp.#define bfd_coff_mkobject_hook(abfd, filehdr, aouthdr)\
1361130561Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_mkobject_hook)\
1362130561Sobrien.   (abfd, filehdr, aouthdr))
136333965Sjdp.
136489857Sobrien.#define bfd_coff_styp_to_sec_flags_hook(abfd, scnhdr, name, section, flags_ptr)\
136589857Sobrien.  ((coff_backend_info (abfd)->_bfd_styp_to_sec_flags_hook)\
136689857Sobrien.   (abfd, scnhdr, name, section, flags_ptr))
136733965Sjdp.
136833965Sjdp.#define bfd_coff_set_alignment_hook(abfd, sec, scnhdr)\
136989857Sobrien.  ((coff_backend_info (abfd)->_bfd_set_alignment_hook) (abfd, sec, scnhdr))
137033965Sjdp.
137133965Sjdp.#define bfd_coff_slurp_symbol_table(abfd)\
137289857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_slurp_symbol_table) (abfd))
137333965Sjdp.
137433965Sjdp.#define bfd_coff_symname_in_debug(abfd, sym)\
137589857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_symname_in_debug) (abfd, sym))
137633965Sjdp.
137777298Sobrien.#define bfd_coff_force_symnames_in_strings(abfd)\
137889857Sobrien.  (coff_backend_info (abfd)->_bfd_coff_force_symnames_in_strings)
137977298Sobrien.
138077298Sobrien.#define bfd_coff_debug_string_prefix_length(abfd)\
138189857Sobrien.  (coff_backend_info (abfd)->_bfd_coff_debug_string_prefix_length)
138277298Sobrien.
138333965Sjdp.#define bfd_coff_print_aux(abfd, file, base, symbol, aux, indaux)\
138489857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_print_aux)\
138589857Sobrien.   (abfd, file, base, symbol, aux, indaux))
138633965Sjdp.
1387130561Sobrien.#define bfd_coff_reloc16_extra_cases(abfd, link_info, link_order,\
1388130561Sobrien.                                     reloc, data, src_ptr, dst_ptr)\
138989857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_reloc16_extra_cases)\
139089857Sobrien.   (abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr))
139133965Sjdp.
139233965Sjdp.#define bfd_coff_reloc16_estimate(abfd, section, reloc, shrink, link_info)\
139389857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_reloc16_estimate)\
139489857Sobrien.   (abfd, section, reloc, shrink, link_info))
139533965Sjdp.
139660484Sobrien.#define bfd_coff_classify_symbol(abfd, sym)\
139789857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_classify_symbol)\
139889857Sobrien.   (abfd, sym))
139933965Sjdp.
140033965Sjdp.#define bfd_coff_compute_section_file_positions(abfd)\
140189857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_compute_section_file_positions)\
140289857Sobrien.   (abfd))
140333965Sjdp.
140433965Sjdp.#define bfd_coff_start_final_link(obfd, info)\
140589857Sobrien.  ((coff_backend_info (obfd)->_bfd_coff_start_final_link)\
140689857Sobrien.   (obfd, info))
140733965Sjdp.#define bfd_coff_relocate_section(obfd,info,ibfd,o,con,rel,isyms,secs)\
140889857Sobrien.  ((coff_backend_info (ibfd)->_bfd_coff_relocate_section)\
140989857Sobrien.   (obfd, info, ibfd, o, con, rel, isyms, secs))
141033965Sjdp.#define bfd_coff_rtype_to_howto(abfd, sec, rel, h, sym, addendp)\
141189857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_rtype_to_howto)\
141289857Sobrien.   (abfd, sec, rel, h, sym, addendp))
141333965Sjdp.#define bfd_coff_adjust_symndx(obfd, info, ibfd, sec, rel, adjustedp)\
141489857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_adjust_symndx)\
141589857Sobrien.   (obfd, info, ibfd, sec, rel, adjustedp))
1416130561Sobrien.#define bfd_coff_link_add_one_symbol(info, abfd, name, flags, section,\
1417130561Sobrien.                                     value, string, cp, coll, hashp)\
141889857Sobrien.  ((coff_backend_info (abfd)->_bfd_coff_link_add_one_symbol)\
141989857Sobrien.   (info, abfd, name, flags, section, value, string, cp, coll, hashp))
142033965Sjdp.
142160484Sobrien.#define bfd_coff_link_output_has_begun(a,p) \
1422218822Sdim.  ((coff_backend_info (a)->_bfd_coff_link_output_has_begun) (a, p))
142338889Sjdp.#define bfd_coff_final_link_postscript(a,p) \
1424218822Sdim.  ((coff_backend_info (a)->_bfd_coff_final_link_postscript) (a, p))
142538889Sjdp.
142633965Sjdp*/
142733965Sjdp
142833965Sjdp/* See whether the magic number matches.  */
142933965Sjdp
1430130561Sobrienstatic bfd_boolean
1431218822Sdimcoff_bad_format_hook (bfd * abfd ATTRIBUTE_UNUSED, void * filehdr)
143233965Sjdp{
143333965Sjdp  struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
143433965Sjdp
143533965Sjdp  if (BADMAG (*internal_f))
1436130561Sobrien    return FALSE;
143733965Sjdp
1438130561Sobrien  /* If the optional header is NULL or not the correct size then
143933965Sjdp     quit; the only difference I can see between m88k dgux headers (MC88DMAGIC)
144033965Sjdp     and Intel 960 readwrite headers (I960WRMAGIC) is that the
144133965Sjdp     optional header is of a different size.
144233965Sjdp
144333965Sjdp     But the mips keeps extra stuff in it's opthdr, so dont check
1444130561Sobrien     when doing that.  */
144533965Sjdp
144633965Sjdp#if defined(M88) || defined(I960)
144760484Sobrien  if (internal_f->f_opthdr != 0 && bfd_coff_aoutsz (abfd) != internal_f->f_opthdr)
1448130561Sobrien    return FALSE;
144933965Sjdp#endif
145033965Sjdp
1451130561Sobrien  return TRUE;
145233965Sjdp}
145333965Sjdp
1454130561Sobrien#ifdef TICOFF
1455130561Sobrienstatic bfd_boolean
1456218822Sdimticoff0_bad_format_hook (bfd *abfd ATTRIBUTE_UNUSED, void * filehdr)
1457130561Sobrien{
1458130561Sobrien  struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
1459130561Sobrien
1460130561Sobrien  if (COFF0_BADMAG (*internal_f))
1461130561Sobrien    return FALSE;
1462130561Sobrien
1463130561Sobrien  return TRUE;
1464130561Sobrien}
1465130561Sobrien#endif
1466130561Sobrien
1467130561Sobrien#ifdef TICOFF
1468130561Sobrienstatic bfd_boolean
1469218822Sdimticoff1_bad_format_hook (bfd *abfd ATTRIBUTE_UNUSED, void * filehdr)
1470130561Sobrien{
1471130561Sobrien  struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
1472130561Sobrien
1473130561Sobrien  if (COFF1_BADMAG (*internal_f))
1474130561Sobrien    return FALSE;
1475130561Sobrien
1476130561Sobrien  return TRUE;
1477130561Sobrien}
1478130561Sobrien#endif
1479130561Sobrien
148060484Sobrien/* Check whether this section uses an alignment other than the
148160484Sobrien   default.  */
148233965Sjdp
148360484Sobrienstatic void
1484218822Sdimcoff_set_custom_section_alignment (bfd *abfd ATTRIBUTE_UNUSED,
1485218822Sdim				   asection *section,
1486218822Sdim				   const struct coff_section_alignment_entry *alignment_table,
1487218822Sdim				   const unsigned int table_size)
148860484Sobrien{
148960484Sobrien  const unsigned int default_alignment = COFF_DEFAULT_SECTION_ALIGNMENT_POWER;
149060484Sobrien  unsigned int i;
149160484Sobrien
149260484Sobrien  for (i = 0; i < table_size; ++i)
149360484Sobrien    {
149460484Sobrien      const char *secname = bfd_get_section_name (abfd, section);
1495130561Sobrien
149660484Sobrien      if (alignment_table[i].comparison_length == (unsigned int) -1
149760484Sobrien	  ? strcmp (alignment_table[i].name, secname) == 0
149860484Sobrien	  : strncmp (alignment_table[i].name, secname,
149960484Sobrien		     alignment_table[i].comparison_length) == 0)
150060484Sobrien	break;
150160484Sobrien    }
150260484Sobrien  if (i >= table_size)
150360484Sobrien    return;
150460484Sobrien
150560484Sobrien  if (alignment_table[i].default_alignment_min != COFF_ALIGNMENT_FIELD_EMPTY
150660484Sobrien      && default_alignment < alignment_table[i].default_alignment_min)
150760484Sobrien    return;
150860484Sobrien
150960484Sobrien  if (alignment_table[i].default_alignment_max != COFF_ALIGNMENT_FIELD_EMPTY
151089857Sobrien#if COFF_DEFAULT_SECTION_ALIGNMENT_POWER != 0
151189857Sobrien      && default_alignment > alignment_table[i].default_alignment_max
151289857Sobrien#endif
151389857Sobrien      )
151460484Sobrien    return;
151560484Sobrien
151660484Sobrien  section->alignment_power = alignment_table[i].alignment_power;
151760484Sobrien}
151860484Sobrien
151960484Sobrien/* Custom section alignment records.  */
152060484Sobrien
152160484Sobrienstatic const struct coff_section_alignment_entry
152260484Sobriencoff_section_alignment_table[] =
152360484Sobrien{
152460484Sobrien#ifdef COFF_SECTION_ALIGNMENT_ENTRIES
152560484Sobrien  COFF_SECTION_ALIGNMENT_ENTRIES,
152660484Sobrien#endif
152760484Sobrien  /* There must not be any gaps between .stabstr sections.  */
152860484Sobrien  { COFF_SECTION_NAME_PARTIAL_MATCH (".stabstr"),
152960484Sobrien    1, COFF_ALIGNMENT_FIELD_EMPTY, 0 },
153060484Sobrien  /* The .stab section must be aligned to 2**2 at most, to avoid gaps.  */
153160484Sobrien  { COFF_SECTION_NAME_PARTIAL_MATCH (".stab"),
153260484Sobrien    3, COFF_ALIGNMENT_FIELD_EMPTY, 2 },
153360484Sobrien  /* Similarly for the .ctors and .dtors sections.  */
153460484Sobrien  { COFF_SECTION_NAME_EXACT_MATCH (".ctors"),
153560484Sobrien    3, COFF_ALIGNMENT_FIELD_EMPTY, 2 },
153660484Sobrien  { COFF_SECTION_NAME_EXACT_MATCH (".dtors"),
153760484Sobrien    3, COFF_ALIGNMENT_FIELD_EMPTY, 2 }
153860484Sobrien};
153960484Sobrien
154060484Sobrienstatic const unsigned int coff_section_alignment_table_size =
154160484Sobrien  sizeof coff_section_alignment_table / sizeof coff_section_alignment_table[0];
154260484Sobrien
154360484Sobrien/* Initialize a section structure with information peculiar to this
154460484Sobrien   particular implementation of COFF.  */
154560484Sobrien
1546130561Sobrienstatic bfd_boolean
1547218822Sdimcoff_new_section_hook (bfd * abfd, asection * section)
154833965Sjdp{
154938889Sjdp  combined_entry_type *native;
155089857Sobrien  bfd_size_type amt;
155138889Sjdp
155233965Sjdp  section->alignment_power = COFF_DEFAULT_SECTION_ALIGNMENT_POWER;
155333965Sjdp
155433965Sjdp#ifdef RS6000COFF_C
1555104834Sobrien  if (bfd_xcoff_text_align_power (abfd) != 0
155633965Sjdp      && strcmp (bfd_get_section_name (abfd, section), ".text") == 0)
1557104834Sobrien    section->alignment_power = bfd_xcoff_text_align_power (abfd);
1558104834Sobrien  if (bfd_xcoff_data_align_power (abfd) != 0
155933965Sjdp      && strcmp (bfd_get_section_name (abfd, section), ".data") == 0)
1560104834Sobrien    section->alignment_power = bfd_xcoff_data_align_power (abfd);
156133965Sjdp#endif
156233965Sjdp
1563218822Sdim  /* Set up the section symbol.  */
1564218822Sdim  if (!_bfd_generic_new_section_hook (abfd, section))
1565218822Sdim    return FALSE;
1566218822Sdim
156733965Sjdp  /* Allocate aux records for section symbols, to store size and
156833965Sjdp     related info.
156933965Sjdp
157033965Sjdp     @@ The 10 is a guess at a plausible maximum number of aux entries
157133965Sjdp     (but shouldn't be a constant).  */
157289857Sobrien  amt = sizeof (combined_entry_type) * 10;
1573218822Sdim  native = bfd_zalloc (abfd, amt);
157438889Sjdp  if (native == NULL)
1575130561Sobrien    return FALSE;
157633965Sjdp
157738889Sjdp  /* We don't need to set up n_name, n_value, or n_scnum in the native
1578130561Sobrien     symbol information, since they'll be overridden by the BFD symbol
157938889Sjdp     anyhow.  However, we do need to set the type and storage class,
158038889Sjdp     in case this symbol winds up getting written out.  The value 0
158138889Sjdp     for n_numaux is already correct.  */
158238889Sjdp
158338889Sjdp  native->u.syment.n_type = T_NULL;
158438889Sjdp  native->u.syment.n_sclass = C_STAT;
158538889Sjdp
158638889Sjdp  coffsymbol (section->symbol)->native = native;
158738889Sjdp
158860484Sobrien  coff_set_custom_section_alignment (abfd, section,
158960484Sobrien				     coff_section_alignment_table,
159060484Sobrien				     coff_section_alignment_table_size);
159133965Sjdp
1592130561Sobrien  return TRUE;
159333965Sjdp}
159433965Sjdp
159538889Sjdp#ifdef COFF_ALIGN_IN_SECTION_HEADER
159633965Sjdp
159733965Sjdp/* Set the alignment of a BFD section.  */
159833965Sjdp
159933965Sjdpstatic void
1600218822Sdimcoff_set_alignment_hook (bfd * abfd ATTRIBUTE_UNUSED,
1601218822Sdim			 asection * section,
1602218822Sdim			 void * scnhdr)
160333965Sjdp{
160433965Sjdp  struct internal_scnhdr *hdr = (struct internal_scnhdr *) scnhdr;
160533965Sjdp  unsigned int i;
160633965Sjdp
160738889Sjdp#ifdef I960
1608130561Sobrien  /* Extract ALIGN from 2**ALIGN stored in section header.  */
160933965Sjdp  for (i = 0; i < 32; i++)
161033965Sjdp    if ((1 << i) >= hdr->s_align)
161133965Sjdp      break;
161238889Sjdp#endif
161360484Sobrien#ifdef TIC80COFF
1614130561Sobrien  /* TI tools puts the alignment power in bits 8-11.  */
161560484Sobrien  i = (hdr->s_flags >> 8) & 0xF ;
161660484Sobrien#endif
161777298Sobrien#ifdef COFF_DECODE_ALIGNMENT
161877298Sobrien  i = COFF_DECODE_ALIGNMENT(hdr->s_flags);
161977298Sobrien#endif
162033965Sjdp  section->alignment_power = i;
162177298Sobrien
162277298Sobrien#ifdef coff_set_section_load_page
162377298Sobrien  coff_set_section_load_page (section, hdr->s_page);
162477298Sobrien#endif
162533965Sjdp}
162633965Sjdp
162738889Sjdp#else /* ! COFF_ALIGN_IN_SECTION_HEADER */
162833965Sjdp#ifdef COFF_WITH_PE
162933965Sjdp
1630130561Sobrien/* A couple of macros to help setting the alignment power field.  */
1631218822Sdim#define ALIGN_SET(field, x, y) \
1632218822Sdim  if (((field) & IMAGE_SCN_ALIGN_64BYTES) == x)\
1633218822Sdim    {\
1634218822Sdim      section->alignment_power = y;\
1635218822Sdim    }
163633965Sjdp
1637218822Sdim#define ELIFALIGN_SET(field, x, y) \
1638218822Sdim  else if (((field) & IMAGE_SCN_ALIGN_64BYTES) == x) \
1639218822Sdim    {\
1640218822Sdim      section->alignment_power = y;\
1641218822Sdim    }
164233965Sjdp
164333965Sjdpstatic void
1644218822Sdimcoff_set_alignment_hook (bfd * abfd ATTRIBUTE_UNUSED,
1645218822Sdim			 asection * section,
1646218822Sdim			 void * scnhdr)
164733965Sjdp{
164833965Sjdp  struct internal_scnhdr *hdr = (struct internal_scnhdr *) scnhdr;
164989857Sobrien  bfd_size_type amt;
165033965Sjdp
165133965Sjdp  ALIGN_SET     (hdr->s_flags, IMAGE_SCN_ALIGN_64BYTES, 6)
165233965Sjdp  ELIFALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_32BYTES, 5)
165333965Sjdp  ELIFALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_16BYTES, 4)
165433965Sjdp  ELIFALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_8BYTES,  3)
165533965Sjdp  ELIFALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_4BYTES,  2)
165633965Sjdp  ELIFALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_2BYTES,  1)
165733965Sjdp  ELIFALIGN_SET (hdr->s_flags, IMAGE_SCN_ALIGN_1BYTES,  0)
165833965Sjdp
165933965Sjdp  /* In a PE image file, the s_paddr field holds the virtual size of a
166060484Sobrien     section, while the s_size field holds the raw size.  We also keep
166160484Sobrien     the original section flag value, since not every bit can be
166260484Sobrien     mapped onto a generic BFD section bit.  */
166360484Sobrien  if (coff_section_data (abfd, section) == NULL)
166433965Sjdp    {
166589857Sobrien      amt = sizeof (struct coff_section_tdata);
1666218822Sdim      section->used_by_bfd = bfd_zalloc (abfd, amt);
166760484Sobrien      if (section->used_by_bfd == NULL)
1668218822Sdim	/* FIXME: Return error.  */
1669218822Sdim	abort ();
167060484Sobrien    }
1671218822Sdim
167260484Sobrien  if (pei_section_data (abfd, section) == NULL)
167360484Sobrien    {
167489857Sobrien      amt = sizeof (struct pei_section_tdata);
1675218822Sdim      coff_section_data (abfd, section)->tdata = bfd_zalloc (abfd, amt);
167660484Sobrien      if (coff_section_data (abfd, section)->tdata == NULL)
1677218822Sdim	/* FIXME: Return error.  */
1678218822Sdim	abort ();
167933965Sjdp    }
168060484Sobrien  pei_section_data (abfd, section)->virt_size = hdr->s_paddr;
168160484Sobrien  pei_section_data (abfd, section)->pe_flags = hdr->s_flags;
168233965Sjdp
168360484Sobrien  section->lma = hdr->s_vaddr;
168477298Sobrien
1685130561Sobrien  /* Check for extended relocs.  */
168677298Sobrien  if (hdr->s_flags & IMAGE_SCN_LNK_NRELOC_OVFL)
168777298Sobrien    {
168877298Sobrien      struct external_reloc dst;
168977298Sobrien      struct internal_reloc n;
169089857Sobrien      file_ptr oldpos = bfd_tell (abfd);
1691130561Sobrien      bfd_size_type relsz = bfd_coff_relsz (abfd);
1692130561Sobrien
169389857Sobrien      bfd_seek (abfd, (file_ptr) hdr->s_relptr, 0);
1694218822Sdim      if (bfd_bread (& dst, relsz, abfd) != relsz)
169577298Sobrien	return;
169677298Sobrien
169777298Sobrien      coff_swap_reloc_in (abfd, &dst, &n);
169877298Sobrien      bfd_seek (abfd, oldpos, 0);
1699130561Sobrien      section->reloc_count = hdr->s_nreloc = n.r_vaddr - 1;
1700130561Sobrien      section->rel_filepos += relsz;
170177298Sobrien    }
1702130561Sobrien  else if (hdr->s_nreloc == 0xffff)
1703130561Sobrien    (*_bfd_error_handler)
1704130561Sobrien      ("%s: warning: claims to have 0xffff relocs, without overflow",
1705130561Sobrien       bfd_get_filename (abfd));
170633965Sjdp}
170733965Sjdp#undef ALIGN_SET
170833965Sjdp#undef ELIFALIGN_SET
170933965Sjdp
171033965Sjdp#else /* ! COFF_WITH_PE */
171133965Sjdp#ifdef RS6000COFF_C
171233965Sjdp
171333965Sjdp/* We grossly abuse this function to handle XCOFF overflow headers.
171433965Sjdp   When we see one, we correct the reloc and line number counts in the
171533965Sjdp   real header, and remove the section we just created.  */
171633965Sjdp
171733965Sjdpstatic void
1718218822Sdimcoff_set_alignment_hook (bfd *abfd, asection *section, void * scnhdr)
171933965Sjdp{
172033965Sjdp  struct internal_scnhdr *hdr = (struct internal_scnhdr *) scnhdr;
172133965Sjdp  asection *real_sec;
172233965Sjdp
172333965Sjdp  if ((hdr->s_flags & STYP_OVRFLO) == 0)
172433965Sjdp    return;
172533965Sjdp
172689857Sobrien  real_sec = coff_section_from_bfd_index (abfd, (int) hdr->s_nreloc);
172733965Sjdp  if (real_sec == NULL)
172833965Sjdp    return;
172933965Sjdp
173033965Sjdp  real_sec->reloc_count = hdr->s_paddr;
173133965Sjdp  real_sec->lineno_count = hdr->s_vaddr;
173233965Sjdp
1733218822Sdim  if (!bfd_section_removed_from_list (abfd, section))
173433965Sjdp    {
1735218822Sdim      bfd_section_list_remove (abfd, section);
1736218822Sdim      --abfd->section_count;
173733965Sjdp    }
173833965Sjdp}
173933965Sjdp
174033965Sjdp#else /* ! RS6000COFF_C */
174133965Sjdp
174233965Sjdp#define coff_set_alignment_hook \
1743218822Sdim  ((void (*) (bfd *, asection *, void *)) bfd_void)
174433965Sjdp
174533965Sjdp#endif /* ! RS6000COFF_C */
174633965Sjdp#endif /* ! COFF_WITH_PE */
174738889Sjdp#endif /* ! COFF_ALIGN_IN_SECTION_HEADER */
174833965Sjdp
174933965Sjdp#ifndef coff_mkobject
175033965Sjdp
1751130561Sobrienstatic bfd_boolean
1752218822Sdimcoff_mkobject (bfd * abfd)
175333965Sjdp{
175433965Sjdp  coff_data_type *coff;
175589857Sobrien  bfd_size_type amt = sizeof (coff_data_type);
175633965Sjdp
1757218822Sdim  abfd->tdata.coff_obj_data = bfd_zalloc (abfd, amt);
1758218822Sdim  if (abfd->tdata.coff_obj_data == NULL)
1759130561Sobrien    return FALSE;
176033965Sjdp  coff = coff_data (abfd);
1761218822Sdim  coff->symbols = NULL;
1762218822Sdim  coff->conversion_table = NULL;
1763218822Sdim  coff->raw_syments = NULL;
176433965Sjdp  coff->relocbase = 0;
176533965Sjdp  coff->local_toc_sym_map = 0;
176633965Sjdp
176733965Sjdp/*  make_abs_section(abfd);*/
176833965Sjdp
1769130561Sobrien  return TRUE;
177033965Sjdp}
177133965Sjdp#endif
177233965Sjdp
177333965Sjdp/* Create the COFF backend specific information.  */
1774130561Sobrien
177533965Sjdp#ifndef coff_mkobject_hook
1776218822Sdimstatic void *
1777218822Sdimcoff_mkobject_hook (bfd * abfd,
1778218822Sdim		    void * filehdr,
1779218822Sdim		    void * aouthdr ATTRIBUTE_UNUSED)
178033965Sjdp{
178133965Sjdp  struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
178233965Sjdp  coff_data_type *coff;
178333965Sjdp
1784104834Sobrien  if (! coff_mkobject (abfd))
178533965Sjdp    return NULL;
178633965Sjdp
178733965Sjdp  coff = coff_data (abfd);
178833965Sjdp
178933965Sjdp  coff->sym_filepos = internal_f->f_symptr;
179033965Sjdp
179133965Sjdp  /* These members communicate important constants about the symbol
179233965Sjdp     table to GDB's symbol-reading code.  These `constants'
179333965Sjdp     unfortunately vary among coff implementations...  */
179433965Sjdp  coff->local_n_btmask = N_BTMASK;
179533965Sjdp  coff->local_n_btshft = N_BTSHFT;
179633965Sjdp  coff->local_n_tmask = N_TMASK;
179733965Sjdp  coff->local_n_tshift = N_TSHIFT;
179860484Sobrien  coff->local_symesz = bfd_coff_symesz (abfd);
179960484Sobrien  coff->local_auxesz = bfd_coff_auxesz (abfd);
180060484Sobrien  coff->local_linesz = bfd_coff_linesz (abfd);
180133965Sjdp
180260484Sobrien  coff->timestamp = internal_f->f_timdat;
180360484Sobrien
180433965Sjdp  obj_raw_syment_count (abfd) =
180533965Sjdp    obj_conv_table_size (abfd) =
180633965Sjdp      internal_f->f_nsyms;
180733965Sjdp
180833965Sjdp#ifdef RS6000COFF_C
180933965Sjdp  if ((internal_f->f_flags & F_SHROBJ) != 0)
181033965Sjdp    abfd->flags |= DYNAMIC;
181160484Sobrien  if (aouthdr != NULL && internal_f->f_opthdr >= bfd_coff_aoutsz (abfd))
181233965Sjdp    {
181333965Sjdp      struct internal_aouthdr *internal_a =
181433965Sjdp	(struct internal_aouthdr *) aouthdr;
181533965Sjdp      struct xcoff_tdata *xcoff;
181633965Sjdp
181733965Sjdp      xcoff = xcoff_data (abfd);
181877298Sobrien# ifdef U803XTOCMAGIC
181977298Sobrien      xcoff->xcoff64 = internal_f->f_magic == U803XTOCMAGIC;
182077298Sobrien# else
182177298Sobrien      xcoff->xcoff64 = 0;
182277298Sobrien# endif
1823130561Sobrien      xcoff->full_aouthdr = TRUE;
182433965Sjdp      xcoff->toc = internal_a->o_toc;
182533965Sjdp      xcoff->sntoc = internal_a->o_sntoc;
182633965Sjdp      xcoff->snentry = internal_a->o_snentry;
1827104834Sobrien      bfd_xcoff_text_align_power (abfd) = internal_a->o_algntext;
1828104834Sobrien      bfd_xcoff_data_align_power (abfd) = internal_a->o_algndata;
182933965Sjdp      xcoff->modtype = internal_a->o_modtype;
183033965Sjdp      xcoff->cputype = internal_a->o_cputype;
183133965Sjdp      xcoff->maxdata = internal_a->o_maxdata;
183233965Sjdp      xcoff->maxstack = internal_a->o_maxstack;
183333965Sjdp    }
183433965Sjdp#endif
183533965Sjdp
183677298Sobrien#ifdef ARM
183791041Sobrien  /* Set the flags field from the COFF header read in.  */
183860484Sobrien  if (! _bfd_coff_arm_set_private_flags (abfd, internal_f->f_flags))
183938889Sjdp    coff->flags = 0;
184038889Sjdp#endif
184177298Sobrien
184260484Sobrien#ifdef COFF_WITH_PE
184360484Sobrien  /* FIXME: I'm not sure this is ever executed, since peicode.h
184460484Sobrien     defines coff_mkobject_hook.  */
184560484Sobrien  if ((internal_f->f_flags & IMAGE_FILE_DEBUG_STRIPPED) == 0)
184660484Sobrien    abfd->flags |= HAS_DEBUG;
184760484Sobrien#endif
184860484Sobrien
1849218822Sdim  return coff;
185033965Sjdp}
185133965Sjdp#endif
185233965Sjdp
185333965Sjdp/* Determine the machine architecture and type.  FIXME: This is target
185433965Sjdp   dependent because the magic numbers are defined in the target
185533965Sjdp   dependent header files.  But there is no particular need for this.
185633965Sjdp   If the magic numbers were moved to a separate file, this function
185733965Sjdp   would be target independent and would also be much more successful
185833965Sjdp   at linking together COFF files for different architectures.  */
185933965Sjdp
1860130561Sobrienstatic bfd_boolean
1861218822Sdimcoff_set_arch_mach_hook (bfd *abfd, void * filehdr)
186233965Sjdp{
186389857Sobrien  unsigned long machine;
186433965Sjdp  enum bfd_architecture arch;
186533965Sjdp  struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
186633965Sjdp
1867130561Sobrien  /* Zero selects the default machine for an arch.  */
186833965Sjdp  machine = 0;
186933965Sjdp  switch (internal_f->f_magic)
187033965Sjdp    {
187191041Sobrien#ifdef OR32_MAGIC_BIG
187291041Sobrien    case OR32_MAGIC_BIG:
187391041Sobrien    case OR32_MAGIC_LITTLE:
187491041Sobrien      arch = bfd_arch_or32;
187591041Sobrien      break;
187691041Sobrien#endif
187733965Sjdp#ifdef PPCMAGIC
187833965Sjdp    case PPCMAGIC:
187933965Sjdp      arch = bfd_arch_powerpc;
188077298Sobrien      break;
188133965Sjdp#endif
188233965Sjdp#ifdef I386MAGIC
188333965Sjdp    case I386MAGIC:
188433965Sjdp    case I386PTXMAGIC:
1885218822Sdim    case I386AIXMAGIC:		/* Danbury PS/2 AIX C Compiler.  */
1886218822Sdim    case LYNXCOFFMAGIC:		/* Shadows the m68k Lynx number below, sigh.  */
188733965Sjdp      arch = bfd_arch_i386;
188833965Sjdp      break;
188933965Sjdp#endif
1890218822Sdim#ifdef AMD64MAGIC
1891218822Sdim    case AMD64MAGIC:
1892218822Sdim      arch = bfd_arch_i386;
1893218822Sdim      machine = bfd_mach_x86_64;
1894218822Sdim      break;
1895218822Sdim#endif
189677298Sobrien#ifdef IA64MAGIC
189777298Sobrien    case IA64MAGIC:
189877298Sobrien      arch = bfd_arch_ia64;
189977298Sobrien      break;
190077298Sobrien#endif
190133965Sjdp#ifdef ARMMAGIC
190233965Sjdp    case ARMMAGIC:
190360484Sobrien    case ARMPEMAGIC:
190460484Sobrien    case THUMBPEMAGIC:
190533965Sjdp      arch = bfd_arch_arm;
1906130561Sobrien      machine = bfd_arm_get_mach_from_notes (abfd, ARM_NOTE_SECTION);
1907130561Sobrien      if (machine == bfd_mach_arm_unknown)
190838889Sjdp	{
1909130561Sobrien	  switch (internal_f->f_flags & F_ARM_ARCHITECTURE_MASK)
1910130561Sobrien	    {
1911130561Sobrien	    case F_ARM_2:  machine = bfd_mach_arm_2;  break;
1912130561Sobrien	    case F_ARM_2a: machine = bfd_mach_arm_2a; break;
1913130561Sobrien	    case F_ARM_3:  machine = bfd_mach_arm_3;  break;
1914130561Sobrien	    default:
1915130561Sobrien	    case F_ARM_3M: machine = bfd_mach_arm_3M; break;
1916130561Sobrien	    case F_ARM_4:  machine = bfd_mach_arm_4;  break;
1917130561Sobrien	    case F_ARM_4T: machine = bfd_mach_arm_4T; break;
1918130561Sobrien	      /* The COFF header does not have enough bits available
1919130561Sobrien		 to cover all the different ARM architectures.  So
1920130561Sobrien		 we interpret F_ARM_5, the highest flag value to mean
1921130561Sobrien		 "the highest ARM architecture known to BFD" which is
1922130561Sobrien		 currently the XScale.  */
1923130561Sobrien	    case F_ARM_5:  machine = bfd_mach_arm_XScale;  break;
1924130561Sobrien	    }
192538889Sjdp	}
192633965Sjdp      break;
192733965Sjdp#endif
192833965Sjdp#ifdef MC68MAGIC
192933965Sjdp    case MC68MAGIC:
193033965Sjdp    case M68MAGIC:
193133965Sjdp#ifdef MC68KBCSMAGIC
193233965Sjdp    case MC68KBCSMAGIC:
193333965Sjdp#endif
193433965Sjdp#ifdef APOLLOM68KMAGIC
193533965Sjdp    case APOLLOM68KMAGIC:
193633965Sjdp#endif
193733965Sjdp#ifdef LYNXCOFFMAGIC
193833965Sjdp    case LYNXCOFFMAGIC:
193933965Sjdp#endif
194033965Sjdp      arch = bfd_arch_m68k;
194138889Sjdp      machine = bfd_mach_m68020;
194233965Sjdp      break;
194333965Sjdp#endif
1944218822Sdim#ifdef MAXQ20MAGIC
1945218822Sdim    case MAXQ20MAGIC:
1946218822Sdim      arch = bfd_arch_maxq;
1947218822Sdim      switch (internal_f->f_flags & F_MACHMASK)
1948218822Sdim	{
1949218822Sdim        case F_MAXQ10:
1950218822Sdim          machine = bfd_mach_maxq10;
1951218822Sdim          break;
1952218822Sdim        case F_MAXQ20:
1953218822Sdim          machine = bfd_mach_maxq20;
1954218822Sdim          break;
1955218822Sdim        default:
1956218822Sdim          return FALSE;
1957218822Sdim	}
1958218822Sdim      break;
1959218822Sdim#endif
196033965Sjdp#ifdef MC88MAGIC
196133965Sjdp    case MC88MAGIC:
196233965Sjdp    case MC88DMAGIC:
196333965Sjdp    case MC88OMAGIC:
196433965Sjdp      arch = bfd_arch_m88k;
196533965Sjdp      machine = 88100;
196633965Sjdp      break;
196733965Sjdp#endif
1968218822Sdim#ifdef Z80MAGIC
1969218822Sdim    case Z80MAGIC:
1970218822Sdim      arch = bfd_arch_z80;
1971218822Sdim      switch (internal_f->f_flags & F_MACHMASK)
1972218822Sdim	{
1973218822Sdim	case 0:
1974218822Sdim	case bfd_mach_z80strict << 12:
1975218822Sdim	case bfd_mach_z80 << 12:
1976218822Sdim	case bfd_mach_z80full << 12:
1977218822Sdim	case bfd_mach_r800 << 12:
1978218822Sdim	  machine = ((unsigned)internal_f->f_flags & F_MACHMASK) >> 12;
1979218822Sdim	  break;
1980218822Sdim	default:
1981218822Sdim	  return FALSE;
1982218822Sdim	}
1983218822Sdim      break;
1984218822Sdim#endif
198533965Sjdp#ifdef Z8KMAGIC
198633965Sjdp    case Z8KMAGIC:
198733965Sjdp      arch = bfd_arch_z8k;
198833965Sjdp      switch (internal_f->f_flags & F_MACHMASK)
198933965Sjdp	{
199033965Sjdp	case F_Z8001:
199133965Sjdp	  machine = bfd_mach_z8001;
199233965Sjdp	  break;
199333965Sjdp	case F_Z8002:
199433965Sjdp	  machine = bfd_mach_z8002;
199533965Sjdp	  break;
199633965Sjdp	default:
1997130561Sobrien	  return FALSE;
199833965Sjdp	}
199933965Sjdp      break;
200033965Sjdp#endif
200133965Sjdp#ifdef I860
200233965Sjdp    case I860MAGIC:
200333965Sjdp      arch = bfd_arch_i860;
200433965Sjdp      break;
200533965Sjdp#endif
200633965Sjdp#ifdef I960
200733965Sjdp#ifdef I960ROMAGIC
200833965Sjdp    case I960ROMAGIC:
200933965Sjdp    case I960RWMAGIC:
201033965Sjdp      arch = bfd_arch_i960;
201133965Sjdp      switch (F_I960TYPE & internal_f->f_flags)
201233965Sjdp	{
201333965Sjdp	default:
201433965Sjdp	case F_I960CORE:
201533965Sjdp	  machine = bfd_mach_i960_core;
201633965Sjdp	  break;
201733965Sjdp	case F_I960KB:
201833965Sjdp	  machine = bfd_mach_i960_kb_sb;
201933965Sjdp	  break;
202033965Sjdp	case F_I960MC:
202133965Sjdp	  machine = bfd_mach_i960_mc;
202233965Sjdp	  break;
202333965Sjdp	case F_I960XA:
202433965Sjdp	  machine = bfd_mach_i960_xa;
202533965Sjdp	  break;
202633965Sjdp	case F_I960CA:
202733965Sjdp	  machine = bfd_mach_i960_ca;
202833965Sjdp	  break;
202933965Sjdp	case F_I960KA:
203033965Sjdp	  machine = bfd_mach_i960_ka_sa;
203133965Sjdp	  break;
203233965Sjdp	case F_I960JX:
203333965Sjdp	  machine = bfd_mach_i960_jx;
203433965Sjdp	  break;
203533965Sjdp	case F_I960HX:
203633965Sjdp	  machine = bfd_mach_i960_hx;
203733965Sjdp	  break;
203833965Sjdp	}
203933965Sjdp      break;
204033965Sjdp#endif
204133965Sjdp#endif
204233965Sjdp
204333965Sjdp#ifdef RS6000COFF_C
204477298Sobrien#ifdef XCOFF64
2045104834Sobrien    case U64_TOCMAGIC:
204677298Sobrien    case U803XTOCMAGIC:
204777298Sobrien#else
204833965Sjdp    case U802ROMAGIC:
204933965Sjdp    case U802WRMAGIC:
205033965Sjdp    case U802TOCMAGIC:
205177298Sobrien#endif
205233965Sjdp      {
205333965Sjdp	int cputype;
205433965Sjdp
205533965Sjdp	if (xcoff_data (abfd)->cputype != -1)
205633965Sjdp	  cputype = xcoff_data (abfd)->cputype & 0xff;
205733965Sjdp	else
205833965Sjdp	  {
205933965Sjdp	    /* We did not get a value from the a.out header.  If the
206033965Sjdp	       file has not been stripped, we may be able to get the
206133965Sjdp	       architecture information from the first symbol, if it
206233965Sjdp	       is a .file symbol.  */
206333965Sjdp	    if (obj_raw_syment_count (abfd) == 0)
206433965Sjdp	      cputype = 0;
206533965Sjdp	    else
206633965Sjdp	      {
206760484Sobrien		bfd_byte *buf;
206833965Sjdp		struct internal_syment sym;
206989857Sobrien		bfd_size_type amt = bfd_coff_symesz (abfd);
207033965Sjdp
2071218822Sdim		buf = bfd_malloc (amt);
207233965Sjdp		if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
207389857Sobrien		    || bfd_bread (buf, amt, abfd) != amt)
207460484Sobrien		  {
207560484Sobrien		    free (buf);
2076130561Sobrien		    return FALSE;
207760484Sobrien		  }
2078218822Sdim		bfd_coff_swap_sym_in (abfd, buf, & sym);
207933965Sjdp		if (sym.n_sclass == C_FILE)
208033965Sjdp		  cputype = sym.n_type & 0xff;
208133965Sjdp		else
208233965Sjdp		  cputype = 0;
208360484Sobrien		free (buf);
208433965Sjdp	      }
208533965Sjdp	  }
208633965Sjdp
208733965Sjdp	/* FIXME: We don't handle all cases here.  */
208833965Sjdp	switch (cputype)
208933965Sjdp	  {
209033965Sjdp	  default:
209133965Sjdp	  case 0:
209289857Sobrien	    arch = bfd_xcoff_architecture (abfd);
209389857Sobrien	    machine = bfd_xcoff_machine (abfd);
209433965Sjdp	    break;
209533965Sjdp
209633965Sjdp	  case 1:
209733965Sjdp	    arch = bfd_arch_powerpc;
209877298Sobrien	    machine = bfd_mach_ppc_601;
209933965Sjdp	    break;
210033965Sjdp	  case 2: /* 64 bit PowerPC */
210133965Sjdp	    arch = bfd_arch_powerpc;
210277298Sobrien	    machine = bfd_mach_ppc_620;
210333965Sjdp	    break;
210433965Sjdp	  case 3:
210533965Sjdp	    arch = bfd_arch_powerpc;
210677298Sobrien	    machine = bfd_mach_ppc;
210733965Sjdp	    break;
210833965Sjdp	  case 4:
210933965Sjdp	    arch = bfd_arch_rs6000;
211077298Sobrien	    machine = bfd_mach_rs6k;
211133965Sjdp	    break;
211233965Sjdp	  }
211333965Sjdp      }
211433965Sjdp      break;
211533965Sjdp#endif
211633965Sjdp
211733965Sjdp#ifdef WE32KMAGIC
211833965Sjdp    case WE32KMAGIC:
211933965Sjdp      arch = bfd_arch_we32k;
212033965Sjdp      break;
212133965Sjdp#endif
212233965Sjdp
212333965Sjdp#ifdef H8300MAGIC
212433965Sjdp    case H8300MAGIC:
212533965Sjdp      arch = bfd_arch_h8300;
212633965Sjdp      machine = bfd_mach_h8300;
2127130561Sobrien      /* !! FIXME this probably isn't the right place for this.  */
212833965Sjdp      abfd->flags |= BFD_IS_RELAXABLE;
212933965Sjdp      break;
213033965Sjdp#endif
213133965Sjdp
213233965Sjdp#ifdef H8300HMAGIC
213333965Sjdp    case H8300HMAGIC:
213433965Sjdp      arch = bfd_arch_h8300;
213533965Sjdp      machine = bfd_mach_h8300h;
2136130561Sobrien      /* !! FIXME this probably isn't the right place for this.  */
213733965Sjdp      abfd->flags |= BFD_IS_RELAXABLE;
213833965Sjdp      break;
213933965Sjdp#endif
214033965Sjdp
214133965Sjdp#ifdef H8300SMAGIC
214233965Sjdp    case H8300SMAGIC:
214333965Sjdp      arch = bfd_arch_h8300;
214433965Sjdp      machine = bfd_mach_h8300s;
2145130561Sobrien      /* !! FIXME this probably isn't the right place for this.  */
214633965Sjdp      abfd->flags |= BFD_IS_RELAXABLE;
214733965Sjdp      break;
214833965Sjdp#endif
214933965Sjdp
2150130561Sobrien#ifdef H8300HNMAGIC
2151130561Sobrien    case H8300HNMAGIC:
2152130561Sobrien      arch = bfd_arch_h8300;
2153130561Sobrien      machine = bfd_mach_h8300hn;
2154130561Sobrien      /* !! FIXME this probably isn't the right place for this.  */
2155130561Sobrien      abfd->flags |= BFD_IS_RELAXABLE;
2156130561Sobrien      break;
2157130561Sobrien#endif
2158130561Sobrien
2159130561Sobrien#ifdef H8300SNMAGIC
2160130561Sobrien    case H8300SNMAGIC:
2161130561Sobrien      arch = bfd_arch_h8300;
2162130561Sobrien      machine = bfd_mach_h8300sn;
2163130561Sobrien      /* !! FIXME this probably isn't the right place for this.  */
2164130561Sobrien      abfd->flags |= BFD_IS_RELAXABLE;
2165130561Sobrien      break;
2166130561Sobrien#endif
2167130561Sobrien
216833965Sjdp#ifdef SH_ARCH_MAGIC_BIG
216933965Sjdp    case SH_ARCH_MAGIC_BIG:
217033965Sjdp    case SH_ARCH_MAGIC_LITTLE:
217160484Sobrien#ifdef COFF_WITH_PE
217260484Sobrien    case SH_ARCH_MAGIC_WINCE:
217360484Sobrien#endif
217433965Sjdp      arch = bfd_arch_sh;
217533965Sjdp      break;
217633965Sjdp#endif
217733965Sjdp
217860484Sobrien#ifdef MIPS_ARCH_MAGIC_WINCE
217960484Sobrien    case MIPS_ARCH_MAGIC_WINCE:
218060484Sobrien      arch = bfd_arch_mips;
218160484Sobrien      break;
218260484Sobrien#endif
218360484Sobrien
218433965Sjdp#ifdef H8500MAGIC
218533965Sjdp    case H8500MAGIC:
218633965Sjdp      arch = bfd_arch_h8500;
218733965Sjdp      break;
218833965Sjdp#endif
218933965Sjdp
219033965Sjdp#ifdef SPARCMAGIC
219133965Sjdp    case SPARCMAGIC:
219233965Sjdp#ifdef LYNXCOFFMAGIC
219333965Sjdp    case LYNXCOFFMAGIC:
219433965Sjdp#endif
219533965Sjdp      arch = bfd_arch_sparc;
219633965Sjdp      break;
219733965Sjdp#endif
219833965Sjdp
219938889Sjdp#ifdef TIC30MAGIC
220038889Sjdp    case TIC30MAGIC:
220138889Sjdp      arch = bfd_arch_tic30;
220233965Sjdp      break;
220333965Sjdp#endif
220433965Sjdp
220577298Sobrien#ifdef TICOFF0MAGIC
220677298Sobrien#ifdef TICOFF_TARGET_ARCH
2207130561Sobrien      /* This TI COFF section should be used by all new TI COFF v0 targets.  */
220877298Sobrien    case TICOFF0MAGIC:
220977298Sobrien      arch = TICOFF_TARGET_ARCH;
2210130561Sobrien      machine = TICOFF_TARGET_MACHINE_GET (internal_f->f_flags);
221177298Sobrien      break;
221277298Sobrien#endif
221377298Sobrien#endif
221477298Sobrien
221577298Sobrien#ifdef TICOFF1MAGIC
2216130561Sobrien      /* This TI COFF section should be used by all new TI COFF v1/2 targets.  */
2217130561Sobrien      /* TI COFF1 and COFF2 use the target_id field to specify which arch.  */
221877298Sobrien    case TICOFF1MAGIC:
221977298Sobrien    case TICOFF2MAGIC:
222077298Sobrien      switch (internal_f->f_target_id)
222177298Sobrien        {
222277298Sobrien#ifdef TI_TARGET_ID
222377298Sobrien        case TI_TARGET_ID:
222477298Sobrien          arch = TICOFF_TARGET_ARCH;
2225130561Sobrien	  machine = TICOFF_TARGET_MACHINE_GET (internal_f->f_flags);
222677298Sobrien          break;
222777298Sobrien#endif
222877298Sobrien        default:
222977298Sobrien          arch = bfd_arch_obscure;
223077298Sobrien          (*_bfd_error_handler)
223177298Sobrien            (_("Unrecognized TI COFF target id '0x%x'"),
223277298Sobrien             internal_f->f_target_id);
223377298Sobrien          break;
223477298Sobrien        }
223577298Sobrien      break;
223677298Sobrien#endif
223777298Sobrien
223860484Sobrien#ifdef TIC80_ARCH_MAGIC
223960484Sobrien    case TIC80_ARCH_MAGIC:
224060484Sobrien      arch = bfd_arch_tic80;
224160484Sobrien      break;
224260484Sobrien#endif
224338889Sjdp
224460484Sobrien#ifdef MCOREMAGIC
224560484Sobrien    case MCOREMAGIC:
224660484Sobrien      arch = bfd_arch_mcore;
224760484Sobrien      break;
224860484Sobrien#endif
2249104834Sobrien
2250104834Sobrien#ifdef W65MAGIC
2251104834Sobrien    case W65MAGIC:
2252104834Sobrien      arch = bfd_arch_w65;
2253104834Sobrien      break;
2254104834Sobrien#endif
2255104834Sobrien
2256130561Sobrien    default:			/* Unreadable input file type.  */
225733965Sjdp      arch = bfd_arch_obscure;
225833965Sjdp      break;
225933965Sjdp    }
226033965Sjdp
226133965Sjdp  bfd_default_set_arch_mach (abfd, arch, machine);
2262130561Sobrien  return TRUE;
226333965Sjdp}
226433965Sjdp
226533965Sjdp#ifdef SYMNAME_IN_DEBUG
226633965Sjdp
2267130561Sobrienstatic bfd_boolean
2268218822Sdimsymname_in_debug_hook (bfd * abfd ATTRIBUTE_UNUSED, struct internal_syment *sym)
226933965Sjdp{
2270104834Sobrien  return SYMNAME_IN_DEBUG (sym) != 0;
227133965Sjdp}
227233965Sjdp
227333965Sjdp#else
227433965Sjdp
227533965Sjdp#define symname_in_debug_hook \
2276218822Sdim  (bfd_boolean (*) (bfd *, struct internal_syment *)) bfd_false
227733965Sjdp
227833965Sjdp#endif
227933965Sjdp
228033965Sjdp#ifdef RS6000COFF_C
228133965Sjdp
228277298Sobrien#ifdef XCOFF64
228377298Sobrien#define FORCE_SYMNAMES_IN_STRINGS
228477298Sobrien#endif
228577298Sobrien
228633965Sjdp/* Handle the csect auxent of a C_EXT or C_HIDEXT symbol.  */
228733965Sjdp
2288130561Sobrienstatic bfd_boolean
2289218822Sdimcoff_pointerize_aux_hook (bfd *abfd ATTRIBUTE_UNUSED,
2290218822Sdim			  combined_entry_type *table_base,
2291218822Sdim			  combined_entry_type *symbol,
2292218822Sdim			  unsigned int indaux,
2293218822Sdim			  combined_entry_type *aux)
229433965Sjdp{
229533965Sjdp  int class = symbol->u.syment.n_sclass;
229633965Sjdp
229733965Sjdp  if ((class == C_EXT || class == C_HIDEXT)
229833965Sjdp      && indaux + 1 == symbol->u.syment.n_numaux)
229933965Sjdp    {
230033965Sjdp      if (SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp) == XTY_LD)
230133965Sjdp	{
230233965Sjdp	  aux->u.auxent.x_csect.x_scnlen.p =
230333965Sjdp	    table_base + aux->u.auxent.x_csect.x_scnlen.l;
230433965Sjdp	  aux->fix_scnlen = 1;
230533965Sjdp	}
230633965Sjdp
2307130561Sobrien      /* Return TRUE to indicate that the caller should not do any
230833965Sjdp         further work on this auxent.  */
2309130561Sobrien      return TRUE;
231033965Sjdp    }
231133965Sjdp
2312130561Sobrien  /* Return FALSE to indicate that this auxent should be handled by
231333965Sjdp     the caller.  */
2314130561Sobrien  return FALSE;
231533965Sjdp}
231633965Sjdp
231733965Sjdp#else
231833965Sjdp#ifdef I960
231933965Sjdp
232033965Sjdp/* We don't want to pointerize bal entries.  */
232133965Sjdp
2322130561Sobrienstatic bfd_boolean
2323218822Sdimcoff_pointerize_aux_hook (bfd *abfd ATTRIBUTE_UNUSED,
2324218822Sdim			  combined_entry_type *table_base ATTRIBUTE_UNUSED,
2325218822Sdim			  combined_entry_type *symbol,
2326218822Sdim			  unsigned int indaux,
2327218822Sdim			  combined_entry_type *aux ATTRIBUTE_UNUSED)
232833965Sjdp{
2329130561Sobrien  /* Return TRUE if we don't want to pointerize this aux entry, which
233033965Sjdp     is the case for the lastfirst aux entry for a C_LEAFPROC symbol.  */
233133965Sjdp  return (indaux == 1
233233965Sjdp	  && (symbol->u.syment.n_sclass == C_LEAFPROC
233333965Sjdp	      || symbol->u.syment.n_sclass == C_LEAFSTAT
233433965Sjdp	      || symbol->u.syment.n_sclass == C_LEAFEXT));
233533965Sjdp}
233633965Sjdp
233733965Sjdp#else /* ! I960 */
233833965Sjdp
233933965Sjdp#define coff_pointerize_aux_hook 0
234033965Sjdp
234133965Sjdp#endif /* ! I960 */
234233965Sjdp#endif /* ! RS6000COFF_C */
234333965Sjdp
2344130561Sobrien/* Print an aux entry.  This returns TRUE if it has printed it.  */
234533965Sjdp
2346130561Sobrienstatic bfd_boolean
2347218822Sdimcoff_print_aux (bfd *abfd ATTRIBUTE_UNUSED,
2348218822Sdim		FILE *file ATTRIBUTE_UNUSED,
2349218822Sdim		combined_entry_type *table_base ATTRIBUTE_UNUSED,
2350218822Sdim		combined_entry_type *symbol ATTRIBUTE_UNUSED,
2351218822Sdim		combined_entry_type *aux ATTRIBUTE_UNUSED,
2352218822Sdim		unsigned int indaux ATTRIBUTE_UNUSED)
235333965Sjdp{
235433965Sjdp#ifdef RS6000COFF_C
235533965Sjdp  if ((symbol->u.syment.n_sclass == C_EXT
235633965Sjdp       || symbol->u.syment.n_sclass == C_HIDEXT)
235733965Sjdp      && indaux + 1 == symbol->u.syment.n_numaux)
235833965Sjdp    {
235933965Sjdp      /* This is a csect entry.  */
236033965Sjdp      fprintf (file, "AUX ");
236133965Sjdp      if (SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp) != XTY_LD)
236233965Sjdp	{
236333965Sjdp	  BFD_ASSERT (! aux->fix_scnlen);
236489857Sobrien#ifdef XCOFF64
2365218822Sdim	  fprintf (file, "val %5lld",
2366218822Sdim		   (long long) aux->u.auxent.x_csect.x_scnlen.l);
236789857Sobrien#else
236889857Sobrien	  fprintf (file, "val %5ld", (long) aux->u.auxent.x_csect.x_scnlen.l);
236989857Sobrien#endif
237033965Sjdp	}
237133965Sjdp      else
237233965Sjdp	{
237333965Sjdp	  fprintf (file, "indx ");
237433965Sjdp	  if (! aux->fix_scnlen)
237589857Sobrien#ifdef XCOFF64
2376218822Sdim	    fprintf (file, "%4lld",
2377218822Sdim		     (long long) aux->u.auxent.x_csect.x_scnlen.l);
237889857Sobrien#else
237989857Sobrien	    fprintf (file, "%4ld", (long) aux->u.auxent.x_csect.x_scnlen.l);
238089857Sobrien#endif
238133965Sjdp	  else
238233965Sjdp	    fprintf (file, "%4ld",
238333965Sjdp		     (long) (aux->u.auxent.x_csect.x_scnlen.p - table_base));
238433965Sjdp	}
238533965Sjdp      fprintf (file,
238633965Sjdp	       " prmhsh %ld snhsh %u typ %d algn %d clss %u stb %ld snstb %u",
238733965Sjdp	       aux->u.auxent.x_csect.x_parmhash,
238833965Sjdp	       (unsigned int) aux->u.auxent.x_csect.x_snhash,
238933965Sjdp	       SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp),
239033965Sjdp	       SMTYP_ALIGN (aux->u.auxent.x_csect.x_smtyp),
239133965Sjdp	       (unsigned int) aux->u.auxent.x_csect.x_smclas,
239233965Sjdp	       aux->u.auxent.x_csect.x_stab,
239333965Sjdp	       (unsigned int) aux->u.auxent.x_csect.x_snstab);
2394130561Sobrien      return TRUE;
239533965Sjdp    }
239633965Sjdp#endif
239733965Sjdp
2398130561Sobrien  /* Return FALSE to indicate that no special action was taken.  */
2399130561Sobrien  return FALSE;
240033965Sjdp}
240133965Sjdp
240233965Sjdp/*
240333965SjdpSUBSUBSECTION
240433965Sjdp	Writing relocations
240533965Sjdp
240633965Sjdp	To write relocations, the back end steps though the
240733965Sjdp	canonical relocation table and create an
240833965Sjdp	@code{internal_reloc}. The symbol index to use is removed from
240933965Sjdp	the @code{offset} field in the symbol table supplied.  The
241033965Sjdp	address comes directly from the sum of the section base
241133965Sjdp	address and the relocation offset; the type is dug directly
241233965Sjdp	from the howto field.  Then the @code{internal_reloc} is
241333965Sjdp	swapped into the shape of an @code{external_reloc} and written
241433965Sjdp	out to disk.
241533965Sjdp
241633965Sjdp*/
241733965Sjdp
241833965Sjdp#ifdef TARG_AUX
241933965Sjdp
242033965Sjdp
2421130561Sobrien/* AUX's ld wants relocations to be sorted.  */
242233965Sjdpstatic int
2423218822Sdimcompare_arelent_ptr (const void * x, const void * y)
242433965Sjdp{
242533965Sjdp  const arelent **a = (const arelent **) x;
242633965Sjdp  const arelent **b = (const arelent **) y;
242733965Sjdp  bfd_size_type aadr = (*a)->address;
242833965Sjdp  bfd_size_type badr = (*b)->address;
242933965Sjdp
243033965Sjdp  return (aadr < badr ? -1 : badr < aadr ? 1 : 0);
243133965Sjdp}
243233965Sjdp
243333965Sjdp#endif /* TARG_AUX */
243433965Sjdp
2435130561Sobrienstatic bfd_boolean
2436218822Sdimcoff_write_relocs (bfd * abfd, int first_undef)
243733965Sjdp{
243833965Sjdp  asection *s;
243933965Sjdp
2440218822Sdim  for (s = abfd->sections; s != NULL; s = s->next)
244133965Sjdp    {
244233965Sjdp      unsigned int i;
244333965Sjdp      struct external_reloc dst;
244433965Sjdp      arelent **p;
244533965Sjdp
244633965Sjdp#ifndef TARG_AUX
244733965Sjdp      p = s->orelocation;
244833965Sjdp#else
244989857Sobrien      {
2450130561Sobrien	/* Sort relocations before we write them out.  */
245189857Sobrien	bfd_size_type amt;
245289857Sobrien
245389857Sobrien	amt = s->reloc_count;
245489857Sobrien	amt *= sizeof (arelent *);
2455218822Sdim	p = bfd_malloc (amt);
245689857Sobrien	if (p == NULL && s->reloc_count > 0)
2457130561Sobrien	  return FALSE;
245889857Sobrien	memcpy (p, s->orelocation, (size_t) amt);
245989857Sobrien	qsort (p, s->reloc_count, sizeof (arelent *), compare_arelent_ptr);
246089857Sobrien      }
246133965Sjdp#endif
246233965Sjdp
246333965Sjdp      if (bfd_seek (abfd, s->rel_filepos, SEEK_SET) != 0)
2464130561Sobrien	return FALSE;
246577298Sobrien
246677298Sobrien#ifdef COFF_WITH_PE
2467104834Sobrien      if (obj_pe (abfd) && s->reloc_count >= 0xffff)
246877298Sobrien	{
2469130561Sobrien	  /* Encode real count here as first reloc.  */
247077298Sobrien	  struct internal_reloc n;
2471130561Sobrien
2472218822Sdim	  memset (& n, 0, sizeof (n));
2473130561Sobrien	  /* Add one to count *this* reloc (grr).  */
247477298Sobrien	  n.r_vaddr = s->reloc_count + 1;
247577298Sobrien	  coff_swap_reloc_out (abfd, &n, &dst);
2476218822Sdim	  if (bfd_bwrite (& dst, (bfd_size_type) bfd_coff_relsz (abfd),
2477218822Sdim			  abfd) != bfd_coff_relsz (abfd))
2478130561Sobrien	    return FALSE;
247977298Sobrien	}
248077298Sobrien#endif
248177298Sobrien
248233965Sjdp      for (i = 0; i < s->reloc_count; i++)
248333965Sjdp	{
248433965Sjdp	  struct internal_reloc n;
248533965Sjdp	  arelent *q = p[i];
2486130561Sobrien
2487218822Sdim	  memset (& n, 0, sizeof (n));
248833965Sjdp
248933965Sjdp	  /* Now we've renumbered the symbols we know where the
249033965Sjdp	     undefined symbols live in the table.  Check the reloc
249133965Sjdp	     entries for symbols who's output bfd isn't the right one.
249233965Sjdp	     This is because the symbol was undefined (which means
249333965Sjdp	     that all the pointers are never made to point to the same
249433965Sjdp	     place). This is a bad thing,'cause the symbols attached
249533965Sjdp	     to the output bfd are indexed, so that the relocation
249633965Sjdp	     entries know which symbol index they point to.  So we
249777298Sobrien	     have to look up the output symbol here.  */
249833965Sjdp
249933965Sjdp	  if (q->sym_ptr_ptr[0]->the_bfd != abfd)
250033965Sjdp	    {
250189857Sobrien	      int j;
250233965Sjdp	      const char *sname = q->sym_ptr_ptr[0]->name;
250333965Sjdp	      asymbol **outsyms = abfd->outsymbols;
2504130561Sobrien
250589857Sobrien	      for (j = first_undef; outsyms[j]; j++)
250633965Sjdp		{
250789857Sobrien		  const char *intable = outsyms[j]->name;
2508130561Sobrien
2509218822Sdim		  if (strcmp (intable, sname) == 0)
2510218822Sdim		    {
2511218822Sdim		      /* Got a hit, so repoint the reloc.  */
2512218822Sdim		      q->sym_ptr_ptr = outsyms + j;
2513218822Sdim		      break;
2514218822Sdim		    }
251533965Sjdp		}
251633965Sjdp	    }
251733965Sjdp
251833965Sjdp	  n.r_vaddr = q->address + s->vma;
251933965Sjdp
252033965Sjdp#ifdef R_IHCONST
252133965Sjdp	  /* The 29k const/consth reloc pair is a real kludge.  The consth
252233965Sjdp	     part doesn't have a symbol; it has an offset.  So rebuilt
252333965Sjdp	     that here.  */
252433965Sjdp	  if (q->howto->type == R_IHCONST)
252533965Sjdp	    n.r_symndx = q->addend;
252633965Sjdp	  else
252733965Sjdp#endif
252833965Sjdp	    if (q->sym_ptr_ptr)
252933965Sjdp	      {
253060484Sobrien#ifdef SECTION_RELATIVE_ABSOLUTE_SYMBOL_P
2531218822Sdim                if (SECTION_RELATIVE_ABSOLUTE_SYMBOL_P (q, s))
253260484Sobrien#else
2533130561Sobrien		if ((*q->sym_ptr_ptr)->section == bfd_abs_section_ptr
2534130561Sobrien		    && ((*q->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0)
253560484Sobrien#endif
253633965Sjdp		  /* This is a relocation relative to the absolute symbol.  */
253733965Sjdp		  n.r_symndx = -1;
253833965Sjdp		else
253933965Sjdp		  {
254033965Sjdp		    n.r_symndx = get_index ((*(q->sym_ptr_ptr)));
2541218822Sdim		    /* Check to see if the symbol reloc points to a symbol
2542218822Sdim		       we don't have in our symbol table.  */
254333965Sjdp		    if (n.r_symndx > obj_conv_table_size (abfd))
2544218822Sdim		      {
2545218822Sdim			bfd_set_error (bfd_error_bad_value);
2546218822Sdim			_bfd_error_handler (_("%B: reloc against a non-existant symbol index: %ld"),
2547218822Sdim					    abfd, n.r_symndx);
2548218822Sdim			return FALSE;
2549218822Sdim		      }
255033965Sjdp		  }
255133965Sjdp	      }
255233965Sjdp
255333965Sjdp#ifdef SWAP_OUT_RELOC_OFFSET
255433965Sjdp	  n.r_offset = q->addend;
255533965Sjdp#endif
255633965Sjdp
255733965Sjdp#ifdef SELECT_RELOC
2558130561Sobrien	  /* Work out reloc type from what is required.  */
255933965Sjdp	  SELECT_RELOC (n, q->howto);
256033965Sjdp#else
256133965Sjdp	  n.r_type = q->howto->type;
256233965Sjdp#endif
256333965Sjdp	  coff_swap_reloc_out (abfd, &n, &dst);
2564130561Sobrien
2565218822Sdim	  if (bfd_bwrite (& dst, (bfd_size_type) bfd_coff_relsz (abfd),
256689857Sobrien			 abfd) != bfd_coff_relsz (abfd))
2567130561Sobrien	    return FALSE;
256833965Sjdp	}
256933965Sjdp
257033965Sjdp#ifdef TARG_AUX
257133965Sjdp      if (p != NULL)
257233965Sjdp	free (p);
257333965Sjdp#endif
257433965Sjdp    }
257533965Sjdp
2576130561Sobrien  return TRUE;
257733965Sjdp}
257833965Sjdp
257933965Sjdp/* Set flags and magic number of a coff file from architecture and machine
2580130561Sobrien   type.  Result is TRUE if we can represent the arch&type, FALSE if not.  */
258133965Sjdp
2582130561Sobrienstatic bfd_boolean
2583218822Sdimcoff_set_flags (bfd * abfd,
2584218822Sdim		unsigned int *magicp ATTRIBUTE_UNUSED,
2585218822Sdim		unsigned short *flagsp ATTRIBUTE_UNUSED)
258633965Sjdp{
258733965Sjdp  switch (bfd_get_arch (abfd))
258833965Sjdp    {
2589218822Sdim#ifdef Z80MAGIC
2590218822Sdim    case bfd_arch_z80:
2591218822Sdim      *magicp = Z80MAGIC;
259233965Sjdp      switch (bfd_get_mach (abfd))
259333965Sjdp	{
2594218822Sdim	case 0:
2595218822Sdim	case bfd_mach_z80strict:
2596218822Sdim	case bfd_mach_z80:
2597218822Sdim	case bfd_mach_z80full:
2598218822Sdim	case bfd_mach_r800:
2599218822Sdim	  *flagsp = bfd_get_mach (abfd) << 12;
260033965Sjdp	  break;
260133965Sjdp	default:
2602130561Sobrien	  return FALSE;
260333965Sjdp	}
2604130561Sobrien      return TRUE;
260533965Sjdp#endif
2606218822Sdim
2607218822Sdim#ifdef Z8KMAGIC
2608218822Sdim    case bfd_arch_z8k:
2609218822Sdim      *magicp = Z8KMAGIC;
2610218822Sdim
2611218822Sdim      switch (bfd_get_mach (abfd))
2612218822Sdim	{
2613218822Sdim	case bfd_mach_z8001: *flagsp = F_Z8001;	break;
2614218822Sdim	case bfd_mach_z8002: *flagsp = F_Z8002;	break;
2615218822Sdim	default:	     return FALSE;
2616218822Sdim	}
2617218822Sdim      return TRUE;
2618218822Sdim#endif
2619218822Sdim
262033965Sjdp#ifdef I960ROMAGIC
262133965Sjdp    case bfd_arch_i960:
262233965Sjdp
262333965Sjdp      {
262433965Sjdp	unsigned flags;
2625218822Sdim
262633965Sjdp	*magicp = I960ROMAGIC;
2627218822Sdim
262833965Sjdp	switch (bfd_get_mach (abfd))
262933965Sjdp	  {
2630218822Sdim	  case bfd_mach_i960_core:  flags = F_I960CORE; break;
2631218822Sdim	  case bfd_mach_i960_kb_sb: flags = F_I960KB;	break;
2632218822Sdim	  case bfd_mach_i960_mc:    flags = F_I960MC;	break;
2633218822Sdim	  case bfd_mach_i960_xa:    flags = F_I960XA;	break;
2634218822Sdim	  case bfd_mach_i960_ca:    flags = F_I960CA;	break;
2635218822Sdim	  case bfd_mach_i960_ka_sa: flags = F_I960KA;	break;
2636218822Sdim	  case bfd_mach_i960_jx:    flags = F_I960JX;	break;
2637218822Sdim	  case bfd_mach_i960_hx:    flags = F_I960HX;	break;
2638218822Sdim	  default:	            return FALSE;
263933965Sjdp	  }
264033965Sjdp	*flagsp = flags;
2641130561Sobrien	return TRUE;
264233965Sjdp      }
264333965Sjdp      break;
264433965Sjdp#endif
264538889Sjdp
264638889Sjdp#ifdef TIC30MAGIC
264738889Sjdp    case bfd_arch_tic30:
264838889Sjdp      *magicp = TIC30MAGIC;
2649130561Sobrien      return TRUE;
265038889Sjdp#endif
265177298Sobrien
265277298Sobrien#ifdef TICOFF_DEFAULT_MAGIC
265377298Sobrien    case TICOFF_TARGET_ARCH:
2654130561Sobrien      /* If there's no indication of which version we want, use the default.  */
265577298Sobrien      if (!abfd->xvec )
265677298Sobrien        *magicp = TICOFF_DEFAULT_MAGIC;
265777298Sobrien      else
265877298Sobrien        {
2659130561Sobrien          /* We may want to output in a different COFF version.  */
266077298Sobrien          switch (abfd->xvec->name[4])
266177298Sobrien            {
266277298Sobrien            case '0':
266377298Sobrien              *magicp = TICOFF0MAGIC;
266477298Sobrien              break;
266577298Sobrien            case '1':
266677298Sobrien              *magicp = TICOFF1MAGIC;
266777298Sobrien              break;
266877298Sobrien            case '2':
266977298Sobrien              *magicp = TICOFF2MAGIC;
267077298Sobrien              break;
267177298Sobrien            default:
2672130561Sobrien              return FALSE;
267377298Sobrien            }
267477298Sobrien        }
2675130561Sobrien      TICOFF_TARGET_MACHINE_SET (flagsp, bfd_get_mach (abfd));
2676130561Sobrien      return TRUE;
267777298Sobrien#endif
267877298Sobrien
267960484Sobrien#ifdef TIC80_ARCH_MAGIC
268060484Sobrien    case bfd_arch_tic80:
268160484Sobrien      *magicp = TIC80_ARCH_MAGIC;
2682130561Sobrien      return TRUE;
268360484Sobrien#endif
2684218822Sdim
268533965Sjdp#ifdef ARMMAGIC
268633965Sjdp    case bfd_arch_arm:
268760484Sobrien#ifdef ARM_WINCE
268860484Sobrien      * magicp = ARMPEMAGIC;
268960484Sobrien#else
269038889Sjdp      * magicp = ARMMAGIC;
269160484Sobrien#endif
269238889Sjdp      * flagsp = 0;
269338889Sjdp      if (APCS_SET (abfd))
269438889Sjdp	{
269538889Sjdp	  if (APCS_26_FLAG (abfd))
269638889Sjdp	    * flagsp |= F_APCS26;
269777298Sobrien
269838889Sjdp	  if (APCS_FLOAT_FLAG (abfd))
269938889Sjdp	    * flagsp |= F_APCS_FLOAT;
270077298Sobrien
270138889Sjdp	  if (PIC_FLAG (abfd))
270238889Sjdp	    * flagsp |= F_PIC;
270338889Sjdp	}
270438889Sjdp      if (INTERWORK_SET (abfd) && INTERWORK_FLAG (abfd))
270538889Sjdp	* flagsp |= F_INTERWORK;
270638889Sjdp      switch (bfd_get_mach (abfd))
270738889Sjdp	{
270838889Sjdp	case bfd_mach_arm_2:  * flagsp |= F_ARM_2;  break;
270938889Sjdp	case bfd_mach_arm_2a: * flagsp |= F_ARM_2a; break;
271038889Sjdp	case bfd_mach_arm_3:  * flagsp |= F_ARM_3;  break;
271138889Sjdp	case bfd_mach_arm_3M: * flagsp |= F_ARM_3M; break;
271238889Sjdp	case bfd_mach_arm_4:  * flagsp |= F_ARM_4;  break;
271338889Sjdp	case bfd_mach_arm_4T: * flagsp |= F_ARM_4T; break;
271460484Sobrien	case bfd_mach_arm_5:  * flagsp |= F_ARM_5;  break;
271591041Sobrien	  /* FIXME: we do not have F_ARM vaues greater than F_ARM_5.
271691041Sobrien	     See also the comment in coff_set_arch_mach_hook().  */
271777298Sobrien	case bfd_mach_arm_5T: * flagsp |= F_ARM_5;  break;
271877298Sobrien	case bfd_mach_arm_5TE: * flagsp |= F_ARM_5; break;
271977298Sobrien	case bfd_mach_arm_XScale: * flagsp |= F_ARM_5; break;
272038889Sjdp	}
2721130561Sobrien      return TRUE;
272233965Sjdp#endif
2723218822Sdim
272433965Sjdp#ifdef PPCMAGIC
272533965Sjdp    case bfd_arch_powerpc:
272633965Sjdp      *magicp = PPCMAGIC;
2727130561Sobrien      return TRUE;
272833965Sjdp#endif
2729218822Sdim
2730218822Sdim#if defined(I386MAGIC) || defined(AMD64MAGIC)
273133965Sjdp    case bfd_arch_i386:
2732218822Sdim#if defined(I386MAGIC)
273333965Sjdp      *magicp = I386MAGIC;
2734218822Sdim#endif
2735218822Sdim#if defined LYNXOS
273677298Sobrien      /* Just overwrite the usual value if we're doing Lynx.  */
273733965Sjdp      *magicp = LYNXCOFFMAGIC;
273833965Sjdp#endif
2739218822Sdim#if defined AMD64MAGIC
2740218822Sdim      *magicp = AMD64MAGIC;
2741218822Sdim#endif
2742130561Sobrien      return TRUE;
274333965Sjdp#endif
2744218822Sdim
274533965Sjdp#ifdef I860MAGIC
274633965Sjdp    case bfd_arch_i860:
274733965Sjdp      *magicp = I860MAGIC;
2748130561Sobrien      return TRUE;
274933965Sjdp#endif
2750218822Sdim
275177298Sobrien#ifdef IA64MAGIC
275277298Sobrien    case bfd_arch_ia64:
275377298Sobrien      *magicp = IA64MAGIC;
2754130561Sobrien      return TRUE;
275577298Sobrien#endif
2756218822Sdim
275733965Sjdp#ifdef MC68MAGIC
275833965Sjdp    case bfd_arch_m68k:
275933965Sjdp#ifdef APOLLOM68KMAGIC
276033965Sjdp      *magicp = APOLLO_COFF_VERSION_NUMBER;
276133965Sjdp#else
276233965Sjdp      /* NAMES_HAVE_UNDERSCORE may be defined by coff-u68k.c.  */
276333965Sjdp#ifdef NAMES_HAVE_UNDERSCORE
276433965Sjdp      *magicp = MC68KBCSMAGIC;
276533965Sjdp#else
276633965Sjdp      *magicp = MC68MAGIC;
276733965Sjdp#endif
276833965Sjdp#endif
276933965Sjdp#ifdef LYNXOS
277077298Sobrien      /* Just overwrite the usual value if we're doing Lynx.  */
277133965Sjdp      *magicp = LYNXCOFFMAGIC;
277233965Sjdp#endif
2773130561Sobrien      return TRUE;
277433965Sjdp#endif
277533965Sjdp
277633965Sjdp#ifdef MC88MAGIC
277733965Sjdp    case bfd_arch_m88k:
277833965Sjdp      *magicp = MC88OMAGIC;
2779130561Sobrien      return TRUE;
278033965Sjdp#endif
2781218822Sdim
278233965Sjdp#ifdef H8300MAGIC
278333965Sjdp    case bfd_arch_h8300:
278433965Sjdp      switch (bfd_get_mach (abfd))
278533965Sjdp	{
2786218822Sdim	case bfd_mach_h8300:   *magicp = H8300MAGIC;   return TRUE;
2787218822Sdim	case bfd_mach_h8300h:  *magicp = H8300HMAGIC;  return TRUE;
2788218822Sdim	case bfd_mach_h8300s:  *magicp = H8300SMAGIC;  return TRUE;
2789218822Sdim	case bfd_mach_h8300hn: *magicp = H8300HNMAGIC; return TRUE;
2790218822Sdim	case bfd_mach_h8300sn: *magicp = H8300SNMAGIC; return TRUE;
2791218822Sdim	default: break;
279233965Sjdp	}
279333965Sjdp      break;
279433965Sjdp#endif
279533965Sjdp
279633965Sjdp#ifdef SH_ARCH_MAGIC_BIG
279733965Sjdp    case bfd_arch_sh:
279860484Sobrien#ifdef COFF_IMAGE_WITH_PE
279960484Sobrien      *magicp = SH_ARCH_MAGIC_WINCE;
280060484Sobrien#else
280133965Sjdp      if (bfd_big_endian (abfd))
280233965Sjdp	*magicp = SH_ARCH_MAGIC_BIG;
280333965Sjdp      else
280433965Sjdp	*magicp = SH_ARCH_MAGIC_LITTLE;
280560484Sobrien#endif
2806130561Sobrien      return TRUE;
280733965Sjdp#endif
280833965Sjdp
280960484Sobrien#ifdef MIPS_ARCH_MAGIC_WINCE
281060484Sobrien    case bfd_arch_mips:
281160484Sobrien      *magicp = MIPS_ARCH_MAGIC_WINCE;
2812130561Sobrien      return TRUE;
281360484Sobrien#endif
281460484Sobrien
281533965Sjdp#ifdef SPARCMAGIC
281633965Sjdp    case bfd_arch_sparc:
281733965Sjdp      *magicp = SPARCMAGIC;
281833965Sjdp#ifdef LYNXOS
281977298Sobrien      /* Just overwrite the usual value if we're doing Lynx.  */
282033965Sjdp      *magicp = LYNXCOFFMAGIC;
282133965Sjdp#endif
2822130561Sobrien      return TRUE;
282333965Sjdp#endif
282433965Sjdp
282533965Sjdp#ifdef H8500MAGIC
282633965Sjdp    case bfd_arch_h8500:
282733965Sjdp      *magicp = H8500MAGIC;
2828130561Sobrien      return TRUE;
282933965Sjdp      break;
283033965Sjdp#endif
283133965Sjdp
283233965Sjdp#ifdef WE32KMAGIC
283333965Sjdp    case bfd_arch_we32k:
283433965Sjdp      *magicp = WE32KMAGIC;
2835130561Sobrien      return TRUE;
283633965Sjdp#endif
283733965Sjdp
283877298Sobrien#ifdef RS6000COFF_C
283933965Sjdp    case bfd_arch_rs6000:
284033965Sjdp#ifndef PPCMAGIC
284133965Sjdp    case bfd_arch_powerpc:
284233965Sjdp#endif
2843104834Sobrien      BFD_ASSERT (bfd_get_flavour (abfd) == bfd_target_xcoff_flavour);
2844104834Sobrien      *magicp = bfd_xcoff_magic_number (abfd);
2845130561Sobrien      return TRUE;
284633965Sjdp#endif
284733965Sjdp
284860484Sobrien#ifdef MCOREMAGIC
284960484Sobrien    case bfd_arch_mcore:
285060484Sobrien      * magicp = MCOREMAGIC;
2851130561Sobrien      return TRUE;
285260484Sobrien#endif
285377298Sobrien
285468765Sobrien#ifdef W65MAGIC
285568765Sobrien    case bfd_arch_w65:
285668765Sobrien      *magicp = W65MAGIC;
2857130561Sobrien      return TRUE;
285868765Sobrien#endif
285968765Sobrien
286091041Sobrien#ifdef OR32_MAGIC_BIG
286191041Sobrien    case bfd_arch_or32:
286291041Sobrien      if (bfd_big_endian (abfd))
286391041Sobrien        * magicp = OR32_MAGIC_BIG;
286491041Sobrien      else
286591041Sobrien        * magicp = OR32_MAGIC_LITTLE;
2866130561Sobrien      return TRUE;
286791041Sobrien#endif
286891041Sobrien
2869218822Sdim#ifdef MAXQ20MAGIC
2870218822Sdim    case bfd_arch_maxq:
2871218822Sdim      * magicp = MAXQ20MAGIC;
2872218822Sdim      switch (bfd_get_mach (abfd))
2873218822Sdim	{
2874218822Sdim	case bfd_mach_maxq10: * flagsp = F_MAXQ10; return TRUE;
2875218822Sdim	case bfd_mach_maxq20: * flagsp = F_MAXQ20; return TRUE;
2876218822Sdim	default:	      return FALSE;
2877218822Sdim	}
2878218822Sdim#endif
2879218822Sdim
288077298Sobrien    default:			/* Unknown architecture.  */
2881130561Sobrien      /* Fall through to "return FALSE" below, to avoid
288277298Sobrien	 "statement never reached" errors on the one below.  */
288333965Sjdp      break;
288433965Sjdp    }
288533965Sjdp
2886130561Sobrien  return FALSE;
288733965Sjdp}
288833965Sjdp
2889130561Sobrienstatic bfd_boolean
2890218822Sdimcoff_set_arch_mach (bfd * abfd,
2891218822Sdim		    enum bfd_architecture arch,
2892218822Sdim		    unsigned long machine)
289333965Sjdp{
289433965Sjdp  unsigned dummy1;
289533965Sjdp  unsigned short dummy2;
289633965Sjdp
289733965Sjdp  if (! bfd_default_set_arch_mach (abfd, arch, machine))
2898130561Sobrien    return FALSE;
289933965Sjdp
2900104834Sobrien  if (arch != bfd_arch_unknown
2901104834Sobrien      && ! coff_set_flags (abfd, &dummy1, &dummy2))
2902218822Sdim    return FALSE;		/* We can't represent this type.  */
290333965Sjdp
2904218822Sdim  return TRUE;			/* We're easy...  */
290533965Sjdp}
290633965Sjdp
290760484Sobrien#ifdef COFF_IMAGE_WITH_PE
290833965Sjdp
290960484Sobrien/* This is used to sort sections by VMA, as required by PE image
291060484Sobrien   files.  */
291160484Sobrien
291260484Sobrienstatic int
2913218822Sdimsort_by_secaddr (const void * arg1, const void * arg2)
291460484Sobrien{
291560484Sobrien  const asection *a = *(const asection **) arg1;
291660484Sobrien  const asection *b = *(const asection **) arg2;
291760484Sobrien
291860484Sobrien  if (a->vma < b->vma)
291960484Sobrien    return -1;
292060484Sobrien  else if (a->vma > b->vma)
292160484Sobrien    return 1;
2922218822Sdim
2923218822Sdim  return 0;
292460484Sobrien}
292560484Sobrien
292660484Sobrien#endif /* COFF_IMAGE_WITH_PE */
292760484Sobrien
292877298Sobrien/* Calculate the file position for each section.  */
292933965Sjdp
293038889Sjdp#ifndef I960
293138889Sjdp#define ALIGN_SECTIONS_IN_FILE
293238889Sjdp#endif
293377298Sobrien#if defined(TIC80COFF) || defined(TICOFF)
293460484Sobrien#undef ALIGN_SECTIONS_IN_FILE
293560484Sobrien#endif
293638889Sjdp
2937130561Sobrienstatic bfd_boolean
2938218822Sdimcoff_compute_section_file_positions (bfd * abfd)
293933965Sjdp{
294033965Sjdp  asection *current;
2941218822Sdim  asection *previous = NULL;
294260484Sobrien  file_ptr sofar = bfd_coff_filhsz (abfd);
2943130561Sobrien  bfd_boolean align_adjust;
294438889Sjdp#ifdef ALIGN_SECTIONS_IN_FILE
294533965Sjdp  file_ptr old_sofar;
294633965Sjdp#endif
294733965Sjdp
294833965Sjdp#ifdef RS6000COFF_C
294933965Sjdp  /* On XCOFF, if we have symbols, set up the .debug section.  */
295033965Sjdp  if (bfd_get_symcount (abfd) > 0)
295133965Sjdp    {
295233965Sjdp      bfd_size_type sz;
295333965Sjdp      bfd_size_type i, symcount;
295433965Sjdp      asymbol **symp;
295533965Sjdp
295633965Sjdp      sz = 0;
295733965Sjdp      symcount = bfd_get_symcount (abfd);
295833965Sjdp      for (symp = abfd->outsymbols, i = 0; i < symcount; symp++, i++)
295933965Sjdp	{
296033965Sjdp	  coff_symbol_type *cf;
296133965Sjdp
296233965Sjdp	  cf = coff_symbol_from (abfd, *symp);
296333965Sjdp	  if (cf != NULL
296433965Sjdp	      && cf->native != NULL
296533965Sjdp	      && SYMNAME_IN_DEBUG (&cf->native->u.syment))
296633965Sjdp	    {
296733965Sjdp	      size_t len;
296833965Sjdp
296933965Sjdp	      len = strlen (bfd_asymbol_name (*symp));
297077298Sobrien	      if (len > SYMNMLEN || bfd_coff_force_symnames_in_strings (abfd))
297177298Sobrien		sz += len + 1 + bfd_coff_debug_string_prefix_length (abfd);
297233965Sjdp	    }
297333965Sjdp	}
297433965Sjdp      if (sz > 0)
297533965Sjdp	{
297633965Sjdp	  asection *dsec;
297733965Sjdp
2978218822Sdim	  dsec = bfd_make_section_old_way (abfd, DOT_DEBUG);
297933965Sjdp	  if (dsec == NULL)
298033965Sjdp	    abort ();
2981218822Sdim	  dsec->size = sz;
298233965Sjdp	  dsec->flags |= SEC_HAS_CONTENTS;
298333965Sjdp	}
298433965Sjdp    }
298533965Sjdp#endif
298633965Sjdp
298733965Sjdp#ifdef COFF_IMAGE_WITH_PE
298833965Sjdp  int page_size;
2989218822Sdim
299077298Sobrien  if (coff_data (abfd)->link_info)
299133965Sjdp    {
299233965Sjdp      page_size = pe_data (abfd)->pe_opthdr.FileAlignment;
2993130561Sobrien
2994130561Sobrien      /* If no file alignment has been set, default to one.
2995130561Sobrien	 This repairs 'ld -r' for arm-wince-pe target.  */
2996130561Sobrien      if (page_size == 0)
2997130561Sobrien        page_size = 1;
299833965Sjdp    }
299933965Sjdp  else
300033965Sjdp    page_size = PE_DEF_FILE_ALIGNMENT;
300133965Sjdp#else
300233965Sjdp#ifdef COFF_PAGE_SIZE
300333965Sjdp  int page_size = COFF_PAGE_SIZE;
300433965Sjdp#endif
300533965Sjdp#endif
300633965Sjdp
300733965Sjdp  if (bfd_get_start_address (abfd))
3008218822Sdim    /*  A start address may have been added to the original file. In this
3009218822Sdim	case it will need an optional header to record it.  */
3010218822Sdim    abfd->flags |= EXEC_P;
301133965Sjdp
301233965Sjdp  if (abfd->flags & EXEC_P)
301360484Sobrien    sofar += bfd_coff_aoutsz (abfd);
301433965Sjdp#ifdef RS6000COFF_C
301533965Sjdp  else if (xcoff_data (abfd)->full_aouthdr)
301660484Sobrien    sofar += bfd_coff_aoutsz (abfd);
301733965Sjdp  else
301833965Sjdp    sofar += SMALL_AOUTSZ;
301933965Sjdp#endif
302033965Sjdp
302160484Sobrien  sofar += abfd->section_count * bfd_coff_scnhsz (abfd);
302233965Sjdp
302333965Sjdp#ifdef RS6000COFF_C
302433965Sjdp  /* XCOFF handles overflows in the reloc and line number count fields
302533965Sjdp     by allocating a new section header to hold the correct counts.  */
302633965Sjdp  for (current = abfd->sections; current != NULL; current = current->next)
302733965Sjdp    if (current->reloc_count >= 0xffff || current->lineno_count >= 0xffff)
302860484Sobrien      sofar += bfd_coff_scnhsz (abfd);
302933965Sjdp#endif
303033965Sjdp
303160484Sobrien#ifdef COFF_IMAGE_WITH_PE
303260484Sobrien  {
303360484Sobrien    /* PE requires the sections to be in memory order when listed in
303460484Sobrien       the section headers.  It also does not like empty loadable
303560484Sobrien       sections.  The sections apparently do not have to be in the
303660484Sobrien       right order in the image file itself, but we do need to get the
303760484Sobrien       target_index values right.  */
303860484Sobrien
303989857Sobrien    unsigned int count;
304060484Sobrien    asection **section_list;
304189857Sobrien    unsigned int i;
304260484Sobrien    int target_index;
304389857Sobrien    bfd_size_type amt;
304460484Sobrien
304560484Sobrien    count = 0;
304660484Sobrien    for (current = abfd->sections; current != NULL; current = current->next)
304760484Sobrien      ++count;
304860484Sobrien
304960484Sobrien    /* We allocate an extra cell to simplify the final loop.  */
305089857Sobrien    amt = sizeof (struct asection *) * (count + 1);
305189857Sobrien    section_list = bfd_malloc (amt);
305260484Sobrien    if (section_list == NULL)
3053130561Sobrien      return FALSE;
305460484Sobrien
305560484Sobrien    i = 0;
305660484Sobrien    for (current = abfd->sections; current != NULL; current = current->next)
305760484Sobrien      {
305860484Sobrien	section_list[i] = current;
305960484Sobrien	++i;
306060484Sobrien      }
306160484Sobrien    section_list[i] = NULL;
306260484Sobrien
306360484Sobrien    qsort (section_list, count, sizeof (asection *), sort_by_secaddr);
306460484Sobrien
306560484Sobrien    /* Rethread the linked list into sorted order; at the same time,
306660484Sobrien       assign target_index values.  */
306760484Sobrien    target_index = 1;
3068218822Sdim    abfd->sections = NULL;
3069218822Sdim    abfd->section_last = NULL;
307060484Sobrien    for (i = 0; i < count; i++)
307160484Sobrien      {
307260484Sobrien	current = section_list[i];
3073218822Sdim	bfd_section_list_append (abfd, current);
307460484Sobrien
307560484Sobrien	/* Later, if the section has zero size, we'll be throwing it
307660484Sobrien	   away, so we don't want to number it now.  Note that having
307760484Sobrien	   a zero size and having real contents are different
307860484Sobrien	   concepts: .bss has no contents, but (usually) non-zero
307960484Sobrien	   size.  */
3080218822Sdim	if (current->size == 0)
308160484Sobrien	  {
308260484Sobrien	    /* Discard.  However, it still might have (valid) symbols
308360484Sobrien	       in it, so arbitrarily set it to section 1 (indexing is
308460484Sobrien	       1-based here; usually .text).  __end__ and other
308560484Sobrien	       contents of .endsection really have this happen.
308660484Sobrien	       FIXME: This seems somewhat dubious.  */
308760484Sobrien	    current->target_index = 1;
308860484Sobrien	  }
308960484Sobrien	else
309060484Sobrien	  current->target_index = target_index++;
309160484Sobrien      }
309260484Sobrien
309360484Sobrien    free (section_list);
309460484Sobrien  }
309560484Sobrien#else /* ! COFF_IMAGE_WITH_PE */
309660484Sobrien  {
309760484Sobrien    /* Set the target_index field.  */
309860484Sobrien    int target_index;
309960484Sobrien
310060484Sobrien    target_index = 1;
310160484Sobrien    for (current = abfd->sections; current != NULL; current = current->next)
310260484Sobrien      current->target_index = target_index++;
310360484Sobrien  }
310460484Sobrien#endif /* ! COFF_IMAGE_WITH_PE */
310560484Sobrien
3106130561Sobrien  align_adjust = FALSE;
310760484Sobrien  for (current = abfd->sections;
3108218822Sdim       current != NULL;
310960484Sobrien       current = current->next)
311033965Sjdp    {
311138889Sjdp#ifdef COFF_IMAGE_WITH_PE
311260484Sobrien      /* With PE we have to pad each section to be a multiple of its
311360484Sobrien	 page size too, and remember both sizes.  */
311460484Sobrien      if (coff_section_data (abfd, current) == NULL)
311538889Sjdp	{
311689857Sobrien	  bfd_size_type amt = sizeof (struct coff_section_tdata);
3117218822Sdim
3118218822Sdim	  current->used_by_bfd = bfd_zalloc (abfd, amt);
311960484Sobrien	  if (current->used_by_bfd == NULL)
3120130561Sobrien	    return FALSE;
312138889Sjdp	}
312260484Sobrien      if (pei_section_data (abfd, current) == NULL)
312360484Sobrien	{
312489857Sobrien	  bfd_size_type amt = sizeof (struct pei_section_tdata);
3125218822Sdim
3126218822Sdim	  coff_section_data (abfd, current)->tdata = bfd_zalloc (abfd, amt);
312760484Sobrien	  if (coff_section_data (abfd, current)->tdata == NULL)
3128130561Sobrien	    return FALSE;
312960484Sobrien	}
313060484Sobrien      if (pei_section_data (abfd, current)->virt_size == 0)
3131218822Sdim	pei_section_data (abfd, current)->virt_size = current->size;
313238889Sjdp#endif
313338889Sjdp
313460484Sobrien      /* Only deal with sections which have contents.  */
313533965Sjdp      if (!(current->flags & SEC_HAS_CONTENTS))
313633965Sjdp	continue;
313733965Sjdp
313860484Sobrien#ifdef COFF_IMAGE_WITH_PE
313960484Sobrien      /* Make sure we skip empty sections in a PE image.  */
3140218822Sdim      if (current->size == 0)
314160484Sobrien	continue;
314260484Sobrien#endif
314360484Sobrien
314433965Sjdp      /* Align the sections in the file to the same boundary on
314533965Sjdp	 which they are aligned in virtual memory.  I960 doesn't
314633965Sjdp	 do this (FIXME) so we can stay in sync with Intel.  960
314777298Sobrien	 doesn't yet page from files...  */
314838889Sjdp#ifdef ALIGN_SECTIONS_IN_FILE
314933965Sjdp      if ((abfd->flags & EXEC_P) != 0)
315033965Sjdp	{
3151130561Sobrien	  /* Make sure this section is aligned on the right boundary - by
3152130561Sobrien	     padding the previous section up if necessary.  */
3153218822Sdim	  old_sofar = sofar;
315433965Sjdp
315589857Sobrien#ifdef RS6000COFF_C
315689857Sobrien	  /* AIX loader checks the text section alignment of (vma - filepos)
315789857Sobrien	     So even though the filepos may be aligned wrt the o_algntext, for
3158130561Sobrien	     AIX executables, this check fails. This shows up when a native
315989857Sobrien	     AIX executable is stripped with gnu strip because the default vma
316089857Sobrien	     of native is 0x10000150 but default for gnu is 0x10000140.  Gnu
3161130561Sobrien	     stripped gnu excutable passes this check because the filepos is
3162104834Sobrien	     0x0140.  This problem also show up with 64 bit shared objects. The
3163104834Sobrien	     data section must also be aligned.  */
3164130561Sobrien	  if (!strcmp (current->name, _TEXT)
3165130561Sobrien	      || !strcmp (current->name, _DATA))
316689857Sobrien	    {
316789857Sobrien	      bfd_vma pad;
316889857Sobrien	      bfd_vma align;
316989857Sobrien
317089857Sobrien	      sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
317189857Sobrien
317289857Sobrien	      align = 1 << current->alignment_power;
317389857Sobrien	      pad = abs (current->vma - sofar) % align;
3174130561Sobrien
3175130561Sobrien	      if (pad)
317689857Sobrien		{
317789857Sobrien		  pad = align - pad;
317889857Sobrien		  sofar += pad;
317989857Sobrien		}
318089857Sobrien	    }
318189857Sobrien	  else
318289857Sobrien#else
318389857Sobrien	    {
318489857Sobrien	      sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
318589857Sobrien	    }
318689857Sobrien#endif
3187218822Sdim	  if (previous != NULL)
3188218822Sdim	    previous->size += sofar - old_sofar;
318933965Sjdp	}
319033965Sjdp
319133965Sjdp#endif
319233965Sjdp
319333965Sjdp      /* In demand paged files the low order bits of the file offset
319433965Sjdp	 must match the low order bits of the virtual address.  */
319533965Sjdp#ifdef COFF_PAGE_SIZE
319633965Sjdp      if ((abfd->flags & D_PAGED) != 0
319733965Sjdp	  && (current->flags & SEC_ALLOC) != 0)
3198218822Sdim	sofar += (current->vma - (bfd_vma) sofar) % page_size;
319933965Sjdp#endif
320033965Sjdp      current->filepos = sofar;
320133965Sjdp
320233965Sjdp#ifdef COFF_IMAGE_WITH_PE
320360484Sobrien      /* Set the padded size.  */
3204218822Sdim      current->size = (current->size + page_size -1) & -page_size;
320533965Sjdp#endif
320633965Sjdp
3207218822Sdim      sofar += current->size;
320833965Sjdp
320938889Sjdp#ifdef ALIGN_SECTIONS_IN_FILE
3210130561Sobrien      /* Make sure that this section is of the right size too.  */
321133965Sjdp      if ((abfd->flags & EXEC_P) == 0)
321233965Sjdp	{
321333965Sjdp	  bfd_size_type old_size;
321433965Sjdp
3215218822Sdim	  old_size = current->size;
3216218822Sdim	  current->size = BFD_ALIGN (current->size,
3217218822Sdim				     1 << current->alignment_power);
3218218822Sdim	  align_adjust = current->size != old_size;
3219218822Sdim	  sofar += current->size - old_size;
322033965Sjdp	}
322133965Sjdp      else
322233965Sjdp	{
322333965Sjdp	  old_sofar = sofar;
322433965Sjdp	  sofar = BFD_ALIGN (sofar, 1 << current->alignment_power);
322533965Sjdp	  align_adjust = sofar != old_sofar;
3226218822Sdim	  current->size += sofar - old_sofar;
322733965Sjdp	}
322833965Sjdp#endif
322933965Sjdp
323038889Sjdp#ifdef COFF_IMAGE_WITH_PE
323138889Sjdp      /* For PE we need to make sure we pad out to the aligned
3232218822Sdim         size, in case the caller only writes out data to the
3233218822Sdim         unaligned size.  */
3234218822Sdim      if (pei_section_data (abfd, current)->virt_size < current->size)
3235130561Sobrien	align_adjust = TRUE;
323638889Sjdp#endif
323738889Sjdp
323833965Sjdp#ifdef _LIB
323933965Sjdp      /* Force .lib sections to start at zero.  The vma is then
324033965Sjdp	 incremented in coff_set_section_contents.  This is right for
324133965Sjdp	 SVR3.2.  */
324233965Sjdp      if (strcmp (current->name, _LIB) == 0)
3243223262Sbenl	(void) bfd_set_section_vma (abfd, current, 0);
324433965Sjdp#endif
324533965Sjdp
324633965Sjdp      previous = current;
324733965Sjdp    }
324833965Sjdp
324933965Sjdp  /* It is now safe to write to the output file.  If we needed an
325033965Sjdp     alignment adjustment for the last section, then make sure that
325133965Sjdp     there is a byte at offset sofar.  If there are no symbols and no
325233965Sjdp     relocs, then nothing follows the last section.  If we don't force
325333965Sjdp     the last byte out, then the file may appear to be truncated.  */
325433965Sjdp  if (align_adjust)
325533965Sjdp    {
325633965Sjdp      bfd_byte b;
325733965Sjdp
325833965Sjdp      b = 0;
325933965Sjdp      if (bfd_seek (abfd, sofar - 1, SEEK_SET) != 0
326089857Sobrien	  || bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
3261130561Sobrien	return FALSE;
326233965Sjdp    }
326333965Sjdp
326433965Sjdp  /* Make sure the relocations are aligned.  We don't need to make
326533965Sjdp     sure that this byte exists, because it will only matter if there
326633965Sjdp     really are relocs.  */
326733965Sjdp  sofar = BFD_ALIGN (sofar, 1 << COFF_DEFAULT_SECTION_ALIGNMENT_POWER);
326833965Sjdp
326933965Sjdp  obj_relocbase (abfd) = sofar;
3270130561Sobrien  abfd->output_has_begun = TRUE;
327133965Sjdp
3272130561Sobrien  return TRUE;
327333965Sjdp}
327433965Sjdp
3275104834Sobrien#ifdef COFF_IMAGE_WITH_PE
3276104834Sobrien
3277104834Sobrienstatic unsigned int pelength;
3278104834Sobrienstatic unsigned int peheader;
3279104834Sobrien
3280130561Sobrienstatic bfd_boolean
3281218822Sdimcoff_read_word (bfd *abfd, unsigned int *value)
3282104834Sobrien{
3283104834Sobrien  unsigned char b[2];
3284104834Sobrien  int status;
3285104834Sobrien
3286104834Sobrien  status = bfd_bread (b, (bfd_size_type) 2, abfd);
3287104834Sobrien  if (status < 1)
3288104834Sobrien    {
3289104834Sobrien      *value = 0;
3290130561Sobrien      return FALSE;
3291104834Sobrien    }
3292104834Sobrien
3293104834Sobrien  if (status == 1)
3294104834Sobrien    *value = (unsigned int) b[0];
3295104834Sobrien  else
3296104834Sobrien    *value = (unsigned int) (b[0] + (b[1] << 8));
3297104834Sobrien
3298104834Sobrien  pelength += (unsigned int) status;
3299104834Sobrien
3300130561Sobrien  return TRUE;
3301104834Sobrien}
3302104834Sobrien
3303104834Sobrienstatic unsigned int
3304218822Sdimcoff_compute_checksum (bfd *abfd)
3305104834Sobrien{
3306130561Sobrien  bfd_boolean more_data;
3307104834Sobrien  file_ptr filepos;
3308104834Sobrien  unsigned int value;
3309104834Sobrien  unsigned int total;
3310104834Sobrien
3311104834Sobrien  total = 0;
3312104834Sobrien  pelength = 0;
3313104834Sobrien  filepos = (file_ptr) 0;
3314104834Sobrien
3315104834Sobrien  do
3316104834Sobrien    {
3317104834Sobrien      if (bfd_seek (abfd, filepos, SEEK_SET) != 0)
3318104834Sobrien	return 0;
3319104834Sobrien
3320104834Sobrien      more_data = coff_read_word (abfd, &value);
3321104834Sobrien      total += value;
3322104834Sobrien      total = 0xffff & (total + (total >> 0x10));
3323104834Sobrien      filepos += 2;
3324104834Sobrien    }
3325104834Sobrien  while (more_data);
3326104834Sobrien
3327104834Sobrien  return (0xffff & (total + (total >> 0x10)));
3328104834Sobrien}
3329104834Sobrien
3330130561Sobrienstatic bfd_boolean
3331218822Sdimcoff_apply_checksum (bfd *abfd)
3332104834Sobrien{
3333104834Sobrien  unsigned int computed;
3334104834Sobrien  unsigned int checksum = 0;
3335104834Sobrien
3336104834Sobrien  if (bfd_seek (abfd, 0x3c, SEEK_SET) != 0)
3337130561Sobrien    return FALSE;
3338104834Sobrien
3339104834Sobrien  if (!coff_read_word (abfd, &peheader))
3340130561Sobrien    return FALSE;
3341104834Sobrien
3342104834Sobrien  if (bfd_seek (abfd, peheader + 0x58, SEEK_SET) != 0)
3343130561Sobrien    return FALSE;
3344104834Sobrien
3345104834Sobrien  checksum = 0;
3346104834Sobrien  bfd_bwrite (&checksum, (bfd_size_type) 4, abfd);
3347104834Sobrien
3348104834Sobrien  if (bfd_seek (abfd, peheader, SEEK_SET) != 0)
3349130561Sobrien    return FALSE;
3350104834Sobrien
3351104834Sobrien  computed = coff_compute_checksum (abfd);
3352104834Sobrien
3353104834Sobrien  checksum = computed + pelength;
3354104834Sobrien
3355104834Sobrien  if (bfd_seek (abfd, peheader + 0x58, SEEK_SET) != 0)
3356130561Sobrien    return FALSE;
3357104834Sobrien
3358104834Sobrien  bfd_bwrite (&checksum, (bfd_size_type) 4, abfd);
3359104834Sobrien
3360130561Sobrien  return TRUE;
3361104834Sobrien}
3362104834Sobrien
3363104834Sobrien#endif /* COFF_IMAGE_WITH_PE */
3364104834Sobrien
3365130561Sobrienstatic bfd_boolean
3366218822Sdimcoff_write_object_contents (bfd * abfd)
336733965Sjdp{
336833965Sjdp  asection *current;
3369130561Sobrien  bfd_boolean hasrelocs = FALSE;
3370130561Sobrien  bfd_boolean haslinno = FALSE;
3371130561Sobrien  bfd_boolean hasdebug = FALSE;
337233965Sjdp  file_ptr scn_base;
337333965Sjdp  file_ptr reloc_base;
337433965Sjdp  file_ptr lineno_base;
337533965Sjdp  file_ptr sym_base;
337677298Sobrien  unsigned long reloc_size = 0, reloc_count = 0;
337733965Sjdp  unsigned long lnno_size = 0;
3378130561Sobrien  bfd_boolean long_section_names;
337933965Sjdp  asection *text_sec = NULL;
338033965Sjdp  asection *data_sec = NULL;
338133965Sjdp  asection *bss_sec = NULL;
338233965Sjdp  struct internal_filehdr internal_f;
338333965Sjdp  struct internal_aouthdr internal_a;
338433965Sjdp#ifdef COFF_LONG_SECTION_NAMES
338533965Sjdp  size_t string_size = STRING_SIZE_SIZE;
338633965Sjdp#endif
338733965Sjdp
338833965Sjdp  bfd_set_error (bfd_error_system_call);
338933965Sjdp
339033965Sjdp  /* Make a pass through the symbol table to count line number entries and
3391130561Sobrien     put them into the correct asections.  */
339260484Sobrien  lnno_size = coff_count_linenumbers (abfd) * bfd_coff_linesz (abfd);
339333965Sjdp
3394104834Sobrien  if (! abfd->output_has_begun)
339533965Sjdp    {
339633965Sjdp      if (! coff_compute_section_file_positions (abfd))
3397130561Sobrien	return FALSE;
339833965Sjdp    }
339933965Sjdp
340033965Sjdp  reloc_base = obj_relocbase (abfd);
340133965Sjdp
3402130561Sobrien  /* Work out the size of the reloc and linno areas.  */
340333965Sjdp
340433965Sjdp  for (current = abfd->sections; current != NULL; current =
340533965Sjdp       current->next)
340677298Sobrien    {
340777298Sobrien#ifdef COFF_WITH_PE
3408130561Sobrien      /* We store the actual reloc count in the first reloc's addr.  */
3409104834Sobrien      if (obj_pe (abfd) && current->reloc_count >= 0xffff)
341077298Sobrien	reloc_count ++;
341177298Sobrien#endif
341277298Sobrien      reloc_count += current->reloc_count;
341377298Sobrien    }
341433965Sjdp
341577298Sobrien  reloc_size = reloc_count * bfd_coff_relsz (abfd);
341677298Sobrien
341733965Sjdp  lineno_base = reloc_base + reloc_size;
341833965Sjdp  sym_base = lineno_base + lnno_size;
341933965Sjdp
3420130561Sobrien  /* Indicate in each section->line_filepos its actual file address.  */
342133965Sjdp  for (current = abfd->sections; current != NULL; current =
342233965Sjdp       current->next)
342333965Sjdp    {
342433965Sjdp      if (current->lineno_count)
342533965Sjdp	{
342633965Sjdp	  current->line_filepos = lineno_base;
342733965Sjdp	  current->moving_line_filepos = lineno_base;
342860484Sobrien	  lineno_base += current->lineno_count * bfd_coff_linesz (abfd);
342933965Sjdp	}
343033965Sjdp      else
3431218822Sdim	current->line_filepos = 0;
3432218822Sdim
343333965Sjdp      if (current->reloc_count)
343433965Sjdp	{
343533965Sjdp	  current->rel_filepos = reloc_base;
343660484Sobrien	  reloc_base += current->reloc_count * bfd_coff_relsz (abfd);
343777298Sobrien#ifdef COFF_WITH_PE
3438130561Sobrien	  /* Extra reloc to hold real count.  */
3439104834Sobrien	  if (obj_pe (abfd) && current->reloc_count >= 0xffff)
344077298Sobrien	    reloc_base += bfd_coff_relsz (abfd);
344177298Sobrien#endif
344233965Sjdp	}
344333965Sjdp      else
3444218822Sdim	current->rel_filepos = 0;
344533965Sjdp    }
344633965Sjdp
344733965Sjdp  /* Write section headers to the file.  */
344833965Sjdp  internal_f.f_nscns = 0;
344933965Sjdp
345033965Sjdp  if ((abfd->flags & EXEC_P) != 0)
345160484Sobrien    scn_base = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
345233965Sjdp  else
345333965Sjdp    {
345460484Sobrien      scn_base = bfd_coff_filhsz (abfd);
345533965Sjdp#ifdef RS6000COFF_C
345689857Sobrien#ifndef XCOFF64
345733965Sjdp      if (xcoff_data (abfd)->full_aouthdr)
345860484Sobrien	scn_base += bfd_coff_aoutsz (abfd);
345933965Sjdp      else
346033965Sjdp	scn_base += SMALL_AOUTSZ;
346133965Sjdp#endif
346289857Sobrien#endif
346333965Sjdp    }
346433965Sjdp
346533965Sjdp  if (bfd_seek (abfd, scn_base, SEEK_SET) != 0)
3466130561Sobrien    return FALSE;
346733965Sjdp
3468130561Sobrien  long_section_names = FALSE;
346933965Sjdp  for (current = abfd->sections;
347033965Sjdp       current != NULL;
347133965Sjdp       current = current->next)
347233965Sjdp    {
347333965Sjdp      struct internal_scnhdr section;
3474130561Sobrien      bfd_boolean is_reloc_section = FALSE;
347533965Sjdp
347633965Sjdp#ifdef COFF_IMAGE_WITH_PE
347733965Sjdp      if (strcmp (current->name, ".reloc") == 0)
347833965Sjdp	{
3479130561Sobrien	  is_reloc_section = TRUE;
3480130561Sobrien	  hasrelocs = TRUE;
348133965Sjdp	  pe_data (abfd)->has_reloc_section = 1;
348233965Sjdp	}
348333965Sjdp#endif
348433965Sjdp
348533965Sjdp      internal_f.f_nscns++;
348633965Sjdp
348733965Sjdp      strncpy (section.s_name, current->name, SCNNMLEN);
348833965Sjdp
348933965Sjdp#ifdef COFF_LONG_SECTION_NAMES
349033965Sjdp      /* Handle long section names as in PE.  This must be compatible
349160484Sobrien         with the code in coff_write_symbols and _bfd_coff_final_link.  */
349233965Sjdp      {
349333965Sjdp	size_t len;
349433965Sjdp
349533965Sjdp	len = strlen (current->name);
349633965Sjdp	if (len > SCNNMLEN)
349733965Sjdp	  {
349833965Sjdp	    memset (section.s_name, 0, SCNNMLEN);
349933965Sjdp	    sprintf (section.s_name, "/%lu", (unsigned long) string_size);
350033965Sjdp	    string_size += len + 1;
3501130561Sobrien	    long_section_names = TRUE;
350233965Sjdp	  }
350333965Sjdp      }
350433965Sjdp#endif
350533965Sjdp
350633965Sjdp#ifdef _LIB
350733965Sjdp      /* Always set s_vaddr of .lib to 0.  This is right for SVR3.2
350833965Sjdp	 Ian Taylor <ian@cygnus.com>.  */
350933965Sjdp      if (strcmp (current->name, _LIB) == 0)
351033965Sjdp	section.s_vaddr = 0;
351133965Sjdp      else
351233965Sjdp#endif
351333965Sjdp      section.s_vaddr = current->vma;
351433965Sjdp      section.s_paddr = current->lma;
3515218822Sdim      section.s_size =  current->size;
351677298Sobrien#ifdef coff_get_section_load_page
351777298Sobrien      section.s_page = coff_get_section_load_page (current);
351877298Sobrien#endif
351933965Sjdp
352033965Sjdp#ifdef COFF_WITH_PE
352133965Sjdp      section.s_paddr = 0;
352233965Sjdp#endif
352333965Sjdp#ifdef COFF_IMAGE_WITH_PE
352433965Sjdp      /* Reminder: s_paddr holds the virtual size of the section.  */
352533965Sjdp      if (coff_section_data (abfd, current) != NULL
352633965Sjdp	  && pei_section_data (abfd, current) != NULL)
352733965Sjdp	section.s_paddr = pei_section_data (abfd, current)->virt_size;
352833965Sjdp      else
352933965Sjdp	section.s_paddr = 0;
353033965Sjdp#endif
353133965Sjdp
3532130561Sobrien      /* If this section has no size or is unloadable then the scnptr
3533130561Sobrien	 will be 0 too.  */
3534218822Sdim      if (current->size == 0
3535218822Sdim	  || (current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
3536130561Sobrien	section.s_scnptr = 0;
353733965Sjdp      else
3538130561Sobrien	section.s_scnptr = current->filepos;
3539130561Sobrien
354033965Sjdp      section.s_relptr = current->rel_filepos;
354133965Sjdp      section.s_lnnoptr = current->line_filepos;
354233965Sjdp      section.s_nreloc = current->reloc_count;
354333965Sjdp      section.s_nlnno = current->lineno_count;
354460484Sobrien#ifndef COFF_IMAGE_WITH_PE
354560484Sobrien      /* In PEI, relocs come in the .reloc section.  */
354633965Sjdp      if (current->reloc_count != 0)
3547130561Sobrien	hasrelocs = TRUE;
354860484Sobrien#endif
354933965Sjdp      if (current->lineno_count != 0)
3550130561Sobrien	haslinno = TRUE;
355160484Sobrien      if ((current->flags & SEC_DEBUGGING) != 0
355260484Sobrien	  && ! is_reloc_section)
3553130561Sobrien	hasdebug = TRUE;
355433965Sjdp
355533965Sjdp#ifdef RS6000COFF_C
355677298Sobrien#ifndef XCOFF64
355733965Sjdp      /* Indicate the use of an XCOFF overflow section header.  */
355833965Sjdp      if (current->reloc_count >= 0xffff || current->lineno_count >= 0xffff)
355933965Sjdp	{
356033965Sjdp	  section.s_nreloc = 0xffff;
356133965Sjdp	  section.s_nlnno = 0xffff;
356233965Sjdp	}
356333965Sjdp#endif
356477298Sobrien#endif
356533965Sjdp
356633965Sjdp      section.s_flags = sec_to_styp_flags (current->name, current->flags);
356733965Sjdp
356833965Sjdp      if (!strcmp (current->name, _TEXT))
3569130561Sobrien	text_sec = current;
357033965Sjdp      else if (!strcmp (current->name, _DATA))
3571130561Sobrien	data_sec = current;
357233965Sjdp      else if (!strcmp (current->name, _BSS))
3573130561Sobrien	bss_sec = current;
357433965Sjdp
357533965Sjdp#ifdef I960
357633965Sjdp      section.s_align = (current->alignment_power
357733965Sjdp			 ? 1 << current->alignment_power
357833965Sjdp			 : 0);
357977298Sobrien#endif
358060484Sobrien#ifdef TIC80COFF
3581130561Sobrien      /* TI COFF puts the alignment power in bits 8-11 of the flags.  */
358260484Sobrien      section.s_flags |= (current->alignment_power & 0xF) << 8;
358333965Sjdp#endif
358477298Sobrien#ifdef COFF_ENCODE_ALIGNMENT
358577298Sobrien      COFF_ENCODE_ALIGNMENT(section, current->alignment_power);
358660484Sobrien#endif
358733965Sjdp
358833965Sjdp#ifdef COFF_IMAGE_WITH_PE
358960484Sobrien      /* Suppress output of the sections if they are null.  ld
359060484Sobrien	 includes the bss and data sections even if there is no size
359160484Sobrien	 assigned to them.  NT loader doesn't like it if these section
359260484Sobrien	 headers are included if the sections themselves are not
359360484Sobrien	 needed.  See also coff_compute_section_file_positions.  */
359433965Sjdp      if (section.s_size == 0)
359533965Sjdp	internal_f.f_nscns--;
359633965Sjdp      else
359733965Sjdp#endif
359833965Sjdp	{
359933965Sjdp	  SCNHDR buff;
360089857Sobrien	  bfd_size_type amt = bfd_coff_scnhsz (abfd);
360189857Sobrien
360233965Sjdp	  if (coff_swap_scnhdr_out (abfd, &section, &buff) == 0
3603218822Sdim	      || bfd_bwrite (& buff, amt, abfd) != amt)
3604130561Sobrien	    return FALSE;
360533965Sjdp	}
360633965Sjdp
360733965Sjdp#ifdef COFF_WITH_PE
360833965Sjdp      /* PE stores COMDAT section information in the symbol table.  If
360933965Sjdp         this section is supposed to have some COMDAT info, track down
361033965Sjdp         the symbol in the symbol table and modify it.  */
361133965Sjdp      if ((current->flags & SEC_LINK_ONCE) != 0)
361233965Sjdp	{
361333965Sjdp	  unsigned int i, count;
361433965Sjdp	  asymbol **psym;
361538889Sjdp	  coff_symbol_type *csym = NULL;
361638889Sjdp	  asymbol **psymsec;
361733965Sjdp
361838889Sjdp	  psymsec = NULL;
361933965Sjdp	  count = bfd_get_symcount (abfd);
362033965Sjdp	  for (i = 0, psym = abfd->outsymbols; i < count; i++, psym++)
362133965Sjdp	    {
362238889Sjdp	      if ((*psym)->section != current)
362338889Sjdp		continue;
362433965Sjdp
362538889Sjdp	      /* Remember the location of the first symbol in this
362638889Sjdp                 section.  */
362738889Sjdp	      if (psymsec == NULL)
362838889Sjdp		psymsec = psym;
362938889Sjdp
363038889Sjdp	      /* See if this is the section symbol.  */
363133965Sjdp	      if (strcmp ((*psym)->name, current->name) == 0)
363233965Sjdp		{
363333965Sjdp		  csym = coff_symbol_from (abfd, *psym);
363433965Sjdp		  if (csym == NULL
363533965Sjdp		      || csym->native == NULL
363633965Sjdp		      || csym->native->u.syment.n_numaux < 1
363733965Sjdp		      || csym->native->u.syment.n_sclass != C_STAT
363833965Sjdp		      || csym->native->u.syment.n_type != T_NULL)
363933965Sjdp		    continue;
364038889Sjdp
364138889Sjdp		  /* Here *PSYM is the section symbol for CURRENT.  */
364238889Sjdp
364333965Sjdp		  break;
364433965Sjdp		}
364533965Sjdp	    }
364633965Sjdp
364733965Sjdp	  /* Did we find it?
364833965Sjdp	     Note that we might not if we're converting the file from
364933965Sjdp	     some other object file format.  */
365033965Sjdp	  if (i < count)
365133965Sjdp	    {
365233965Sjdp	      combined_entry_type *aux;
365333965Sjdp
365433965Sjdp	      /* We don't touch the x_checksum field.  The
365533965Sjdp		 x_associated field is not currently supported.  */
365633965Sjdp
365733965Sjdp	      aux = csym->native + 1;
365833965Sjdp	      switch (current->flags & SEC_LINK_DUPLICATES)
365933965Sjdp		{
366033965Sjdp		case SEC_LINK_DUPLICATES_DISCARD:
366133965Sjdp		  aux->u.auxent.x_scn.x_comdat = IMAGE_COMDAT_SELECT_ANY;
366233965Sjdp		  break;
366333965Sjdp
366433965Sjdp		case SEC_LINK_DUPLICATES_ONE_ONLY:
366533965Sjdp		  aux->u.auxent.x_scn.x_comdat =
366633965Sjdp		    IMAGE_COMDAT_SELECT_NODUPLICATES;
366733965Sjdp		  break;
366833965Sjdp
366933965Sjdp		case SEC_LINK_DUPLICATES_SAME_SIZE:
367033965Sjdp		  aux->u.auxent.x_scn.x_comdat =
367133965Sjdp		    IMAGE_COMDAT_SELECT_SAME_SIZE;
367233965Sjdp		  break;
367333965Sjdp
367433965Sjdp		case SEC_LINK_DUPLICATES_SAME_CONTENTS:
367533965Sjdp		  aux->u.auxent.x_scn.x_comdat =
367633965Sjdp		    IMAGE_COMDAT_SELECT_EXACT_MATCH;
367733965Sjdp		  break;
367833965Sjdp		}
367938889Sjdp
368038889Sjdp	      /* The COMDAT symbol must be the first symbol from this
368138889Sjdp                 section in the symbol table.  In order to make this
368238889Sjdp                 work, we move the COMDAT symbol before the first
368338889Sjdp                 symbol we found in the search above.  It's OK to
368438889Sjdp                 rearrange the symbol table at this point, because
368538889Sjdp                 coff_renumber_symbols is going to rearrange it
368638889Sjdp                 further and fix up all the aux entries.  */
368738889Sjdp	      if (psym != psymsec)
368838889Sjdp		{
368938889Sjdp		  asymbol *hold;
369038889Sjdp		  asymbol **pcopy;
369138889Sjdp
369238889Sjdp		  hold = *psym;
369338889Sjdp		  for (pcopy = psym; pcopy > psymsec; pcopy--)
369438889Sjdp		    pcopy[0] = pcopy[-1];
369538889Sjdp		  *psymsec = hold;
369638889Sjdp		}
369733965Sjdp	    }
369833965Sjdp	}
369933965Sjdp#endif /* COFF_WITH_PE */
370033965Sjdp    }
370133965Sjdp
370233965Sjdp#ifdef RS6000COFF_C
370389857Sobrien#ifndef XCOFF64
370433965Sjdp  /* XCOFF handles overflows in the reloc and line number count fields
370533965Sjdp     by creating a new section header to hold the correct values.  */
370633965Sjdp  for (current = abfd->sections; current != NULL; current = current->next)
370733965Sjdp    {
370833965Sjdp      if (current->reloc_count >= 0xffff || current->lineno_count >= 0xffff)
370933965Sjdp	{
371033965Sjdp	  struct internal_scnhdr scnhdr;
371133965Sjdp	  SCNHDR buff;
371289857Sobrien	  bfd_size_type amt;
371333965Sjdp
371433965Sjdp	  internal_f.f_nscns++;
371533965Sjdp	  strncpy (&(scnhdr.s_name[0]), current->name, 8);
371633965Sjdp	  scnhdr.s_paddr = current->reloc_count;
371733965Sjdp	  scnhdr.s_vaddr = current->lineno_count;
371833965Sjdp	  scnhdr.s_size = 0;
371933965Sjdp	  scnhdr.s_scnptr = 0;
372033965Sjdp	  scnhdr.s_relptr = current->rel_filepos;
372133965Sjdp	  scnhdr.s_lnnoptr = current->line_filepos;
372233965Sjdp	  scnhdr.s_nreloc = current->target_index;
372333965Sjdp	  scnhdr.s_nlnno = current->target_index;
372433965Sjdp	  scnhdr.s_flags = STYP_OVRFLO;
372589857Sobrien	  amt = bfd_coff_scnhsz (abfd);
372633965Sjdp	  if (coff_swap_scnhdr_out (abfd, &scnhdr, &buff) == 0
3727218822Sdim	      || bfd_bwrite (& buff, amt, abfd) != amt)
3728130561Sobrien	    return FALSE;
372933965Sjdp	}
373033965Sjdp    }
373133965Sjdp#endif
373289857Sobrien#endif
373333965Sjdp
373477298Sobrien  /* OK, now set up the filehdr...  */
373533965Sjdp
373633965Sjdp  /* Don't include the internal abs section in the section count */
373733965Sjdp
3738130561Sobrien  /* We will NOT put a fucking timestamp in the header here. Every time you
373933965Sjdp     put it back, I will come in and take it out again.  I'm sorry.  This
374033965Sjdp     field does not belong here.  We fill it with a 0 so it compares the
3741130561Sobrien     same but is not a reasonable time. -- gnu@cygnus.com  */
374233965Sjdp  internal_f.f_timdat = 0;
374333965Sjdp  internal_f.f_flags = 0;
374433965Sjdp
374533965Sjdp  if (abfd->flags & EXEC_P)
374660484Sobrien    internal_f.f_opthdr = bfd_coff_aoutsz (abfd);
374733965Sjdp  else
374833965Sjdp    {
374933965Sjdp      internal_f.f_opthdr = 0;
375033965Sjdp#ifdef RS6000COFF_C
375189857Sobrien#ifndef XCOFF64
375233965Sjdp      if (xcoff_data (abfd)->full_aouthdr)
375360484Sobrien	internal_f.f_opthdr = bfd_coff_aoutsz (abfd);
375433965Sjdp      else
375533965Sjdp	internal_f.f_opthdr = SMALL_AOUTSZ;
375633965Sjdp#endif
375789857Sobrien#endif
375833965Sjdp    }
375933965Sjdp
376033965Sjdp  if (!hasrelocs)
376133965Sjdp    internal_f.f_flags |= F_RELFLG;
376233965Sjdp  if (!haslinno)
376333965Sjdp    internal_f.f_flags |= F_LNNO;
376433965Sjdp  if (abfd->flags & EXEC_P)
376533965Sjdp    internal_f.f_flags |= F_EXEC;
376660484Sobrien#ifdef COFF_IMAGE_WITH_PE
376760484Sobrien  if (! hasdebug)
376860484Sobrien    internal_f.f_flags |= IMAGE_FILE_DEBUG_STRIPPED;
3769218822Sdim  if (pe_data (abfd)->real_flags & IMAGE_FILE_LARGE_ADDRESS_AWARE)
3770218822Sdim    internal_f.f_flags |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
377160484Sobrien#endif
377233965Sjdp
3773218822Sdim#ifndef COFF_WITH_pex64
3774130561Sobrien#ifdef COFF_WITH_PE
3775130561Sobrien  internal_f.f_flags |= IMAGE_FILE_32BIT_MACHINE;
3776130561Sobrien#else
377733965Sjdp  if (bfd_little_endian (abfd))
377833965Sjdp    internal_f.f_flags |= F_AR32WR;
377933965Sjdp  else
378033965Sjdp    internal_f.f_flags |= F_AR32W;
378160484Sobrien#endif
3782218822Sdim#endif
378333965Sjdp
378477298Sobrien#ifdef TI_TARGET_ID
3785130561Sobrien  /* Target id is used in TI COFF v1 and later; COFF0 won't use this field,
3786130561Sobrien     but it doesn't hurt to set it internally.  */
378777298Sobrien  internal_f.f_target_id = TI_TARGET_ID;
378877298Sobrien#endif
378960484Sobrien#ifdef TIC80_TARGET_ID
379060484Sobrien  internal_f.f_target_id = TIC80_TARGET_ID;
379160484Sobrien#endif
379238889Sjdp
3793130561Sobrien  /* FIXME, should do something about the other byte orders and
3794130561Sobrien     architectures.  */
379533965Sjdp
379633965Sjdp#ifdef RS6000COFF_C
379733965Sjdp  if ((abfd->flags & DYNAMIC) != 0)
379833965Sjdp    internal_f.f_flags |= F_SHROBJ;
379933965Sjdp  if (bfd_get_section_by_name (abfd, _LOADER) != NULL)
380033965Sjdp    internal_f.f_flags |= F_DYNLOAD;
380133965Sjdp#endif
380233965Sjdp
380333965Sjdp  memset (&internal_a, 0, sizeof internal_a);
380433965Sjdp
3805130561Sobrien  /* Set up architecture-dependent stuff.  */
380633965Sjdp  {
380733965Sjdp    unsigned int magic = 0;
380833965Sjdp    unsigned short flags = 0;
3809130561Sobrien
381033965Sjdp    coff_set_flags (abfd, &magic, &flags);
381133965Sjdp    internal_f.f_magic = magic;
381233965Sjdp    internal_f.f_flags |= flags;
381377298Sobrien    /* ...and the "opt"hdr...  */
381433965Sjdp
381577298Sobrien#ifdef TICOFF_AOUT_MAGIC
381677298Sobrien    internal_a.magic = TICOFF_AOUT_MAGIC;
381777298Sobrien#define __A_MAGIC_SET__
381877298Sobrien#endif
381960484Sobrien#ifdef TIC80COFF
382060484Sobrien    internal_a.magic = TIC80_ARCH_MAGIC;
382160484Sobrien#define __A_MAGIC_SET__
382260484Sobrien#endif /* TIC80 */
382333965Sjdp#ifdef I860
382433965Sjdp    /* FIXME: What are the a.out magic numbers for the i860?  */
382533965Sjdp    internal_a.magic = 0;
382633965Sjdp#define __A_MAGIC_SET__
382733965Sjdp#endif /* I860 */
382833965Sjdp#ifdef I960
382933965Sjdp    internal_a.magic = (magic == I960ROMAGIC ? NMAGIC : OMAGIC);
383033965Sjdp#define __A_MAGIC_SET__
383133965Sjdp#endif /* I960 */
383233965Sjdp#if M88
383333965Sjdp#define __A_MAGIC_SET__
383433965Sjdp    internal_a.magic = PAGEMAGICBCS;
383533965Sjdp#endif /* M88 */
383633965Sjdp
383733965Sjdp#if APOLLO_M68
383833965Sjdp#define __A_MAGIC_SET__
383933965Sjdp    internal_a.magic = APOLLO_COFF_VERSION_NUMBER;
384033965Sjdp#endif
384133965Sjdp
384233965Sjdp#if defined(M68) || defined(WE32K) || defined(M68K)
384333965Sjdp#define __A_MAGIC_SET__
384433965Sjdp#if defined(LYNXOS)
384533965Sjdp    internal_a.magic = LYNXCOFFMAGIC;
384633965Sjdp#else
384733965Sjdp#if defined(TARG_AUX)
384833965Sjdp    internal_a.magic = (abfd->flags & D_PAGED ? PAGEMAGICPEXECPAGED :
384933965Sjdp			abfd->flags & WP_TEXT ? PAGEMAGICPEXECSWAPPED :
385033965Sjdp			PAGEMAGICEXECSWAPPED);
385133965Sjdp#else
385233965Sjdp#if defined (PAGEMAGICPEXECPAGED)
385333965Sjdp    internal_a.magic = PAGEMAGICPEXECPAGED;
385433965Sjdp#endif
385533965Sjdp#endif /* TARG_AUX */
385633965Sjdp#endif /* LYNXOS */
385733965Sjdp#endif /* M68 || WE32K || M68K */
385833965Sjdp
385933965Sjdp#if defined(ARM)
386033965Sjdp#define __A_MAGIC_SET__
386133965Sjdp    internal_a.magic = ZMAGIC;
386277298Sobrien#endif
386338889Sjdp
386433965Sjdp#if defined(PPC_PE)
386533965Sjdp#define __A_MAGIC_SET__
386633965Sjdp    internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
386733965Sjdp#endif
386838889Sjdp
386960484Sobrien#if defined MCORE_PE
387060484Sobrien#define __A_MAGIC_SET__
387160484Sobrien    internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
387277298Sobrien#endif
387360484Sobrien
387433965Sjdp#if defined(I386)
387533965Sjdp#define __A_MAGIC_SET__
3876218822Sdim#if defined LYNXOS
387733965Sjdp    internal_a.magic = LYNXCOFFMAGIC;
3878218822Sdim#elif defined AMD64
3879218822Sdim    internal_a.magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC;
3880218822Sdim#else
388133965Sjdp    internal_a.magic = ZMAGIC;
3882218822Sdim#endif
388333965Sjdp#endif /* I386 */
388433965Sjdp
388577298Sobrien#if defined(IA64)
388677298Sobrien#define __A_MAGIC_SET__
3887218822Sdim    internal_a.magic = PE32PMAGIC;
388877298Sobrien#endif /* IA64 */
388977298Sobrien
389033965Sjdp#if defined(SPARC)
389133965Sjdp#define __A_MAGIC_SET__
389233965Sjdp#if defined(LYNXOS)
389333965Sjdp    internal_a.magic = LYNXCOFFMAGIC;
389433965Sjdp#endif /* LYNXOS */
389533965Sjdp#endif /* SPARC */
389633965Sjdp
389738889Sjdp#ifdef RS6000COFF_C
389833965Sjdp#define __A_MAGIC_SET__
389933965Sjdp    internal_a.magic = (abfd->flags & D_PAGED) ? RS6K_AOUTHDR_ZMAGIC :
390033965Sjdp    (abfd->flags & WP_TEXT) ? RS6K_AOUTHDR_NMAGIC :
390133965Sjdp    RS6K_AOUTHDR_OMAGIC;
390233965Sjdp#endif
390333965Sjdp
390460484Sobrien#if defined(SH) && defined(COFF_WITH_PE)
390560484Sobrien#define __A_MAGIC_SET__
390660484Sobrien    internal_a.magic = SH_PE_MAGIC;
390760484Sobrien#endif
390860484Sobrien
390960484Sobrien#if defined(MIPS) && defined(COFF_WITH_PE)
391060484Sobrien#define __A_MAGIC_SET__
391160484Sobrien    internal_a.magic = MIPS_PE_MAGIC;
391260484Sobrien#endif
391360484Sobrien
391491041Sobrien#ifdef OR32
391591041Sobrien#define __A_MAGIC_SET__
391691041Sobrien    internal_a.magic = NMAGIC; /* Assume separate i/d.  */
391791041Sobrien#endif
391891041Sobrien
3919218822Sdim#ifdef MAXQ20MAGIC
3920218822Sdim#define __A_MAGIC_SET__
3921218822Sdim      internal_a.magic = MAXQ20MAGIC;
3922218822Sdim#endif
3923218822Sdim
392433965Sjdp#ifndef __A_MAGIC_SET__
392533965Sjdp#include "Your aouthdr magic number is not being set!"
392633965Sjdp#else
392733965Sjdp#undef __A_MAGIC_SET__
392833965Sjdp#endif
392933965Sjdp  }
393033965Sjdp
393133965Sjdp  /* FIXME: Does anybody ever set this to another value?  */
393233965Sjdp  internal_a.vstamp = 0;
393333965Sjdp
3934130561Sobrien  /* Now should write relocs, strings, syms.  */
393533965Sjdp  obj_sym_filepos (abfd) = sym_base;
393633965Sjdp
393733965Sjdp  if (bfd_get_symcount (abfd) != 0)
393833965Sjdp    {
393933965Sjdp      int firstundef;
3940218822Sdim
394133965Sjdp      if (!coff_renumber_symbols (abfd, &firstundef))
3942130561Sobrien	return FALSE;
394333965Sjdp      coff_mangle_symbols (abfd);
394433965Sjdp      if (! coff_write_symbols (abfd))
3945130561Sobrien	return FALSE;
394633965Sjdp      if (! coff_write_linenumbers (abfd))
3947130561Sobrien	return FALSE;
394833965Sjdp      if (! coff_write_relocs (abfd, firstundef))
3949130561Sobrien	return FALSE;
395033965Sjdp    }
395160484Sobrien#ifdef COFF_LONG_SECTION_NAMES
395277298Sobrien  else if (long_section_names && ! obj_coff_strings_written (abfd))
395360484Sobrien    {
395460484Sobrien      /* If we have long section names we have to write out the string
395560484Sobrien         table even if there are no symbols.  */
395660484Sobrien      if (! coff_write_symbols (abfd))
3957130561Sobrien	return FALSE;
395860484Sobrien    }
395960484Sobrien#endif
396033965Sjdp#ifdef COFF_IMAGE_WITH_PE
396133965Sjdp#ifdef PPC_PE
396233965Sjdp  else if ((abfd->flags & EXEC_P) != 0)
396333965Sjdp    {
396433965Sjdp      bfd_byte b;
396533965Sjdp
396633965Sjdp      /* PowerPC PE appears to require that all executable files be
396733965Sjdp         rounded up to the page size.  */
396833965Sjdp      b = 0;
396933965Sjdp      if (bfd_seek (abfd,
397089857Sobrien		    (file_ptr) BFD_ALIGN (sym_base, COFF_PAGE_SIZE) - 1,
397133965Sjdp		    SEEK_SET) != 0
397289857Sobrien	  || bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
3973130561Sobrien	return FALSE;
397433965Sjdp    }
397533965Sjdp#endif
397633965Sjdp#endif
397733965Sjdp
397833965Sjdp  /* If bfd_get_symcount (abfd) != 0, then we are not using the COFF
397933965Sjdp     backend linker, and obj_raw_syment_count is not valid until after
398033965Sjdp     coff_write_symbols is called.  */
398133965Sjdp  if (obj_raw_syment_count (abfd) != 0)
398233965Sjdp    {
398333965Sjdp      internal_f.f_symptr = sym_base;
398433965Sjdp#ifdef RS6000COFF_C
398533965Sjdp      /* AIX appears to require that F_RELFLG not be set if there are
398633965Sjdp         local symbols but no relocations.  */
398733965Sjdp      internal_f.f_flags &=~ F_RELFLG;
398833965Sjdp#endif
398933965Sjdp    }
399033965Sjdp  else
399133965Sjdp    {
399233965Sjdp      if (long_section_names)
399333965Sjdp	internal_f.f_symptr = sym_base;
399433965Sjdp      else
399533965Sjdp	internal_f.f_symptr = 0;
399633965Sjdp      internal_f.f_flags |= F_LSYMS;
399733965Sjdp    }
399833965Sjdp
399933965Sjdp  if (text_sec)
400033965Sjdp    {
4001218822Sdim      internal_a.tsize = text_sec->size;
400233965Sjdp      internal_a.text_start = internal_a.tsize ? text_sec->vma : 0;
400333965Sjdp    }
400433965Sjdp  if (data_sec)
400533965Sjdp    {
4006218822Sdim      internal_a.dsize = data_sec->size;
400733965Sjdp      internal_a.data_start = internal_a.dsize ? data_sec->vma : 0;
400833965Sjdp    }
400933965Sjdp  if (bss_sec)
401033965Sjdp    {
4011218822Sdim      internal_a.bsize = bss_sec->size;
401233965Sjdp      if (internal_a.bsize && bss_sec->vma < internal_a.data_start)
401333965Sjdp	internal_a.data_start = bss_sec->vma;
401433965Sjdp    }
401533965Sjdp
401633965Sjdp  internal_a.entry = bfd_get_start_address (abfd);
401733965Sjdp  internal_f.f_nsyms = obj_raw_syment_count (abfd);
401833965Sjdp
401933965Sjdp#ifdef RS6000COFF_C
402033965Sjdp  if (xcoff_data (abfd)->full_aouthdr)
402133965Sjdp    {
402233965Sjdp      bfd_vma toc;
402333965Sjdp      asection *loader_sec;
402433965Sjdp
402533965Sjdp      internal_a.vstamp = 1;
402633965Sjdp
402733965Sjdp      internal_a.o_snentry = xcoff_data (abfd)->snentry;
402833965Sjdp      if (internal_a.o_snentry == 0)
402933965Sjdp	internal_a.entry = (bfd_vma) -1;
403033965Sjdp
403133965Sjdp      if (text_sec != NULL)
403233965Sjdp	{
403333965Sjdp	  internal_a.o_sntext = text_sec->target_index;
403433965Sjdp	  internal_a.o_algntext = bfd_get_section_alignment (abfd, text_sec);
403533965Sjdp	}
403633965Sjdp      else
403733965Sjdp	{
403833965Sjdp	  internal_a.o_sntext = 0;
403933965Sjdp	  internal_a.o_algntext = 0;
404033965Sjdp	}
404133965Sjdp      if (data_sec != NULL)
404233965Sjdp	{
404333965Sjdp	  internal_a.o_sndata = data_sec->target_index;
404433965Sjdp	  internal_a.o_algndata = bfd_get_section_alignment (abfd, data_sec);
404533965Sjdp	}
404633965Sjdp      else
404733965Sjdp	{
404833965Sjdp	  internal_a.o_sndata = 0;
404933965Sjdp	  internal_a.o_algndata = 0;
405033965Sjdp	}
405133965Sjdp      loader_sec = bfd_get_section_by_name (abfd, ".loader");
405233965Sjdp      if (loader_sec != NULL)
405333965Sjdp	internal_a.o_snloader = loader_sec->target_index;
405433965Sjdp      else
405533965Sjdp	internal_a.o_snloader = 0;
405633965Sjdp      if (bss_sec != NULL)
405733965Sjdp	internal_a.o_snbss = bss_sec->target_index;
405833965Sjdp      else
405933965Sjdp	internal_a.o_snbss = 0;
406033965Sjdp
406133965Sjdp      toc = xcoff_data (abfd)->toc;
406233965Sjdp      internal_a.o_toc = toc;
406333965Sjdp      internal_a.o_sntoc = xcoff_data (abfd)->sntoc;
406433965Sjdp
406533965Sjdp      internal_a.o_modtype = xcoff_data (abfd)->modtype;
406633965Sjdp      if (xcoff_data (abfd)->cputype != -1)
406733965Sjdp	internal_a.o_cputype = xcoff_data (abfd)->cputype;
406833965Sjdp      else
406933965Sjdp	{
407033965Sjdp	  switch (bfd_get_arch (abfd))
407133965Sjdp	    {
407233965Sjdp	    case bfd_arch_rs6000:
407333965Sjdp	      internal_a.o_cputype = 4;
407433965Sjdp	      break;
407533965Sjdp	    case bfd_arch_powerpc:
4076130561Sobrien	      if (bfd_get_mach (abfd) == bfd_mach_ppc)
407733965Sjdp		internal_a.o_cputype = 3;
407833965Sjdp	      else
407933965Sjdp		internal_a.o_cputype = 1;
408033965Sjdp	      break;
408133965Sjdp	    default:
408233965Sjdp	      abort ();
408333965Sjdp	    }
408433965Sjdp	}
408533965Sjdp      internal_a.o_maxstack = xcoff_data (abfd)->maxstack;
408633965Sjdp      internal_a.o_maxdata = xcoff_data (abfd)->maxdata;
408733965Sjdp    }
408833965Sjdp#endif
408933965Sjdp
4090218822Sdim  /* Now write them.  */
409133965Sjdp  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
4092130561Sobrien    return FALSE;
409377298Sobrien
409433965Sjdp  {
409560484Sobrien    char * buff;
409689857Sobrien    bfd_size_type amount = bfd_coff_filhsz (abfd);
409777298Sobrien
409889857Sobrien    buff = bfd_malloc (amount);
409977298Sobrien    if (buff == NULL)
4100130561Sobrien      return FALSE;
410177298Sobrien
4102218822Sdim    bfd_coff_swap_filehdr_out (abfd, & internal_f, buff);
4103218822Sdim    amount = bfd_bwrite (buff, amount, abfd);
410477298Sobrien
410560484Sobrien    free (buff);
410677298Sobrien
410760484Sobrien    if (amount != bfd_coff_filhsz (abfd))
4108130561Sobrien      return FALSE;
410933965Sjdp  }
411077298Sobrien
411133965Sjdp  if (abfd->flags & EXEC_P)
411233965Sjdp    {
411377298Sobrien      /* Note that peicode.h fills in a PEAOUTHDR, not an AOUTHDR.
4114130561Sobrien	 include/coff/pe.h sets AOUTSZ == sizeof (PEAOUTHDR)).  */
411560484Sobrien      char * buff;
411689857Sobrien      bfd_size_type amount = bfd_coff_aoutsz (abfd);
411760484Sobrien
411889857Sobrien      buff = bfd_malloc (amount);
411977298Sobrien      if (buff == NULL)
4120130561Sobrien	return FALSE;
412177298Sobrien
4122218822Sdim      coff_swap_aouthdr_out (abfd, & internal_a, buff);
4123218822Sdim      amount = bfd_bwrite (buff, amount, abfd);
412477298Sobrien
412560484Sobrien      free (buff);
412677298Sobrien
412760484Sobrien      if (amount != bfd_coff_aoutsz (abfd))
4128130561Sobrien	return FALSE;
4129104834Sobrien
4130104834Sobrien#ifdef COFF_IMAGE_WITH_PE
4131104834Sobrien      if (! coff_apply_checksum (abfd))
4132130561Sobrien	return FALSE;
4133104834Sobrien#endif
413433965Sjdp    }
413533965Sjdp#ifdef RS6000COFF_C
413633965Sjdp  else
413733965Sjdp    {
413833965Sjdp      AOUTHDR buff;
413933965Sjdp      size_t size;
414033965Sjdp
414133965Sjdp      /* XCOFF seems to always write at least a small a.out header.  */
4142218822Sdim      coff_swap_aouthdr_out (abfd, & internal_a, & buff);
414333965Sjdp      if (xcoff_data (abfd)->full_aouthdr)
414460484Sobrien	size = bfd_coff_aoutsz (abfd);
414533965Sjdp      else
414633965Sjdp	size = SMALL_AOUTSZ;
4147218822Sdim      if (bfd_bwrite (& buff, (bfd_size_type) size, abfd) != size)
4148130561Sobrien	return FALSE;
414933965Sjdp    }
415033965Sjdp#endif
415133965Sjdp
4152130561Sobrien  return TRUE;
415333965Sjdp}
415433965Sjdp
4155130561Sobrienstatic bfd_boolean
4156218822Sdimcoff_set_section_contents (bfd * abfd,
4157218822Sdim			   sec_ptr section,
4158218822Sdim			   const void * location,
4159218822Sdim			   file_ptr offset,
4160218822Sdim			   bfd_size_type count)
416133965Sjdp{
4162130561Sobrien  if (! abfd->output_has_begun)	/* Set by bfd.c handler.  */
416333965Sjdp    {
416433965Sjdp      if (! coff_compute_section_file_positions (abfd))
4165130561Sobrien	return FALSE;
416633965Sjdp    }
416733965Sjdp
416833965Sjdp#if defined(_LIB) && !defined(TARG_AUX)
416933965Sjdp   /* The physical address field of a .lib section is used to hold the
417033965Sjdp      number of shared libraries in the section.  This code counts the
417133965Sjdp      number of sections being written, and increments the lma field
417233965Sjdp      with the number.
417333965Sjdp
417433965Sjdp      I have found no documentation on the contents of this section.
417533965Sjdp      Experimentation indicates that the section contains zero or more
417633965Sjdp      records, each of which has the following structure:
417733965Sjdp
417833965Sjdp      - a (four byte) word holding the length of this record, in words,
417933965Sjdp      - a word that always seems to be set to "2",
418033965Sjdp      - the path to a shared library, null-terminated and then padded
418133965Sjdp        to a whole word boundary.
418233965Sjdp
418333965Sjdp      bfd_assert calls have been added to alert if an attempt is made
418433965Sjdp      to write a section which doesn't follow these assumptions.  The
418533965Sjdp      code has been tested on ISC 4.1 by me, and on SCO by Robert Lipe
418633965Sjdp      <robertl@arnet.com> (Thanks!).
418777298Sobrien
4188130561Sobrien      Gvran Uddeborg <gvran@uddeborg.pp.se>.  */
418933965Sjdp    if (strcmp (section->name, _LIB) == 0)
419033965Sjdp      {
419133965Sjdp	bfd_byte *rec, *recend;
419233965Sjdp
419333965Sjdp	rec = (bfd_byte *) location;
419433965Sjdp	recend = rec + count;
419533965Sjdp	while (rec < recend)
419633965Sjdp	  {
419733965Sjdp	    ++section->lma;
419833965Sjdp	    rec += bfd_get_32 (abfd, rec) * 4;
419933965Sjdp	  }
420033965Sjdp
420133965Sjdp	BFD_ASSERT (rec == recend);
420233965Sjdp      }
420333965Sjdp#endif
420433965Sjdp
420533965Sjdp  /* Don't write out bss sections - one way to do this is to
420677298Sobrien       see if the filepos has not been set.  */
420733965Sjdp  if (section->filepos == 0)
4208130561Sobrien    return TRUE;
420933965Sjdp
421089857Sobrien  if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0)
4211130561Sobrien    return FALSE;
421233965Sjdp
421389857Sobrien  if (count == 0)
4214130561Sobrien    return TRUE;
421589857Sobrien
421689857Sobrien  return bfd_bwrite (location, count, abfd) == count;
421733965Sjdp}
4218218822Sdim
4219218822Sdimstatic void *
4220218822Sdimbuy_and_read (bfd *abfd, file_ptr where, bfd_size_type size)
422133965Sjdp{
4222218822Sdim  void * area = bfd_alloc (abfd, size);
422333965Sjdp
422433965Sjdp  if (!area)
422533965Sjdp    return (NULL);
422689857Sobrien  if (bfd_seek (abfd, where, SEEK_SET) != 0
422789857Sobrien      || bfd_bread (area, size, abfd) != size)
422833965Sjdp    return (NULL);
422933965Sjdp  return (area);
4230218822Sdim}
423133965Sjdp
423233965Sjdp/*
423333965SjdpSUBSUBSECTION
423433965Sjdp	Reading linenumbers
423533965Sjdp
423633965Sjdp	Creating the linenumber table is done by reading in the entire
423733965Sjdp	coff linenumber table, and creating another table for internal use.
423833965Sjdp
423933965Sjdp	A coff linenumber table is structured so that each function
424033965Sjdp	is marked as having a line number of 0. Each line within the
424133965Sjdp	function is an offset from the first line in the function. The
424233965Sjdp	base of the line number information for the table is stored in
424333965Sjdp	the symbol associated with the function.
424433965Sjdp
424560484Sobrien	Note: The PE format uses line number 0 for a flag indicating a
424660484Sobrien	new source file.
424760484Sobrien
424833965Sjdp	The information is copied from the external to the internal
424933965Sjdp	table, and each symbol which marks a function is marked by
425033965Sjdp	pointing its...
425133965Sjdp
425233965Sjdp	How does this work ?
425333965Sjdp*/
425433965Sjdp
4255130561Sobrienstatic bfd_boolean
4256218822Sdimcoff_slurp_line_table (bfd *abfd, asection *asect)
425733965Sjdp{
425833965Sjdp  LINENO *native_lineno;
425933965Sjdp  alent *lineno_cache;
426089857Sobrien  bfd_size_type amt;
426133965Sjdp
4262218822Sdim  BFD_ASSERT (asect->lineno == NULL);
426333965Sjdp
426489857Sobrien  amt = (bfd_size_type) bfd_coff_linesz (abfd) * asect->lineno_count;
426589857Sobrien  native_lineno = (LINENO *) buy_and_read (abfd, asect->line_filepos, amt);
4266130561Sobrien  if (native_lineno == NULL)
4267130561Sobrien    {
4268130561Sobrien      (*_bfd_error_handler)
4269218822Sdim        (_("%B: warning: line number table read failed"), abfd);
4270130561Sobrien      return FALSE;
4271130561Sobrien    }
427289857Sobrien  amt = ((bfd_size_type) asect->lineno_count + 1) * sizeof (alent);
4273218822Sdim  lineno_cache = bfd_alloc (abfd, amt);
427433965Sjdp  if (lineno_cache == NULL)
4275130561Sobrien    return FALSE;
427633965Sjdp  else
427733965Sjdp    {
427833965Sjdp      unsigned int counter = 0;
427933965Sjdp      alent *cache_ptr = lineno_cache;
428033965Sjdp      LINENO *src = native_lineno;
428133965Sjdp
428233965Sjdp      while (counter < asect->lineno_count)
428333965Sjdp	{
428433965Sjdp	  struct internal_lineno dst;
4285130561Sobrien
428677298Sobrien	  bfd_coff_swap_lineno_in (abfd, src, &dst);
428733965Sjdp	  cache_ptr->line_number = dst.l_lnno;
428833965Sjdp
428933965Sjdp	  if (cache_ptr->line_number == 0)
429033965Sjdp	    {
4291130561Sobrien	      bfd_boolean warned;
429289857Sobrien	      bfd_signed_vma symndx;
429333965Sjdp	      coff_symbol_type *sym;
429433965Sjdp
4295130561Sobrien	      warned = FALSE;
429633965Sjdp	      symndx = dst.l_addr.l_symndx;
429738889Sjdp	      if (symndx < 0
429889857Sobrien		  || (bfd_vma) symndx >= obj_raw_syment_count (abfd))
429933965Sjdp		{
430033965Sjdp		  (*_bfd_error_handler)
4301218822Sdim		    (_("%B: warning: illegal symbol index %ld in line numbers"),
4302218822Sdim		     abfd, dst.l_addr.l_symndx);
430333965Sjdp		  symndx = 0;
4304130561Sobrien		  warned = TRUE;
430533965Sjdp		}
430633965Sjdp	      /* FIXME: We should not be casting between ints and
430733965Sjdp                 pointers like this.  */
430833965Sjdp	      sym = ((coff_symbol_type *)
430933965Sjdp		     ((symndx + obj_raw_syments (abfd))
431033965Sjdp		      ->u.syment._n._n_n._n_zeroes));
431133965Sjdp	      cache_ptr->u.sym = (asymbol *) sym;
431233965Sjdp	      if (sym->lineno != NULL && ! warned)
431333965Sjdp		{
431433965Sjdp		  (*_bfd_error_handler)
4315218822Sdim		    (_("%B: warning: duplicate line number information for `%s'"),
4316218822Sdim		     abfd, bfd_asymbol_name (&sym->symbol));
431733965Sjdp		}
431833965Sjdp	      sym->lineno = cache_ptr;
431933965Sjdp	    }
432033965Sjdp	  else
4321218822Sdim	    cache_ptr->u.offset = dst.l_addr.l_paddr
4322218822Sdim	      - bfd_section_vma (abfd, asect);
432333965Sjdp
432433965Sjdp	  cache_ptr++;
432533965Sjdp	  src++;
432633965Sjdp	  counter++;
432733965Sjdp	}
432833965Sjdp      cache_ptr->line_number = 0;
432933965Sjdp
433033965Sjdp    }
433133965Sjdp  asect->lineno = lineno_cache;
433277298Sobrien  /* FIXME, free native_lineno here, or use alloca or something.  */
4333130561Sobrien  return TRUE;
433433965Sjdp}
433533965Sjdp
433660484Sobrien/* Slurp in the symbol table, converting it to generic form.  Note
433760484Sobrien   that if coff_relocate_section is defined, the linker will read
433860484Sobrien   symbols via coff_link_add_symbols, rather than via this routine.  */
433960484Sobrien
4340130561Sobrienstatic bfd_boolean
4341218822Sdimcoff_slurp_symbol_table (bfd * abfd)
434233965Sjdp{
434333965Sjdp  combined_entry_type *native_symbols;
434433965Sjdp  coff_symbol_type *cached_area;
434533965Sjdp  unsigned int *table_ptr;
434689857Sobrien  bfd_size_type amt;
434733965Sjdp  unsigned int number_of_symbols = 0;
434833965Sjdp
434933965Sjdp  if (obj_symbols (abfd))
4350130561Sobrien    return TRUE;
435133965Sjdp
4352130561Sobrien  /* Read in the symbol table.  */
435333965Sjdp  if ((native_symbols = coff_get_normalized_symtab (abfd)) == NULL)
4354130561Sobrien    return FALSE;
435533965Sjdp
4356130561Sobrien  /* Allocate enough room for all the symbols in cached form.  */
435789857Sobrien  amt = obj_raw_syment_count (abfd);
435889857Sobrien  amt *= sizeof (coff_symbol_type);
4359218822Sdim  cached_area = bfd_alloc (abfd, amt);
436033965Sjdp  if (cached_area == NULL)
4361130561Sobrien    return FALSE;
436233965Sjdp
436389857Sobrien  amt = obj_raw_syment_count (abfd);
436489857Sobrien  amt *= sizeof (unsigned int);
4365218822Sdim  table_ptr = bfd_alloc (abfd, amt);
436689857Sobrien
436733965Sjdp  if (table_ptr == NULL)
4368130561Sobrien    return FALSE;
436933965Sjdp  else
437033965Sjdp    {
437133965Sjdp      coff_symbol_type *dst = cached_area;
437233965Sjdp      unsigned int last_native_index = obj_raw_syment_count (abfd);
437333965Sjdp      unsigned int this_index = 0;
4374130561Sobrien
437533965Sjdp      while (this_index < last_native_index)
437633965Sjdp	{
437733965Sjdp	  combined_entry_type *src = native_symbols + this_index;
437833965Sjdp	  table_ptr[this_index] = number_of_symbols;
437933965Sjdp	  dst->symbol.the_bfd = abfd;
438033965Sjdp
438133965Sjdp	  dst->symbol.name = (char *) (src->u.syment._n._n_n._n_offset);
438233965Sjdp	  /* We use the native name field to point to the cached field.  */
438333965Sjdp	  src->u.syment._n._n_n._n_zeroes = (long) dst;
438433965Sjdp	  dst->symbol.section = coff_section_from_bfd_index (abfd,
438533965Sjdp						     src->u.syment.n_scnum);
438633965Sjdp	  dst->symbol.flags = 0;
4387130561Sobrien	  dst->done_lineno = FALSE;
438833965Sjdp
438933965Sjdp	  switch (src->u.syment.n_sclass)
439033965Sjdp	    {
439133965Sjdp#ifdef I960
439233965Sjdp	    case C_LEAFEXT:
4393130561Sobrien	      /* Fall through to next case.  */
439433965Sjdp#endif
439533965Sjdp
439633965Sjdp	    case C_EXT:
439760484Sobrien	    case C_WEAKEXT:
439838889Sjdp#if defined ARM
439938889Sjdp            case C_THUMBEXT:
440038889Sjdp            case C_THUMBEXTFUNC:
440138889Sjdp#endif
440233965Sjdp#ifdef RS6000COFF_C
440333965Sjdp	    case C_HIDEXT:
440433965Sjdp#endif
440538889Sjdp#ifdef C_SYSTEM
4406130561Sobrien	    case C_SYSTEM:	/* System Wide variable.  */
440738889Sjdp#endif
440833965Sjdp#ifdef COFF_WITH_PE
4409130561Sobrien            /* In PE, 0x68 (104) denotes a section symbol.  */
441033965Sjdp            case C_SECTION:
441160484Sobrien	    /* In PE, 0x69 (105) denotes a weak external symbol.  */
441233965Sjdp	    case C_NT_WEAK:
441333965Sjdp#endif
441460484Sobrien	      switch (coff_classify_symbol (abfd, &src->u.syment))
441533965Sjdp		{
441660484Sobrien		case COFF_SYMBOL_GLOBAL:
441733965Sjdp		  dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL;
441838889Sjdp#if defined COFF_WITH_PE
441938889Sjdp		  /* PE sets the symbol to a value relative to the
442038889Sjdp                     start of the section.  */
442138889Sjdp		  dst->symbol.value = src->u.syment.n_value;
442238889Sjdp#else
442333965Sjdp		  dst->symbol.value = (src->u.syment.n_value
442433965Sjdp				       - dst->symbol.section->vma);
442538889Sjdp#endif
442633965Sjdp		  if (ISFCN ((src->u.syment.n_type)))
4427218822Sdim		    /* A function ext does not go at the end of a
4428218822Sdim		       file.  */
4429218822Sdim		    dst->symbol.flags |= BSF_NOT_AT_END | BSF_FUNCTION;
443060484Sobrien		  break;
443160484Sobrien
443260484Sobrien		case COFF_SYMBOL_COMMON:
443360484Sobrien		  dst->symbol.section = bfd_com_section_ptr;
443460484Sobrien		  dst->symbol.value = src->u.syment.n_value;
443560484Sobrien		  break;
443660484Sobrien
443760484Sobrien		case COFF_SYMBOL_UNDEFINED:
443860484Sobrien		  dst->symbol.section = bfd_und_section_ptr;
443960484Sobrien		  dst->symbol.value = 0;
444077298Sobrien		  break;
444160484Sobrien
444260484Sobrien		case COFF_SYMBOL_PE_SECTION:
444360484Sobrien		  dst->symbol.flags |= BSF_EXPORT | BSF_SECTION_SYM;
444460484Sobrien		  dst->symbol.value = 0;
444560484Sobrien		  break;
444660484Sobrien
444760484Sobrien		case COFF_SYMBOL_LOCAL:
444860484Sobrien		  dst->symbol.flags = BSF_LOCAL;
444960484Sobrien#if defined COFF_WITH_PE
445060484Sobrien		  /* PE sets the symbol to a value relative to the
445160484Sobrien                     start of the section.  */
445260484Sobrien		  dst->symbol.value = src->u.syment.n_value;
445360484Sobrien#else
445460484Sobrien		  dst->symbol.value = (src->u.syment.n_value
445560484Sobrien				       - dst->symbol.section->vma);
445660484Sobrien#endif
445760484Sobrien		  if (ISFCN ((src->u.syment.n_type)))
445860484Sobrien		    dst->symbol.flags |= BSF_NOT_AT_END | BSF_FUNCTION;
445960484Sobrien		  break;
446033965Sjdp		}
446133965Sjdp
446233965Sjdp#ifdef RS6000COFF_C
446333965Sjdp	      /* A symbol with a csect entry should not go at the end.  */
446433965Sjdp	      if (src->u.syment.n_numaux > 0)
446533965Sjdp		dst->symbol.flags |= BSF_NOT_AT_END;
446633965Sjdp#endif
446733965Sjdp
446833965Sjdp#ifdef COFF_WITH_PE
446933965Sjdp	      if (src->u.syment.n_sclass == C_NT_WEAK)
447094536Sobrien		dst->symbol.flags |= BSF_WEAK;
447194536Sobrien
447260484Sobrien	      if (src->u.syment.n_sclass == C_SECTION
447360484Sobrien		  && src->u.syment.n_scnum > 0)
447494536Sobrien		dst->symbol.flags = BSF_LOCAL;
447533965Sjdp#endif
447660484Sobrien	      if (src->u.syment.n_sclass == C_WEAKEXT)
447794536Sobrien		dst->symbol.flags |= BSF_WEAK;
447860484Sobrien
447933965Sjdp	      break;
448033965Sjdp
4481130561Sobrien	    case C_STAT:	 /* Static.  */
448233965Sjdp#ifdef I960
4483130561Sobrien	    case C_LEAFSTAT:	 /* Static leaf procedure.  */
448433965Sjdp#endif
448577298Sobrien#if defined ARM
4486130561Sobrien            case C_THUMBSTAT:    /* Thumb static.  */
4487130561Sobrien            case C_THUMBLABEL:   /* Thumb label.  */
4488130561Sobrien            case C_THUMBSTATFUNC:/* Thumb static function.  */
448938889Sjdp#endif
4490130561Sobrien	    case C_LABEL:	 /* Label.  */
449160484Sobrien	      if (src->u.syment.n_scnum == N_DEBUG)
449233965Sjdp		dst->symbol.flags = BSF_DEBUGGING;
449333965Sjdp	      else
449433965Sjdp		dst->symbol.flags = BSF_LOCAL;
449533965Sjdp
449633965Sjdp	      /* Base the value as an index from the base of the
449733965Sjdp		 section, if there is one.  */
449833965Sjdp	      if (dst->symbol.section)
449938889Sjdp		{
450038889Sjdp#if defined COFF_WITH_PE
450138889Sjdp		  /* PE sets the symbol to a value relative to the
450238889Sjdp                     start of the section.  */
450338889Sjdp		  dst->symbol.value = src->u.syment.n_value;
450438889Sjdp#else
450538889Sjdp		  dst->symbol.value = (src->u.syment.n_value
450638889Sjdp				       - dst->symbol.section->vma);
450738889Sjdp#endif
450838889Sjdp		}
450933965Sjdp	      else
451033965Sjdp		dst->symbol.value = src->u.syment.n_value;
451133965Sjdp	      break;
451233965Sjdp
4513130561Sobrien	    case C_MOS:		/* Member of structure.  */
4514130561Sobrien	    case C_EOS:		/* End of structure.  */
4515130561Sobrien	    case C_REGPARM:	/* Register parameter.  */
4516130561Sobrien	    case C_REG:		/* register variable.  */
4517130561Sobrien              /* C_AUTOARG conflicts with TI COFF C_UEXT.  */
451877298Sobrien#if !defined (TIC80COFF) && !defined (TICOFF)
451933965Sjdp#ifdef C_AUTOARG
4520130561Sobrien	    case C_AUTOARG:	/* 960-specific storage class.  */
452133965Sjdp#endif
452260484Sobrien#endif
4523130561Sobrien	    case C_TPDEF:	/* Type definition.  */
452433965Sjdp	    case C_ARG:
4525130561Sobrien	    case C_AUTO:	/* Automatic variable.  */
4526130561Sobrien	    case C_FIELD:	/* Bit field.  */
4527130561Sobrien	    case C_ENTAG:	/* Enumeration tag.  */
4528130561Sobrien	    case C_MOE:		/* Member of enumeration.  */
4529130561Sobrien	    case C_MOU:		/* Member of union.  */
4530130561Sobrien	    case C_UNTAG:	/* Union tag.  */
453133965Sjdp	      dst->symbol.flags = BSF_DEBUGGING;
453233965Sjdp	      dst->symbol.value = (src->u.syment.n_value);
453333965Sjdp	      break;
453433965Sjdp
4535130561Sobrien	    case C_FILE:	/* File name.  */
4536130561Sobrien	    case C_STRTAG:	/* Structure tag.  */
453733965Sjdp#ifdef RS6000COFF_C
453833965Sjdp	    case C_GSYM:
453933965Sjdp	    case C_LSYM:
454033965Sjdp	    case C_PSYM:
454133965Sjdp	    case C_RSYM:
454233965Sjdp	    case C_RPSYM:
454333965Sjdp	    case C_STSYM:
4544130561Sobrien	    case C_TCSYM:
454533965Sjdp	    case C_BCOMM:
4546130561Sobrien	    case C_ECOML:
454733965Sjdp	    case C_ECOMM:
454833965Sjdp	    case C_DECL:
454933965Sjdp	    case C_ENTRY:
455033965Sjdp	    case C_FUN:
455133965Sjdp	    case C_ESTAT:
455233965Sjdp#endif
455333965Sjdp	      dst->symbol.flags = BSF_DEBUGGING;
455433965Sjdp	      dst->symbol.value = (src->u.syment.n_value);
455533965Sjdp	      break;
455633965Sjdp
455733965Sjdp#ifdef RS6000COFF_C
4558130561Sobrien	    case C_BINCL:	/* Beginning of include file.  */
4559130561Sobrien	    case C_EINCL:	/* Ending of include file.  */
456033965Sjdp	      /* The value is actually a pointer into the line numbers
456133965Sjdp                 of the file.  We locate the line number entry, and
456233965Sjdp                 set the section to the section which contains it, and
456333965Sjdp                 the value to the index in that section.  */
456433965Sjdp	      {
456533965Sjdp		asection *sec;
456633965Sjdp
456733965Sjdp		dst->symbol.flags = BSF_DEBUGGING;
456833965Sjdp		for (sec = abfd->sections; sec != NULL; sec = sec->next)
456933965Sjdp		  if (sec->line_filepos <= (file_ptr) src->u.syment.n_value
457033965Sjdp		      && ((file_ptr) (sec->line_filepos
457160484Sobrien				      + sec->lineno_count * bfd_coff_linesz (abfd))
457233965Sjdp			  > (file_ptr) src->u.syment.n_value))
457333965Sjdp		    break;
457433965Sjdp		if (sec == NULL)
457533965Sjdp		  dst->symbol.value = 0;
457633965Sjdp		else
457733965Sjdp		  {
457833965Sjdp		    dst->symbol.section = sec;
457933965Sjdp		    dst->symbol.value = ((src->u.syment.n_value
458033965Sjdp					  - sec->line_filepos)
458160484Sobrien					 / bfd_coff_linesz (abfd));
458233965Sjdp		    src->fix_line = 1;
458333965Sjdp		  }
458433965Sjdp	      }
458533965Sjdp	      break;
458633965Sjdp
458733965Sjdp	    case C_BSTAT:
458833965Sjdp	      dst->symbol.flags = BSF_DEBUGGING;
458933965Sjdp
459033965Sjdp	      /* The value is actually a symbol index.  Save a pointer
459133965Sjdp		 to the symbol instead of the index.  FIXME: This
459233965Sjdp		 should use a union.  */
459333965Sjdp	      src->u.syment.n_value =
459433965Sjdp		(long) (native_symbols + src->u.syment.n_value);
459533965Sjdp	      dst->symbol.value = src->u.syment.n_value;
459633965Sjdp	      src->fix_value = 1;
459733965Sjdp	      break;
459833965Sjdp#endif
459933965Sjdp
4600130561Sobrien	    case C_BLOCK:	/* ".bb" or ".eb".  */
4601130561Sobrien	    case C_FCN:		/* ".bf" or ".ef" (or PE ".lf").  */
4602130561Sobrien	    case C_EFCN:	/* Physical end of function.  */
460338889Sjdp#if defined COFF_WITH_PE
460438889Sjdp	      /* PE sets the symbol to a value relative to the start
460538889Sjdp		 of the section.  */
460638889Sjdp	      dst->symbol.value = src->u.syment.n_value;
460760484Sobrien	      if (strcmp (dst->symbol.name, ".bf") != 0)
460860484Sobrien		{
460960484Sobrien		  /* PE uses funny values for .ef and .lf; don't
461060484Sobrien                     relocate them.  */
461160484Sobrien		  dst->symbol.flags = BSF_DEBUGGING;
461260484Sobrien		}
461360484Sobrien	      else
461460484Sobrien		dst->symbol.flags = BSF_DEBUGGING | BSF_DEBUGGING_RELOC;
461538889Sjdp#else
461633965Sjdp	      /* Base the value as an index from the base of the
461733965Sjdp		 section.  */
461860484Sobrien	      dst->symbol.flags = BSF_LOCAL;
461933965Sjdp	      dst->symbol.value = (src->u.syment.n_value
462033965Sjdp				   - dst->symbol.section->vma);
462138889Sjdp#endif
462233965Sjdp	      break;
462333965Sjdp
4624130561Sobrien	    case C_STATLAB:	/* Static load time label.  */
462577298Sobrien              dst->symbol.value = src->u.syment.n_value;
462677298Sobrien              dst->symbol.flags = BSF_GLOBAL;
462777298Sobrien              break;
462877298Sobrien
462933965Sjdp	    case C_NULL:
463060484Sobrien	      /* PE DLLs sometimes have zeroed out symbols for some
463160484Sobrien                 reason.  Just ignore them without a warning.  */
463260484Sobrien	      if (src->u.syment.n_type == 0
463360484Sobrien		  && src->u.syment.n_value == 0
463460484Sobrien		  && src->u.syment.n_scnum == 0)
463560484Sobrien		break;
463660484Sobrien	      /* Fall through.  */
4637130561Sobrien	    case C_EXTDEF:	/* External definition.  */
4638130561Sobrien	    case C_ULABEL:	/* Undefined label.  */
4639130561Sobrien	    case C_USTATIC:	/* Undefined static.  */
464033965Sjdp#ifndef COFF_WITH_PE
464133965Sjdp            /* C_LINE in regular coff is 0x68.  NT has taken over this storage
4642130561Sobrien               class to represent a section symbol.  */
4643130561Sobrien	    case C_LINE:	/* line # reformatted as symbol table entry.  */
464433965Sjdp	      /* NT uses 0x67 for a weak symbol, not C_ALIAS.  */
4645130561Sobrien	    case C_ALIAS:	/* Duplicate tag.  */
464633965Sjdp#endif
4647130561Sobrien	      /* New storage classes for TI COFF.  */
464877298Sobrien#if defined(TIC80COFF) || defined(TICOFF)
4649130561Sobrien	    case C_UEXT:	/* Tentative external definition.  */
465060484Sobrien#endif
4651130561Sobrien	    case C_EXTLAB:	/* External load time label.  */
4652130561Sobrien	    case C_HIDDEN:	/* Ext symbol in dmert public lib.  */
465333965Sjdp	    default:
465433965Sjdp	      (*_bfd_error_handler)
4655218822Sdim		(_("%B: Unrecognized storage class %d for %s symbol `%s'"),
4656218822Sdim		 abfd, src->u.syment.n_sclass,
465733965Sjdp		 dst->symbol.section->name, dst->symbol.name);
465833965Sjdp	      dst->symbol.flags = BSF_DEBUGGING;
465933965Sjdp	      dst->symbol.value = (src->u.syment.n_value);
466033965Sjdp	      break;
466133965Sjdp	    }
466233965Sjdp
466333965Sjdp	  dst->native = src;
466433965Sjdp
466533965Sjdp	  dst->symbol.udata.i = 0;
4666218822Sdim	  dst->lineno = NULL;
466733965Sjdp	  this_index += (src->u.syment.n_numaux) + 1;
466833965Sjdp	  dst++;
466933965Sjdp	  number_of_symbols++;
4670130561Sobrien	}
4671130561Sobrien    }
467233965Sjdp
467333965Sjdp  obj_symbols (abfd) = cached_area;
467433965Sjdp  obj_raw_syments (abfd) = native_symbols;
467533965Sjdp
467633965Sjdp  bfd_get_symcount (abfd) = number_of_symbols;
467733965Sjdp  obj_convert (abfd) = table_ptr;
4678130561Sobrien  /* Slurp the line tables for each section too.  */
467933965Sjdp  {
468033965Sjdp    asection *p;
4681130561Sobrien
468233965Sjdp    p = abfd->sections;
468333965Sjdp    while (p)
468433965Sjdp      {
468533965Sjdp	coff_slurp_line_table (abfd, p);
468633965Sjdp	p = p->next;
468733965Sjdp      }
468833965Sjdp  }
4689130561Sobrien
4690130561Sobrien  return TRUE;
4691218822Sdim}
469233965Sjdp
469360484Sobrien/* Classify a COFF symbol.  A couple of targets have globally visible
469460484Sobrien   symbols which are not class C_EXT, and this handles those.  It also
469560484Sobrien   recognizes some special PE cases.  */
469633965Sjdp
469760484Sobrienstatic enum coff_symbol_classification
4698218822Sdimcoff_classify_symbol (bfd *abfd,
4699218822Sdim		      struct internal_syment *syment)
470060484Sobrien{
470160484Sobrien  /* FIXME: This partially duplicates the switch in
470260484Sobrien     coff_slurp_symbol_table.  */
470360484Sobrien  switch (syment->n_sclass)
470460484Sobrien    {
470560484Sobrien    case C_EXT:
470660484Sobrien    case C_WEAKEXT:
470733965Sjdp#ifdef I960
470860484Sobrien    case C_LEAFEXT:
470933965Sjdp#endif
471060484Sobrien#ifdef ARM
471160484Sobrien    case C_THUMBEXT:
471260484Sobrien    case C_THUMBEXTFUNC:
471360484Sobrien#endif
471460484Sobrien#ifdef C_SYSTEM
471560484Sobrien    case C_SYSTEM:
471660484Sobrien#endif
471733965Sjdp#ifdef COFF_WITH_PE
471860484Sobrien    case C_NT_WEAK:
471933965Sjdp#endif
472060484Sobrien      if (syment->n_scnum == 0)
472160484Sobrien	{
472260484Sobrien	  if (syment->n_value == 0)
472360484Sobrien	    return COFF_SYMBOL_UNDEFINED;
472460484Sobrien	  else
472560484Sobrien	    return COFF_SYMBOL_COMMON;
472660484Sobrien	}
472760484Sobrien      return COFF_SYMBOL_GLOBAL;
472833965Sjdp
472960484Sobrien    default:
473060484Sobrien      break;
473160484Sobrien    }
473233965Sjdp
473360484Sobrien#ifdef COFF_WITH_PE
473460484Sobrien  if (syment->n_sclass == C_STAT)
473560484Sobrien    {
473660484Sobrien      if (syment->n_scnum == 0)
4737218822Sdim	/* The Microsoft compiler sometimes generates these if a
4738218822Sdim	   small static function is inlined every time it is used.
4739218822Sdim	   The function is discarded, but the symbol table entry
4740218822Sdim	   remains.  */
4741218822Sdim	return COFF_SYMBOL_LOCAL;
474233965Sjdp
474360484Sobrien#ifdef STRICT_PE_FORMAT
474460484Sobrien      /* This is correct for Microsoft generated objects, but it
474560484Sobrien         breaks gas generated objects.  */
474660484Sobrien      if (syment->n_value == 0)
474760484Sobrien	{
474860484Sobrien	  asection *sec;
474960484Sobrien	  char buf[SYMNMLEN + 1];
475033965Sjdp
475160484Sobrien	  sec = coff_section_from_bfd_index (abfd, syment->n_scnum);
475260484Sobrien	  if (sec != NULL
475360484Sobrien	      && (strcmp (bfd_get_section_name (abfd, sec),
475460484Sobrien			  _bfd_coff_internal_syment_name (abfd, syment, buf))
475560484Sobrien		  == 0))
475660484Sobrien	    return COFF_SYMBOL_PE_SECTION;
475760484Sobrien	}
475860484Sobrien#endif
475933965Sjdp
476060484Sobrien      return COFF_SYMBOL_LOCAL;
476160484Sobrien    }
476233965Sjdp
476360484Sobrien  if (syment->n_sclass == C_SECTION)
476460484Sobrien    {
476560484Sobrien      /* In some cases in a DLL generated by the Microsoft linker, the
476660484Sobrien         n_value field will contain garbage.  FIXME: This should
476760484Sobrien         probably be handled by the swapping function instead.  */
476860484Sobrien      syment->n_value = 0;
476960484Sobrien      if (syment->n_scnum == 0)
477060484Sobrien	return COFF_SYMBOL_UNDEFINED;
477160484Sobrien      return COFF_SYMBOL_PE_SECTION;
477260484Sobrien    }
477360484Sobrien#endif /* COFF_WITH_PE */
477433965Sjdp
477560484Sobrien  /* If it is not a global symbol, we presume it is a local symbol.  */
477660484Sobrien  if (syment->n_scnum == 0)
477760484Sobrien    {
477860484Sobrien      char buf[SYMNMLEN + 1];
477960484Sobrien
478060484Sobrien      (*_bfd_error_handler)
4781218822Sdim	(_("warning: %B: local symbol `%s' has no section"),
4782218822Sdim	 abfd, _bfd_coff_internal_syment_name (abfd, syment, buf));
478360484Sobrien    }
478460484Sobrien
478560484Sobrien  return COFF_SYMBOL_LOCAL;
478660484Sobrien}
478760484Sobrien
478833965Sjdp/*
478933965SjdpSUBSUBSECTION
479033965Sjdp	Reading relocations
479133965Sjdp
479233965Sjdp	Coff relocations are easily transformed into the internal BFD form
479333965Sjdp	(@code{arelent}).
479433965Sjdp
479533965Sjdp	Reading a coff relocation table is done in the following stages:
479633965Sjdp
479733965Sjdp	o Read the entire coff relocation table into memory.
479833965Sjdp
479933965Sjdp	o Process each relocation in turn; first swap it from the
480033965Sjdp	external to the internal form.
480133965Sjdp
480233965Sjdp	o Turn the symbol referenced in the relocation's symbol index
480333965Sjdp	into a pointer into the canonical symbol table.
480433965Sjdp	This table is the same as the one returned by a call to
480533965Sjdp	@code{bfd_canonicalize_symtab}. The back end will call that
480633965Sjdp	routine and save the result if a canonicalization hasn't been done.
480733965Sjdp
480833965Sjdp	o The reloc index is turned into a pointer to a howto
480933965Sjdp	structure, in a back end specific way. For instance, the 386
481033965Sjdp	and 960 use the @code{r_type} to directly produce an index
481133965Sjdp	into a howto table vector; the 88k subtracts a number from the
481233965Sjdp	@code{r_type} field and creates an addend field.
481333965Sjdp*/
481433965Sjdp
481533965Sjdp#ifndef CALC_ADDEND
481633965Sjdp#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr)                \
481733965Sjdp  {                                                             \
4818218822Sdim    coff_symbol_type *coffsym = NULL;      			\
4819218822Sdim                                                                \
482033965Sjdp    if (ptr && bfd_asymbol_bfd (ptr) != abfd)                   \
482133965Sjdp      coffsym = (obj_symbols (abfd)                             \
482233965Sjdp                 + (cache_ptr->sym_ptr_ptr - symbols));         \
482333965Sjdp    else if (ptr)                                               \
482433965Sjdp      coffsym = coff_symbol_from (abfd, ptr);                   \
4825218822Sdim    if (coffsym != NULL				                \
482633965Sjdp        && coffsym->native->u.syment.n_scnum == 0)              \
482733965Sjdp      cache_ptr->addend = 0;                                    \
482833965Sjdp    else if (ptr && bfd_asymbol_bfd (ptr) == abfd               \
4829218822Sdim             && ptr->section != NULL)		                \
483033965Sjdp      cache_ptr->addend = - (ptr->section->vma + ptr->value);   \
483133965Sjdp    else                                                        \
483233965Sjdp      cache_ptr->addend = 0;                                    \
483333965Sjdp  }
483433965Sjdp#endif
483533965Sjdp
4836130561Sobrienstatic bfd_boolean
4837218822Sdimcoff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols)
483833965Sjdp{
483933965Sjdp  RELOC *native_relocs;
484033965Sjdp  arelent *reloc_cache;
484133965Sjdp  arelent *cache_ptr;
484233965Sjdp  unsigned int idx;
484389857Sobrien  bfd_size_type amt;
484433965Sjdp
484533965Sjdp  if (asect->relocation)
4846130561Sobrien    return TRUE;
484733965Sjdp  if (asect->reloc_count == 0)
4848130561Sobrien    return TRUE;
484933965Sjdp  if (asect->flags & SEC_CONSTRUCTOR)
4850130561Sobrien    return TRUE;
485133965Sjdp  if (!coff_slurp_symbol_table (abfd))
4852130561Sobrien    return FALSE;
4853218822Sdim
485489857Sobrien  amt = (bfd_size_type) bfd_coff_relsz (abfd) * asect->reloc_count;
485589857Sobrien  native_relocs = (RELOC *) buy_and_read (abfd, asect->rel_filepos, amt);
485689857Sobrien  amt = (bfd_size_type) asect->reloc_count * sizeof (arelent);
4857218822Sdim  reloc_cache = bfd_alloc (abfd, amt);
485833965Sjdp
4859218822Sdim  if (reloc_cache == NULL || native_relocs == NULL)
4860130561Sobrien    return FALSE;
486133965Sjdp
486233965Sjdp  for (idx = 0; idx < asect->reloc_count; idx++)
486333965Sjdp    {
486433965Sjdp      struct internal_reloc dst;
486533965Sjdp      struct external_reloc *src;
486633965Sjdp#ifndef RELOC_PROCESSING
486733965Sjdp      asymbol *ptr;
486833965Sjdp#endif
486933965Sjdp
487033965Sjdp      cache_ptr = reloc_cache + idx;
487133965Sjdp      src = native_relocs + idx;
487233965Sjdp
4873218822Sdim      dst.r_offset = 0;
487433965Sjdp      coff_swap_reloc_in (abfd, src, &dst);
487533965Sjdp
487633965Sjdp#ifdef RELOC_PROCESSING
487733965Sjdp      RELOC_PROCESSING (cache_ptr, &dst, symbols, abfd, asect);
487833965Sjdp#else
487933965Sjdp      cache_ptr->address = dst.r_vaddr;
488033965Sjdp
488133965Sjdp      if (dst.r_symndx != -1)
488233965Sjdp	{
488333965Sjdp	  if (dst.r_symndx < 0 || dst.r_symndx >= obj_conv_table_size (abfd))
488433965Sjdp	    {
488533965Sjdp	      (*_bfd_error_handler)
4886218822Sdim		(_("%B: warning: illegal symbol index %ld in relocs"),
4887218822Sdim		 abfd, dst.r_symndx);
488833965Sjdp	      cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
488933965Sjdp	      ptr = NULL;
489033965Sjdp	    }
489133965Sjdp	  else
489233965Sjdp	    {
489333965Sjdp	      cache_ptr->sym_ptr_ptr = (symbols
489433965Sjdp					+ obj_convert (abfd)[dst.r_symndx]);
489533965Sjdp	      ptr = *(cache_ptr->sym_ptr_ptr);
489633965Sjdp	    }
489733965Sjdp	}
489833965Sjdp      else
489933965Sjdp	{
490033965Sjdp	  cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
490133965Sjdp	  ptr = NULL;
490233965Sjdp	}
490333965Sjdp
490433965Sjdp      /* The symbols definitions that we have read in have been
490533965Sjdp	 relocated as if their sections started at 0. But the offsets
490633965Sjdp	 refering to the symbols in the raw data have not been
490733965Sjdp	 modified, so we have to have a negative addend to compensate.
490833965Sjdp
4909130561Sobrien	 Note that symbols which used to be common must be left alone.  */
491033965Sjdp
4911130561Sobrien      /* Calculate any reloc addend by looking at the symbol.  */
491233965Sjdp      CALC_ADDEND (abfd, ptr, dst, cache_ptr);
491333965Sjdp
491433965Sjdp      cache_ptr->address -= asect->vma;
4915218822Sdim      /* !! cache_ptr->section = NULL;*/
491633965Sjdp
4917130561Sobrien      /* Fill in the cache_ptr->howto field from dst.r_type.  */
491833965Sjdp      RTYPE2HOWTO (cache_ptr, &dst);
491933965Sjdp#endif	/* RELOC_PROCESSING */
492033965Sjdp
492133965Sjdp      if (cache_ptr->howto == NULL)
492233965Sjdp	{
492333965Sjdp	  (*_bfd_error_handler)
4924218822Sdim	    (_("%B: illegal relocation type %d at address 0x%lx"),
4925218822Sdim	     abfd, dst.r_type, (long) dst.r_vaddr);
492633965Sjdp	  bfd_set_error (bfd_error_bad_value);
4927130561Sobrien	  return FALSE;
492833965Sjdp	}
492933965Sjdp    }
493033965Sjdp
493133965Sjdp  asect->relocation = reloc_cache;
4932130561Sobrien  return TRUE;
493333965Sjdp}
493433965Sjdp
493533965Sjdp#ifndef coff_rtype_to_howto
493633965Sjdp#ifdef RTYPE2HOWTO
493733965Sjdp
493833965Sjdp/* Get the howto structure for a reloc.  This is only used if the file
493933965Sjdp   including this one defines coff_relocate_section to be
494033965Sjdp   _bfd_coff_generic_relocate_section, so it is OK if it does not
494133965Sjdp   always work.  It is the responsibility of the including file to
494233965Sjdp   make sure it is reasonable if it is needed.  */
494333965Sjdp
494433965Sjdpstatic reloc_howto_type *
4945218822Sdimcoff_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
4946218822Sdim		     asection *sec ATTRIBUTE_UNUSED,
4947218822Sdim		     struct internal_reloc *rel,
4948218822Sdim		     struct coff_link_hash_entry *h ATTRIBUTE_UNUSED,
4949218822Sdim		     struct internal_syment *sym ATTRIBUTE_UNUSED,
4950218822Sdim		     bfd_vma *addendp ATTRIBUTE_UNUSED)
495133965Sjdp{
495233965Sjdp  arelent genrel;
495333965Sjdp
4954218822Sdim  genrel.howto = NULL;
495533965Sjdp  RTYPE2HOWTO (&genrel, rel);
495633965Sjdp  return genrel.howto;
495733965Sjdp}
495833965Sjdp
495933965Sjdp#else /* ! defined (RTYPE2HOWTO) */
496033965Sjdp
496133965Sjdp#define coff_rtype_to_howto NULL
496233965Sjdp
496333965Sjdp#endif /* ! defined (RTYPE2HOWTO) */
496433965Sjdp#endif /* ! defined (coff_rtype_to_howto) */
496533965Sjdp
496633965Sjdp/* This is stupid.  This function should be a boolean predicate.  */
4967218822Sdim
496833965Sjdpstatic long
4969218822Sdimcoff_canonicalize_reloc (bfd * abfd,
4970218822Sdim			 sec_ptr section,
4971218822Sdim			 arelent ** relptr,
4972218822Sdim			 asymbol ** symbols)
497333965Sjdp{
497433965Sjdp  arelent *tblptr = section->relocation;
497533965Sjdp  unsigned int count = 0;
497633965Sjdp
497733965Sjdp  if (section->flags & SEC_CONSTRUCTOR)
497833965Sjdp    {
4979130561Sobrien      /* This section has relocs made up by us, they are not in the
4980130561Sobrien	 file, so take them out of their chain and place them into
4981130561Sobrien	 the data area provided.  */
498233965Sjdp      arelent_chain *chain = section->constructor_chain;
4983130561Sobrien
498433965Sjdp      for (count = 0; count < section->reloc_count; count++)
498533965Sjdp	{
498633965Sjdp	  *relptr++ = &chain->relent;
498733965Sjdp	  chain = chain->next;
498833965Sjdp	}
498933965Sjdp    }
499033965Sjdp  else
499133965Sjdp    {
499233965Sjdp      if (! coff_slurp_reloc_table (abfd, section, symbols))
499333965Sjdp	return -1;
499433965Sjdp
499533965Sjdp      tblptr = section->relocation;
499633965Sjdp
499733965Sjdp      for (; count++ < section->reloc_count;)
499833965Sjdp	*relptr++ = tblptr++;
499933965Sjdp    }
500033965Sjdp  *relptr = 0;
500133965Sjdp  return section->reloc_count;
500233965Sjdp}
500333965Sjdp
500433965Sjdp#ifndef coff_reloc16_estimate
500533965Sjdp#define coff_reloc16_estimate dummy_reloc16_estimate
500633965Sjdp
500733965Sjdpstatic int
5008218822Sdimdummy_reloc16_estimate (bfd *abfd ATTRIBUTE_UNUSED,
5009218822Sdim			asection *input_section ATTRIBUTE_UNUSED,
5010218822Sdim			arelent *reloc ATTRIBUTE_UNUSED,
5011218822Sdim			unsigned int shrink ATTRIBUTE_UNUSED,
5012218822Sdim			struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
501333965Sjdp{
501433965Sjdp  abort ();
501560484Sobrien  return 0;
501633965Sjdp}
501733965Sjdp
501833965Sjdp#endif
501933965Sjdp
502033965Sjdp#ifndef coff_reloc16_extra_cases
502133965Sjdp
502233965Sjdp#define coff_reloc16_extra_cases dummy_reloc16_extra_cases
502333965Sjdp
502433965Sjdp/* This works even if abort is not declared in any header file.  */
502533965Sjdp
502633965Sjdpstatic void
5027218822Sdimdummy_reloc16_extra_cases (bfd *abfd ATTRIBUTE_UNUSED,
5028218822Sdim			   struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
5029218822Sdim			   struct bfd_link_order *link_order ATTRIBUTE_UNUSED,
5030218822Sdim			   arelent *reloc ATTRIBUTE_UNUSED,
5031218822Sdim			   bfd_byte *data ATTRIBUTE_UNUSED,
5032218822Sdim			   unsigned int *src_ptr ATTRIBUTE_UNUSED,
5033218822Sdim			   unsigned int *dst_ptr ATTRIBUTE_UNUSED)
503433965Sjdp{
503533965Sjdp  abort ();
503633965Sjdp}
503733965Sjdp#endif
503833965Sjdp
5039104834Sobrien#ifndef coff_bfd_link_hash_table_free
5040104834Sobrien#define coff_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
5041104834Sobrien#endif
5042104834Sobrien
504333965Sjdp/* If coff_relocate_section is defined, we can use the optimized COFF
504433965Sjdp   backend linker.  Otherwise we must continue to use the old linker.  */
5045218822Sdim
504633965Sjdp#ifdef coff_relocate_section
5047218822Sdim
504833965Sjdp#ifndef coff_bfd_link_hash_table_create
504933965Sjdp#define coff_bfd_link_hash_table_create _bfd_coff_link_hash_table_create
505033965Sjdp#endif
505133965Sjdp#ifndef coff_bfd_link_add_symbols
505233965Sjdp#define coff_bfd_link_add_symbols _bfd_coff_link_add_symbols
505333965Sjdp#endif
505433965Sjdp#ifndef coff_bfd_final_link
505533965Sjdp#define coff_bfd_final_link _bfd_coff_final_link
505633965Sjdp#endif
5057218822Sdim
505833965Sjdp#else /* ! defined (coff_relocate_section) */
5059218822Sdim
506033965Sjdp#define coff_relocate_section NULL
506133965Sjdp#ifndef coff_bfd_link_hash_table_create
506233965Sjdp#define coff_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
506333965Sjdp#endif
506433965Sjdp#ifndef coff_bfd_link_add_symbols
506533965Sjdp#define coff_bfd_link_add_symbols _bfd_generic_link_add_symbols
506633965Sjdp#endif
506733965Sjdp#define coff_bfd_final_link _bfd_generic_final_link
5068218822Sdim
506933965Sjdp#endif /* ! defined (coff_relocate_section) */
507038889Sjdp
5071218822Sdim#define coff_bfd_link_just_syms      _bfd_generic_link_just_syms
507233965Sjdp#define coff_bfd_link_split_section  _bfd_generic_link_split_section
507333965Sjdp
507433965Sjdp#ifndef coff_start_final_link
507533965Sjdp#define coff_start_final_link NULL
507633965Sjdp#endif
507733965Sjdp
507833965Sjdp#ifndef coff_adjust_symndx
507933965Sjdp#define coff_adjust_symndx NULL
508033965Sjdp#endif
508133965Sjdp
508233965Sjdp#ifndef coff_link_add_one_symbol
508333965Sjdp#define coff_link_add_one_symbol _bfd_generic_link_add_one_symbol
508433965Sjdp#endif
508533965Sjdp
508638889Sjdp#ifndef coff_link_output_has_begun
508760484Sobrien
5088130561Sobrienstatic bfd_boolean
5089218822Sdimcoff_link_output_has_begun (bfd * abfd,
5090218822Sdim			    struct coff_final_link_info * info ATTRIBUTE_UNUSED)
509138889Sjdp{
509238889Sjdp  return abfd->output_has_begun;
509338889Sjdp}
509438889Sjdp#endif
509538889Sjdp
509638889Sjdp#ifndef coff_final_link_postscript
509760484Sobrien
5098130561Sobrienstatic bfd_boolean
5099218822Sdimcoff_final_link_postscript (bfd * abfd ATTRIBUTE_UNUSED,
5100218822Sdim			    struct coff_final_link_info * pfinfo ATTRIBUTE_UNUSED)
510138889Sjdp{
5102130561Sobrien  return TRUE;
510338889Sjdp}
510438889Sjdp#endif
510538889Sjdp
510638889Sjdp#ifndef coff_SWAP_aux_in
510738889Sjdp#define coff_SWAP_aux_in coff_swap_aux_in
510838889Sjdp#endif
510938889Sjdp#ifndef coff_SWAP_sym_in
511038889Sjdp#define coff_SWAP_sym_in coff_swap_sym_in
511138889Sjdp#endif
511238889Sjdp#ifndef coff_SWAP_lineno_in
511338889Sjdp#define coff_SWAP_lineno_in coff_swap_lineno_in
511438889Sjdp#endif
511538889Sjdp#ifndef coff_SWAP_aux_out
511638889Sjdp#define coff_SWAP_aux_out coff_swap_aux_out
511738889Sjdp#endif
511838889Sjdp#ifndef coff_SWAP_sym_out
511938889Sjdp#define coff_SWAP_sym_out coff_swap_sym_out
512038889Sjdp#endif
512138889Sjdp#ifndef coff_SWAP_lineno_out
512238889Sjdp#define coff_SWAP_lineno_out coff_swap_lineno_out
512338889Sjdp#endif
512438889Sjdp#ifndef coff_SWAP_reloc_out
512538889Sjdp#define coff_SWAP_reloc_out coff_swap_reloc_out
512638889Sjdp#endif
512738889Sjdp#ifndef coff_SWAP_filehdr_out
512838889Sjdp#define coff_SWAP_filehdr_out coff_swap_filehdr_out
512938889Sjdp#endif
513038889Sjdp#ifndef coff_SWAP_aouthdr_out
513138889Sjdp#define coff_SWAP_aouthdr_out coff_swap_aouthdr_out
513238889Sjdp#endif
513338889Sjdp#ifndef coff_SWAP_scnhdr_out
513438889Sjdp#define coff_SWAP_scnhdr_out coff_swap_scnhdr_out
513538889Sjdp#endif
513638889Sjdp#ifndef coff_SWAP_reloc_in
513738889Sjdp#define coff_SWAP_reloc_in coff_swap_reloc_in
513838889Sjdp#endif
513938889Sjdp#ifndef coff_SWAP_filehdr_in
514038889Sjdp#define coff_SWAP_filehdr_in coff_swap_filehdr_in
514138889Sjdp#endif
514238889Sjdp#ifndef coff_SWAP_aouthdr_in
514338889Sjdp#define coff_SWAP_aouthdr_in coff_swap_aouthdr_in
514438889Sjdp#endif
514538889Sjdp#ifndef coff_SWAP_scnhdr_in
514638889Sjdp#define coff_SWAP_scnhdr_in coff_swap_scnhdr_in
514738889Sjdp#endif
514838889Sjdp
5149218822Sdimstatic const bfd_coff_backend_data bfd_coff_std_swap_table ATTRIBUTE_UNUSED =
515033965Sjdp{
515138889Sjdp  coff_SWAP_aux_in, coff_SWAP_sym_in, coff_SWAP_lineno_in,
515238889Sjdp  coff_SWAP_aux_out, coff_SWAP_sym_out,
515338889Sjdp  coff_SWAP_lineno_out, coff_SWAP_reloc_out,
515438889Sjdp  coff_SWAP_filehdr_out, coff_SWAP_aouthdr_out,
515538889Sjdp  coff_SWAP_scnhdr_out,
515660484Sobrien  FILHSZ, AOUTSZ, SCNHSZ, SYMESZ, AUXESZ, RELSZ, LINESZ, FILNMLEN,
515733965Sjdp#ifdef COFF_LONG_FILENAMES
5158130561Sobrien  TRUE,
515933965Sjdp#else
5160130561Sobrien  FALSE,
516133965Sjdp#endif
516233965Sjdp#ifdef COFF_LONG_SECTION_NAMES
5163130561Sobrien  TRUE,
516433965Sjdp#else
5165130561Sobrien  FALSE,
516633965Sjdp#endif
516733965Sjdp  COFF_DEFAULT_SECTION_ALIGNMENT_POWER,
516877298Sobrien#ifdef COFF_FORCE_SYMBOLS_IN_STRINGS
5169130561Sobrien  TRUE,
517077298Sobrien#else
5171130561Sobrien  FALSE,
517277298Sobrien#endif
517377298Sobrien#ifdef COFF_DEBUG_STRING_WIDE_PREFIX
517477298Sobrien  4,
517577298Sobrien#else
517677298Sobrien  2,
517777298Sobrien#endif
517838889Sjdp  coff_SWAP_filehdr_in, coff_SWAP_aouthdr_in, coff_SWAP_scnhdr_in,
517938889Sjdp  coff_SWAP_reloc_in, coff_bad_format_hook, coff_set_arch_mach_hook,
518033965Sjdp  coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook,
518133965Sjdp  coff_slurp_symbol_table, symname_in_debug_hook, coff_pointerize_aux_hook,
518233965Sjdp  coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
518360484Sobrien  coff_classify_symbol, coff_compute_section_file_positions,
518433965Sjdp  coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
518538889Sjdp  coff_adjust_symndx, coff_link_add_one_symbol,
518638889Sjdp  coff_link_output_has_begun, coff_final_link_postscript
518733965Sjdp};
518833965Sjdp
5189130561Sobrien#ifdef TICOFF
5190130561Sobrien/* COFF0 differs in file/section header size and relocation entry size.  */
5191218822Sdim
5192130561Sobrienstatic const bfd_coff_backend_data ticoff0_swap_table =
5193130561Sobrien{
5194130561Sobrien  coff_SWAP_aux_in, coff_SWAP_sym_in, coff_SWAP_lineno_in,
5195130561Sobrien  coff_SWAP_aux_out, coff_SWAP_sym_out,
5196130561Sobrien  coff_SWAP_lineno_out, coff_SWAP_reloc_out,
5197130561Sobrien  coff_SWAP_filehdr_out, coff_SWAP_aouthdr_out,
5198130561Sobrien  coff_SWAP_scnhdr_out,
5199130561Sobrien  FILHSZ_V0, AOUTSZ, SCNHSZ_V01, SYMESZ, AUXESZ, RELSZ_V0, LINESZ, FILNMLEN,
5200130561Sobrien#ifdef COFF_LONG_FILENAMES
5201130561Sobrien  TRUE,
5202130561Sobrien#else
5203130561Sobrien  FALSE,
5204130561Sobrien#endif
5205130561Sobrien#ifdef COFF_LONG_SECTION_NAMES
5206130561Sobrien  TRUE,
5207130561Sobrien#else
5208130561Sobrien  FALSE,
5209130561Sobrien#endif
5210130561Sobrien  COFF_DEFAULT_SECTION_ALIGNMENT_POWER,
5211130561Sobrien#ifdef COFF_FORCE_SYMBOLS_IN_STRINGS
5212130561Sobrien  TRUE,
5213130561Sobrien#else
5214130561Sobrien  FALSE,
5215130561Sobrien#endif
5216130561Sobrien#ifdef COFF_DEBUG_STRING_WIDE_PREFIX
5217130561Sobrien  4,
5218130561Sobrien#else
5219130561Sobrien  2,
5220130561Sobrien#endif
5221130561Sobrien  coff_SWAP_filehdr_in, coff_SWAP_aouthdr_in, coff_SWAP_scnhdr_in,
5222130561Sobrien  coff_SWAP_reloc_in, ticoff0_bad_format_hook, coff_set_arch_mach_hook,
5223130561Sobrien  coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook,
5224130561Sobrien  coff_slurp_symbol_table, symname_in_debug_hook, coff_pointerize_aux_hook,
5225130561Sobrien  coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
5226130561Sobrien  coff_classify_symbol, coff_compute_section_file_positions,
5227130561Sobrien  coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
5228130561Sobrien  coff_adjust_symndx, coff_link_add_one_symbol,
5229130561Sobrien  coff_link_output_has_begun, coff_final_link_postscript
5230130561Sobrien};
5231130561Sobrien#endif
5232130561Sobrien
5233130561Sobrien#ifdef TICOFF
5234130561Sobrien/* COFF1 differs in section header size.  */
5235218822Sdim
5236130561Sobrienstatic const bfd_coff_backend_data ticoff1_swap_table =
5237130561Sobrien{
5238130561Sobrien  coff_SWAP_aux_in, coff_SWAP_sym_in, coff_SWAP_lineno_in,
5239130561Sobrien  coff_SWAP_aux_out, coff_SWAP_sym_out,
5240130561Sobrien  coff_SWAP_lineno_out, coff_SWAP_reloc_out,
5241130561Sobrien  coff_SWAP_filehdr_out, coff_SWAP_aouthdr_out,
5242130561Sobrien  coff_SWAP_scnhdr_out,
5243130561Sobrien  FILHSZ, AOUTSZ, SCNHSZ_V01, SYMESZ, AUXESZ, RELSZ, LINESZ, FILNMLEN,
5244130561Sobrien#ifdef COFF_LONG_FILENAMES
5245130561Sobrien  TRUE,
5246130561Sobrien#else
5247130561Sobrien  FALSE,
5248130561Sobrien#endif
5249130561Sobrien#ifdef COFF_LONG_SECTION_NAMES
5250130561Sobrien  TRUE,
5251130561Sobrien#else
5252130561Sobrien  FALSE,
5253130561Sobrien#endif
5254130561Sobrien  COFF_DEFAULT_SECTION_ALIGNMENT_POWER,
5255130561Sobrien#ifdef COFF_FORCE_SYMBOLS_IN_STRINGS
5256130561Sobrien  TRUE,
5257130561Sobrien#else
5258130561Sobrien  FALSE,
5259130561Sobrien#endif
5260130561Sobrien#ifdef COFF_DEBUG_STRING_WIDE_PREFIX
5261130561Sobrien  4,
5262130561Sobrien#else
5263130561Sobrien  2,
5264130561Sobrien#endif
5265130561Sobrien  coff_SWAP_filehdr_in, coff_SWAP_aouthdr_in, coff_SWAP_scnhdr_in,
5266130561Sobrien  coff_SWAP_reloc_in, ticoff1_bad_format_hook, coff_set_arch_mach_hook,
5267130561Sobrien  coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook,
5268130561Sobrien  coff_slurp_symbol_table, symname_in_debug_hook, coff_pointerize_aux_hook,
5269130561Sobrien  coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
5270130561Sobrien  coff_classify_symbol, coff_compute_section_file_positions,
5271130561Sobrien  coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
5272130561Sobrien  coff_adjust_symndx, coff_link_add_one_symbol,
5273130561Sobrien  coff_link_output_has_begun, coff_final_link_postscript
5274130561Sobrien};
5275130561Sobrien#endif
5276130561Sobrien
527738889Sjdp#ifndef coff_close_and_cleanup
527838889Sjdp#define	coff_close_and_cleanup              _bfd_generic_close_and_cleanup
527938889Sjdp#endif
528033965Sjdp
528138889Sjdp#ifndef coff_bfd_free_cached_info
528238889Sjdp#define coff_bfd_free_cached_info           _bfd_generic_bfd_free_cached_info
528338889Sjdp#endif
528438889Sjdp
528538889Sjdp#ifndef coff_get_section_contents
528638889Sjdp#define	coff_get_section_contents           _bfd_generic_get_section_contents
528738889Sjdp#endif
528838889Sjdp
528933965Sjdp#ifndef coff_bfd_copy_private_symbol_data
529038889Sjdp#define coff_bfd_copy_private_symbol_data   _bfd_generic_bfd_copy_private_symbol_data
529133965Sjdp#endif
529233965Sjdp
5293218822Sdim#ifndef coff_bfd_copy_private_header_data
5294218822Sdim#define coff_bfd_copy_private_header_data   _bfd_generic_bfd_copy_private_header_data
5295218822Sdim#endif
5296218822Sdim
529733965Sjdp#ifndef coff_bfd_copy_private_section_data
529833965Sjdp#define coff_bfd_copy_private_section_data  _bfd_generic_bfd_copy_private_section_data
529933965Sjdp#endif
530033965Sjdp
530177298Sobrien#ifndef coff_bfd_copy_private_bfd_data
530238889Sjdp#define coff_bfd_copy_private_bfd_data      _bfd_generic_bfd_copy_private_bfd_data
530333965Sjdp#endif
530433965Sjdp
530538889Sjdp#ifndef coff_bfd_merge_private_bfd_data
530638889Sjdp#define coff_bfd_merge_private_bfd_data     _bfd_generic_bfd_merge_private_bfd_data
530738889Sjdp#endif
530833965Sjdp
530938889Sjdp#ifndef coff_bfd_set_private_flags
531038889Sjdp#define coff_bfd_set_private_flags          _bfd_generic_bfd_set_private_flags
531138889Sjdp#endif
531238889Sjdp
531377298Sobrien#ifndef coff_bfd_print_private_bfd_data
531438889Sjdp#define coff_bfd_print_private_bfd_data     _bfd_generic_bfd_print_private_bfd_data
531533965Sjdp#endif
531633965Sjdp
531733965Sjdp#ifndef coff_bfd_is_local_label_name
531838889Sjdp#define coff_bfd_is_local_label_name	    _bfd_coff_is_local_label_name
531933965Sjdp#endif
532038889Sjdp
5321218822Sdim#ifndef coff_bfd_is_target_special_symbol
5322218822Sdim#define coff_bfd_is_target_special_symbol   ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
5323218822Sdim#endif
5324218822Sdim
532533965Sjdp#ifndef coff_read_minisymbols
532638889Sjdp#define coff_read_minisymbols		    _bfd_generic_read_minisymbols
532733965Sjdp#endif
532838889Sjdp
532933965Sjdp#ifndef coff_minisymbol_to_symbol
533038889Sjdp#define coff_minisymbol_to_symbol	    _bfd_generic_minisymbol_to_symbol
533133965Sjdp#endif
533233965Sjdp
533333965Sjdp/* The reloc lookup routine must be supplied by each individual COFF
533433965Sjdp   backend.  */
533533965Sjdp#ifndef coff_bfd_reloc_type_lookup
533638889Sjdp#define coff_bfd_reloc_type_lookup	    _bfd_norelocs_bfd_reloc_type_lookup
533733965Sjdp#endif
5338218822Sdim#ifndef coff_bfd_reloc_name_lookup
5339218822Sdim#define coff_bfd_reloc_name_lookup    _bfd_norelocs_bfd_reloc_name_lookup
5340218822Sdim#endif
534133965Sjdp
534233965Sjdp#ifndef coff_bfd_get_relocated_section_contents
534333965Sjdp#define coff_bfd_get_relocated_section_contents \
534433965Sjdp  bfd_generic_get_relocated_section_contents
534533965Sjdp#endif
534638889Sjdp
534733965Sjdp#ifndef coff_bfd_relax_section
534838889Sjdp#define coff_bfd_relax_section		    bfd_generic_relax_section
534933965Sjdp#endif
535060484Sobrien
535160484Sobrien#ifndef coff_bfd_gc_sections
535260484Sobrien#define coff_bfd_gc_sections		    bfd_generic_gc_sections
535360484Sobrien#endif
535460484Sobrien
535589857Sobrien#ifndef coff_bfd_merge_sections
535689857Sobrien#define coff_bfd_merge_sections		    bfd_generic_merge_sections
535789857Sobrien#endif
535889857Sobrien
5359218822Sdim#ifndef coff_bfd_is_group_section
5360218822Sdim#define coff_bfd_is_group_section	    bfd_generic_is_group_section
5361218822Sdim#endif
5362218822Sdim
5363104834Sobrien#ifndef coff_bfd_discard_group
5364104834Sobrien#define coff_bfd_discard_group		    bfd_generic_discard_group
5365104834Sobrien#endif
5366104834Sobrien
5367218822Sdim#ifndef coff_section_already_linked
5368218822Sdim#define coff_section_already_linked \
5369218822Sdim  _bfd_generic_section_already_linked
5370218822Sdim#endif
5371218822Sdim
5372130561Sobrien#define CREATE_BIG_COFF_TARGET_VEC(VAR, NAME, EXTRA_O_FLAGS, EXTRA_S_FLAGS, UNDER, ALTERNATIVE, SWAP_TABLE)	\
537360484Sobrienconst bfd_target VAR =							\
537460484Sobrien{									\
537560484Sobrien  NAME ,								\
537660484Sobrien  bfd_target_coff_flavour,						\
5377218822Sdim  BFD_ENDIAN_BIG,		/* Data byte order is big.  */		\
5378218822Sdim  BFD_ENDIAN_BIG,		/* Header byte order is big.  */	\
537960484Sobrien  /* object flags */							\
538060484Sobrien  (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG |			\
538160484Sobrien   HAS_SYMS | HAS_LOCALS | WP_TEXT | EXTRA_O_FLAGS),			\
538260484Sobrien  /* section flags */							\
538360484Sobrien  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | EXTRA_S_FLAGS),\
5384218822Sdim  UNDER,			/* Leading symbol underscore.  */	\
5385218822Sdim  '/',				/* AR_pad_char.  */			\
5386218822Sdim  15,				/* AR_max_namelen.  */			\
538760484Sobrien  									\
538860484Sobrien  /* Data conversion functions.  */					\
538960484Sobrien  bfd_getb64, bfd_getb_signed_64, bfd_putb64,				\
539060484Sobrien  bfd_getb32, bfd_getb_signed_32, bfd_putb32,				\
539160484Sobrien  bfd_getb16, bfd_getb_signed_16, bfd_putb16,				\
539260484Sobrien  									\
539360484Sobrien  /* Header conversion functions.  */					\
539460484Sobrien  bfd_getb64, bfd_getb_signed_64, bfd_putb64,				\
539560484Sobrien  bfd_getb32, bfd_getb_signed_32, bfd_putb32,				\
539660484Sobrien  bfd_getb16, bfd_getb_signed_16, bfd_putb16,				\
539760484Sobrien									\
5398218822Sdim	/* bfd_check_format.  */					\
539960484Sobrien  { _bfd_dummy_target, coff_object_p, bfd_generic_archive_p,		\
540060484Sobrien    _bfd_dummy_target },						\
5401218822Sdim	/* bfd_set_format.  */						\
540260484Sobrien  { bfd_false, coff_mkobject, _bfd_generic_mkarchive, bfd_false },	\
5403218822Sdim	/* bfd_write_contents.  */					\
540460484Sobrien  { bfd_false, coff_write_object_contents, _bfd_write_archive_contents,	\
540560484Sobrien    bfd_false },							\
540660484Sobrien									\
540760484Sobrien  BFD_JUMP_TABLE_GENERIC (coff),					\
540860484Sobrien  BFD_JUMP_TABLE_COPY (coff),						\
540960484Sobrien  BFD_JUMP_TABLE_CORE (_bfd_nocore),					\
541060484Sobrien  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),				\
541160484Sobrien  BFD_JUMP_TABLE_SYMBOLS (coff),					\
541260484Sobrien  BFD_JUMP_TABLE_RELOCS (coff),						\
541360484Sobrien  BFD_JUMP_TABLE_WRITE (coff),						\
541460484Sobrien  BFD_JUMP_TABLE_LINK (coff),						\
541560484Sobrien  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),				\
541660484Sobrien  									\
541760484Sobrien  ALTERNATIVE,								\
541860484Sobrien  									\
5419130561Sobrien  SWAP_TABLE								\
542060484Sobrien};
542160484Sobrien
5422130561Sobrien#define CREATE_BIGHDR_COFF_TARGET_VEC(VAR, NAME, EXTRA_O_FLAGS, EXTRA_S_FLAGS, UNDER, ALTERNATIVE, SWAP_TABLE)	\
542360484Sobrienconst bfd_target VAR =							\
542460484Sobrien{									\
542560484Sobrien  NAME ,								\
542660484Sobrien  bfd_target_coff_flavour,						\
5427218822Sdim  BFD_ENDIAN_LITTLE,		/* Data byte order is little.  */	\
5428218822Sdim  BFD_ENDIAN_BIG,		/* Header byte order is big.  */	\
5429130561Sobrien  /* object flags */							\
5430130561Sobrien  (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG |			\
5431130561Sobrien   HAS_SYMS | HAS_LOCALS | WP_TEXT | EXTRA_O_FLAGS),			\
5432130561Sobrien  /* section flags */							\
5433130561Sobrien  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | EXTRA_S_FLAGS),\
5434218822Sdim  UNDER,			/* Leading symbol underscore.  */	\
5435218822Sdim  '/',				/* AR_pad_char.  */			\
5436218822Sdim  15,				/* AR_max_namelen.  */			\
5437130561Sobrien  									\
5438130561Sobrien  /* Data conversion functions.  */					\
5439130561Sobrien  bfd_getb64, bfd_getb_signed_64, bfd_putb64,				\
5440130561Sobrien  bfd_getb32, bfd_getb_signed_32, bfd_putb32,				\
5441130561Sobrien  bfd_getb16, bfd_getb_signed_16, bfd_putb16,				\
5442130561Sobrien  									\
5443130561Sobrien  /* Header conversion functions.  */					\
5444130561Sobrien  bfd_getb64, bfd_getb_signed_64, bfd_putb64,				\
5445130561Sobrien  bfd_getb32, bfd_getb_signed_32, bfd_putb32,				\
5446130561Sobrien  bfd_getb16, bfd_getb_signed_16, bfd_putb16,				\
5447130561Sobrien									\
5448218822Sdim	/* bfd_check_format.  */					\
5449130561Sobrien  { _bfd_dummy_target, coff_object_p, bfd_generic_archive_p,		\
5450130561Sobrien    _bfd_dummy_target },						\
5451218822Sdim	/* bfd_set_format.  */						\
5452130561Sobrien  { bfd_false, coff_mkobject, _bfd_generic_mkarchive, bfd_false },	\
5453218822Sdim	/* bfd_write_contents.  */					\
5454130561Sobrien  { bfd_false, coff_write_object_contents, _bfd_write_archive_contents,	\
5455130561Sobrien    bfd_false },							\
5456130561Sobrien									\
5457130561Sobrien  BFD_JUMP_TABLE_GENERIC (coff),					\
5458130561Sobrien  BFD_JUMP_TABLE_COPY (coff),						\
5459130561Sobrien  BFD_JUMP_TABLE_CORE (_bfd_nocore),					\
5460130561Sobrien  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),				\
5461130561Sobrien  BFD_JUMP_TABLE_SYMBOLS (coff),					\
5462130561Sobrien  BFD_JUMP_TABLE_RELOCS (coff),						\
5463130561Sobrien  BFD_JUMP_TABLE_WRITE (coff),						\
5464130561Sobrien  BFD_JUMP_TABLE_LINK (coff),						\
5465130561Sobrien  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),				\
5466130561Sobrien  									\
5467130561Sobrien  ALTERNATIVE,								\
5468130561Sobrien  									\
5469130561Sobrien  SWAP_TABLE								\
5470130561Sobrien};
5471130561Sobrien
5472130561Sobrien#define CREATE_LITTLE_COFF_TARGET_VEC(VAR, NAME, EXTRA_O_FLAGS, EXTRA_S_FLAGS, UNDER, ALTERNATIVE, SWAP_TABLE)	\
5473130561Sobrienconst bfd_target VAR =							\
5474130561Sobrien{									\
5475130561Sobrien  NAME ,								\
5476130561Sobrien  bfd_target_coff_flavour,						\
5477218822Sdim  BFD_ENDIAN_LITTLE,		/* Data byte order is little.  */	\
5478218822Sdim  BFD_ENDIAN_LITTLE,		/* Header byte order is little.  */	\
547960484Sobrien	/* object flags */						\
548060484Sobrien  (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG |			\
548160484Sobrien   HAS_SYMS | HAS_LOCALS | WP_TEXT | EXTRA_O_FLAGS),			\
548260484Sobrien	/* section flags */						\
548360484Sobrien  (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | EXTRA_S_FLAGS),\
5484218822Sdim  UNDER,			/* Leading symbol underscore.  */	\
5485218822Sdim  '/',				/* AR_pad_char.  */			\
5486218822Sdim  15,				/* AR_max_namelen.  */			\
548760484Sobrien									\
548860484Sobrien  /* Data conversion functions.  */					\
548960484Sobrien  bfd_getl64, bfd_getl_signed_64, bfd_putl64,				\
549060484Sobrien  bfd_getl32, bfd_getl_signed_32, bfd_putl32,				\
549160484Sobrien  bfd_getl16, bfd_getl_signed_16, bfd_putl16,				\
549260484Sobrien  /* Header conversion functions.  */					\
549360484Sobrien  bfd_getl64, bfd_getl_signed_64, bfd_putl64,				\
549460484Sobrien  bfd_getl32, bfd_getl_signed_32, bfd_putl32,				\
549560484Sobrien  bfd_getl16, bfd_getl_signed_16, bfd_putl16,				\
5496218822Sdim	/* bfd_check_format.  */					\
549760484Sobrien  { _bfd_dummy_target, coff_object_p, bfd_generic_archive_p,		\
549860484Sobrien    _bfd_dummy_target },						\
5499218822Sdim       /* bfd_set_format.  */						\
550060484Sobrien  { bfd_false, coff_mkobject, _bfd_generic_mkarchive, bfd_false },	\
5501218822Sdim	/* bfd_write_contents.  */					\
550260484Sobrien  { bfd_false, coff_write_object_contents, _bfd_write_archive_contents,	\
550360484Sobrien    bfd_false },							\
550460484Sobrien									\
550560484Sobrien  BFD_JUMP_TABLE_GENERIC (coff),					\
550660484Sobrien  BFD_JUMP_TABLE_COPY (coff),						\
550760484Sobrien  BFD_JUMP_TABLE_CORE (_bfd_nocore),					\
550860484Sobrien  BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),				\
550960484Sobrien  BFD_JUMP_TABLE_SYMBOLS (coff),					\
551060484Sobrien  BFD_JUMP_TABLE_RELOCS (coff),						\
551160484Sobrien  BFD_JUMP_TABLE_WRITE (coff),						\
551260484Sobrien  BFD_JUMP_TABLE_LINK (coff),						\
551360484Sobrien  BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),				\
551460484Sobrien									\
551560484Sobrien  ALTERNATIVE,								\
551660484Sobrien  									\
5517130561Sobrien  SWAP_TABLE								\
551860484Sobrien};
5519