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, §ion, &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