xcofflink.c revision 130561
184865Sobrien/* POWER/PowerPC XCOFF linker support. 2130561Sobrien Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 384865Sobrien Free Software Foundation, Inc. 484865Sobrien Written by Ian Lance Taylor <ian@cygnus.com>, Cygnus Support. 584865Sobrien 6104834Sobrien This file is part of BFD, the Binary File Descriptor library. 784865Sobrien 8104834Sobrien This program is free software; you can redistribute it and/or modify 9104834Sobrien it under the terms of the GNU General Public License as published by 10104834Sobrien the Free Software Foundation; either version 2 of the License, or 11104834Sobrien (at your option) any later version. 1284865Sobrien 13104834Sobrien This program is distributed in the hope that it will be useful, 14104834Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 15104834Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16104834Sobrien GNU General Public License for more details. 1784865Sobrien 18104834Sobrien You should have received a copy of the GNU General Public License 19104834Sobrien along with this program; if not, write to the Free Software 20104834Sobrien Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 2184865Sobrien 2284865Sobrien#include "bfd.h" 2384865Sobrien#include "sysdep.h" 2484865Sobrien#include "bfdlink.h" 2584865Sobrien#include "libbfd.h" 2684865Sobrien#include "coff/internal.h" 2794536Sobrien#include "coff/xcoff.h" 2884865Sobrien#include "libcoff.h" 2994536Sobrien#include "libxcoff.h" 3084865Sobrien 3184865Sobrien/* This file holds the XCOFF linker code. */ 3284865Sobrien 3384865Sobrien#define STRING_SIZE_SIZE (4) 3484865Sobrien 3584865Sobrien/* We reuse the SEC_ROM flag as a mark flag for garbage collection. 3684865Sobrien This flag will only be used on input sections. */ 3784865Sobrien 3884865Sobrien#define SEC_MARK (SEC_ROM) 3984865Sobrien 4084865Sobrien/* The list of import files. */ 4184865Sobrien 4294536Sobrienstruct xcoff_import_file 4394536Sobrien{ 4484865Sobrien /* The next entry in the list. */ 4584865Sobrien struct xcoff_import_file *next; 4684865Sobrien /* The path. */ 4784865Sobrien const char *path; 4884865Sobrien /* The file name. */ 4984865Sobrien const char *file; 5084865Sobrien /* The member name. */ 5184865Sobrien const char *member; 5284865Sobrien}; 5384865Sobrien 5484865Sobrien/* Information we keep for each section in the output file during the 5584865Sobrien final link phase. */ 5684865Sobrien 5794536Sobrienstruct xcoff_link_section_info 5894536Sobrien{ 5984865Sobrien /* The relocs to be output. */ 6084865Sobrien struct internal_reloc *relocs; 6184865Sobrien /* For each reloc against a global symbol whose index was not known 6284865Sobrien when the reloc was handled, the global hash table entry. */ 6384865Sobrien struct xcoff_link_hash_entry **rel_hashes; 6484865Sobrien /* If there is a TOC relative reloc against a global symbol, and the 6584865Sobrien index of the TOC symbol is not known when the reloc was handled, 6684865Sobrien an entry is added to this linked list. This is not an array, 6784865Sobrien like rel_hashes, because this case is quite uncommon. */ 6884865Sobrien struct xcoff_toc_rel_hash { 6984865Sobrien struct xcoff_toc_rel_hash *next; 7084865Sobrien struct xcoff_link_hash_entry *h; 7184865Sobrien struct internal_reloc *rel; 7284865Sobrien } *toc_rel_hashes; 7384865Sobrien}; 7484865Sobrien 7584865Sobrien/* Information that we pass around while doing the final link step. */ 7684865Sobrien 7794536Sobrienstruct xcoff_final_link_info 7894536Sobrien{ 7984865Sobrien /* General link information. */ 8084865Sobrien struct bfd_link_info *info; 8184865Sobrien /* Output BFD. */ 8284865Sobrien bfd *output_bfd; 8384865Sobrien /* Hash table for long symbol names. */ 8484865Sobrien struct bfd_strtab_hash *strtab; 8584865Sobrien /* Array of information kept for each output section, indexed by the 8684865Sobrien target_index field. */ 8784865Sobrien struct xcoff_link_section_info *section_info; 8884865Sobrien /* Symbol index of last C_FILE symbol (-1 if none). */ 8984865Sobrien long last_file_index; 9084865Sobrien /* Contents of last C_FILE symbol. */ 9184865Sobrien struct internal_syment last_file; 9284865Sobrien /* Symbol index of TOC symbol. */ 9384865Sobrien long toc_symindx; 9484865Sobrien /* Start of .loader symbols. */ 9594536Sobrien bfd_byte *ldsym; 9684865Sobrien /* Next .loader reloc to swap out. */ 9794536Sobrien bfd_byte *ldrel; 9884865Sobrien /* File position of start of line numbers. */ 9984865Sobrien file_ptr line_filepos; 10084865Sobrien /* Buffer large enough to hold swapped symbols of any input file. */ 10184865Sobrien struct internal_syment *internal_syms; 10284865Sobrien /* Buffer large enough to hold output indices of symbols of any 10384865Sobrien input file. */ 10484865Sobrien long *sym_indices; 10584865Sobrien /* Buffer large enough to hold output symbols for any input file. */ 10684865Sobrien bfd_byte *outsyms; 10784865Sobrien /* Buffer large enough to hold external line numbers for any input 10884865Sobrien section. */ 10984865Sobrien bfd_byte *linenos; 11084865Sobrien /* Buffer large enough to hold any input section. */ 11184865Sobrien bfd_byte *contents; 11284865Sobrien /* Buffer large enough to hold external relocs of any input section. */ 11384865Sobrien bfd_byte *external_relocs; 11484865Sobrien}; 11584865Sobrien 11684865Sobrienstatic struct bfd_hash_entry *xcoff_link_hash_newfunc 11784865Sobrien PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); 118130561Sobrienstatic bfd_boolean xcoff_get_section_contents PARAMS ((bfd *, asection *)); 11984865Sobrienstatic struct internal_reloc *xcoff_read_internal_relocs 120130561Sobrien PARAMS ((bfd *, asection *, bfd_boolean, bfd_byte *, bfd_boolean, 12184865Sobrien struct internal_reloc *)); 122130561Sobrienstatic bfd_boolean xcoff_link_add_object_symbols 12384865Sobrien PARAMS ((bfd *, struct bfd_link_info *)); 124130561Sobrienstatic bfd_boolean xcoff_link_check_archive_element 125130561Sobrien PARAMS ((bfd *, struct bfd_link_info *, bfd_boolean *)); 126130561Sobrienstatic bfd_boolean xcoff_link_check_ar_symbols 127130561Sobrien PARAMS ((bfd *, struct bfd_link_info *, bfd_boolean *)); 128130561Sobrienstatic bfd_boolean xcoff_link_check_dynamic_ar_symbols 129130561Sobrien PARAMS ((bfd *, struct bfd_link_info *, bfd_boolean *)); 13084865Sobrienstatic bfd_size_type xcoff_find_reloc 13184865Sobrien PARAMS ((struct internal_reloc *, bfd_size_type, bfd_vma)); 132130561Sobrienstatic bfd_boolean xcoff_link_add_symbols 13384865Sobrien PARAMS ((bfd *, struct bfd_link_info *)); 134130561Sobrienstatic bfd_boolean xcoff_link_add_dynamic_symbols 135130561Sobrien PARAMS ((bfd *, struct bfd_link_info *)); 136130561Sobrienstatic bfd_boolean xcoff_mark_symbol 13784865Sobrien PARAMS ((struct bfd_link_info *, struct xcoff_link_hash_entry *)); 138130561Sobrienstatic bfd_boolean xcoff_mark PARAMS ((struct bfd_link_info *, asection *)); 13984865Sobrienstatic void xcoff_sweep PARAMS ((struct bfd_link_info *)); 140130561Sobrienstatic bfd_boolean xcoff_build_ldsyms 14184865Sobrien PARAMS ((struct xcoff_link_hash_entry *, PTR)); 142130561Sobrienstatic bfd_boolean xcoff_link_input_bfd 14384865Sobrien PARAMS ((struct xcoff_final_link_info *, bfd *)); 144130561Sobrienstatic bfd_boolean xcoff_write_global_symbol 14584865Sobrien PARAMS ((struct xcoff_link_hash_entry *, PTR)); 146130561Sobrienstatic bfd_boolean xcoff_reloc_link_order 14784865Sobrien PARAMS ((bfd *, struct xcoff_final_link_info *, asection *, 14884865Sobrien struct bfd_link_order *)); 14984865Sobrienstatic int xcoff_sort_relocs PARAMS ((const PTR, const PTR)); 15084865Sobrien 15184865Sobrien 15284865Sobrien/* Routines to read XCOFF dynamic information. This don't really 15384865Sobrien belong here, but we already have the ldsym manipulation routines 15484865Sobrien here. */ 15584865Sobrien 15684865Sobrien/* Read the contents of a section. */ 15784865Sobrien 158130561Sobrienstatic bfd_boolean 15984865Sobrienxcoff_get_section_contents (abfd, sec) 16084865Sobrien bfd *abfd; 16184865Sobrien asection *sec; 16284865Sobrien{ 16394536Sobrien 16484865Sobrien if (coff_section_data (abfd, sec) == NULL) 16584865Sobrien { 16694536Sobrien bfd_size_type amt = sizeof (struct coff_section_tdata); 16794536Sobrien sec->used_by_bfd = bfd_zalloc (abfd, amt); 16884865Sobrien if (sec->used_by_bfd == NULL) 169130561Sobrien return FALSE; 17084865Sobrien } 17184865Sobrien 17284865Sobrien if (coff_section_data (abfd, sec)->contents == NULL) 17384865Sobrien { 17494536Sobrien coff_section_data (abfd, sec)->contents = ((bfd_byte *) 17594536Sobrien bfd_malloc (sec->_raw_size)); 17684865Sobrien if (coff_section_data (abfd, sec)->contents == NULL) 177130561Sobrien return FALSE; 17884865Sobrien 17984865Sobrien if (! bfd_get_section_contents (abfd, sec, 18084865Sobrien coff_section_data (abfd, sec)->contents, 18184865Sobrien (file_ptr) 0, sec->_raw_size)) 182130561Sobrien return FALSE; 18384865Sobrien } 18484865Sobrien 185130561Sobrien return TRUE; 18684865Sobrien} 18784865Sobrien 18884865Sobrien/* Get the size required to hold the dynamic symbols. */ 18984865Sobrien 19084865Sobrienlong 19184865Sobrien_bfd_xcoff_get_dynamic_symtab_upper_bound (abfd) 19284865Sobrien bfd *abfd; 19384865Sobrien{ 19484865Sobrien asection *lsec; 19584865Sobrien bfd_byte *contents; 19684865Sobrien struct internal_ldhdr ldhdr; 19784865Sobrien 19884865Sobrien if ((abfd->flags & DYNAMIC) == 0) 19984865Sobrien { 20084865Sobrien bfd_set_error (bfd_error_invalid_operation); 20184865Sobrien return -1; 20284865Sobrien } 20384865Sobrien 20484865Sobrien lsec = bfd_get_section_by_name (abfd, ".loader"); 20584865Sobrien if (lsec == NULL) 20684865Sobrien { 20784865Sobrien bfd_set_error (bfd_error_no_symbols); 20884865Sobrien return -1; 20984865Sobrien } 21084865Sobrien 21184865Sobrien if (! xcoff_get_section_contents (abfd, lsec)) 21284865Sobrien return -1; 21384865Sobrien contents = coff_section_data (abfd, lsec)->contents; 21484865Sobrien 21594536Sobrien bfd_xcoff_swap_ldhdr_in (abfd, (PTR) contents, &ldhdr); 21684865Sobrien 21784865Sobrien return (ldhdr.l_nsyms + 1) * sizeof (asymbol *); 21884865Sobrien} 21984865Sobrien 22084865Sobrien/* Get the dynamic symbols. */ 22184865Sobrien 22284865Sobrienlong 22384865Sobrien_bfd_xcoff_canonicalize_dynamic_symtab (abfd, psyms) 22484865Sobrien bfd *abfd; 22584865Sobrien asymbol **psyms; 22684865Sobrien{ 22784865Sobrien asection *lsec; 22884865Sobrien bfd_byte *contents; 22984865Sobrien struct internal_ldhdr ldhdr; 23084865Sobrien const char *strings; 23194536Sobrien bfd_byte *elsym, *elsymend; 23284865Sobrien coff_symbol_type *symbuf; 23384865Sobrien 23484865Sobrien if ((abfd->flags & DYNAMIC) == 0) 23584865Sobrien { 23684865Sobrien bfd_set_error (bfd_error_invalid_operation); 23784865Sobrien return -1; 23884865Sobrien } 23984865Sobrien 24084865Sobrien lsec = bfd_get_section_by_name (abfd, ".loader"); 24184865Sobrien if (lsec == NULL) 24284865Sobrien { 24384865Sobrien bfd_set_error (bfd_error_no_symbols); 24484865Sobrien return -1; 24584865Sobrien } 24684865Sobrien 24784865Sobrien if (! xcoff_get_section_contents (abfd, lsec)) 24884865Sobrien return -1; 24984865Sobrien contents = coff_section_data (abfd, lsec)->contents; 25084865Sobrien 251130561Sobrien coff_section_data (abfd, lsec)->keep_contents = TRUE; 25284865Sobrien 25394536Sobrien bfd_xcoff_swap_ldhdr_in (abfd, contents, &ldhdr); 25484865Sobrien 25584865Sobrien strings = (char *) contents + ldhdr.l_stoff; 25684865Sobrien 25784865Sobrien symbuf = ((coff_symbol_type *) 25884865Sobrien bfd_zalloc (abfd, ldhdr.l_nsyms * sizeof (coff_symbol_type))); 25984865Sobrien if (symbuf == NULL) 26084865Sobrien return -1; 26184865Sobrien 26294536Sobrien elsym = contents + bfd_xcoff_loader_symbol_offset(abfd, &ldhdr); 26394536Sobrien 26494536Sobrien elsymend = elsym + ldhdr.l_nsyms * bfd_xcoff_ldsymsz(abfd); 26594536Sobrien for (; elsym < elsymend; elsym += bfd_xcoff_ldsymsz(abfd), symbuf++, psyms++) 26684865Sobrien { 26784865Sobrien struct internal_ldsym ldsym; 26884865Sobrien 26994536Sobrien bfd_xcoff_swap_ldsym_in (abfd, elsym, &ldsym); 27084865Sobrien 27184865Sobrien symbuf->symbol.the_bfd = abfd; 27284865Sobrien 27384865Sobrien if (ldsym._l._l_l._l_zeroes == 0) 27484865Sobrien symbuf->symbol.name = strings + ldsym._l._l_l._l_offset; 27584865Sobrien else 27684865Sobrien { 27794536Sobrien char *c; 27884865Sobrien 27994536Sobrien c = bfd_alloc (abfd, (bfd_size_type) SYMNMLEN + 1); 28094536Sobrien if (c == NULL) 28194536Sobrien return -1; 28294536Sobrien memcpy (c, ldsym._l._l_name, SYMNMLEN); 28394536Sobrien c[SYMNMLEN] = '\0'; 28494536Sobrien symbuf->symbol.name = c; 28584865Sobrien } 28684865Sobrien 28784865Sobrien if (ldsym.l_smclas == XMC_XO) 28884865Sobrien symbuf->symbol.section = bfd_abs_section_ptr; 28984865Sobrien else 29084865Sobrien symbuf->symbol.section = coff_section_from_bfd_index (abfd, 29184865Sobrien ldsym.l_scnum); 29284865Sobrien symbuf->symbol.value = ldsym.l_value - symbuf->symbol.section->vma; 29384865Sobrien 29484865Sobrien symbuf->symbol.flags = BSF_NO_FLAGS; 29584865Sobrien if ((ldsym.l_smtype & L_EXPORT) != 0) 29684865Sobrien symbuf->symbol.flags |= BSF_GLOBAL; 29784865Sobrien 29884865Sobrien /* FIXME: We have no way to record the other information stored 299130561Sobrien with the loader symbol. */ 30084865Sobrien 30184865Sobrien *psyms = (asymbol *) symbuf; 30284865Sobrien } 30384865Sobrien 30484865Sobrien *psyms = NULL; 30584865Sobrien 30684865Sobrien return ldhdr.l_nsyms; 30784865Sobrien} 30884865Sobrien 30984865Sobrien/* Get the size required to hold the dynamic relocs. */ 31084865Sobrien 31184865Sobrienlong 31284865Sobrien_bfd_xcoff_get_dynamic_reloc_upper_bound (abfd) 31384865Sobrien bfd *abfd; 31484865Sobrien{ 31584865Sobrien asection *lsec; 31684865Sobrien bfd_byte *contents; 31784865Sobrien struct internal_ldhdr ldhdr; 31884865Sobrien 31984865Sobrien if ((abfd->flags & DYNAMIC) == 0) 32084865Sobrien { 32184865Sobrien bfd_set_error (bfd_error_invalid_operation); 32284865Sobrien return -1; 32384865Sobrien } 32484865Sobrien 32584865Sobrien lsec = bfd_get_section_by_name (abfd, ".loader"); 32684865Sobrien if (lsec == NULL) 32784865Sobrien { 32884865Sobrien bfd_set_error (bfd_error_no_symbols); 32984865Sobrien return -1; 33084865Sobrien } 33184865Sobrien 33284865Sobrien if (! xcoff_get_section_contents (abfd, lsec)) 33384865Sobrien return -1; 33484865Sobrien contents = coff_section_data (abfd, lsec)->contents; 33584865Sobrien 33694536Sobrien bfd_xcoff_swap_ldhdr_in (abfd, (struct external_ldhdr *) contents, &ldhdr); 33784865Sobrien 33884865Sobrien return (ldhdr.l_nreloc + 1) * sizeof (arelent *); 33984865Sobrien} 34084865Sobrien 34184865Sobrien/* Get the dynamic relocs. */ 34284865Sobrien 34384865Sobrienlong 34484865Sobrien_bfd_xcoff_canonicalize_dynamic_reloc (abfd, prelocs, syms) 34584865Sobrien bfd *abfd; 34684865Sobrien arelent **prelocs; 34784865Sobrien asymbol **syms; 34884865Sobrien{ 34984865Sobrien asection *lsec; 35084865Sobrien bfd_byte *contents; 35184865Sobrien struct internal_ldhdr ldhdr; 35284865Sobrien arelent *relbuf; 35394536Sobrien bfd_byte *elrel, *elrelend; 35484865Sobrien 35584865Sobrien if ((abfd->flags & DYNAMIC) == 0) 35684865Sobrien { 35784865Sobrien bfd_set_error (bfd_error_invalid_operation); 35884865Sobrien return -1; 35984865Sobrien } 36084865Sobrien 36184865Sobrien lsec = bfd_get_section_by_name (abfd, ".loader"); 36284865Sobrien if (lsec == NULL) 36384865Sobrien { 36484865Sobrien bfd_set_error (bfd_error_no_symbols); 36584865Sobrien return -1; 36684865Sobrien } 36784865Sobrien 36884865Sobrien if (! xcoff_get_section_contents (abfd, lsec)) 36984865Sobrien return -1; 37084865Sobrien contents = coff_section_data (abfd, lsec)->contents; 37184865Sobrien 37294536Sobrien bfd_xcoff_swap_ldhdr_in (abfd, contents, &ldhdr); 37384865Sobrien 37484865Sobrien relbuf = (arelent *) bfd_alloc (abfd, ldhdr.l_nreloc * sizeof (arelent)); 37584865Sobrien if (relbuf == NULL) 37684865Sobrien return -1; 37784865Sobrien 37894536Sobrien elrel = contents + bfd_xcoff_loader_reloc_offset(abfd, &ldhdr); 37994536Sobrien 38094536Sobrien elrelend = elrel + ldhdr.l_nreloc * bfd_xcoff_ldrelsz(abfd); 38194536Sobrien for (; elrel < elrelend; elrel += bfd_xcoff_ldrelsz(abfd), relbuf++, 38294536Sobrien prelocs++) 38384865Sobrien { 38484865Sobrien struct internal_ldrel ldrel; 38584865Sobrien 38694536Sobrien bfd_xcoff_swap_ldrel_in (abfd, elrel, &ldrel); 38784865Sobrien 38884865Sobrien if (ldrel.l_symndx >= 3) 38984865Sobrien relbuf->sym_ptr_ptr = syms + (ldrel.l_symndx - 3); 39084865Sobrien else 39184865Sobrien { 39284865Sobrien const char *name; 39384865Sobrien asection *sec; 39484865Sobrien 39584865Sobrien switch (ldrel.l_symndx) 39684865Sobrien { 39784865Sobrien case 0: 39884865Sobrien name = ".text"; 39984865Sobrien break; 40084865Sobrien case 1: 40184865Sobrien name = ".data"; 40284865Sobrien break; 40384865Sobrien case 2: 40484865Sobrien name = ".bss"; 40584865Sobrien break; 40684865Sobrien default: 40784865Sobrien abort (); 40884865Sobrien break; 40984865Sobrien } 41084865Sobrien 41184865Sobrien sec = bfd_get_section_by_name (abfd, name); 41284865Sobrien if (sec == NULL) 41384865Sobrien { 41484865Sobrien bfd_set_error (bfd_error_bad_value); 41584865Sobrien return -1; 41684865Sobrien } 41784865Sobrien 41884865Sobrien relbuf->sym_ptr_ptr = sec->symbol_ptr_ptr; 41984865Sobrien } 42084865Sobrien 42184865Sobrien relbuf->address = ldrel.l_vaddr; 42284865Sobrien relbuf->addend = 0; 42384865Sobrien 42484865Sobrien /* Most dynamic relocs have the same type. FIXME: This is only 425130561Sobrien correct if ldrel.l_rtype == 0. In other cases, we should use 426130561Sobrien a different howto. */ 42794536Sobrien relbuf->howto = bfd_xcoff_dynamic_reloc_howto(abfd); 42884865Sobrien 42984865Sobrien /* FIXME: We have no way to record the l_rsecnm field. */ 43084865Sobrien 43184865Sobrien *prelocs = relbuf; 43284865Sobrien } 43384865Sobrien 43484865Sobrien *prelocs = NULL; 43584865Sobrien 43684865Sobrien return ldhdr.l_nreloc; 43784865Sobrien} 43884865Sobrien 43984865Sobrien/* Routine to create an entry in an XCOFF link hash table. */ 44084865Sobrien 44184865Sobrienstatic struct bfd_hash_entry * 44284865Sobrienxcoff_link_hash_newfunc (entry, table, string) 44384865Sobrien struct bfd_hash_entry *entry; 44484865Sobrien struct bfd_hash_table *table; 44584865Sobrien const char *string; 44684865Sobrien{ 44784865Sobrien struct xcoff_link_hash_entry *ret = (struct xcoff_link_hash_entry *) entry; 44884865Sobrien 44984865Sobrien /* Allocate the structure if it has not already been allocated by a 45084865Sobrien subclass. */ 45184865Sobrien if (ret == (struct xcoff_link_hash_entry *) NULL) 45284865Sobrien ret = ((struct xcoff_link_hash_entry *) 45384865Sobrien bfd_hash_allocate (table, sizeof (struct xcoff_link_hash_entry))); 45484865Sobrien if (ret == (struct xcoff_link_hash_entry *) NULL) 45584865Sobrien return (struct bfd_hash_entry *) ret; 45684865Sobrien 45784865Sobrien /* Call the allocation method of the superclass. */ 45884865Sobrien ret = ((struct xcoff_link_hash_entry *) 45984865Sobrien _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret, 46084865Sobrien table, string)); 46184865Sobrien if (ret != NULL) 46284865Sobrien { 46384865Sobrien /* Set local fields. */ 46484865Sobrien ret->indx = -1; 46584865Sobrien ret->toc_section = NULL; 46684865Sobrien ret->u.toc_indx = -1; 46784865Sobrien ret->descriptor = NULL; 46884865Sobrien ret->ldsym = NULL; 46984865Sobrien ret->ldindx = -1; 47084865Sobrien ret->flags = 0; 47184865Sobrien ret->smclas = XMC_UA; 47284865Sobrien } 47384865Sobrien 47484865Sobrien return (struct bfd_hash_entry *) ret; 47584865Sobrien} 47684865Sobrien 47784865Sobrien/* Create a XCOFF link hash table. */ 47884865Sobrien 47984865Sobrienstruct bfd_link_hash_table * 48084865Sobrien_bfd_xcoff_bfd_link_hash_table_create (abfd) 48184865Sobrien bfd *abfd; 48284865Sobrien{ 48384865Sobrien struct xcoff_link_hash_table *ret; 48494536Sobrien bfd_size_type amt = sizeof (struct xcoff_link_hash_table); 48584865Sobrien 486104834Sobrien ret = (struct xcoff_link_hash_table *) bfd_malloc (amt); 48784865Sobrien if (ret == (struct xcoff_link_hash_table *) NULL) 48884865Sobrien return (struct bfd_link_hash_table *) NULL; 48984865Sobrien if (! _bfd_link_hash_table_init (&ret->root, abfd, xcoff_link_hash_newfunc)) 49084865Sobrien { 491104834Sobrien free (ret); 49284865Sobrien return (struct bfd_link_hash_table *) NULL; 49384865Sobrien } 49484865Sobrien 49584865Sobrien ret->debug_strtab = _bfd_xcoff_stringtab_init (); 49684865Sobrien ret->debug_section = NULL; 49784865Sobrien ret->loader_section = NULL; 49884865Sobrien ret->ldrel_count = 0; 49984865Sobrien memset (&ret->ldhdr, 0, sizeof (struct internal_ldhdr)); 50084865Sobrien ret->linkage_section = NULL; 50184865Sobrien ret->toc_section = NULL; 50284865Sobrien ret->descriptor_section = NULL; 50384865Sobrien ret->imports = NULL; 50484865Sobrien ret->file_align = 0; 505130561Sobrien ret->textro = FALSE; 506130561Sobrien ret->gc = FALSE; 50784865Sobrien memset (ret->special_sections, 0, sizeof ret->special_sections); 50884865Sobrien 50984865Sobrien /* The linker will always generate a full a.out header. We need to 51084865Sobrien record that fact now, before the sizeof_headers routine could be 51184865Sobrien called. */ 512130561Sobrien xcoff_data (abfd)->full_aouthdr = TRUE; 51384865Sobrien 51484865Sobrien return &ret->root; 51584865Sobrien} 51684865Sobrien 517104834Sobrien/* Free a XCOFF link hash table. */ 518104834Sobrien 519104834Sobrienvoid 520104834Sobrien_bfd_xcoff_bfd_link_hash_table_free (hash) 521104834Sobrien struct bfd_link_hash_table *hash; 522104834Sobrien{ 523104834Sobrien struct xcoff_link_hash_table *ret = (struct xcoff_link_hash_table *) hash; 524104834Sobrien 525104834Sobrien _bfd_stringtab_free (ret->debug_strtab); 526104834Sobrien bfd_hash_table_free (&ret->root.table); 527104834Sobrien free (ret); 528104834Sobrien} 52984865Sobrien 53084865Sobrien/* Read internal relocs for an XCOFF csect. This is a wrapper around 53184865Sobrien _bfd_coff_read_internal_relocs which tries to take advantage of any 53284865Sobrien relocs which may have been cached for the enclosing section. */ 53384865Sobrien 53484865Sobrienstatic struct internal_reloc * 53584865Sobrienxcoff_read_internal_relocs (abfd, sec, cache, external_relocs, 53684865Sobrien require_internal, internal_relocs) 53784865Sobrien bfd *abfd; 53884865Sobrien asection *sec; 539130561Sobrien bfd_boolean cache; 54084865Sobrien bfd_byte *external_relocs; 541130561Sobrien bfd_boolean require_internal; 54284865Sobrien struct internal_reloc *internal_relocs; 54384865Sobrien{ 54494536Sobrien 54584865Sobrien if (coff_section_data (abfd, sec) != NULL 54684865Sobrien && coff_section_data (abfd, sec)->relocs == NULL 54784865Sobrien && xcoff_section_data (abfd, sec) != NULL) 54884865Sobrien { 54984865Sobrien asection *enclosing; 55084865Sobrien 55184865Sobrien enclosing = xcoff_section_data (abfd, sec)->enclosing; 55284865Sobrien 55384865Sobrien if (enclosing != NULL 55484865Sobrien && (coff_section_data (abfd, enclosing) == NULL 55584865Sobrien || coff_section_data (abfd, enclosing)->relocs == NULL) 55684865Sobrien && cache 55784865Sobrien && enclosing->reloc_count > 0) 55884865Sobrien { 559130561Sobrien if (_bfd_coff_read_internal_relocs (abfd, enclosing, TRUE, 560130561Sobrien external_relocs, FALSE, 56184865Sobrien (struct internal_reloc *) NULL) 56284865Sobrien == NULL) 56384865Sobrien return NULL; 56484865Sobrien } 56584865Sobrien 56684865Sobrien if (enclosing != NULL 56784865Sobrien && coff_section_data (abfd, enclosing) != NULL 56884865Sobrien && coff_section_data (abfd, enclosing)->relocs != NULL) 56984865Sobrien { 57084865Sobrien size_t off; 57184865Sobrien 57284865Sobrien off = ((sec->rel_filepos - enclosing->rel_filepos) 57384865Sobrien / bfd_coff_relsz (abfd)); 57494536Sobrien 57584865Sobrien if (! require_internal) 57684865Sobrien return coff_section_data (abfd, enclosing)->relocs + off; 57784865Sobrien memcpy (internal_relocs, 57884865Sobrien coff_section_data (abfd, enclosing)->relocs + off, 57984865Sobrien sec->reloc_count * sizeof (struct internal_reloc)); 58084865Sobrien return internal_relocs; 58184865Sobrien } 58284865Sobrien } 58384865Sobrien 58484865Sobrien return _bfd_coff_read_internal_relocs (abfd, sec, cache, external_relocs, 58584865Sobrien require_internal, internal_relocs); 58684865Sobrien} 58784865Sobrien 58884865Sobrien/* Given an XCOFF BFD, add symbols to the global hash table as 58984865Sobrien appropriate. */ 59084865Sobrien 591130561Sobrienbfd_boolean 59284865Sobrien_bfd_xcoff_bfd_link_add_symbols (abfd, info) 59384865Sobrien bfd *abfd; 59484865Sobrien struct bfd_link_info *info; 59584865Sobrien{ 59694536Sobrien 59784865Sobrien switch (bfd_get_format (abfd)) 59884865Sobrien { 59984865Sobrien case bfd_object: 60084865Sobrien return xcoff_link_add_object_symbols (abfd, info); 60184865Sobrien 60284865Sobrien case bfd_archive: 60384865Sobrien /* If the archive has a map, do the usual search. We then need 604130561Sobrien to check the archive for dynamic objects, because they may not 605130561Sobrien appear in the archive map even though they should, perhaps, be 606130561Sobrien included. If the archive has no map, we just consider each object 607130561Sobrien file in turn, since that apparently is what the AIX native linker 608104834Sobrien does. */ 60984865Sobrien if (bfd_has_map (abfd)) 61084865Sobrien { 61184865Sobrien if (! (_bfd_generic_link_add_archive_symbols 61284865Sobrien (abfd, info, xcoff_link_check_archive_element))) 613130561Sobrien return FALSE; 61484865Sobrien } 61584865Sobrien 61684865Sobrien { 61784865Sobrien bfd *member; 618130561Sobrien 61984865Sobrien member = bfd_openr_next_archived_file (abfd, (bfd *) NULL); 62084865Sobrien while (member != NULL) 62184865Sobrien { 62284865Sobrien if (bfd_check_format (member, bfd_object) 623104834Sobrien && (info->hash->creator == member->xvec) 624104834Sobrien && (! bfd_has_map (abfd) || (member->flags & DYNAMIC) != 0)) 62584865Sobrien { 626130561Sobrien bfd_boolean needed; 627130561Sobrien 628130561Sobrien if (! xcoff_link_check_archive_element (member, info, 629104834Sobrien &needed)) 630130561Sobrien return FALSE; 63184865Sobrien if (needed) 63284865Sobrien member->archive_pass = -1; 63384865Sobrien } 63484865Sobrien member = bfd_openr_next_archived_file (abfd, member); 63584865Sobrien } 63684865Sobrien } 63784865Sobrien 638130561Sobrien return TRUE; 63984865Sobrien 64084865Sobrien default: 64184865Sobrien bfd_set_error (bfd_error_wrong_format); 642130561Sobrien return FALSE; 64384865Sobrien } 64484865Sobrien} 64584865Sobrien 64684865Sobrien/* Add symbols from an XCOFF object file. */ 64784865Sobrien 648130561Sobrienstatic bfd_boolean 64984865Sobrienxcoff_link_add_object_symbols (abfd, info) 65084865Sobrien bfd *abfd; 65184865Sobrien struct bfd_link_info *info; 65284865Sobrien{ 65394536Sobrien 65484865Sobrien if (! _bfd_coff_get_external_symbols (abfd)) 655130561Sobrien return FALSE; 65684865Sobrien if (! xcoff_link_add_symbols (abfd, info)) 657130561Sobrien return FALSE; 65884865Sobrien if (! info->keep_memory) 65984865Sobrien { 66084865Sobrien if (! _bfd_coff_free_symbols (abfd)) 661130561Sobrien return FALSE; 66284865Sobrien } 663130561Sobrien return TRUE; 66484865Sobrien} 66584865Sobrien 66684865Sobrien/* Check a single archive element to see if we need to include it in 66784865Sobrien the link. *PNEEDED is set according to whether this element is 66884865Sobrien needed in the link or not. This is called via 66984865Sobrien _bfd_generic_link_add_archive_symbols. */ 67084865Sobrien 671130561Sobrienstatic bfd_boolean 67284865Sobrienxcoff_link_check_archive_element (abfd, info, pneeded) 67384865Sobrien bfd *abfd; 67484865Sobrien struct bfd_link_info *info; 675130561Sobrien bfd_boolean *pneeded; 67684865Sobrien{ 67794536Sobrien 67884865Sobrien if (! _bfd_coff_get_external_symbols (abfd)) 679130561Sobrien return FALSE; 68084865Sobrien 68184865Sobrien if (! xcoff_link_check_ar_symbols (abfd, info, pneeded)) 682130561Sobrien return FALSE; 68384865Sobrien 68484865Sobrien if (*pneeded) 68584865Sobrien { 68684865Sobrien if (! xcoff_link_add_symbols (abfd, info)) 687130561Sobrien return FALSE; 68884865Sobrien } 68984865Sobrien 69084865Sobrien if (! info->keep_memory || ! *pneeded) 69184865Sobrien { 69284865Sobrien if (! _bfd_coff_free_symbols (abfd)) 693130561Sobrien return FALSE; 69484865Sobrien } 69584865Sobrien 696130561Sobrien return TRUE; 69784865Sobrien} 69884865Sobrien 69984865Sobrien/* Look through the symbols to see if this object file should be 70084865Sobrien included in the link. */ 70184865Sobrien 702130561Sobrienstatic bfd_boolean 70384865Sobrienxcoff_link_check_ar_symbols (abfd, info, pneeded) 70484865Sobrien bfd *abfd; 70584865Sobrien struct bfd_link_info *info; 706130561Sobrien bfd_boolean *pneeded; 70784865Sobrien{ 70884865Sobrien bfd_size_type symesz; 70984865Sobrien bfd_byte *esym; 71084865Sobrien bfd_byte *esym_end; 71184865Sobrien 712130561Sobrien *pneeded = FALSE; 71384865Sobrien 71484865Sobrien if ((abfd->flags & DYNAMIC) != 0 71584865Sobrien && ! info->static_link 71684865Sobrien && info->hash->creator == abfd->xvec) 71784865Sobrien return xcoff_link_check_dynamic_ar_symbols (abfd, info, pneeded); 71884865Sobrien 71984865Sobrien symesz = bfd_coff_symesz (abfd); 72084865Sobrien esym = (bfd_byte *) obj_coff_external_syms (abfd); 72184865Sobrien esym_end = esym + obj_raw_syment_count (abfd) * symesz; 72284865Sobrien while (esym < esym_end) 72384865Sobrien { 72484865Sobrien struct internal_syment sym; 72584865Sobrien 72684865Sobrien bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym); 72784865Sobrien 72884865Sobrien if (sym.n_sclass == C_EXT && sym.n_scnum != N_UNDEF) 72984865Sobrien { 73084865Sobrien const char *name; 73184865Sobrien char buf[SYMNMLEN + 1]; 73284865Sobrien struct bfd_link_hash_entry *h; 73384865Sobrien 73484865Sobrien /* This symbol is externally visible, and is defined by this 735130561Sobrien object file. */ 73684865Sobrien 73784865Sobrien name = _bfd_coff_internal_syment_name (abfd, &sym, buf); 73894536Sobrien 73984865Sobrien if (name == NULL) 740130561Sobrien return FALSE; 741130561Sobrien h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE); 74284865Sobrien 74384865Sobrien /* We are only interested in symbols that are currently 74484865Sobrien undefined. If a symbol is currently known to be common, 74584865Sobrien XCOFF linkers do not bring in an object file which 74684865Sobrien defines it. We also don't bring in symbols to satisfy 74784865Sobrien undefined references in shared objects. */ 74884865Sobrien if (h != (struct bfd_link_hash_entry *) NULL 74984865Sobrien && h->type == bfd_link_hash_undefined 75094536Sobrien && (info->hash->creator != abfd->xvec 75184865Sobrien || (((struct xcoff_link_hash_entry *) h)->flags 75284865Sobrien & XCOFF_DEF_DYNAMIC) == 0)) 75384865Sobrien { 75484865Sobrien if (! (*info->callbacks->add_archive_element) (info, abfd, name)) 755130561Sobrien return FALSE; 756130561Sobrien *pneeded = TRUE; 757130561Sobrien return TRUE; 75884865Sobrien } 75984865Sobrien } 76084865Sobrien 76184865Sobrien esym += (sym.n_numaux + 1) * symesz; 76284865Sobrien } 76384865Sobrien 76484865Sobrien /* We do not need this object file. */ 765130561Sobrien return TRUE; 76684865Sobrien} 76784865Sobrien 76884865Sobrien/* Look through the loader symbols to see if this dynamic object 76984865Sobrien should be included in the link. The native linker uses the loader 77084865Sobrien symbols, not the normal symbol table, so we do too. */ 77184865Sobrien 772130561Sobrienstatic bfd_boolean 77384865Sobrienxcoff_link_check_dynamic_ar_symbols (abfd, info, pneeded) 77484865Sobrien bfd *abfd; 77584865Sobrien struct bfd_link_info *info; 776130561Sobrien bfd_boolean *pneeded; 77784865Sobrien{ 77884865Sobrien asection *lsec; 77994536Sobrien bfd_byte *contents; 78084865Sobrien struct internal_ldhdr ldhdr; 78184865Sobrien const char *strings; 78294536Sobrien bfd_byte *elsym, *elsymend; 78384865Sobrien 784130561Sobrien *pneeded = FALSE; 78584865Sobrien 78684865Sobrien lsec = bfd_get_section_by_name (abfd, ".loader"); 78784865Sobrien if (lsec == NULL) 78884865Sobrien { 78984865Sobrien /* There are no symbols, so don't try to include it. */ 790130561Sobrien return TRUE; 79184865Sobrien } 79284865Sobrien 79384865Sobrien if (! xcoff_get_section_contents (abfd, lsec)) 794130561Sobrien return FALSE; 79594536Sobrien contents = coff_section_data (abfd, lsec)->contents; 79684865Sobrien 79794536Sobrien bfd_xcoff_swap_ldhdr_in (abfd, contents, &ldhdr); 79884865Sobrien 79994536Sobrien strings = (char *) contents + ldhdr.l_stoff; 80084865Sobrien 80194536Sobrien elsym = contents + bfd_xcoff_loader_symbol_offset(abfd, &ldhdr); 80294536Sobrien 80394536Sobrien elsymend = elsym + ldhdr.l_nsyms * bfd_xcoff_ldsymsz(abfd); 80494536Sobrien for (; elsym < elsymend; elsym += bfd_xcoff_ldsymsz(abfd)) 80584865Sobrien { 80684865Sobrien struct internal_ldsym ldsym; 80784865Sobrien char nambuf[SYMNMLEN + 1]; 80884865Sobrien const char *name; 80984865Sobrien struct bfd_link_hash_entry *h; 81084865Sobrien 81194536Sobrien bfd_xcoff_swap_ldsym_in (abfd, elsym, &ldsym); 81284865Sobrien 81384865Sobrien /* We are only interested in exported symbols. */ 81484865Sobrien if ((ldsym.l_smtype & L_EXPORT) == 0) 81584865Sobrien continue; 81684865Sobrien 81784865Sobrien if (ldsym._l._l_l._l_zeroes == 0) 81884865Sobrien name = strings + ldsym._l._l_l._l_offset; 81984865Sobrien else 82084865Sobrien { 82184865Sobrien memcpy (nambuf, ldsym._l._l_name, SYMNMLEN); 82284865Sobrien nambuf[SYMNMLEN] = '\0'; 82384865Sobrien name = nambuf; 82484865Sobrien } 82584865Sobrien 826130561Sobrien h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE); 82784865Sobrien 82884865Sobrien /* We are only interested in symbols that are currently 829130561Sobrien undefined. At this point we know that we are using an XCOFF 830130561Sobrien hash table. */ 83184865Sobrien if (h != NULL 83284865Sobrien && h->type == bfd_link_hash_undefined 83384865Sobrien && (((struct xcoff_link_hash_entry *) h)->flags 83484865Sobrien & XCOFF_DEF_DYNAMIC) == 0) 83584865Sobrien { 83684865Sobrien if (! (*info->callbacks->add_archive_element) (info, abfd, name)) 837130561Sobrien return FALSE; 838130561Sobrien *pneeded = TRUE; 839130561Sobrien return TRUE; 84084865Sobrien } 84184865Sobrien } 84284865Sobrien 84384865Sobrien /* We do not need this shared object. */ 84484865Sobrien 84594536Sobrien if (contents != NULL && ! coff_section_data (abfd, lsec)->keep_contents) 84684865Sobrien { 84784865Sobrien free (coff_section_data (abfd, lsec)->contents); 84884865Sobrien coff_section_data (abfd, lsec)->contents = NULL; 84984865Sobrien } 85084865Sobrien 851130561Sobrien return TRUE; 85284865Sobrien} 85384865Sobrien 85484865Sobrien/* Returns the index of reloc in RELOCS with the least address greater 85584865Sobrien than or equal to ADDRESS. The relocs are sorted by address. */ 85684865Sobrien 85784865Sobrienstatic bfd_size_type 85884865Sobrienxcoff_find_reloc (relocs, count, address) 85984865Sobrien struct internal_reloc *relocs; 86084865Sobrien bfd_size_type count; 86184865Sobrien bfd_vma address; 86284865Sobrien{ 86384865Sobrien bfd_size_type min, max, this; 86484865Sobrien 86584865Sobrien if (count < 2) 86684865Sobrien { 86784865Sobrien if (count == 1 && relocs[0].r_vaddr < address) 86884865Sobrien return 1; 86984865Sobrien else 87084865Sobrien return 0; 87184865Sobrien } 87284865Sobrien 87384865Sobrien min = 0; 87484865Sobrien max = count; 87584865Sobrien 87684865Sobrien /* Do a binary search over (min,max]. */ 87784865Sobrien while (min + 1 < max) 87884865Sobrien { 87984865Sobrien bfd_vma raddr; 88084865Sobrien 88184865Sobrien this = (max + min) / 2; 88284865Sobrien raddr = relocs[this].r_vaddr; 88384865Sobrien if (raddr > address) 88484865Sobrien max = this; 88584865Sobrien else if (raddr < address) 88684865Sobrien min = this; 88784865Sobrien else 88884865Sobrien { 88984865Sobrien min = this; 89084865Sobrien break; 89184865Sobrien } 89284865Sobrien } 89384865Sobrien 89484865Sobrien if (relocs[min].r_vaddr < address) 89584865Sobrien return min + 1; 89684865Sobrien 89784865Sobrien while (min > 0 89884865Sobrien && relocs[min - 1].r_vaddr == address) 89984865Sobrien --min; 90084865Sobrien 90184865Sobrien return min; 90284865Sobrien} 90384865Sobrien 90484865Sobrien 90594536Sobrien/* xcoff_link_create_extra_sections 90684865Sobrien 90794536Sobrien Takes care of creating the .loader, .gl, .ds, .debug and sections. */ 90884865Sobrien 909130561Sobrienstatic bfd_boolean 91094536Sobrienxcoff_link_create_extra_sections(bfd * abfd, struct bfd_link_info *info) 91184865Sobrien{ 91284865Sobrien 913130561Sobrien bfd_boolean return_value = FALSE; 91484865Sobrien 91594536Sobrien if (info->hash->creator == abfd->xvec) 91684865Sobrien { 91784865Sobrien 91884865Sobrien /* We need to build a .loader section, so we do it here. This 91984865Sobrien won't work if we're producing an XCOFF output file with no 92084865Sobrien XCOFF input files. FIXME. */ 92194536Sobrien 92284865Sobrien if (xcoff_hash_table (info)->loader_section == NULL) 92384865Sobrien { 92484865Sobrien asection *lsec; 92584865Sobrien 92684865Sobrien lsec = bfd_make_section_anyway (abfd, ".loader"); 92784865Sobrien if (lsec == NULL) 92894536Sobrien { 92994536Sobrien goto end_return; 93094536Sobrien } 93184865Sobrien xcoff_hash_table (info)->loader_section = lsec; 93284865Sobrien lsec->flags |= SEC_HAS_CONTENTS | SEC_IN_MEMORY; 93384865Sobrien } 93494536Sobrien 93584865Sobrien /* Likewise for the linkage section. */ 93684865Sobrien if (xcoff_hash_table (info)->linkage_section == NULL) 93784865Sobrien { 93884865Sobrien asection *lsec; 93984865Sobrien 94084865Sobrien lsec = bfd_make_section_anyway (abfd, ".gl"); 94184865Sobrien if (lsec == NULL) 94294536Sobrien { 94394536Sobrien goto end_return; 94494536Sobrien } 94594536Sobrien 94684865Sobrien xcoff_hash_table (info)->linkage_section = lsec; 94784865Sobrien lsec->flags |= (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS 94884865Sobrien | SEC_IN_MEMORY); 94984865Sobrien lsec->alignment_power = 2; 95084865Sobrien } 95194536Sobrien 95284865Sobrien /* Likewise for the TOC section. */ 95384865Sobrien if (xcoff_hash_table (info)->toc_section == NULL) 95484865Sobrien { 95584865Sobrien asection *tsec; 95684865Sobrien 95784865Sobrien tsec = bfd_make_section_anyway (abfd, ".tc"); 95884865Sobrien if (tsec == NULL) 95994536Sobrien { 96094536Sobrien goto end_return; 96194536Sobrien } 96294536Sobrien 96384865Sobrien xcoff_hash_table (info)->toc_section = tsec; 96484865Sobrien tsec->flags |= (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS 96584865Sobrien | SEC_IN_MEMORY); 96684865Sobrien tsec->alignment_power = 2; 96784865Sobrien } 96894536Sobrien 96984865Sobrien /* Likewise for the descriptor section. */ 97084865Sobrien if (xcoff_hash_table (info)->descriptor_section == NULL) 97184865Sobrien { 97284865Sobrien asection *dsec; 97384865Sobrien 97484865Sobrien dsec = bfd_make_section_anyway (abfd, ".ds"); 97584865Sobrien if (dsec == NULL) 97694536Sobrien { 97794536Sobrien goto end_return; 97894536Sobrien } 97994536Sobrien 98084865Sobrien xcoff_hash_table (info)->descriptor_section = dsec; 98184865Sobrien dsec->flags |= (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS 98284865Sobrien | SEC_IN_MEMORY); 98384865Sobrien dsec->alignment_power = 2; 98484865Sobrien } 98594536Sobrien 98684865Sobrien /* Likewise for the .debug section. */ 98784865Sobrien if (xcoff_hash_table (info)->debug_section == NULL 98884865Sobrien && info->strip != strip_all) 98984865Sobrien { 99084865Sobrien asection *dsec; 99184865Sobrien 99284865Sobrien dsec = bfd_make_section_anyway (abfd, ".debug"); 99384865Sobrien if (dsec == NULL) 99494536Sobrien { 99594536Sobrien goto end_return; 99694536Sobrien } 99784865Sobrien xcoff_hash_table (info)->debug_section = dsec; 99884865Sobrien dsec->flags |= SEC_HAS_CONTENTS | SEC_IN_MEMORY; 99984865Sobrien } 100084865Sobrien } 100184865Sobrien 1002130561Sobrien return_value = TRUE; 100394536Sobrien 100494536Sobrien end_return: 100594536Sobrien 100694536Sobrien return return_value; 100794536Sobrien} 100894536Sobrien 100994536Sobrien/* Add all the symbols from an object file to the hash table. 101094536Sobrien 101194536Sobrien XCOFF is a weird format. A normal XCOFF .o files will have three 101294536Sobrien COFF sections--.text, .data, and .bss--but each COFF section will 101394536Sobrien contain many csects. These csects are described in the symbol 101494536Sobrien table. From the linker's point of view, each csect must be 101594536Sobrien considered a section in its own right. For example, a TOC entry is 101694536Sobrien handled as a small XMC_TC csect. The linker must be able to merge 101794536Sobrien different TOC entries together, which means that it must be able to 101894536Sobrien extract the XMC_TC csects from the .data section of the input .o 101994536Sobrien file. 102094536Sobrien 102194536Sobrien From the point of view of our linker, this is, of course, a hideous 102294536Sobrien nightmare. We cope by actually creating sections for each csect, 102394536Sobrien and discarding the original sections. We then have to handle the 102494536Sobrien relocation entries carefully, since the only way to tell which 102594536Sobrien csect they belong to is to examine the address. */ 102694536Sobrien 1027130561Sobrienstatic bfd_boolean 102894536Sobrienxcoff_link_add_symbols (abfd, info) 102994536Sobrien bfd *abfd; 103094536Sobrien struct bfd_link_info *info; 103194536Sobrien{ 103294536Sobrien unsigned int n_tmask; 103394536Sobrien unsigned int n_btshft; 1034130561Sobrien bfd_boolean default_copy; 103594536Sobrien bfd_size_type symcount; 103694536Sobrien struct xcoff_link_hash_entry **sym_hash; 103794536Sobrien asection **csect_cache; 103894536Sobrien bfd_size_type linesz; 103994536Sobrien asection *o; 104094536Sobrien asection *last_real; 1041130561Sobrien bfd_boolean keep_syms; 104294536Sobrien asection *csect; 104394536Sobrien unsigned int csect_index; 104494536Sobrien asection *first_csect; 104594536Sobrien bfd_size_type symesz; 104694536Sobrien bfd_byte *esym; 104794536Sobrien bfd_byte *esym_end; 104894536Sobrien struct reloc_info_struct 104994536Sobrien { 105094536Sobrien struct internal_reloc *relocs; 105194536Sobrien asection **csects; 105294536Sobrien bfd_byte *linenos; 105394536Sobrien } *reloc_info = NULL; 105494536Sobrien bfd_size_type amt; 105594536Sobrien 105694536Sobrien keep_syms = obj_coff_keep_syms (abfd); 105794536Sobrien 105884865Sobrien if ((abfd->flags & DYNAMIC) != 0 105984865Sobrien && ! info->static_link) 106094536Sobrien { 106194536Sobrien if (! xcoff_link_add_dynamic_symbols (abfd, info)) 1062130561Sobrien return FALSE; 106394536Sobrien } 106494536Sobrien 106594536Sobrien /* create the loader, toc, gl, ds and debug sections, if needed */ 1066130561Sobrien if (! xcoff_link_create_extra_sections (abfd, info)) 1067104834Sobrien goto error_return; 106894536Sobrien 106994536Sobrien if ((abfd->flags & DYNAMIC) != 0 107094536Sobrien && ! info->static_link) 1071130561Sobrien return TRUE; 107284865Sobrien 107384865Sobrien n_tmask = coff_data (abfd)->local_n_tmask; 107484865Sobrien n_btshft = coff_data (abfd)->local_n_btshft; 107584865Sobrien 107684865Sobrien /* Define macros so that ISFCN, et. al., macros work correctly. */ 107784865Sobrien#define N_TMASK n_tmask 107884865Sobrien#define N_BTSHFT n_btshft 107984865Sobrien 108084865Sobrien if (info->keep_memory) 1081130561Sobrien default_copy = FALSE; 108284865Sobrien else 1083130561Sobrien default_copy = TRUE; 108484865Sobrien 108584865Sobrien symcount = obj_raw_syment_count (abfd); 108684865Sobrien 108784865Sobrien /* We keep a list of the linker hash table entries that correspond 108884865Sobrien to each external symbol. */ 108994536Sobrien amt = symcount * sizeof (struct xcoff_link_hash_entry *); 1090104834Sobrien sym_hash = (struct xcoff_link_hash_entry **) bfd_zalloc (abfd, amt); 109184865Sobrien if (sym_hash == NULL && symcount != 0) 109284865Sobrien goto error_return; 109384865Sobrien coff_data (abfd)->sym_hashes = (struct coff_link_hash_entry **) sym_hash; 109484865Sobrien 109584865Sobrien /* Because of the weird stuff we are doing with XCOFF csects, we can 109684865Sobrien not easily determine which section a symbol is in, so we store 109784865Sobrien the information in the tdata for the input file. */ 109894536Sobrien amt = symcount * sizeof (asection *); 1099104834Sobrien csect_cache = (asection **) bfd_zalloc (abfd, amt); 110084865Sobrien if (csect_cache == NULL && symcount != 0) 110184865Sobrien goto error_return; 110284865Sobrien xcoff_data (abfd)->csects = csect_cache; 110384865Sobrien 110484865Sobrien /* While splitting sections into csects, we need to assign the 110584865Sobrien relocs correctly. The relocs and the csects must both be in 110684865Sobrien order by VMA within a given section, so we handle this by 110784865Sobrien scanning along the relocs as we process the csects. We index 110884865Sobrien into reloc_info using the section target_index. */ 110994536Sobrien amt = abfd->section_count + 1; 111094536Sobrien amt *= sizeof (struct reloc_info_struct); 1111104834Sobrien reloc_info = (struct reloc_info_struct *) bfd_zmalloc (amt); 111284865Sobrien if (reloc_info == NULL) 111384865Sobrien goto error_return; 111484865Sobrien 111584865Sobrien /* Read in the relocs and line numbers for each section. */ 111684865Sobrien linesz = bfd_coff_linesz (abfd); 111784865Sobrien last_real = NULL; 111884865Sobrien for (o = abfd->sections; o != NULL; o = o->next) 111984865Sobrien { 112094536Sobrien 112184865Sobrien last_real = o; 112284865Sobrien if ((o->flags & SEC_RELOC) != 0) 112384865Sobrien { 112494536Sobrien 112584865Sobrien reloc_info[o->target_index].relocs = 1126130561Sobrien xcoff_read_internal_relocs (abfd, o, TRUE, (bfd_byte *) NULL, 1127130561Sobrien FALSE, (struct internal_reloc *) NULL); 112894536Sobrien amt = o->reloc_count; 112994536Sobrien amt *= sizeof (asection *); 1130104834Sobrien reloc_info[o->target_index].csects = (asection **) bfd_zmalloc (amt); 113184865Sobrien if (reloc_info[o->target_index].csects == NULL) 113284865Sobrien goto error_return; 113384865Sobrien } 113484865Sobrien 113584865Sobrien if ((info->strip == strip_none || info->strip == strip_some) 113684865Sobrien && o->lineno_count > 0) 113784865Sobrien { 113894536Sobrien 113984865Sobrien bfd_byte *linenos; 114084865Sobrien 114194536Sobrien amt = linesz * o->lineno_count; 114294536Sobrien linenos = (bfd_byte *) bfd_malloc (amt); 114384865Sobrien if (linenos == NULL) 114484865Sobrien goto error_return; 114584865Sobrien reloc_info[o->target_index].linenos = linenos; 114684865Sobrien if (bfd_seek (abfd, o->line_filepos, SEEK_SET) != 0 114794536Sobrien || bfd_bread (linenos, amt, abfd) != amt) 114884865Sobrien goto error_return; 114994536Sobrien 115084865Sobrien } 115184865Sobrien } 115284865Sobrien 115384865Sobrien /* Don't let the linker relocation routines discard the symbols. */ 1154130561Sobrien obj_coff_keep_syms (abfd) = TRUE; 115584865Sobrien 115684865Sobrien csect = NULL; 115784865Sobrien csect_index = 0; 115884865Sobrien first_csect = NULL; 115984865Sobrien 116084865Sobrien symesz = bfd_coff_symesz (abfd); 116184865Sobrien BFD_ASSERT (symesz == bfd_coff_auxesz (abfd)); 116284865Sobrien esym = (bfd_byte *) obj_coff_external_syms (abfd); 116384865Sobrien esym_end = esym + symcount * symesz; 116494536Sobrien 116584865Sobrien while (esym < esym_end) 116684865Sobrien { 116784865Sobrien struct internal_syment sym; 116884865Sobrien union internal_auxent aux; 116984865Sobrien const char *name; 117084865Sobrien char buf[SYMNMLEN + 1]; 117184865Sobrien int smtyp; 117284865Sobrien flagword flags; 117384865Sobrien asection *section; 117484865Sobrien bfd_vma value; 117584865Sobrien struct xcoff_link_hash_entry *set_toc; 117684865Sobrien 117784865Sobrien bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &sym); 117884865Sobrien 117984865Sobrien /* In this pass we are only interested in symbols with csect 118094536Sobrien information. */ 118184865Sobrien if (sym.n_sclass != C_EXT && sym.n_sclass != C_HIDEXT) 118284865Sobrien { 118394536Sobrien 118494536Sobrien /* Set csect_cache, 118594536Sobrien Normally csect is a .pr, .rw etc. created in the loop 118694536Sobrien If C_FILE or first time, handle special 118794536Sobrien 118894536Sobrien Advance esym, sym_hash, csect_hash ptr's 118994536Sobrien Keep track of the last_symndx for the current file. */ 119084865Sobrien if (sym.n_sclass == C_FILE && csect != NULL) 119184865Sobrien { 119284865Sobrien xcoff_section_data (abfd, csect)->last_symndx = 119384865Sobrien ((esym 119484865Sobrien - (bfd_byte *) obj_coff_external_syms (abfd)) 119584865Sobrien / symesz); 119684865Sobrien csect = NULL; 119784865Sobrien } 119884865Sobrien 119984865Sobrien if (csect != NULL) 120084865Sobrien *csect_cache = csect; 120184865Sobrien else if (first_csect == NULL || sym.n_sclass == C_FILE) 120284865Sobrien *csect_cache = coff_section_from_bfd_index (abfd, sym.n_scnum); 120384865Sobrien else 120484865Sobrien *csect_cache = NULL; 120584865Sobrien esym += (sym.n_numaux + 1) * symesz; 120684865Sobrien sym_hash += sym.n_numaux + 1; 120784865Sobrien csect_cache += sym.n_numaux + 1; 120894536Sobrien 120984865Sobrien continue; 121084865Sobrien } 121184865Sobrien 121284865Sobrien name = _bfd_coff_internal_syment_name (abfd, &sym, buf); 121394536Sobrien 121484865Sobrien if (name == NULL) 121584865Sobrien goto error_return; 121684865Sobrien 121784865Sobrien /* If this symbol has line number information attached to it, 1218130561Sobrien and we're not stripping it, count the number of entries and 1219130561Sobrien add them to the count for this csect. In the final link pass 1220130561Sobrien we are going to attach line number information by symbol, 1221130561Sobrien rather than by section, in order to more easily handle 1222130561Sobrien garbage collection. */ 122384865Sobrien if ((info->strip == strip_none || info->strip == strip_some) 122484865Sobrien && sym.n_numaux > 1 122584865Sobrien && csect != NULL 122684865Sobrien && ISFCN (sym.n_type)) 122784865Sobrien { 122894536Sobrien 122984865Sobrien union internal_auxent auxlin; 123084865Sobrien 123184865Sobrien bfd_coff_swap_aux_in (abfd, (PTR) (esym + symesz), 123284865Sobrien sym.n_type, sym.n_sclass, 123384865Sobrien 0, sym.n_numaux, (PTR) &auxlin); 123494536Sobrien 123584865Sobrien if (auxlin.x_sym.x_fcnary.x_fcn.x_lnnoptr != 0) 123684865Sobrien { 123784865Sobrien asection *enclosing; 123894536Sobrien bfd_signed_vma linoff; 123984865Sobrien 124084865Sobrien enclosing = xcoff_section_data (abfd, csect)->enclosing; 124184865Sobrien if (enclosing == NULL) 124284865Sobrien { 124384865Sobrien (*_bfd_error_handler) 124484865Sobrien (_("%s: `%s' has line numbers but no enclosing section"), 124594536Sobrien bfd_archive_filename (abfd), name); 124684865Sobrien bfd_set_error (bfd_error_bad_value); 124784865Sobrien goto error_return; 124884865Sobrien } 124984865Sobrien linoff = (auxlin.x_sym.x_fcnary.x_fcn.x_lnnoptr 125084865Sobrien - enclosing->line_filepos); 1251130561Sobrien /* explicit cast to bfd_signed_vma for compiler */ 125294536Sobrien if (linoff < (bfd_signed_vma) (enclosing->lineno_count * linesz)) 125384865Sobrien { 125484865Sobrien struct internal_lineno lin; 125584865Sobrien bfd_byte *linpstart; 125684865Sobrien 125784865Sobrien linpstart = (reloc_info[enclosing->target_index].linenos 125884865Sobrien + linoff); 125984865Sobrien bfd_coff_swap_lineno_in (abfd, (PTR) linpstart, (PTR) &lin); 126084865Sobrien if (lin.l_lnno == 0 126184865Sobrien && ((bfd_size_type) lin.l_addr.l_symndx 126284865Sobrien == ((esym 126384865Sobrien - (bfd_byte *) obj_coff_external_syms (abfd)) 126484865Sobrien / symesz))) 126584865Sobrien { 126684865Sobrien bfd_byte *linpend, *linp; 126784865Sobrien 126884865Sobrien linpend = (reloc_info[enclosing->target_index].linenos 126984865Sobrien + enclosing->lineno_count * linesz); 127084865Sobrien for (linp = linpstart + linesz; 127184865Sobrien linp < linpend; 127284865Sobrien linp += linesz) 127384865Sobrien { 127484865Sobrien bfd_coff_swap_lineno_in (abfd, (PTR) linp, 127584865Sobrien (PTR) &lin); 127684865Sobrien if (lin.l_lnno == 0) 127784865Sobrien break; 127884865Sobrien } 127984865Sobrien csect->lineno_count += (linp - linpstart) / linesz; 128084865Sobrien /* The setting of line_filepos will only be 128194536Sobrien useful if all the line number entries for a 128294536Sobrien csect are contiguous; this only matters for 128394536Sobrien error reporting. */ 128484865Sobrien if (csect->line_filepos == 0) 128584865Sobrien csect->line_filepos = 128684865Sobrien auxlin.x_sym.x_fcnary.x_fcn.x_lnnoptr; 128784865Sobrien } 128884865Sobrien } 128984865Sobrien } 129084865Sobrien } 129184865Sobrien 129284865Sobrien /* Pick up the csect auxiliary information. */ 129384865Sobrien 129484865Sobrien if (sym.n_numaux == 0) 129584865Sobrien { 129684865Sobrien (*_bfd_error_handler) 129784865Sobrien (_("%s: class %d symbol `%s' has no aux entries"), 129894536Sobrien bfd_archive_filename (abfd), sym.n_sclass, name); 129984865Sobrien bfd_set_error (bfd_error_bad_value); 130084865Sobrien goto error_return; 130184865Sobrien } 130284865Sobrien 130384865Sobrien bfd_coff_swap_aux_in (abfd, 130484865Sobrien (PTR) (esym + symesz * sym.n_numaux), 130584865Sobrien sym.n_type, sym.n_sclass, 130684865Sobrien sym.n_numaux - 1, sym.n_numaux, 130784865Sobrien (PTR) &aux); 130884865Sobrien 130984865Sobrien smtyp = SMTYP_SMTYP (aux.x_csect.x_smtyp); 131084865Sobrien 131184865Sobrien flags = BSF_GLOBAL; 131284865Sobrien section = NULL; 131384865Sobrien value = 0; 131484865Sobrien set_toc = NULL; 131584865Sobrien 131684865Sobrien switch (smtyp) 131784865Sobrien { 131884865Sobrien default: 131984865Sobrien (*_bfd_error_handler) 132084865Sobrien (_("%s: symbol `%s' has unrecognized csect type %d"), 132194536Sobrien bfd_archive_filename (abfd), name, smtyp); 132284865Sobrien bfd_set_error (bfd_error_bad_value); 132384865Sobrien goto error_return; 132484865Sobrien 132584865Sobrien case XTY_ER: 132684865Sobrien /* This is an external reference. */ 132784865Sobrien if (sym.n_sclass == C_HIDEXT 132884865Sobrien || sym.n_scnum != N_UNDEF 132984865Sobrien || aux.x_csect.x_scnlen.l != 0) 133084865Sobrien { 133184865Sobrien (*_bfd_error_handler) 133284865Sobrien (_("%s: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"), 133394536Sobrien bfd_archive_filename (abfd), name, sym.n_sclass, sym.n_scnum, 133484865Sobrien aux.x_csect.x_scnlen.l); 133584865Sobrien bfd_set_error (bfd_error_bad_value); 133684865Sobrien goto error_return; 133784865Sobrien } 133884865Sobrien 133984865Sobrien /* An XMC_XO external reference is actually a reference to 1340130561Sobrien an absolute location. */ 134184865Sobrien if (aux.x_csect.x_smclas != XMC_XO) 134284865Sobrien section = bfd_und_section_ptr; 134384865Sobrien else 134484865Sobrien { 134584865Sobrien section = bfd_abs_section_ptr; 134684865Sobrien value = sym.n_value; 134784865Sobrien } 134884865Sobrien break; 134984865Sobrien 135084865Sobrien case XTY_SD: 135184865Sobrien /* This is a csect definition. */ 135284865Sobrien if (csect != NULL) 135384865Sobrien { 135484865Sobrien xcoff_section_data (abfd, csect)->last_symndx = 135594536Sobrien ((esym - (bfd_byte *) obj_coff_external_syms (abfd)) / symesz); 135684865Sobrien } 135784865Sobrien 135884865Sobrien csect = NULL; 135994536Sobrien csect_index = -(unsigned) 1; 136084865Sobrien 136184865Sobrien /* When we see a TOC anchor, we record the TOC value. */ 136284865Sobrien if (aux.x_csect.x_smclas == XMC_TC0) 136384865Sobrien { 136484865Sobrien if (sym.n_sclass != C_HIDEXT 136584865Sobrien || aux.x_csect.x_scnlen.l != 0) 136684865Sobrien { 136784865Sobrien (*_bfd_error_handler) 136884865Sobrien (_("%s: XMC_TC0 symbol `%s' is class %d scnlen %d"), 136994536Sobrien bfd_archive_filename (abfd), name, sym.n_sclass, 137084865Sobrien aux.x_csect.x_scnlen.l); 137184865Sobrien bfd_set_error (bfd_error_bad_value); 137284865Sobrien goto error_return; 137384865Sobrien } 137484865Sobrien xcoff_data (abfd)->toc = sym.n_value; 137584865Sobrien } 137684865Sobrien 137784865Sobrien /* We must merge TOC entries for the same symbol. We can 137884865Sobrien merge two TOC entries if they are both C_HIDEXT, they 137994536Sobrien both have the same name, they are both 4 or 8 bytes long, and 138084865Sobrien they both have a relocation table entry for an external 138184865Sobrien symbol with the same name. Unfortunately, this means 138294536Sobrien that we must look through the relocations. Ick. 138394536Sobrien 138494536Sobrien Logic for 32 bit vs 64 bit. 138594536Sobrien 32 bit has a csect length of 4 for TOC 138694536Sobrien 64 bit has a csect length of 8 for TOC 138794536Sobrien 138894536Sobrien The conditions to get past the if-check are not that bad. 138994536Sobrien They are what is used to create the TOC csects in the first 139094536Sobrien place. */ 139184865Sobrien if (aux.x_csect.x_smclas == XMC_TC 139284865Sobrien && sym.n_sclass == C_HIDEXT 139394536Sobrien && info->hash->creator == abfd->xvec 139494536Sobrien && ((bfd_xcoff_is_xcoff32 (abfd) 139594536Sobrien && aux.x_csect.x_scnlen.l == 4) 139694536Sobrien || (bfd_xcoff_is_xcoff64 (abfd) 139794536Sobrien && aux.x_csect.x_scnlen.l == 8))) 139884865Sobrien { 139984865Sobrien asection *enclosing; 140084865Sobrien struct internal_reloc *relocs; 140184865Sobrien bfd_size_type relindx; 140284865Sobrien struct internal_reloc *rel; 140384865Sobrien 140484865Sobrien enclosing = coff_section_from_bfd_index (abfd, sym.n_scnum); 140584865Sobrien if (enclosing == NULL) 140684865Sobrien goto error_return; 140784865Sobrien 140884865Sobrien relocs = reloc_info[enclosing->target_index].relocs; 140994536Sobrien amt = enclosing->reloc_count; 141094536Sobrien relindx = xcoff_find_reloc (relocs, amt, sym.n_value); 141184865Sobrien rel = relocs + relindx; 141294536Sobrien 141394536Sobrien /* 32 bit R_POS r_size is 31 141494536Sobrien 64 bit R_POS r_size is 63 */ 141584865Sobrien if (relindx < enclosing->reloc_count 141684865Sobrien && rel->r_vaddr == (bfd_vma) sym.n_value 141794536Sobrien && rel->r_type == R_POS 141894536Sobrien && ((bfd_xcoff_is_xcoff32 (abfd) 141994536Sobrien && rel->r_size == 31) 142094536Sobrien || (bfd_xcoff_is_xcoff64 (abfd) 142194536Sobrien && rel->r_size == 63))) 142284865Sobrien { 142384865Sobrien bfd_byte *erelsym; 142494536Sobrien 142584865Sobrien struct internal_syment relsym; 142684865Sobrien 142784865Sobrien erelsym = ((bfd_byte *) obj_coff_external_syms (abfd) 142884865Sobrien + rel->r_symndx * symesz); 142984865Sobrien bfd_coff_swap_sym_in (abfd, (PTR) erelsym, (PTR) &relsym); 143084865Sobrien if (relsym.n_sclass == C_EXT) 143184865Sobrien { 143284865Sobrien const char *relname; 143384865Sobrien char relbuf[SYMNMLEN + 1]; 1434130561Sobrien bfd_boolean copy; 143584865Sobrien struct xcoff_link_hash_entry *h; 143684865Sobrien 143784865Sobrien /* At this point we know that the TOC entry is 143884865Sobrien for an externally visible symbol. */ 143994536Sobrien 144084865Sobrien relname = _bfd_coff_internal_syment_name (abfd, &relsym, 144184865Sobrien relbuf); 144284865Sobrien if (relname == NULL) 144384865Sobrien goto error_return; 144484865Sobrien 144584865Sobrien /* We only merge TOC entries if the TC name is 144694536Sobrien the same as the symbol name. This handles 144794536Sobrien the normal case, but not common cases like 144894536Sobrien SYM.P4 which gcc generates to store SYM + 4 144994536Sobrien in the TOC. FIXME. */ 145094536Sobrien 145184865Sobrien if (strcmp (name, relname) == 0) 145284865Sobrien { 145384865Sobrien copy = (! info->keep_memory 145484865Sobrien || relsym._n._n_n._n_zeroes != 0 145584865Sobrien || relsym._n._n_n._n_offset == 0); 145684865Sobrien h = xcoff_link_hash_lookup (xcoff_hash_table (info), 1457130561Sobrien relname, TRUE, copy, 1458130561Sobrien FALSE); 145984865Sobrien if (h == NULL) 146084865Sobrien goto error_return; 146184865Sobrien 146284865Sobrien /* At this point h->root.type could be 146384865Sobrien bfd_link_hash_new. That should be OK, 146484865Sobrien since we know for sure that we will come 146584865Sobrien across this symbol as we step through the 146684865Sobrien file. */ 146784865Sobrien 146884865Sobrien /* We store h in *sym_hash for the 146984865Sobrien convenience of the relocate_section 147084865Sobrien function. */ 147184865Sobrien *sym_hash = h; 147284865Sobrien 147384865Sobrien if (h->toc_section != NULL) 147484865Sobrien { 147584865Sobrien asection **rel_csects; 147684865Sobrien 147784865Sobrien /* We already have a TOC entry for this 147884865Sobrien symbol, so we can just ignore this 147984865Sobrien one. */ 148084865Sobrien rel_csects = 148184865Sobrien reloc_info[enclosing->target_index].csects; 148284865Sobrien rel_csects[relindx] = bfd_und_section_ptr; 148384865Sobrien break; 148484865Sobrien } 148584865Sobrien 148684865Sobrien /* We are about to create a TOC entry for 148784865Sobrien this symbol. */ 148884865Sobrien set_toc = h; 148994536Sobrien } /* merge toc reloc */ 149094536Sobrien } /* c_ext */ 149194536Sobrien } /* reloc */ 149294536Sobrien } /* merge toc */ 149384865Sobrien 149484865Sobrien { 149594536Sobrien 149684865Sobrien asection *enclosing; 149784865Sobrien 149894536Sobrien /* We need to create a new section. We get the name from 149994536Sobrien the csect storage mapping class, so that the linker can 150094536Sobrien accumulate similar csects together. */ 150194536Sobrien 150294536Sobrien csect = bfd_xcoff_create_csect_from_smclas(abfd, &aux, name); 150394536Sobrien if (NULL == csect) 150484865Sobrien { 150584865Sobrien goto error_return; 150684865Sobrien } 150784865Sobrien 150894536Sobrien /* The enclosing section is the main section : .data, .text 150994536Sobrien or .bss that the csect is coming from. */ 151084865Sobrien enclosing = coff_section_from_bfd_index (abfd, sym.n_scnum); 151184865Sobrien if (enclosing == NULL) 151284865Sobrien goto error_return; 151394536Sobrien 151484865Sobrien if (! bfd_is_abs_section (enclosing) 151584865Sobrien && ((bfd_vma) sym.n_value < enclosing->vma 151684865Sobrien || ((bfd_vma) sym.n_value + aux.x_csect.x_scnlen.l 151784865Sobrien > enclosing->vma + enclosing->_raw_size))) 151884865Sobrien { 151984865Sobrien (*_bfd_error_handler) 152084865Sobrien (_("%s: csect `%s' not in enclosing section"), 152194536Sobrien bfd_archive_filename (abfd), name); 152284865Sobrien bfd_set_error (bfd_error_bad_value); 152384865Sobrien goto error_return; 152484865Sobrien } 152584865Sobrien csect->vma = sym.n_value; 152684865Sobrien csect->filepos = (enclosing->filepos 152784865Sobrien + sym.n_value 152884865Sobrien - enclosing->vma); 152984865Sobrien csect->_raw_size = aux.x_csect.x_scnlen.l; 153084865Sobrien csect->flags |= SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS; 153184865Sobrien csect->alignment_power = SMTYP_ALIGN (aux.x_csect.x_smtyp); 153284865Sobrien 153384865Sobrien /* Record the enclosing section in the tdata for this new 153484865Sobrien section. */ 153594536Sobrien amt = sizeof (struct coff_section_tdata); 153694536Sobrien csect->used_by_bfd = (PTR) bfd_zalloc (abfd, amt); 153784865Sobrien if (csect->used_by_bfd == NULL) 153884865Sobrien goto error_return; 153994536Sobrien amt = sizeof (struct xcoff_section_tdata); 154094536Sobrien coff_section_data (abfd, csect)->tdata = bfd_zalloc (abfd, amt); 154184865Sobrien if (coff_section_data (abfd, csect)->tdata == NULL) 154284865Sobrien goto error_return; 154384865Sobrien xcoff_section_data (abfd, csect)->enclosing = enclosing; 154484865Sobrien xcoff_section_data (abfd, csect)->lineno_count = 154584865Sobrien enclosing->lineno_count; 154684865Sobrien 154784865Sobrien if (enclosing->owner == abfd) 154884865Sobrien { 154984865Sobrien struct internal_reloc *relocs; 155084865Sobrien bfd_size_type relindx; 155184865Sobrien struct internal_reloc *rel; 155284865Sobrien asection **rel_csect; 155384865Sobrien 155484865Sobrien relocs = reloc_info[enclosing->target_index].relocs; 155594536Sobrien amt = enclosing->reloc_count; 155694536Sobrien relindx = xcoff_find_reloc (relocs, amt, csect->vma); 155794536Sobrien 155884865Sobrien rel = relocs + relindx; 155984865Sobrien rel_csect = (reloc_info[enclosing->target_index].csects 156084865Sobrien + relindx); 156194536Sobrien 156284865Sobrien csect->rel_filepos = (enclosing->rel_filepos 156384865Sobrien + relindx * bfd_coff_relsz (abfd)); 156484865Sobrien while (relindx < enclosing->reloc_count 156584865Sobrien && *rel_csect == NULL 156684865Sobrien && rel->r_vaddr < csect->vma + csect->_raw_size) 156784865Sobrien { 156894536Sobrien 156984865Sobrien *rel_csect = csect; 157084865Sobrien csect->flags |= SEC_RELOC; 157184865Sobrien ++csect->reloc_count; 157284865Sobrien ++relindx; 157384865Sobrien ++rel; 157484865Sobrien ++rel_csect; 157584865Sobrien } 157684865Sobrien } 157784865Sobrien 157884865Sobrien /* There are a number of other fields and section flags 157984865Sobrien which we do not bother to set. */ 158084865Sobrien 158184865Sobrien csect_index = ((esym 158284865Sobrien - (bfd_byte *) obj_coff_external_syms (abfd)) 158384865Sobrien / symesz); 158484865Sobrien 158584865Sobrien xcoff_section_data (abfd, csect)->first_symndx = csect_index; 158684865Sobrien 158784865Sobrien if (first_csect == NULL) 158884865Sobrien first_csect = csect; 158984865Sobrien 159084865Sobrien /* If this symbol is C_EXT, we treat it as starting at the 159184865Sobrien beginning of the newly created section. */ 159284865Sobrien if (sym.n_sclass == C_EXT) 159384865Sobrien { 159484865Sobrien section = csect; 159584865Sobrien value = 0; 159684865Sobrien } 159784865Sobrien 159884865Sobrien /* If this is a TOC section for a symbol, record it. */ 159984865Sobrien if (set_toc != NULL) 160084865Sobrien set_toc->toc_section = csect; 160184865Sobrien } 160284865Sobrien break; 160384865Sobrien 160484865Sobrien case XTY_LD: 160584865Sobrien /* This is a label definition. The x_scnlen field is the 160694536Sobrien symbol index of the csect. Usually the XTY_LD symbol will 160794536Sobrien follow its appropriate XTY_SD symbol. The .set pseudo op can 160894536Sobrien cause the XTY_LD to not follow the XTY_SD symbol. */ 160984865Sobrien { 1610130561Sobrien bfd_boolean bad; 161184865Sobrien 1612130561Sobrien bad = FALSE; 161384865Sobrien if (aux.x_csect.x_scnlen.l < 0 161484865Sobrien || (aux.x_csect.x_scnlen.l 161584865Sobrien >= esym - (bfd_byte *) obj_coff_external_syms (abfd))) 1616130561Sobrien bad = TRUE; 161784865Sobrien if (! bad) 161884865Sobrien { 161984865Sobrien section = xcoff_data (abfd)->csects[aux.x_csect.x_scnlen.l]; 162084865Sobrien if (section == NULL 162184865Sobrien || (section->flags & SEC_HAS_CONTENTS) == 0) 1622130561Sobrien bad = TRUE; 162384865Sobrien } 162484865Sobrien if (bad) 162584865Sobrien { 162684865Sobrien (*_bfd_error_handler) 162784865Sobrien (_("%s: misplaced XTY_LD `%s'"), 162894536Sobrien bfd_archive_filename (abfd), name); 162984865Sobrien bfd_set_error (bfd_error_bad_value); 163084865Sobrien goto error_return; 163184865Sobrien } 163294536Sobrien csect = section; 163384865Sobrien value = sym.n_value - csect->vma; 163484865Sobrien } 163584865Sobrien break; 163684865Sobrien 163784865Sobrien case XTY_CM: 163884865Sobrien /* This is an unitialized csect. We could base the name on 1639130561Sobrien the storage mapping class, but we don't bother except for 1640130561Sobrien an XMC_TD symbol. If this csect is externally visible, 1641130561Sobrien it is a common symbol. We put XMC_TD symbols in sections 1642130561Sobrien named .tocbss, and rely on the linker script to put that 1643130561Sobrien in the TOC area. */ 164484865Sobrien 164584865Sobrien if (csect != NULL) 164684865Sobrien { 164784865Sobrien xcoff_section_data (abfd, csect)->last_symndx = 164884865Sobrien ((esym 164984865Sobrien - (bfd_byte *) obj_coff_external_syms (abfd)) 165084865Sobrien / symesz); 165184865Sobrien } 165284865Sobrien 165384865Sobrien if (aux.x_csect.x_smclas == XMC_TD) 165494536Sobrien { 165594536Sobrien /* The linker script puts the .td section in the data 165694536Sobrien section after the .tc section. */ 165794536Sobrien csect = bfd_make_section_anyway (abfd, ".td"); 165894536Sobrien 165994536Sobrien } 166084865Sobrien else 166194536Sobrien { 166294536Sobrien csect = bfd_make_section_anyway (abfd, ".bss"); 166394536Sobrien } 166484865Sobrien if (csect == NULL) 166584865Sobrien goto error_return; 166684865Sobrien csect->vma = sym.n_value; 166784865Sobrien csect->_raw_size = aux.x_csect.x_scnlen.l; 166884865Sobrien csect->flags |= SEC_ALLOC; 166984865Sobrien csect->alignment_power = SMTYP_ALIGN (aux.x_csect.x_smtyp); 167084865Sobrien /* There are a number of other fields and section flags 167184865Sobrien which we do not bother to set. */ 167284865Sobrien 167384865Sobrien csect_index = ((esym 167484865Sobrien - (bfd_byte *) obj_coff_external_syms (abfd)) 167584865Sobrien / symesz); 167684865Sobrien 167794536Sobrien amt = sizeof (struct coff_section_tdata); 167894536Sobrien csect->used_by_bfd = (PTR) bfd_zalloc (abfd, amt); 167984865Sobrien if (csect->used_by_bfd == NULL) 168084865Sobrien goto error_return; 168194536Sobrien amt = sizeof (struct xcoff_section_tdata); 168294536Sobrien coff_section_data (abfd, csect)->tdata = bfd_zalloc (abfd, amt); 168384865Sobrien if (coff_section_data (abfd, csect)->tdata == NULL) 168484865Sobrien goto error_return; 168584865Sobrien xcoff_section_data (abfd, csect)->first_symndx = csect_index; 168684865Sobrien 168784865Sobrien if (first_csect == NULL) 168884865Sobrien first_csect = csect; 168984865Sobrien 169084865Sobrien if (sym.n_sclass == C_EXT) 169184865Sobrien { 169284865Sobrien csect->flags |= SEC_IS_COMMON; 169384865Sobrien csect->_raw_size = 0; 169484865Sobrien section = csect; 169584865Sobrien value = aux.x_csect.x_scnlen.l; 169684865Sobrien } 169784865Sobrien 169884865Sobrien break; 169984865Sobrien } 170084865Sobrien 170184865Sobrien /* Check for magic symbol names. */ 170284865Sobrien if ((smtyp == XTY_SD || smtyp == XTY_CM) 170384865Sobrien && aux.x_csect.x_smclas != XMC_TC 170484865Sobrien && aux.x_csect.x_smclas != XMC_TD) 170584865Sobrien { 170684865Sobrien 170794536Sobrien int i = -1; 170894536Sobrien 170984865Sobrien if (name[0] == '_') 171084865Sobrien { 171184865Sobrien if (strcmp (name, "_text") == 0) 171294536Sobrien i = XCOFF_SPECIAL_SECTION_TEXT; 171384865Sobrien else if (strcmp (name, "_etext") == 0) 171494536Sobrien i = XCOFF_SPECIAL_SECTION_ETEXT; 171584865Sobrien else if (strcmp (name, "_data") == 0) 171694536Sobrien i = XCOFF_SPECIAL_SECTION_DATA; 171784865Sobrien else if (strcmp (name, "_edata") == 0) 171894536Sobrien i = XCOFF_SPECIAL_SECTION_EDATA; 171984865Sobrien else if (strcmp (name, "_end") == 0) 172094536Sobrien i = XCOFF_SPECIAL_SECTION_END; 172184865Sobrien } 172284865Sobrien else if (name[0] == 'e' && strcmp (name, "end") == 0) 172394536Sobrien { 172494536Sobrien i = XCOFF_SPECIAL_SECTION_END2; 172594536Sobrien } 172684865Sobrien 172784865Sobrien if (i != -1) 172894536Sobrien { 172994536Sobrien xcoff_hash_table (info)->special_sections[i] = csect; 173094536Sobrien } 173184865Sobrien } 173284865Sobrien 173384865Sobrien /* Now we have enough information to add the symbol to the 1734130561Sobrien linker hash table. */ 173584865Sobrien 173684865Sobrien if (sym.n_sclass == C_EXT) 173784865Sobrien { 1738130561Sobrien bfd_boolean copy; 173984865Sobrien 174084865Sobrien BFD_ASSERT (section != NULL); 174184865Sobrien 174284865Sobrien /* We must copy the name into memory if we got it from the 1743130561Sobrien syment itself, rather than the string table. */ 174484865Sobrien copy = default_copy; 174584865Sobrien if (sym._n._n_n._n_zeroes != 0 174684865Sobrien || sym._n._n_n._n_offset == 0) 1747130561Sobrien copy = TRUE; 174884865Sobrien 174984865Sobrien /* The AIX linker appears to only detect multiple symbol 175084865Sobrien definitions when there is a reference to the symbol. If 175184865Sobrien a symbol is defined multiple times, and the only 175284865Sobrien references are from the same object file, the AIX linker 175384865Sobrien appears to permit it. It does not merge the different 175484865Sobrien definitions, but handles them independently. On the 175584865Sobrien other hand, if there is a reference, the linker reports 175684865Sobrien an error. 175784865Sobrien 175884865Sobrien This matters because the AIX <net/net_globals.h> header 175984865Sobrien file actually defines an initialized array, so we have to 176084865Sobrien actually permit that to work. 176184865Sobrien 176284865Sobrien Just to make matters even more confusing, the AIX linker 176384865Sobrien appears to permit multiple symbol definitions whenever 176484865Sobrien the second definition is in an archive rather than an 176584865Sobrien object file. This may be a consequence of the manner in 176684865Sobrien which it handles archives: I think it may load the entire 176784865Sobrien archive in as separate csects, and then let garbage 176884865Sobrien collection discard symbols. 176984865Sobrien 177084865Sobrien We also have to handle the case of statically linking a 177184865Sobrien shared object, which will cause symbol redefinitions, 177284865Sobrien although this is an easier case to detect. */ 177384865Sobrien 177494536Sobrien if (info->hash->creator == abfd->xvec) 177584865Sobrien { 177684865Sobrien if (! bfd_is_und_section (section)) 1777104834Sobrien { 1778104834Sobrien *sym_hash = xcoff_link_hash_lookup (xcoff_hash_table (info), 1779130561Sobrien name, TRUE, copy, FALSE); 1780104834Sobrien } 178184865Sobrien else 1782104834Sobrien { 1783104834Sobrien /* Make a copy of the symbol name to prevent problems with 1784104834Sobrien merging symbols. */ 1785104834Sobrien *sym_hash = ((struct xcoff_link_hash_entry *) 1786104834Sobrien bfd_wrapped_link_hash_lookup (abfd, info, name, 1787130561Sobrien TRUE, TRUE, 1788130561Sobrien FALSE)); 1789104834Sobrien } 179084865Sobrien if (*sym_hash == NULL) 179184865Sobrien goto error_return; 179284865Sobrien if (((*sym_hash)->root.type == bfd_link_hash_defined 179384865Sobrien || (*sym_hash)->root.type == bfd_link_hash_defweak) 179484865Sobrien && ! bfd_is_und_section (section) 179584865Sobrien && ! bfd_is_com_section (section)) 179684865Sobrien { 179784865Sobrien /* This is a second definition of a defined symbol. */ 179884865Sobrien if ((abfd->flags & DYNAMIC) != 0 179984865Sobrien && ((*sym_hash)->smclas != XMC_GL 180084865Sobrien || aux.x_csect.x_smclas == XMC_GL 180184865Sobrien || ((*sym_hash)->root.u.def.section->owner->flags 180284865Sobrien & DYNAMIC) == 0)) 180384865Sobrien { 180484865Sobrien /* The new symbol is from a shared library, and 1805130561Sobrien either the existing symbol is not global 1806130561Sobrien linkage code or this symbol is global linkage 1807130561Sobrien code. If the existing symbol is global 1808130561Sobrien linkage code and the new symbol is not, then 1809130561Sobrien we want to use the new symbol. */ 181084865Sobrien section = bfd_und_section_ptr; 181184865Sobrien value = 0; 181284865Sobrien } 181384865Sobrien else if (((*sym_hash)->root.u.def.section->owner->flags 181484865Sobrien & DYNAMIC) != 0) 181584865Sobrien { 181684865Sobrien /* The existing symbol is from a shared library. 1817130561Sobrien Replace it. */ 181884865Sobrien (*sym_hash)->root.type = bfd_link_hash_undefined; 181984865Sobrien (*sym_hash)->root.u.undef.abfd = 182084865Sobrien (*sym_hash)->root.u.def.section->owner; 182184865Sobrien } 182284865Sobrien else if (abfd->my_archive != NULL) 182384865Sobrien { 182484865Sobrien /* This is a redefinition in an object contained 1825130561Sobrien in an archive. Just ignore it. See the 1826130561Sobrien comment above. */ 182784865Sobrien section = bfd_und_section_ptr; 182884865Sobrien value = 0; 182984865Sobrien } 1830130561Sobrien else if ((*sym_hash)->root.und_next != NULL 183184865Sobrien || info->hash->undefs_tail == &(*sym_hash)->root) 183284865Sobrien { 183384865Sobrien /* This symbol has been referenced. In this 1834130561Sobrien case, we just continue and permit the 1835130561Sobrien multiple definition error. See the comment 1836130561Sobrien above about the behaviour of the AIX linker. */ 183784865Sobrien } 183884865Sobrien else if ((*sym_hash)->smclas == aux.x_csect.x_smclas) 183984865Sobrien { 184084865Sobrien /* The symbols are both csects of the same 1841130561Sobrien class. There is at least a chance that this 1842130561Sobrien is a semi-legitimate redefinition. */ 184384865Sobrien section = bfd_und_section_ptr; 184484865Sobrien value = 0; 184584865Sobrien (*sym_hash)->flags |= XCOFF_MULTIPLY_DEFINED; 184684865Sobrien } 184784865Sobrien } 184884865Sobrien else if (((*sym_hash)->flags & XCOFF_MULTIPLY_DEFINED) != 0 184984865Sobrien && ((*sym_hash)->root.type == bfd_link_hash_defined 185084865Sobrien || (*sym_hash)->root.type == bfd_link_hash_defweak) 185184865Sobrien && (bfd_is_und_section (section) 185284865Sobrien || bfd_is_com_section (section))) 185384865Sobrien { 185484865Sobrien /* This is a reference to a multiply defined symbol. 185584865Sobrien Report the error now. See the comment above 185684865Sobrien about the behaviour of the AIX linker. We could 185784865Sobrien also do this with warning symbols, but I'm not 185884865Sobrien sure the XCOFF linker is wholly prepared to 185984865Sobrien handle them, and that would only be a warning, 186084865Sobrien not an error. */ 186184865Sobrien if (! ((*info->callbacks->multiple_definition) 186284865Sobrien (info, (*sym_hash)->root.root.string, 186394536Sobrien (bfd *) NULL, (asection *) NULL, (bfd_vma) 0, 186484865Sobrien (*sym_hash)->root.u.def.section->owner, 186584865Sobrien (*sym_hash)->root.u.def.section, 186684865Sobrien (*sym_hash)->root.u.def.value))) 186784865Sobrien goto error_return; 186884865Sobrien /* Try not to give this error too many times. */ 186984865Sobrien (*sym_hash)->flags &= ~XCOFF_MULTIPLY_DEFINED; 187084865Sobrien } 187184865Sobrien } 187284865Sobrien 187384865Sobrien /* _bfd_generic_link_add_one_symbol may call the linker to 187484865Sobrien generate an error message, and the linker may try to read 187584865Sobrien the symbol table to give a good error. Right now, the 187684865Sobrien line numbers are in an inconsistent state, since they are 187784865Sobrien counted both in the real sections and in the new csects. 187884865Sobrien We need to leave the count in the real sections so that 187984865Sobrien the linker can report the line number of the error 188084865Sobrien correctly, so temporarily clobber the link to the csects 188184865Sobrien so that the linker will not try to read the line numbers 188284865Sobrien a second time from the csects. */ 188384865Sobrien BFD_ASSERT (last_real->next == first_csect); 188484865Sobrien last_real->next = NULL; 188584865Sobrien if (! (_bfd_generic_link_add_one_symbol 188684865Sobrien (info, abfd, name, flags, section, value, 1887130561Sobrien (const char *) NULL, copy, TRUE, 188884865Sobrien (struct bfd_link_hash_entry **) sym_hash))) 188984865Sobrien goto error_return; 189084865Sobrien last_real->next = first_csect; 189184865Sobrien 189284865Sobrien if (smtyp == XTY_CM) 189384865Sobrien { 189484865Sobrien if ((*sym_hash)->root.type != bfd_link_hash_common 189584865Sobrien || (*sym_hash)->root.u.c.p->section != csect) 189684865Sobrien { 189784865Sobrien /* We don't need the common csect we just created. */ 189884865Sobrien csect->_raw_size = 0; 189984865Sobrien } 190084865Sobrien else 190184865Sobrien { 190284865Sobrien (*sym_hash)->root.u.c.p->alignment_power 190384865Sobrien = csect->alignment_power; 190484865Sobrien } 190584865Sobrien } 190684865Sobrien 190794536Sobrien if (info->hash->creator == abfd->xvec) 190884865Sobrien { 190984865Sobrien int flag; 191084865Sobrien 191184865Sobrien if (smtyp == XTY_ER || smtyp == XTY_CM) 191284865Sobrien flag = XCOFF_REF_REGULAR; 191384865Sobrien else 191484865Sobrien flag = XCOFF_DEF_REGULAR; 191584865Sobrien (*sym_hash)->flags |= flag; 191684865Sobrien 191784865Sobrien if ((*sym_hash)->smclas == XMC_UA 191884865Sobrien || flag == XCOFF_DEF_REGULAR) 191984865Sobrien (*sym_hash)->smclas = aux.x_csect.x_smclas; 192084865Sobrien } 192184865Sobrien } 192284865Sobrien 192384865Sobrien *csect_cache = csect; 192484865Sobrien 192584865Sobrien esym += (sym.n_numaux + 1) * symesz; 192684865Sobrien sym_hash += sym.n_numaux + 1; 192784865Sobrien csect_cache += sym.n_numaux + 1; 192884865Sobrien } 192984865Sobrien 193084865Sobrien BFD_ASSERT (last_real == NULL || last_real->next == first_csect); 193184865Sobrien 193284865Sobrien /* Make sure that we have seen all the relocs. */ 193384865Sobrien for (o = abfd->sections; o != first_csect; o = o->next) 193484865Sobrien { 193584865Sobrien /* Reset the section size and the line number count, since the 193684865Sobrien data is now attached to the csects. Don't reset the size of 193784865Sobrien the .debug section, since we need to read it below in 193884865Sobrien bfd_xcoff_size_dynamic_sections. */ 193984865Sobrien if (strcmp (bfd_get_section_name (abfd, o), ".debug") != 0) 194084865Sobrien o->_raw_size = 0; 194184865Sobrien o->lineno_count = 0; 194284865Sobrien 194384865Sobrien if ((o->flags & SEC_RELOC) != 0) 194484865Sobrien { 194584865Sobrien bfd_size_type i; 194684865Sobrien struct internal_reloc *rel; 194784865Sobrien asection **rel_csect; 194884865Sobrien 194984865Sobrien rel = reloc_info[o->target_index].relocs; 195084865Sobrien rel_csect = reloc_info[o->target_index].csects; 195194536Sobrien 195284865Sobrien for (i = 0; i < o->reloc_count; i++, rel++, rel_csect++) 195384865Sobrien { 195494536Sobrien 195584865Sobrien if (*rel_csect == NULL) 195684865Sobrien { 195784865Sobrien (*_bfd_error_handler) 195884865Sobrien (_("%s: reloc %s:%d not in csect"), 195994536Sobrien bfd_archive_filename (abfd), o->name, i); 196084865Sobrien bfd_set_error (bfd_error_bad_value); 196184865Sobrien goto error_return; 196284865Sobrien } 196384865Sobrien 196484865Sobrien /* We identify all symbols which are called, so that we 196584865Sobrien can create glue code for calls to functions imported 196684865Sobrien from dynamic objects. */ 196794536Sobrien if (info->hash->creator == abfd->xvec 196884865Sobrien && *rel_csect != bfd_und_section_ptr 196984865Sobrien && (rel->r_type == R_BR 197084865Sobrien || rel->r_type == R_RBR) 197184865Sobrien && obj_xcoff_sym_hashes (abfd)[rel->r_symndx] != NULL) 197284865Sobrien { 197384865Sobrien struct xcoff_link_hash_entry *h; 197484865Sobrien 197584865Sobrien h = obj_xcoff_sym_hashes (abfd)[rel->r_symndx]; 197684865Sobrien h->flags |= XCOFF_CALLED; 197784865Sobrien /* If the symbol name starts with a period, it is 1978130561Sobrien the code of a function. If the symbol is 1979130561Sobrien currently undefined, then add an undefined symbol 1980130561Sobrien for the function descriptor. This should do no 1981130561Sobrien harm, because any regular object that defines the 1982130561Sobrien function should also define the function 1983130561Sobrien descriptor. It helps, because it means that we 1984130561Sobrien will identify the function descriptor with a 1985130561Sobrien dynamic object if a dynamic object defines it. */ 198684865Sobrien if (h->root.root.string[0] == '.' 198784865Sobrien && h->descriptor == NULL) 198884865Sobrien { 198984865Sobrien struct xcoff_link_hash_entry *hds; 1990107492Sobrien struct bfd_link_hash_entry *bh; 199184865Sobrien 199284865Sobrien hds = xcoff_link_hash_lookup (xcoff_hash_table (info), 199384865Sobrien h->root.root.string + 1, 1994130561Sobrien TRUE, FALSE, TRUE); 199584865Sobrien if (hds == NULL) 199684865Sobrien goto error_return; 199784865Sobrien if (hds->root.type == bfd_link_hash_new) 199884865Sobrien { 1999107492Sobrien bh = &hds->root; 200084865Sobrien if (! (_bfd_generic_link_add_one_symbol 200184865Sobrien (info, abfd, hds->root.root.string, 200284865Sobrien (flagword) 0, bfd_und_section_ptr, 2003130561Sobrien (bfd_vma) 0, (const char *) NULL, FALSE, 2004130561Sobrien TRUE, &bh))) 200584865Sobrien goto error_return; 2006107492Sobrien hds = (struct xcoff_link_hash_entry *) bh; 200784865Sobrien } 200884865Sobrien hds->flags |= XCOFF_DESCRIPTOR; 200984865Sobrien BFD_ASSERT ((hds->flags & XCOFF_CALLED) == 0 201084865Sobrien && (h->flags & XCOFF_DESCRIPTOR) == 0); 201184865Sobrien hds->descriptor = h; 201284865Sobrien h->descriptor = hds; 201384865Sobrien } 201484865Sobrien } 201584865Sobrien } 201684865Sobrien 201784865Sobrien free (reloc_info[o->target_index].csects); 201884865Sobrien reloc_info[o->target_index].csects = NULL; 201984865Sobrien 202084865Sobrien /* Reset SEC_RELOC and the reloc_count, since the reloc 202184865Sobrien information is now attached to the csects. */ 202294536Sobrien o->flags &=~ SEC_RELOC; 202384865Sobrien o->reloc_count = 0; 202484865Sobrien 202584865Sobrien /* If we are not keeping memory, free the reloc information. */ 202684865Sobrien if (! info->keep_memory 202784865Sobrien && coff_section_data (abfd, o) != NULL 202884865Sobrien && coff_section_data (abfd, o)->relocs != NULL 202984865Sobrien && ! coff_section_data (abfd, o)->keep_relocs) 203084865Sobrien { 203184865Sobrien free (coff_section_data (abfd, o)->relocs); 203284865Sobrien coff_section_data (abfd, o)->relocs = NULL; 203384865Sobrien } 203484865Sobrien } 203584865Sobrien 203684865Sobrien /* Free up the line numbers. FIXME: We could cache these 2037130561Sobrien somewhere for the final link, to avoid reading them again. */ 203884865Sobrien if (reloc_info[o->target_index].linenos != NULL) 203984865Sobrien { 204084865Sobrien free (reloc_info[o->target_index].linenos); 204184865Sobrien reloc_info[o->target_index].linenos = NULL; 204284865Sobrien } 204384865Sobrien } 204484865Sobrien 204584865Sobrien free (reloc_info); 204684865Sobrien 204784865Sobrien obj_coff_keep_syms (abfd) = keep_syms; 204884865Sobrien 2049130561Sobrien return TRUE; 205084865Sobrien 205184865Sobrien error_return: 205284865Sobrien if (reloc_info != NULL) 205384865Sobrien { 205484865Sobrien for (o = abfd->sections; o != NULL; o = o->next) 205584865Sobrien { 205684865Sobrien if (reloc_info[o->target_index].csects != NULL) 205784865Sobrien free (reloc_info[o->target_index].csects); 205884865Sobrien if (reloc_info[o->target_index].linenos != NULL) 205984865Sobrien free (reloc_info[o->target_index].linenos); 206084865Sobrien } 206194536Sobrien free (reloc_info); 206284865Sobrien } 206384865Sobrien obj_coff_keep_syms (abfd) = keep_syms; 2064130561Sobrien return FALSE; 206584865Sobrien} 206684865Sobrien 206784865Sobrien#undef N_TMASK 206884865Sobrien#undef N_BTSHFT 206984865Sobrien 207084865Sobrien/* This function is used to add symbols from a dynamic object to the 207184865Sobrien global symbol table. */ 207284865Sobrien 2073130561Sobrienstatic bfd_boolean 207484865Sobrienxcoff_link_add_dynamic_symbols (abfd, info) 207584865Sobrien bfd *abfd; 207684865Sobrien struct bfd_link_info *info; 207784865Sobrien{ 207884865Sobrien asection *lsec; 207994536Sobrien bfd_byte *contents; 208084865Sobrien struct internal_ldhdr ldhdr; 208184865Sobrien const char *strings; 208294536Sobrien bfd_byte *elsym, *elsymend; 208384865Sobrien struct xcoff_import_file *n; 208484865Sobrien const char *bname; 208584865Sobrien const char *mname; 208684865Sobrien const char *s; 208784865Sobrien unsigned int c; 208884865Sobrien struct xcoff_import_file **pp; 208984865Sobrien 209084865Sobrien /* We can only handle a dynamic object if we are generating an XCOFF 209184865Sobrien output file. */ 209294536Sobrien if (info->hash->creator != abfd->xvec) 209384865Sobrien { 209484865Sobrien (*_bfd_error_handler) 209584865Sobrien (_("%s: XCOFF shared object when not producing XCOFF output"), 209684865Sobrien bfd_get_filename (abfd)); 209784865Sobrien bfd_set_error (bfd_error_invalid_operation); 2098130561Sobrien return FALSE; 209984865Sobrien } 210084865Sobrien 210184865Sobrien /* The symbols we use from a dynamic object are not the symbols in 210284865Sobrien the normal symbol table, but, rather, the symbols in the export 210384865Sobrien table. If there is a global symbol in a dynamic object which is 210484865Sobrien not in the export table, the loader will not be able to find it, 210584865Sobrien so we don't want to find it either. Also, on AIX 4.1.3, shr.o in 210684865Sobrien libc.a has symbols in the export table which are not in the 210784865Sobrien symbol table. */ 210884865Sobrien 210984865Sobrien /* Read in the .loader section. FIXME: We should really use the 211084865Sobrien o_snloader field in the a.out header, rather than grabbing the 211184865Sobrien section by name. */ 211284865Sobrien lsec = bfd_get_section_by_name (abfd, ".loader"); 211384865Sobrien if (lsec == NULL) 211484865Sobrien { 211584865Sobrien (*_bfd_error_handler) 211684865Sobrien (_("%s: dynamic object with no .loader section"), 211784865Sobrien bfd_get_filename (abfd)); 211884865Sobrien bfd_set_error (bfd_error_no_symbols); 2119130561Sobrien return FALSE; 212084865Sobrien } 212184865Sobrien 212294536Sobrien 212384865Sobrien if (! xcoff_get_section_contents (abfd, lsec)) 2124130561Sobrien return FALSE; 212594536Sobrien contents = coff_section_data (abfd, lsec)->contents; 212684865Sobrien 212784865Sobrien /* Remove the sections from this object, so that they do not get 212884865Sobrien included in the link. */ 212999461Sobrien bfd_section_list_clear (abfd); 213084865Sobrien 213194536Sobrien bfd_xcoff_swap_ldhdr_in (abfd, contents, &ldhdr); 213284865Sobrien 213394536Sobrien strings = (char *) contents + ldhdr.l_stoff; 213484865Sobrien 213594536Sobrien elsym = contents + bfd_xcoff_loader_symbol_offset(abfd, &ldhdr); 213694536Sobrien 213794536Sobrien elsymend = elsym + ldhdr.l_nsyms * bfd_xcoff_ldsymsz(abfd); 213894536Sobrien 213994536Sobrien for (; elsym < elsymend; elsym += bfd_xcoff_ldsymsz(abfd)) 214084865Sobrien { 214184865Sobrien struct internal_ldsym ldsym; 214284865Sobrien char nambuf[SYMNMLEN + 1]; 214384865Sobrien const char *name; 214484865Sobrien struct xcoff_link_hash_entry *h; 214584865Sobrien 214694536Sobrien bfd_xcoff_swap_ldsym_in (abfd, elsym, &ldsym); 214784865Sobrien 214884865Sobrien /* We are only interested in exported symbols. */ 214984865Sobrien if ((ldsym.l_smtype & L_EXPORT) == 0) 215084865Sobrien continue; 215184865Sobrien 215284865Sobrien if (ldsym._l._l_l._l_zeroes == 0) 215384865Sobrien name = strings + ldsym._l._l_l._l_offset; 215484865Sobrien else 215584865Sobrien { 215684865Sobrien memcpy (nambuf, ldsym._l._l_name, SYMNMLEN); 215784865Sobrien nambuf[SYMNMLEN] = '\0'; 215884865Sobrien name = nambuf; 215984865Sobrien } 216084865Sobrien 216184865Sobrien /* Normally we could not call xcoff_link_hash_lookup in an add 216284865Sobrien symbols routine, since we might not be using an XCOFF hash 216384865Sobrien table. However, we verified above that we are using an XCOFF 216484865Sobrien hash table. */ 216584865Sobrien 2166130561Sobrien h = xcoff_link_hash_lookup (xcoff_hash_table (info), name, TRUE, 2167130561Sobrien TRUE, TRUE); 216884865Sobrien if (h == NULL) 2169130561Sobrien return FALSE; 217084865Sobrien 217184865Sobrien h->flags |= XCOFF_DEF_DYNAMIC; 217284865Sobrien 217384865Sobrien /* If the symbol is undefined, and the BFD it was found in is 217484865Sobrien not a dynamic object, change the BFD to this dynamic object, 217584865Sobrien so that we can get the correct import file ID. */ 217684865Sobrien if ((h->root.type == bfd_link_hash_undefined 217784865Sobrien || h->root.type == bfd_link_hash_undefweak) 217884865Sobrien && (h->root.u.undef.abfd == NULL 217984865Sobrien || (h->root.u.undef.abfd->flags & DYNAMIC) == 0)) 218084865Sobrien h->root.u.undef.abfd = abfd; 218184865Sobrien 218284865Sobrien if (h->root.type == bfd_link_hash_new) 218384865Sobrien { 218484865Sobrien h->root.type = bfd_link_hash_undefined; 218584865Sobrien h->root.u.undef.abfd = abfd; 218684865Sobrien /* We do not want to add this to the undefined symbol list. */ 218784865Sobrien } 218884865Sobrien 218984865Sobrien if (h->smclas == XMC_UA 219084865Sobrien || h->root.type == bfd_link_hash_undefined 219184865Sobrien || h->root.type == bfd_link_hash_undefweak) 219284865Sobrien h->smclas = ldsym.l_smclas; 219384865Sobrien 219484865Sobrien /* Unless this is an XMC_XO symbol, we don't bother to actually 2195130561Sobrien define it, since we don't have a section to put it in anyhow. 2196130561Sobrien Instead, the relocation routines handle the DEF_DYNAMIC flag 2197130561Sobrien correctly. */ 219884865Sobrien 219984865Sobrien if (h->smclas == XMC_XO 220084865Sobrien && (h->root.type == bfd_link_hash_undefined 220184865Sobrien || h->root.type == bfd_link_hash_undefweak)) 220284865Sobrien { 220384865Sobrien /* This symbol has an absolute value. */ 220484865Sobrien h->root.type = bfd_link_hash_defined; 220584865Sobrien h->root.u.def.section = bfd_abs_section_ptr; 220684865Sobrien h->root.u.def.value = ldsym.l_value; 220784865Sobrien } 220884865Sobrien 220984865Sobrien /* If this symbol defines a function descriptor, then it 221084865Sobrien implicitly defines the function code as well. */ 221184865Sobrien if (h->smclas == XMC_DS 221284865Sobrien || (h->smclas == XMC_XO && name[0] != '.')) 221384865Sobrien h->flags |= XCOFF_DESCRIPTOR; 221484865Sobrien if ((h->flags & XCOFF_DESCRIPTOR) != 0) 221584865Sobrien { 221684865Sobrien struct xcoff_link_hash_entry *hds; 221784865Sobrien 221884865Sobrien hds = h->descriptor; 221984865Sobrien if (hds == NULL) 222084865Sobrien { 222184865Sobrien char *dsnm; 222284865Sobrien 222394536Sobrien dsnm = bfd_malloc ((bfd_size_type) strlen (name) + 2); 222484865Sobrien if (dsnm == NULL) 2225130561Sobrien return FALSE; 222684865Sobrien dsnm[0] = '.'; 222784865Sobrien strcpy (dsnm + 1, name); 222884865Sobrien hds = xcoff_link_hash_lookup (xcoff_hash_table (info), dsnm, 2229130561Sobrien TRUE, TRUE, TRUE); 223084865Sobrien free (dsnm); 223184865Sobrien if (hds == NULL) 2232130561Sobrien return FALSE; 223384865Sobrien 223484865Sobrien if (hds->root.type == bfd_link_hash_new) 223584865Sobrien { 223684865Sobrien hds->root.type = bfd_link_hash_undefined; 223784865Sobrien hds->root.u.undef.abfd = abfd; 223884865Sobrien /* We do not want to add this to the undefined 2239130561Sobrien symbol list. */ 224084865Sobrien } 224184865Sobrien 224284865Sobrien hds->descriptor = h; 224384865Sobrien h->descriptor = hds; 224484865Sobrien } 224584865Sobrien 224684865Sobrien hds->flags |= XCOFF_DEF_DYNAMIC; 224784865Sobrien if (hds->smclas == XMC_UA) 224884865Sobrien hds->smclas = XMC_PR; 224984865Sobrien 225084865Sobrien /* An absolute symbol appears to actually define code, not a 225184865Sobrien function descriptor. This is how some math functions are 225284865Sobrien implemented on AIX 4.1. */ 225384865Sobrien if (h->smclas == XMC_XO 225484865Sobrien && (hds->root.type == bfd_link_hash_undefined 225584865Sobrien || hds->root.type == bfd_link_hash_undefweak)) 225684865Sobrien { 225784865Sobrien hds->smclas = XMC_XO; 225884865Sobrien hds->root.type = bfd_link_hash_defined; 225984865Sobrien hds->root.u.def.section = bfd_abs_section_ptr; 226084865Sobrien hds->root.u.def.value = ldsym.l_value; 226184865Sobrien } 226284865Sobrien } 226384865Sobrien } 226484865Sobrien 226594536Sobrien if (contents != NULL && ! coff_section_data (abfd, lsec)->keep_contents) 226684865Sobrien { 226784865Sobrien free (coff_section_data (abfd, lsec)->contents); 226884865Sobrien coff_section_data (abfd, lsec)->contents = NULL; 226984865Sobrien } 227084865Sobrien 227184865Sobrien /* Record this file in the import files. */ 227284865Sobrien 227384865Sobrien n = ((struct xcoff_import_file *) 227494536Sobrien bfd_alloc (abfd, (bfd_size_type) sizeof (struct xcoff_import_file))); 227584865Sobrien if (n == NULL) 2276130561Sobrien return FALSE; 227784865Sobrien n->next = NULL; 227884865Sobrien 227984865Sobrien /* For some reason, the path entry in the import file list for a 228084865Sobrien shared object appears to always be empty. The file name is the 228184865Sobrien base name. */ 228284865Sobrien n->path = ""; 228384865Sobrien if (abfd->my_archive == NULL) 228484865Sobrien { 228584865Sobrien bname = bfd_get_filename (abfd); 228684865Sobrien mname = ""; 228784865Sobrien } 228884865Sobrien else 228984865Sobrien { 229084865Sobrien bname = bfd_get_filename (abfd->my_archive); 229184865Sobrien mname = bfd_get_filename (abfd); 229284865Sobrien } 229384865Sobrien s = strrchr (bname, '/'); 229484865Sobrien if (s != NULL) 229584865Sobrien bname = s + 1; 229684865Sobrien n->file = bname; 229784865Sobrien n->member = mname; 229884865Sobrien 229984865Sobrien /* We start c at 1 because the first import file number is reserved 230084865Sobrien for LIBPATH. */ 230184865Sobrien for (pp = &xcoff_hash_table (info)->imports, c = 1; 230284865Sobrien *pp != NULL; 230384865Sobrien pp = &(*pp)->next, ++c) 230484865Sobrien ; 230584865Sobrien *pp = n; 230684865Sobrien 230784865Sobrien xcoff_data (abfd)->import_file_id = c; 230884865Sobrien 2309130561Sobrien return TRUE; 231084865Sobrien} 231184865Sobrien 231284865Sobrien/* Routines that are called after all the input files have been 231384865Sobrien handled, but before the sections are laid out in memory. */ 231484865Sobrien 231584865Sobrien/* Mark a symbol as not being garbage, including the section in which 231684865Sobrien it is defined. */ 231784865Sobrien 2318130561Sobrienstatic INLINE bfd_boolean 231984865Sobrienxcoff_mark_symbol (info, h) 232084865Sobrien struct bfd_link_info *info; 232184865Sobrien struct xcoff_link_hash_entry *h; 232284865Sobrien{ 232394536Sobrien 232484865Sobrien if ((h->flags & XCOFF_MARK) != 0) 2325130561Sobrien return TRUE; 232684865Sobrien 232784865Sobrien h->flags |= XCOFF_MARK; 232884865Sobrien if (h->root.type == bfd_link_hash_defined 232984865Sobrien || h->root.type == bfd_link_hash_defweak) 233084865Sobrien { 233184865Sobrien asection *hsec; 233284865Sobrien 233384865Sobrien hsec = h->root.u.def.section; 233484865Sobrien if (! bfd_is_abs_section (hsec) 233584865Sobrien && (hsec->flags & SEC_MARK) == 0) 233684865Sobrien { 233784865Sobrien if (! xcoff_mark (info, hsec)) 2338130561Sobrien return FALSE; 233984865Sobrien } 234084865Sobrien } 234184865Sobrien 234284865Sobrien if (h->toc_section != NULL 234384865Sobrien && (h->toc_section->flags & SEC_MARK) == 0) 234484865Sobrien { 234584865Sobrien if (! xcoff_mark (info, h->toc_section)) 2346130561Sobrien return FALSE; 234784865Sobrien } 234884865Sobrien 2349130561Sobrien return TRUE; 235084865Sobrien} 235184865Sobrien 235284865Sobrien/* The mark phase of garbage collection. For a given section, mark 235384865Sobrien it, and all the sections which define symbols to which it refers. 235484865Sobrien Because this function needs to look at the relocs, we also count 235584865Sobrien the number of relocs which need to be copied into the .loader 235684865Sobrien section. */ 235784865Sobrien 2358130561Sobrienstatic bfd_boolean 235984865Sobrienxcoff_mark (info, sec) 236084865Sobrien struct bfd_link_info *info; 236184865Sobrien asection *sec; 236284865Sobrien{ 236384865Sobrien if (bfd_is_abs_section (sec) 236484865Sobrien || (sec->flags & SEC_MARK) != 0) 2365130561Sobrien return TRUE; 236684865Sobrien 236784865Sobrien sec->flags |= SEC_MARK; 236884865Sobrien 236984865Sobrien if (sec->owner->xvec == info->hash->creator 237084865Sobrien && coff_section_data (sec->owner, sec) != NULL 237184865Sobrien && xcoff_section_data (sec->owner, sec) != NULL) 237284865Sobrien { 237384865Sobrien register struct xcoff_link_hash_entry **hp, **hpend; 237484865Sobrien struct internal_reloc *rel, *relend; 237584865Sobrien 237684865Sobrien /* Mark all the symbols in this section. */ 237784865Sobrien 237884865Sobrien hp = (obj_xcoff_sym_hashes (sec->owner) 237984865Sobrien + xcoff_section_data (sec->owner, sec)->first_symndx); 238084865Sobrien hpend = (obj_xcoff_sym_hashes (sec->owner) 238184865Sobrien + xcoff_section_data (sec->owner, sec)->last_symndx); 238284865Sobrien for (; hp < hpend; hp++) 238384865Sobrien { 238484865Sobrien register struct xcoff_link_hash_entry *h; 238584865Sobrien 238684865Sobrien h = *hp; 238784865Sobrien if (h != NULL 238884865Sobrien && (h->flags & XCOFF_MARK) == 0) 238984865Sobrien { 239084865Sobrien if (! xcoff_mark_symbol (info, h)) 2391130561Sobrien return FALSE; 239284865Sobrien } 239384865Sobrien } 239484865Sobrien 239584865Sobrien /* Look through the section relocs. */ 239684865Sobrien 239784865Sobrien if ((sec->flags & SEC_RELOC) != 0 239884865Sobrien && sec->reloc_count > 0) 239984865Sobrien { 2400130561Sobrien rel = xcoff_read_internal_relocs (sec->owner, sec, TRUE, 2401130561Sobrien (bfd_byte *) NULL, FALSE, 240284865Sobrien (struct internal_reloc *) NULL); 240384865Sobrien if (rel == NULL) 2404130561Sobrien return FALSE; 240584865Sobrien relend = rel + sec->reloc_count; 240684865Sobrien for (; rel < relend; rel++) 240784865Sobrien { 240884865Sobrien asection *rsec; 240984865Sobrien struct xcoff_link_hash_entry *h; 241084865Sobrien 241184865Sobrien if ((unsigned int) rel->r_symndx 241284865Sobrien > obj_raw_syment_count (sec->owner)) 241384865Sobrien continue; 241484865Sobrien 241584865Sobrien h = obj_xcoff_sym_hashes (sec->owner)[rel->r_symndx]; 241684865Sobrien if (h != NULL 241784865Sobrien && (h->flags & XCOFF_MARK) == 0) 241884865Sobrien { 241984865Sobrien if (! xcoff_mark_symbol (info, h)) 2420130561Sobrien return FALSE; 242184865Sobrien } 242284865Sobrien 242384865Sobrien rsec = xcoff_data (sec->owner)->csects[rel->r_symndx]; 242484865Sobrien if (rsec != NULL 242584865Sobrien && (rsec->flags & SEC_MARK) == 0) 242684865Sobrien { 242784865Sobrien if (! xcoff_mark (info, rsec)) 2428130561Sobrien return FALSE; 242984865Sobrien } 243084865Sobrien 243184865Sobrien /* See if this reloc needs to be copied into the .loader 2432130561Sobrien section. */ 243384865Sobrien switch (rel->r_type) 243484865Sobrien { 243584865Sobrien default: 243684865Sobrien if (h == NULL 243784865Sobrien || h->root.type == bfd_link_hash_defined 243884865Sobrien || h->root.type == bfd_link_hash_defweak 243984865Sobrien || h->root.type == bfd_link_hash_common 244084865Sobrien || ((h->flags & XCOFF_CALLED) != 0 244184865Sobrien && (h->root.type == bfd_link_hash_undefined 244284865Sobrien || h->root.type == bfd_link_hash_undefweak) 244384865Sobrien && h->root.root.string[0] == '.' 244484865Sobrien && h->descriptor != NULL 244584865Sobrien && ((h->descriptor->flags & XCOFF_DEF_DYNAMIC) != 0 244684865Sobrien || ((h->descriptor->flags & XCOFF_IMPORT) != 0 244784865Sobrien && (h->descriptor->flags 244884865Sobrien & XCOFF_DEF_REGULAR) == 0)))) 244984865Sobrien break; 245084865Sobrien /* Fall through. */ 245184865Sobrien case R_POS: 245284865Sobrien case R_NEG: 245384865Sobrien case R_RL: 245484865Sobrien case R_RLA: 245584865Sobrien ++xcoff_hash_table (info)->ldrel_count; 245684865Sobrien if (h != NULL) 245784865Sobrien h->flags |= XCOFF_LDREL; 245884865Sobrien break; 245984865Sobrien case R_TOC: 246084865Sobrien case R_GL: 246184865Sobrien case R_TCL: 246284865Sobrien case R_TRL: 246384865Sobrien case R_TRLA: 246484865Sobrien /* We should never need a .loader reloc for a TOC 246584865Sobrien relative reloc. */ 246684865Sobrien break; 246784865Sobrien } 246884865Sobrien } 246984865Sobrien 247084865Sobrien if (! info->keep_memory 247184865Sobrien && coff_section_data (sec->owner, sec) != NULL 247284865Sobrien && coff_section_data (sec->owner, sec)->relocs != NULL 247384865Sobrien && ! coff_section_data (sec->owner, sec)->keep_relocs) 247484865Sobrien { 247584865Sobrien free (coff_section_data (sec->owner, sec)->relocs); 247684865Sobrien coff_section_data (sec->owner, sec)->relocs = NULL; 247784865Sobrien } 247884865Sobrien } 247984865Sobrien } 248084865Sobrien 2481130561Sobrien return TRUE; 248284865Sobrien} 248384865Sobrien 248484865Sobrien/* The sweep phase of garbage collection. Remove all garbage 248584865Sobrien sections. */ 248684865Sobrien 248784865Sobrienstatic void 248884865Sobrienxcoff_sweep (info) 248984865Sobrien struct bfd_link_info *info; 249084865Sobrien{ 249184865Sobrien bfd *sub; 249284865Sobrien 249384865Sobrien for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) 249484865Sobrien { 249584865Sobrien asection *o; 249684865Sobrien 249784865Sobrien for (o = sub->sections; o != NULL; o = o->next) 249884865Sobrien { 249984865Sobrien if ((o->flags & SEC_MARK) == 0) 250084865Sobrien { 250184865Sobrien /* Keep all sections from non-XCOFF input files. Keep 2502130561Sobrien special sections. Keep .debug sections for the 2503130561Sobrien moment. */ 250484865Sobrien if (sub->xvec != info->hash->creator 250584865Sobrien || o == xcoff_hash_table (info)->debug_section 250684865Sobrien || o == xcoff_hash_table (info)->loader_section 250784865Sobrien || o == xcoff_hash_table (info)->linkage_section 250884865Sobrien || o == xcoff_hash_table (info)->toc_section 250984865Sobrien || o == xcoff_hash_table (info)->descriptor_section 251084865Sobrien || strcmp (o->name, ".debug") == 0) 251184865Sobrien o->flags |= SEC_MARK; 251284865Sobrien else 251384865Sobrien { 251484865Sobrien o->_raw_size = 0; 251584865Sobrien o->reloc_count = 0; 251684865Sobrien o->lineno_count = 0; 251784865Sobrien } 251884865Sobrien } 251984865Sobrien } 252084865Sobrien } 252184865Sobrien} 252284865Sobrien 252384865Sobrien/* Record the number of elements in a set. This is used to output the 252484865Sobrien correct csect length. */ 252584865Sobrien 2526130561Sobrienbfd_boolean 252784865Sobrienbfd_xcoff_link_record_set (output_bfd, info, harg, size) 252884865Sobrien bfd *output_bfd; 252984865Sobrien struct bfd_link_info *info; 253084865Sobrien struct bfd_link_hash_entry *harg; 253184865Sobrien bfd_size_type size; 253284865Sobrien{ 253384865Sobrien struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg; 253484865Sobrien struct xcoff_link_size_list *n; 253594536Sobrien bfd_size_type amt; 253684865Sobrien 253784865Sobrien if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour) 2538130561Sobrien return TRUE; 253984865Sobrien 254084865Sobrien /* This will hardly ever be called. I don't want to burn four bytes 254184865Sobrien per global symbol, so instead the size is kept on a linked list 254284865Sobrien attached to the hash table. */ 254384865Sobrien 254494536Sobrien amt = sizeof (struct xcoff_link_size_list); 254594536Sobrien n = (struct xcoff_link_size_list *) bfd_alloc (output_bfd, amt); 254684865Sobrien if (n == NULL) 2547130561Sobrien return FALSE; 254884865Sobrien n->next = xcoff_hash_table (info)->size_list; 254984865Sobrien n->h = h; 255084865Sobrien n->size = size; 255184865Sobrien xcoff_hash_table (info)->size_list = n; 255284865Sobrien 255384865Sobrien h->flags |= XCOFF_HAS_SIZE; 255484865Sobrien 2555130561Sobrien return TRUE; 255684865Sobrien} 255784865Sobrien 255884865Sobrien/* Import a symbol. */ 255984865Sobrien 2560130561Sobrienbfd_boolean 256184865Sobrienbfd_xcoff_import_symbol (output_bfd, info, harg, val, imppath, impfile, 256294536Sobrien impmember, syscall_flag) 256384865Sobrien bfd *output_bfd; 256484865Sobrien struct bfd_link_info *info; 256584865Sobrien struct bfd_link_hash_entry *harg; 256684865Sobrien bfd_vma val; 256784865Sobrien const char *imppath; 256884865Sobrien const char *impfile; 256984865Sobrien const char *impmember; 257094536Sobrien unsigned int syscall_flag; 257184865Sobrien{ 257284865Sobrien struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg; 257384865Sobrien 257484865Sobrien if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour) 2575130561Sobrien return TRUE; 257684865Sobrien 257784865Sobrien /* A symbol name which starts with a period is the code for a 257884865Sobrien function. If the symbol is undefined, then add an undefined 257984865Sobrien symbol for the function descriptor, and import that instead. */ 258084865Sobrien if (h->root.root.string[0] == '.' 258184865Sobrien && h->root.type == bfd_link_hash_undefined 258284865Sobrien && val == (bfd_vma) -1) 258384865Sobrien { 258484865Sobrien struct xcoff_link_hash_entry *hds; 258584865Sobrien 258684865Sobrien hds = h->descriptor; 258784865Sobrien if (hds == NULL) 258884865Sobrien { 258984865Sobrien hds = xcoff_link_hash_lookup (xcoff_hash_table (info), 259084865Sobrien h->root.root.string + 1, 2591130561Sobrien TRUE, FALSE, TRUE); 259284865Sobrien if (hds == NULL) 2593130561Sobrien return FALSE; 259484865Sobrien if (hds->root.type == bfd_link_hash_new) 259584865Sobrien { 259684865Sobrien hds->root.type = bfd_link_hash_undefined; 259784865Sobrien hds->root.u.undef.abfd = h->root.u.undef.abfd; 259884865Sobrien } 259984865Sobrien hds->flags |= XCOFF_DESCRIPTOR; 260084865Sobrien BFD_ASSERT ((hds->flags & XCOFF_CALLED) == 0 260184865Sobrien && (h->flags & XCOFF_DESCRIPTOR) == 0); 260284865Sobrien hds->descriptor = h; 260384865Sobrien h->descriptor = hds; 260484865Sobrien } 260584865Sobrien 260684865Sobrien /* Now, if the descriptor is undefined, import the descriptor 2607130561Sobrien rather than the symbol we were told to import. FIXME: Is 2608130561Sobrien this correct in all cases? */ 260984865Sobrien if (hds->root.type == bfd_link_hash_undefined) 261084865Sobrien h = hds; 261184865Sobrien } 261284865Sobrien 261394536Sobrien h->flags |= (XCOFF_IMPORT | syscall_flag); 261484865Sobrien 261584865Sobrien if (val != (bfd_vma) -1) 261684865Sobrien { 261784865Sobrien if (h->root.type == bfd_link_hash_defined 261884865Sobrien && (! bfd_is_abs_section (h->root.u.def.section) 261984865Sobrien || h->root.u.def.value != val)) 262084865Sobrien { 262184865Sobrien if (! ((*info->callbacks->multiple_definition) 262284865Sobrien (info, h->root.root.string, h->root.u.def.section->owner, 262384865Sobrien h->root.u.def.section, h->root.u.def.value, 262484865Sobrien output_bfd, bfd_abs_section_ptr, val))) 2625130561Sobrien return FALSE; 262684865Sobrien } 262784865Sobrien 262884865Sobrien h->root.type = bfd_link_hash_defined; 262984865Sobrien h->root.u.def.section = bfd_abs_section_ptr; 263084865Sobrien h->root.u.def.value = val; 263184865Sobrien } 263284865Sobrien 263384865Sobrien /* We overload the ldindx field to hold the l_ifile value for this 263484865Sobrien symbol. */ 263584865Sobrien BFD_ASSERT (h->ldsym == NULL); 263684865Sobrien BFD_ASSERT ((h->flags & XCOFF_BUILT_LDSYM) == 0); 263784865Sobrien if (imppath == NULL) 263884865Sobrien h->ldindx = -1; 263984865Sobrien else 264084865Sobrien { 264184865Sobrien unsigned int c; 264284865Sobrien struct xcoff_import_file **pp; 264384865Sobrien 264484865Sobrien /* We start c at 1 because the first entry in the import list is 2645130561Sobrien reserved for the library search path. */ 264684865Sobrien for (pp = &xcoff_hash_table (info)->imports, c = 1; 264784865Sobrien *pp != NULL; 264884865Sobrien pp = &(*pp)->next, ++c) 264984865Sobrien { 265084865Sobrien if (strcmp ((*pp)->path, imppath) == 0 265184865Sobrien && strcmp ((*pp)->file, impfile) == 0 265284865Sobrien && strcmp ((*pp)->member, impmember) == 0) 265384865Sobrien break; 265484865Sobrien } 265584865Sobrien 265684865Sobrien if (*pp == NULL) 265784865Sobrien { 265884865Sobrien struct xcoff_import_file *n; 265994536Sobrien bfd_size_type amt = sizeof (struct xcoff_import_file); 266084865Sobrien 266194536Sobrien n = (struct xcoff_import_file *) bfd_alloc (output_bfd, amt); 266284865Sobrien if (n == NULL) 2663130561Sobrien return FALSE; 266484865Sobrien n->next = NULL; 266584865Sobrien n->path = imppath; 266684865Sobrien n->file = impfile; 266784865Sobrien n->member = impmember; 266884865Sobrien *pp = n; 266984865Sobrien } 267084865Sobrien 267184865Sobrien h->ldindx = c; 267284865Sobrien } 267384865Sobrien 2674130561Sobrien return TRUE; 267584865Sobrien} 267684865Sobrien 267784865Sobrien/* Export a symbol. */ 267884865Sobrien 2679130561Sobrienbfd_boolean 268094536Sobrienbfd_xcoff_export_symbol (output_bfd, info, harg) 268184865Sobrien bfd *output_bfd; 268284865Sobrien struct bfd_link_info *info; 268384865Sobrien struct bfd_link_hash_entry *harg; 268484865Sobrien{ 268584865Sobrien struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg; 268684865Sobrien 268784865Sobrien if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour) 2688130561Sobrien return TRUE; 268984865Sobrien 269084865Sobrien h->flags |= XCOFF_EXPORT; 269184865Sobrien 269284865Sobrien /* FIXME: I'm not at all sure what syscall is supposed to mean, so 269384865Sobrien I'm just going to ignore it until somebody explains it. */ 269484865Sobrien 269584865Sobrien /* See if this is a function descriptor. It may be one even though 269684865Sobrien it is not so marked. */ 269784865Sobrien if ((h->flags & XCOFF_DESCRIPTOR) == 0 269884865Sobrien && h->root.root.string[0] != '.') 269984865Sobrien { 270084865Sobrien char *fnname; 270184865Sobrien struct xcoff_link_hash_entry *hfn; 270294536Sobrien bfd_size_type amt = strlen (h->root.root.string) + 2; 270384865Sobrien 270494536Sobrien fnname = (char *) bfd_malloc (amt); 270584865Sobrien if (fnname == NULL) 2706130561Sobrien return FALSE; 270784865Sobrien fnname[0] = '.'; 270884865Sobrien strcpy (fnname + 1, h->root.root.string); 270984865Sobrien hfn = xcoff_link_hash_lookup (xcoff_hash_table (info), 2710130561Sobrien fnname, FALSE, FALSE, TRUE); 271184865Sobrien free (fnname); 271284865Sobrien if (hfn != NULL 271384865Sobrien && hfn->smclas == XMC_PR 271484865Sobrien && (hfn->root.type == bfd_link_hash_defined 271584865Sobrien || hfn->root.type == bfd_link_hash_defweak)) 271684865Sobrien { 271784865Sobrien h->flags |= XCOFF_DESCRIPTOR; 271884865Sobrien h->descriptor = hfn; 271984865Sobrien hfn->descriptor = h; 272084865Sobrien } 272184865Sobrien } 272284865Sobrien 272384865Sobrien /* Make sure we don't garbage collect this symbol. */ 272484865Sobrien if (! xcoff_mark_symbol (info, h)) 2725130561Sobrien return FALSE; 272684865Sobrien 272784865Sobrien /* If this is a function descriptor, make sure we don't garbage 272884865Sobrien collect the associated function code. We normally don't have to 272984865Sobrien worry about this, because the descriptor will be attached to a 273084865Sobrien section with relocs, but if we are creating the descriptor 273184865Sobrien ourselves those relocs will not be visible to the mark code. */ 273284865Sobrien if ((h->flags & XCOFF_DESCRIPTOR) != 0) 273384865Sobrien { 273484865Sobrien if (! xcoff_mark_symbol (info, h->descriptor)) 2735130561Sobrien return FALSE; 273684865Sobrien } 273784865Sobrien 2738130561Sobrien return TRUE; 273984865Sobrien} 274084865Sobrien 274184865Sobrien/* Count a reloc against a symbol. This is called for relocs 274284865Sobrien generated by the linker script, typically for global constructors 274384865Sobrien and destructors. */ 274484865Sobrien 2745130561Sobrienbfd_boolean 274684865Sobrienbfd_xcoff_link_count_reloc (output_bfd, info, name) 274784865Sobrien bfd *output_bfd; 274884865Sobrien struct bfd_link_info *info; 274984865Sobrien const char *name; 275084865Sobrien{ 275184865Sobrien struct xcoff_link_hash_entry *h; 275284865Sobrien 275384865Sobrien if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour) 2754130561Sobrien return TRUE; 275584865Sobrien 275684865Sobrien h = ((struct xcoff_link_hash_entry *) 2757130561Sobrien bfd_wrapped_link_hash_lookup (output_bfd, info, name, FALSE, FALSE, 2758130561Sobrien FALSE)); 275984865Sobrien if (h == NULL) 276084865Sobrien { 276184865Sobrien (*_bfd_error_handler) (_("%s: no such symbol"), name); 276284865Sobrien bfd_set_error (bfd_error_no_symbols); 2763130561Sobrien return FALSE; 276484865Sobrien } 276584865Sobrien 276684865Sobrien h->flags |= XCOFF_REF_REGULAR | XCOFF_LDREL; 276784865Sobrien ++xcoff_hash_table (info)->ldrel_count; 276884865Sobrien 276984865Sobrien /* Mark the symbol to avoid garbage collection. */ 277084865Sobrien if (! xcoff_mark_symbol (info, h)) 2771130561Sobrien return FALSE; 277284865Sobrien 2773130561Sobrien return TRUE; 277484865Sobrien} 277584865Sobrien 277684865Sobrien/* This function is called for each symbol to which the linker script 277784865Sobrien assigns a value. */ 277884865Sobrien 2779130561Sobrienbfd_boolean 278084865Sobrienbfd_xcoff_record_link_assignment (output_bfd, info, name) 278184865Sobrien bfd *output_bfd; 278284865Sobrien struct bfd_link_info *info; 278384865Sobrien const char *name; 278484865Sobrien{ 278584865Sobrien struct xcoff_link_hash_entry *h; 278684865Sobrien 278784865Sobrien if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour) 2788130561Sobrien return TRUE; 278984865Sobrien 2790130561Sobrien h = xcoff_link_hash_lookup (xcoff_hash_table (info), name, TRUE, TRUE, 2791130561Sobrien FALSE); 279284865Sobrien if (h == NULL) 2793130561Sobrien return FALSE; 279484865Sobrien 279584865Sobrien h->flags |= XCOFF_DEF_REGULAR; 279684865Sobrien 2797130561Sobrien return TRUE; 279884865Sobrien} 279984865Sobrien 280084865Sobrien/* Build the .loader section. This is called by the XCOFF linker 280184865Sobrien emulation before_allocation routine. We must set the size of the 280284865Sobrien .loader section before the linker lays out the output file. 280384865Sobrien LIBPATH is the library path to search for shared objects; this is 280484865Sobrien normally built from the -L arguments passed to the linker. ENTRY 280584865Sobrien is the name of the entry point symbol (the -e linker option). 280684865Sobrien FILE_ALIGN is the alignment to use for sections within the file 280784865Sobrien (the -H linker option). MAXSTACK is the maximum stack size (the 280884865Sobrien -bmaxstack linker option). MAXDATA is the maximum data size (the 280984865Sobrien -bmaxdata linker option). GC is whether to do garbage collection 281084865Sobrien (the -bgc linker option). MODTYPE is the module type (the 281184865Sobrien -bmodtype linker option). TEXTRO is whether the text section must 281284865Sobrien be read only (the -btextro linker option). EXPORT_DEFINEDS is 281384865Sobrien whether all defined symbols should be exported (the -unix linker 281484865Sobrien option). SPECIAL_SECTIONS is set by this routine to csects with 281584865Sobrien magic names like _end. */ 281684865Sobrien 2817130561Sobrienbfd_boolean 281884865Sobrienbfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry, 281984865Sobrien file_align, maxstack, maxdata, gc, 282084865Sobrien modtype, textro, export_defineds, 2821104834Sobrien special_sections, rtld) 282284865Sobrien bfd *output_bfd; 282384865Sobrien struct bfd_link_info *info; 282484865Sobrien const char *libpath; 282584865Sobrien const char *entry; 282684865Sobrien unsigned long file_align; 282784865Sobrien unsigned long maxstack; 282884865Sobrien unsigned long maxdata; 2829130561Sobrien bfd_boolean gc; 283084865Sobrien int modtype; 2831130561Sobrien bfd_boolean textro; 2832130561Sobrien bfd_boolean export_defineds; 283384865Sobrien asection **special_sections; 2834130561Sobrien bfd_boolean rtld; 283584865Sobrien{ 283684865Sobrien struct xcoff_link_hash_entry *hentry; 283784865Sobrien asection *lsec; 283884865Sobrien struct xcoff_loader_info ldinfo; 283984865Sobrien int i; 284084865Sobrien size_t impsize, impcount; 284184865Sobrien struct xcoff_import_file *fl; 284284865Sobrien struct internal_ldhdr *ldhdr; 284384865Sobrien bfd_size_type stoff; 284484865Sobrien register char *out; 284584865Sobrien asection *sec; 284684865Sobrien bfd *sub; 284784865Sobrien struct bfd_strtab_hash *debug_strtab; 284884865Sobrien bfd_byte *debug_contents = NULL; 284994536Sobrien bfd_size_type amt; 285084865Sobrien 285184865Sobrien if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour) 285284865Sobrien { 285394536Sobrien for (i = 0; i < XCOFF_NUMBER_OF_SPECIAL_SECTIONS; i++) 285484865Sobrien special_sections[i] = NULL; 2855130561Sobrien return TRUE; 285684865Sobrien } 285784865Sobrien 2858130561Sobrien ldinfo.failed = FALSE; 285984865Sobrien ldinfo.output_bfd = output_bfd; 286084865Sobrien ldinfo.info = info; 286184865Sobrien ldinfo.export_defineds = export_defineds; 286284865Sobrien ldinfo.ldsym_count = 0; 286384865Sobrien ldinfo.string_size = 0; 286484865Sobrien ldinfo.strings = NULL; 286584865Sobrien ldinfo.string_alc = 0; 286684865Sobrien 286784865Sobrien xcoff_data (output_bfd)->maxstack = maxstack; 286884865Sobrien xcoff_data (output_bfd)->maxdata = maxdata; 286984865Sobrien xcoff_data (output_bfd)->modtype = modtype; 287084865Sobrien 287184865Sobrien xcoff_hash_table (info)->file_align = file_align; 287284865Sobrien xcoff_hash_table (info)->textro = textro; 287384865Sobrien 2874104834Sobrien hentry = NULL; 2875104834Sobrien if (entry != NULL) 287694536Sobrien { 287784865Sobrien hentry = xcoff_link_hash_lookup (xcoff_hash_table (info), entry, 2878130561Sobrien FALSE, FALSE, TRUE); 287984865Sobrien if (hentry != NULL) 288084865Sobrien hentry->flags |= XCOFF_ENTRY; 288184865Sobrien } 288284865Sobrien 288394536Sobrien /* __rtinit */ 2884130561Sobrien if (info->init_function || info->fini_function || rtld) 2885104834Sobrien { 2886104834Sobrien struct xcoff_link_hash_entry *hsym; 2887104834Sobrien struct internal_ldsym *ldsym; 2888130561Sobrien 2889104834Sobrien hsym = xcoff_link_hash_lookup (xcoff_hash_table (info), 2890130561Sobrien "__rtinit", FALSE, FALSE, TRUE); 2891104834Sobrien if (hsym == NULL) 2892104834Sobrien { 2893104834Sobrien (*_bfd_error_handler) 2894104834Sobrien (_("error: undefined symbol __rtinit")); 2895130561Sobrien return FALSE; 2896104834Sobrien } 2897130561Sobrien 2898104834Sobrien xcoff_mark_symbol (info, hsym); 2899104834Sobrien hsym->flags |= (XCOFF_DEF_REGULAR | XCOFF_RTINIT); 290094536Sobrien 2901130561Sobrien /* __rtinit initialized */ 2902104834Sobrien amt = sizeof (struct internal_ldsym); 2903104834Sobrien ldsym = (struct internal_ldsym *) bfd_malloc (amt); 2904130561Sobrien 2905130561Sobrien ldsym->l_value = 0; /* will be filled in later */ 2906130561Sobrien ldsym->l_scnum = 2; /* data section */ 2907130561Sobrien ldsym->l_smtype = XTY_SD; /* csect section definition */ 2908130561Sobrien ldsym->l_smclas = 5; /* .rw */ 2909130561Sobrien ldsym->l_ifile = 0; /* special system loader symbol */ 2910130561Sobrien ldsym->l_parm = 0; /* NA */ 2911130561Sobrien 2912104834Sobrien /* Force __rtinit to be the first symbol in the loader symbol table 2913104834Sobrien See xcoff_build_ldsyms 2914130561Sobrien 2915104834Sobrien The first 3 symbol table indices are reserved to indicate the data, 2916104834Sobrien text and bss sections. */ 2917104834Sobrien BFD_ASSERT (0 == ldinfo.ldsym_count); 2918130561Sobrien 2919104834Sobrien hsym->ldindx = 3; 2920104834Sobrien ldinfo.ldsym_count = 1; 2921104834Sobrien hsym->ldsym = ldsym; 2922130561Sobrien 2923130561Sobrien if (! bfd_xcoff_put_ldsymbol_name (ldinfo.output_bfd, &ldinfo, 2924130561Sobrien hsym->ldsym, hsym->root.root.string)) 2925130561Sobrien return FALSE; 2926130561Sobrien 2927104834Sobrien /* This symbol is written out by xcoff_write_global_symbol 2928104834Sobrien Set stuff up so xcoff_write_global_symbol logic works. */ 2929104834Sobrien hsym->flags |= XCOFF_DEF_REGULAR | XCOFF_MARK; 2930104834Sobrien hsym->root.type = bfd_link_hash_defined; 2931104834Sobrien hsym->root.u.def.value = 0; 2932104834Sobrien } 293394536Sobrien 293484865Sobrien /* Garbage collect unused sections. */ 2935130561Sobrien if (info->relocatable 293684865Sobrien || ! gc 293784865Sobrien || hentry == NULL 293884865Sobrien || (hentry->root.type != bfd_link_hash_defined 293984865Sobrien && hentry->root.type != bfd_link_hash_defweak)) 294084865Sobrien { 2941130561Sobrien gc = FALSE; 2942130561Sobrien xcoff_hash_table (info)->gc = FALSE; 294384865Sobrien 294484865Sobrien /* We still need to call xcoff_mark, in order to set ldrel_count 2945130561Sobrien correctly. */ 294684865Sobrien for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) 294784865Sobrien { 294884865Sobrien asection *o; 294984865Sobrien 295084865Sobrien for (o = sub->sections; o != NULL; o = o->next) 295184865Sobrien { 295284865Sobrien if ((o->flags & SEC_MARK) == 0) 295384865Sobrien { 295484865Sobrien if (! xcoff_mark (info, o)) 295584865Sobrien goto error_return; 295684865Sobrien } 295784865Sobrien } 295884865Sobrien } 295984865Sobrien } 296084865Sobrien else 296184865Sobrien { 296284865Sobrien if (! xcoff_mark (info, hentry->root.u.def.section)) 296384865Sobrien goto error_return; 296484865Sobrien xcoff_sweep (info); 2965130561Sobrien xcoff_hash_table (info)->gc = TRUE; 296684865Sobrien } 296784865Sobrien 296884865Sobrien /* Return special sections to the caller. */ 296994536Sobrien for (i = 0; i < XCOFF_NUMBER_OF_SPECIAL_SECTIONS; i++) 297084865Sobrien { 297194536Sobrien sec = xcoff_hash_table (info)->special_sections[i]; 297284865Sobrien 297384865Sobrien if (sec != NULL 297484865Sobrien && gc 297584865Sobrien && (sec->flags & SEC_MARK) == 0) 297694536Sobrien { 297794536Sobrien sec = NULL; 297894536Sobrien } 297984865Sobrien special_sections[i] = sec; 298084865Sobrien } 298184865Sobrien 298284865Sobrien if (info->input_bfds == NULL) 298384865Sobrien { 298484865Sobrien /* I'm not sure what to do in this bizarre case. */ 2985130561Sobrien return TRUE; 298684865Sobrien } 298784865Sobrien 298884865Sobrien xcoff_link_hash_traverse (xcoff_hash_table (info), xcoff_build_ldsyms, 298984865Sobrien (PTR) &ldinfo); 299084865Sobrien if (ldinfo.failed) 299184865Sobrien goto error_return; 299284865Sobrien 299384865Sobrien /* Work out the size of the import file names. Each import file ID 299484865Sobrien consists of three null terminated strings: the path, the file 299584865Sobrien name, and the archive member name. The first entry in the list 299684865Sobrien of names is the path to use to find objects, which the linker has 299784865Sobrien passed in as the libpath argument. For some reason, the path 299884865Sobrien entry in the other import file names appears to always be empty. */ 299984865Sobrien impsize = strlen (libpath) + 3; 300084865Sobrien impcount = 1; 300184865Sobrien for (fl = xcoff_hash_table (info)->imports; fl != NULL; fl = fl->next) 300284865Sobrien { 300384865Sobrien ++impcount; 300484865Sobrien impsize += (strlen (fl->path) 300584865Sobrien + strlen (fl->file) 300684865Sobrien + strlen (fl->member) 300784865Sobrien + 3); 300884865Sobrien } 300984865Sobrien 301084865Sobrien /* Set up the .loader section header. */ 301184865Sobrien ldhdr = &xcoff_hash_table (info)->ldhdr; 301294536Sobrien ldhdr->l_version = bfd_xcoff_ldhdr_version(output_bfd); 301384865Sobrien ldhdr->l_nsyms = ldinfo.ldsym_count; 301484865Sobrien ldhdr->l_nreloc = xcoff_hash_table (info)->ldrel_count; 301584865Sobrien ldhdr->l_istlen = impsize; 301684865Sobrien ldhdr->l_nimpid = impcount; 301794536Sobrien ldhdr->l_impoff = (bfd_xcoff_ldhdrsz(output_bfd) 301894536Sobrien + ldhdr->l_nsyms * bfd_xcoff_ldsymsz(output_bfd) 301994536Sobrien + ldhdr->l_nreloc * bfd_xcoff_ldrelsz(output_bfd)); 302084865Sobrien ldhdr->l_stlen = ldinfo.string_size; 302184865Sobrien stoff = ldhdr->l_impoff + impsize; 302284865Sobrien if (ldinfo.string_size == 0) 302384865Sobrien ldhdr->l_stoff = 0; 302484865Sobrien else 302584865Sobrien ldhdr->l_stoff = stoff; 302684865Sobrien 302794536Sobrien /* 64 bit elements to ldhdr 302894536Sobrien The swap out routine for 32 bit will ignore them. 302994536Sobrien Nothing fancy, symbols come after the header and relocs come 303094536Sobrien after symbols. */ 303194536Sobrien ldhdr->l_symoff = bfd_xcoff_ldhdrsz (output_bfd); 303294536Sobrien ldhdr->l_rldoff = (bfd_xcoff_ldhdrsz (output_bfd) 303394536Sobrien + ldhdr->l_nsyms * bfd_xcoff_ldsymsz (output_bfd)); 303494536Sobrien 303584865Sobrien /* We now know the final size of the .loader section. Allocate 303684865Sobrien space for it. */ 303784865Sobrien lsec = xcoff_hash_table (info)->loader_section; 303884865Sobrien lsec->_raw_size = stoff + ldhdr->l_stlen; 303984865Sobrien lsec->contents = (bfd_byte *) bfd_zalloc (output_bfd, lsec->_raw_size); 304084865Sobrien if (lsec->contents == NULL) 304184865Sobrien goto error_return; 304284865Sobrien 304384865Sobrien /* Set up the header. */ 304494536Sobrien bfd_xcoff_swap_ldhdr_out (output_bfd, ldhdr, lsec->contents); 304584865Sobrien 304684865Sobrien /* Set up the import file names. */ 304784865Sobrien out = (char *) lsec->contents + ldhdr->l_impoff; 304884865Sobrien strcpy (out, libpath); 304984865Sobrien out += strlen (libpath) + 1; 305084865Sobrien *out++ = '\0'; 305184865Sobrien *out++ = '\0'; 305284865Sobrien for (fl = xcoff_hash_table (info)->imports; fl != NULL; fl = fl->next) 305384865Sobrien { 305484865Sobrien register const char *s; 305584865Sobrien 305684865Sobrien s = fl->path; 305784865Sobrien while ((*out++ = *s++) != '\0') 305884865Sobrien ; 305984865Sobrien s = fl->file; 306084865Sobrien while ((*out++ = *s++) != '\0') 306184865Sobrien ; 306284865Sobrien s = fl->member; 306384865Sobrien while ((*out++ = *s++) != '\0') 306484865Sobrien ; 306584865Sobrien } 306684865Sobrien 306784865Sobrien BFD_ASSERT ((bfd_size_type) ((bfd_byte *) out - lsec->contents) == stoff); 306884865Sobrien 306984865Sobrien /* Set up the symbol string table. */ 307084865Sobrien if (ldinfo.string_size > 0) 307184865Sobrien { 307284865Sobrien memcpy (out, ldinfo.strings, ldinfo.string_size); 307384865Sobrien free (ldinfo.strings); 307484865Sobrien ldinfo.strings = NULL; 307584865Sobrien } 307684865Sobrien 307784865Sobrien /* We can't set up the symbol table or the relocs yet, because we 307884865Sobrien don't yet know the final position of the various sections. The 307984865Sobrien .loader symbols are written out when the corresponding normal 308084865Sobrien symbols are written out in xcoff_link_input_bfd or 308184865Sobrien xcoff_write_global_symbol. The .loader relocs are written out 308284865Sobrien when the corresponding normal relocs are handled in 308394536Sobrien xcoff_link_input_bfd. 308494536Sobrien */ 308584865Sobrien 308684865Sobrien /* Allocate space for the magic sections. */ 308784865Sobrien sec = xcoff_hash_table (info)->linkage_section; 308884865Sobrien if (sec->_raw_size > 0) 308984865Sobrien { 309084865Sobrien sec->contents = (bfd_byte *) bfd_zalloc (output_bfd, sec->_raw_size); 309184865Sobrien if (sec->contents == NULL) 309284865Sobrien goto error_return; 309384865Sobrien } 309484865Sobrien sec = xcoff_hash_table (info)->toc_section; 309584865Sobrien if (sec->_raw_size > 0) 309684865Sobrien { 309784865Sobrien sec->contents = (bfd_byte *) bfd_zalloc (output_bfd, sec->_raw_size); 309884865Sobrien if (sec->contents == NULL) 309984865Sobrien goto error_return; 310084865Sobrien } 310184865Sobrien sec = xcoff_hash_table (info)->descriptor_section; 310284865Sobrien if (sec->_raw_size > 0) 310384865Sobrien { 310484865Sobrien sec->contents = (bfd_byte *) bfd_zalloc (output_bfd, sec->_raw_size); 310584865Sobrien if (sec->contents == NULL) 310684865Sobrien goto error_return; 310784865Sobrien } 310884865Sobrien 310984865Sobrien /* Now that we've done garbage collection, figure out the contents 311084865Sobrien of the .debug section. */ 311184865Sobrien debug_strtab = xcoff_hash_table (info)->debug_strtab; 311284865Sobrien 311384865Sobrien for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) 311484865Sobrien { 311584865Sobrien asection *subdeb; 311684865Sobrien bfd_size_type symcount; 311784865Sobrien unsigned long *debug_index; 311884865Sobrien asection **csectpp; 311984865Sobrien bfd_byte *esym, *esymend; 312084865Sobrien bfd_size_type symesz; 312184865Sobrien 312284865Sobrien if (sub->xvec != info->hash->creator) 312384865Sobrien continue; 312484865Sobrien subdeb = bfd_get_section_by_name (sub, ".debug"); 312584865Sobrien if (subdeb == NULL || subdeb->_raw_size == 0) 312684865Sobrien continue; 312784865Sobrien 312884865Sobrien if (info->strip == strip_all 312984865Sobrien || info->strip == strip_debugger 313084865Sobrien || info->discard == discard_all) 313184865Sobrien { 313284865Sobrien subdeb->_raw_size = 0; 313384865Sobrien continue; 313484865Sobrien } 313584865Sobrien 313684865Sobrien if (! _bfd_coff_get_external_symbols (sub)) 313784865Sobrien goto error_return; 313884865Sobrien 313984865Sobrien symcount = obj_raw_syment_count (sub); 314084865Sobrien debug_index = ((unsigned long *) 314184865Sobrien bfd_zalloc (sub, symcount * sizeof (unsigned long))); 314284865Sobrien if (debug_index == NULL) 314384865Sobrien goto error_return; 314484865Sobrien xcoff_data (sub)->debug_indices = debug_index; 314584865Sobrien 314684865Sobrien /* Grab the contents of the .debug section. We use malloc and 314784865Sobrien copy the names into the debug stringtab, rather than 314884865Sobrien bfd_alloc, because I expect that, when linking many files 314984865Sobrien together, many of the strings will be the same. Storing the 315084865Sobrien strings in the hash table should save space in this case. */ 315184865Sobrien debug_contents = (bfd_byte *) bfd_malloc (subdeb->_raw_size); 315284865Sobrien if (debug_contents == NULL) 315384865Sobrien goto error_return; 315484865Sobrien if (! bfd_get_section_contents (sub, subdeb, (PTR) debug_contents, 315584865Sobrien (file_ptr) 0, subdeb->_raw_size)) 315684865Sobrien goto error_return; 315784865Sobrien 315884865Sobrien csectpp = xcoff_data (sub)->csects; 315984865Sobrien 3160104834Sobrien /* Dynamic object do not have csectpp's. */ 3161130561Sobrien if (NULL != csectpp) 316284865Sobrien { 3163104834Sobrien symesz = bfd_coff_symesz (sub); 3164104834Sobrien esym = (bfd_byte *) obj_coff_external_syms (sub); 3165104834Sobrien esymend = esym + symcount * symesz; 316684865Sobrien 3167104834Sobrien while (esym < esymend) 3168104834Sobrien { 3169104834Sobrien struct internal_syment sym; 317084865Sobrien 3171104834Sobrien bfd_coff_swap_sym_in (sub, (PTR) esym, (PTR) &sym); 317284865Sobrien 3173104834Sobrien *debug_index = (unsigned long) -1; 317484865Sobrien 3175104834Sobrien if (sym._n._n_n._n_zeroes == 0 3176104834Sobrien && *csectpp != NULL 3177104834Sobrien && (! gc 3178104834Sobrien || ((*csectpp)->flags & SEC_MARK) != 0 3179104834Sobrien || *csectpp == bfd_abs_section_ptr) 3180104834Sobrien && bfd_coff_symname_in_debug (sub, &sym)) 3181104834Sobrien { 3182104834Sobrien char *name; 3183104834Sobrien bfd_size_type indx; 3184104834Sobrien 3185104834Sobrien name = (char *) debug_contents + sym._n._n_n._n_offset; 3186130561Sobrien indx = _bfd_stringtab_add (debug_strtab, name, TRUE, TRUE); 3187104834Sobrien if (indx == (bfd_size_type) -1) 3188104834Sobrien goto error_return; 3189104834Sobrien *debug_index = indx; 3190104834Sobrien } 3191104834Sobrien 3192104834Sobrien esym += (sym.n_numaux + 1) * symesz; 3193104834Sobrien csectpp += sym.n_numaux + 1; 3194104834Sobrien debug_index += sym.n_numaux + 1; 319584865Sobrien } 319684865Sobrien } 319784865Sobrien 319884865Sobrien free (debug_contents); 319984865Sobrien debug_contents = NULL; 320084865Sobrien 320184865Sobrien /* Clear the size of subdeb, so that it is not included directly 320284865Sobrien in the output file. */ 320384865Sobrien subdeb->_raw_size = 0; 320484865Sobrien 320584865Sobrien if (! info->keep_memory) 320684865Sobrien { 320784865Sobrien if (! _bfd_coff_free_symbols (sub)) 320884865Sobrien goto error_return; 320984865Sobrien } 321084865Sobrien } 321184865Sobrien 321284865Sobrien if (info->strip != strip_all) 321384865Sobrien xcoff_hash_table (info)->debug_section->_raw_size = 321484865Sobrien _bfd_stringtab_size (debug_strtab); 321584865Sobrien 3216130561Sobrien return TRUE; 321784865Sobrien 321884865Sobrien error_return: 321984865Sobrien if (ldinfo.strings != NULL) 322084865Sobrien free (ldinfo.strings); 322184865Sobrien if (debug_contents != NULL) 322284865Sobrien free (debug_contents); 3223130561Sobrien return FALSE; 322484865Sobrien} 322584865Sobrien 3226130561Sobrienbfd_boolean 3227104834Sobrienbfd_xcoff_link_generate_rtinit (abfd, init, fini, rtld) 322894536Sobrien bfd *abfd; 322994536Sobrien const char *init; 323094536Sobrien const char *fini; 3231130561Sobrien bfd_boolean rtld; 323294536Sobrien{ 323394536Sobrien struct bfd_in_memory *bim; 3234130561Sobrien 323594536Sobrien bim = ((struct bfd_in_memory *) 323694536Sobrien bfd_malloc ((bfd_size_type) sizeof (struct bfd_in_memory))); 323794536Sobrien if (bim == NULL) 3238130561Sobrien return FALSE; 323994536Sobrien 324094536Sobrien bim->size = 0; 324194536Sobrien bim->buffer = 0; 324294536Sobrien 324394536Sobrien abfd->link_next = 0; 324494536Sobrien abfd->format = bfd_object; 324594536Sobrien abfd->iostream = (PTR) bim; 324694536Sobrien abfd->flags = BFD_IN_MEMORY; 324794536Sobrien abfd->direction = write_direction; 324894536Sobrien abfd->where = 0; 324994536Sobrien 3250130561Sobrien if (! bfd_xcoff_generate_rtinit (abfd, init, fini, rtld)) 3251130561Sobrien return FALSE; 325294536Sobrien 325394536Sobrien /* need to reset to unknown or it will not be read back in correctly */ 325494536Sobrien abfd->format = bfd_unknown; 325594536Sobrien abfd->direction = read_direction; 325694536Sobrien abfd->where = 0; 325794536Sobrien 3258130561Sobrien return TRUE; 325994536Sobrien} 326094536Sobrien 326194536Sobrien 326284865Sobrien/* Add a symbol to the .loader symbols, if necessary. */ 326384865Sobrien 3264130561Sobrienstatic bfd_boolean 326584865Sobrienxcoff_build_ldsyms (h, p) 326684865Sobrien struct xcoff_link_hash_entry *h; 326784865Sobrien PTR p; 326884865Sobrien{ 326984865Sobrien struct xcoff_loader_info *ldinfo = (struct xcoff_loader_info *) p; 327094536Sobrien bfd_size_type amt; 327184865Sobrien 327294536Sobrien if (h->root.type == bfd_link_hash_warning) 327394536Sobrien h = (struct xcoff_link_hash_entry *) h->root.u.i.link; 327494536Sobrien 3275104834Sobrien /* __rtinit, this symbol has special handling. */ 327694536Sobrien if (h->flags & XCOFF_RTINIT) 3277130561Sobrien return TRUE; 327894536Sobrien 327984865Sobrien /* If this is a final link, and the symbol was defined as a common 328084865Sobrien symbol in a regular object file, and there was no definition in 328184865Sobrien any dynamic object, then the linker will have allocated space for 328284865Sobrien the symbol in a common section but the XCOFF_DEF_REGULAR flag 328384865Sobrien will not have been set. */ 328484865Sobrien if (h->root.type == bfd_link_hash_defined 328584865Sobrien && (h->flags & XCOFF_DEF_REGULAR) == 0 328684865Sobrien && (h->flags & XCOFF_REF_REGULAR) != 0 328784865Sobrien && (h->flags & XCOFF_DEF_DYNAMIC) == 0 328884865Sobrien && (bfd_is_abs_section (h->root.u.def.section) 328984865Sobrien || (h->root.u.def.section->owner->flags & DYNAMIC) == 0)) 329084865Sobrien h->flags |= XCOFF_DEF_REGULAR; 329184865Sobrien 329284865Sobrien /* If all defined symbols should be exported, mark them now. We 329384865Sobrien don't want to export the actual functions, just the function 329484865Sobrien descriptors. */ 329584865Sobrien if (ldinfo->export_defineds 329684865Sobrien && (h->flags & XCOFF_DEF_REGULAR) != 0 329784865Sobrien && h->root.root.string[0] != '.') 329884865Sobrien { 3299130561Sobrien bfd_boolean export; 330084865Sobrien 330184865Sobrien /* We don't export a symbol which is being defined by an object 330284865Sobrien included from an archive which contains a shared object. The 330384865Sobrien rationale is that if an archive contains both an unshared and 330484865Sobrien a shared object, then there must be some reason that the 330584865Sobrien unshared object is unshared, and we don't want to start 330684865Sobrien providing a shared version of it. In particular, this solves 330784865Sobrien a bug involving the _savefNN set of functions. gcc will call 330884865Sobrien those functions without providing a slot to restore the TOC, 330984865Sobrien so it is essential that these functions be linked in directly 331084865Sobrien and not from a shared object, which means that a shared 331184865Sobrien object which also happens to link them in must not export 331284865Sobrien them. This is confusing, but I haven't been able to think of 331384865Sobrien a different approach. Note that the symbols can, of course, 331484865Sobrien be exported explicitly. */ 3315130561Sobrien export = TRUE; 331684865Sobrien if ((h->root.type == bfd_link_hash_defined 331784865Sobrien || h->root.type == bfd_link_hash_defweak) 331884865Sobrien && h->root.u.def.section->owner != NULL 331984865Sobrien && h->root.u.def.section->owner->my_archive != NULL) 332084865Sobrien { 332184865Sobrien bfd *arbfd, *member; 332284865Sobrien 332384865Sobrien arbfd = h->root.u.def.section->owner->my_archive; 332484865Sobrien member = bfd_openr_next_archived_file (arbfd, (bfd *) NULL); 332584865Sobrien while (member != NULL) 332684865Sobrien { 332784865Sobrien if ((member->flags & DYNAMIC) != 0) 332884865Sobrien { 3329130561Sobrien export = FALSE; 333084865Sobrien break; 333184865Sobrien } 333284865Sobrien member = bfd_openr_next_archived_file (arbfd, member); 333384865Sobrien } 333484865Sobrien } 333584865Sobrien 333684865Sobrien if (export) 333784865Sobrien h->flags |= XCOFF_EXPORT; 333884865Sobrien } 333984865Sobrien 334084865Sobrien /* We don't want to garbage collect symbols which are not defined in 334184865Sobrien XCOFF files. This is a convenient place to mark them. */ 334284865Sobrien if (xcoff_hash_table (ldinfo->info)->gc 334384865Sobrien && (h->flags & XCOFF_MARK) == 0 334484865Sobrien && (h->root.type == bfd_link_hash_defined 334584865Sobrien || h->root.type == bfd_link_hash_defweak) 334684865Sobrien && (h->root.u.def.section->owner == NULL 334784865Sobrien || (h->root.u.def.section->owner->xvec 334884865Sobrien != ldinfo->info->hash->creator))) 334984865Sobrien h->flags |= XCOFF_MARK; 335084865Sobrien 335184865Sobrien /* If this symbol is called and defined in a dynamic object, or it 335284865Sobrien is imported, then we need to set up global linkage code for it. 335384865Sobrien (Unless we did garbage collection and we didn't need this 335484865Sobrien symbol.) */ 335584865Sobrien if ((h->flags & XCOFF_CALLED) != 0 335684865Sobrien && (h->root.type == bfd_link_hash_undefined 335784865Sobrien || h->root.type == bfd_link_hash_undefweak) 335884865Sobrien && h->root.root.string[0] == '.' 335984865Sobrien && h->descriptor != NULL 336084865Sobrien && ((h->descriptor->flags & XCOFF_DEF_DYNAMIC) != 0 336184865Sobrien || ((h->descriptor->flags & XCOFF_IMPORT) != 0 336284865Sobrien && (h->descriptor->flags & XCOFF_DEF_REGULAR) == 0)) 336384865Sobrien && (! xcoff_hash_table (ldinfo->info)->gc 336484865Sobrien || (h->flags & XCOFF_MARK) != 0)) 336584865Sobrien { 336684865Sobrien asection *sec; 336784865Sobrien struct xcoff_link_hash_entry *hds; 336884865Sobrien 336984865Sobrien sec = xcoff_hash_table (ldinfo->info)->linkage_section; 337084865Sobrien h->root.type = bfd_link_hash_defined; 337184865Sobrien h->root.u.def.section = sec; 337284865Sobrien h->root.u.def.value = sec->_raw_size; 337384865Sobrien h->smclas = XMC_GL; 337484865Sobrien h->flags |= XCOFF_DEF_REGULAR; 337594536Sobrien sec->_raw_size += bfd_xcoff_glink_code_size(ldinfo->output_bfd); 337684865Sobrien 337784865Sobrien /* The global linkage code requires a TOC entry for the 3378130561Sobrien descriptor. */ 337984865Sobrien hds = h->descriptor; 338084865Sobrien BFD_ASSERT ((hds->root.type == bfd_link_hash_undefined 338184865Sobrien || hds->root.type == bfd_link_hash_undefweak) 338284865Sobrien && (hds->flags & XCOFF_DEF_REGULAR) == 0); 338384865Sobrien hds->flags |= XCOFF_MARK; 338484865Sobrien if (hds->toc_section == NULL) 338584865Sobrien { 338694536Sobrien int byte_size; 338794536Sobrien 338894536Sobrien /* 32 vs 64 338994536Sobrien xcoff32 uses 4 bytes in the toc. 339094536Sobrien xcoff64 uses 8 bytes in the toc. */ 339194536Sobrien if (bfd_xcoff_is_xcoff64 (ldinfo->output_bfd)) 3392104834Sobrien byte_size = 8; 339394536Sobrien else if (bfd_xcoff_is_xcoff32 (ldinfo->output_bfd)) 3394104834Sobrien byte_size = 4; 339594536Sobrien else 3396130561Sobrien return FALSE; 339794536Sobrien 339884865Sobrien hds->toc_section = xcoff_hash_table (ldinfo->info)->toc_section; 339984865Sobrien hds->u.toc_offset = hds->toc_section->_raw_size; 340094536Sobrien hds->toc_section->_raw_size += byte_size; 340184865Sobrien ++xcoff_hash_table (ldinfo->info)->ldrel_count; 340284865Sobrien ++hds->toc_section->reloc_count; 340384865Sobrien hds->indx = -2; 340484865Sobrien hds->flags |= XCOFF_SET_TOC | XCOFF_LDREL; 340584865Sobrien 340684865Sobrien /* We need to call xcoff_build_ldsyms recursively here, 340794536Sobrien because we may already have passed hds on the traversal. */ 340884865Sobrien xcoff_build_ldsyms (hds, p); 340984865Sobrien } 341084865Sobrien } 341184865Sobrien 341284865Sobrien /* If this symbol is exported, but not defined, we need to try to 341384865Sobrien define it. */ 341484865Sobrien if ((h->flags & XCOFF_EXPORT) != 0 341584865Sobrien && (h->flags & XCOFF_IMPORT) == 0 341684865Sobrien && (h->flags & XCOFF_DEF_REGULAR) == 0 341784865Sobrien && (h->flags & XCOFF_DEF_DYNAMIC) == 0 341884865Sobrien && (h->root.type == bfd_link_hash_undefined 341984865Sobrien || h->root.type == bfd_link_hash_undefweak)) 342084865Sobrien { 342184865Sobrien if ((h->flags & XCOFF_DESCRIPTOR) != 0 342284865Sobrien && (h->descriptor->root.type == bfd_link_hash_defined 342384865Sobrien || h->descriptor->root.type == bfd_link_hash_defweak)) 342484865Sobrien { 342584865Sobrien asection *sec; 342684865Sobrien 342784865Sobrien /* This is an undefined function descriptor associated with 3428130561Sobrien a defined entry point. We can build up a function 3429130561Sobrien descriptor ourselves. Believe it or not, the AIX linker 3430130561Sobrien actually does this, and there are cases where we need to 3431130561Sobrien do it as well. */ 343284865Sobrien sec = xcoff_hash_table (ldinfo->info)->descriptor_section; 343384865Sobrien h->root.type = bfd_link_hash_defined; 343484865Sobrien h->root.u.def.section = sec; 343584865Sobrien h->root.u.def.value = sec->_raw_size; 343684865Sobrien h->smclas = XMC_DS; 343784865Sobrien h->flags |= XCOFF_DEF_REGULAR; 343884865Sobrien 343994536Sobrien /* The size of the function descriptor depends if this is an 344094536Sobrien xcoff32 (12) or xcoff64 (24). */ 344194536Sobrien sec->_raw_size += 344294536Sobrien bfd_xcoff_function_descriptor_size(ldinfo->output_bfd); 344394536Sobrien 344484865Sobrien /* A function descriptor uses two relocs: one for the 344594536Sobrien associated code, and one for the TOC address. */ 344684865Sobrien xcoff_hash_table (ldinfo->info)->ldrel_count += 2; 344784865Sobrien sec->reloc_count += 2; 344884865Sobrien 344984865Sobrien /* We handle writing out the contents of the descriptor in 345094536Sobrien xcoff_write_global_symbol. */ 345184865Sobrien } 345284865Sobrien else 345384865Sobrien { 345484865Sobrien (*_bfd_error_handler) 345584865Sobrien (_("warning: attempt to export undefined symbol `%s'"), 345684865Sobrien h->root.root.string); 345784865Sobrien h->ldsym = NULL; 3458130561Sobrien return TRUE; 345984865Sobrien } 346084865Sobrien } 346184865Sobrien 346284865Sobrien /* If this is still a common symbol, and it wasn't garbage 346384865Sobrien collected, we need to actually allocate space for it in the .bss 346484865Sobrien section. */ 346584865Sobrien if (h->root.type == bfd_link_hash_common 346684865Sobrien && (! xcoff_hash_table (ldinfo->info)->gc 346784865Sobrien || (h->flags & XCOFF_MARK) != 0) 346884865Sobrien && h->root.u.c.p->section->_raw_size == 0) 346984865Sobrien { 347084865Sobrien BFD_ASSERT (bfd_is_com_section (h->root.u.c.p->section)); 347184865Sobrien h->root.u.c.p->section->_raw_size = h->root.u.c.size; 347284865Sobrien } 347384865Sobrien 347484865Sobrien /* We need to add a symbol to the .loader section if it is mentioned 347584865Sobrien in a reloc which we are copying to the .loader section and it was 347684865Sobrien not defined or common, or if it is the entry point, or if it is 347784865Sobrien being exported. */ 347884865Sobrien 347984865Sobrien if (((h->flags & XCOFF_LDREL) == 0 348084865Sobrien || h->root.type == bfd_link_hash_defined 348184865Sobrien || h->root.type == bfd_link_hash_defweak 348284865Sobrien || h->root.type == bfd_link_hash_common) 348384865Sobrien && (h->flags & XCOFF_ENTRY) == 0 348484865Sobrien && (h->flags & XCOFF_EXPORT) == 0) 348584865Sobrien { 348684865Sobrien h->ldsym = NULL; 3487130561Sobrien return TRUE; 348884865Sobrien } 348984865Sobrien 349084865Sobrien /* We don't need to add this symbol if we did garbage collection and 349184865Sobrien we did not mark this symbol. */ 349284865Sobrien if (xcoff_hash_table (ldinfo->info)->gc 349384865Sobrien && (h->flags & XCOFF_MARK) == 0) 349484865Sobrien { 349584865Sobrien h->ldsym = NULL; 3496130561Sobrien return TRUE; 349784865Sobrien } 349884865Sobrien 349984865Sobrien /* We may have already processed this symbol due to the recursive 350084865Sobrien call above. */ 350184865Sobrien if ((h->flags & XCOFF_BUILT_LDSYM) != 0) 3502130561Sobrien return TRUE; 350384865Sobrien 350484865Sobrien /* We need to add this symbol to the .loader symbols. */ 350584865Sobrien 350684865Sobrien BFD_ASSERT (h->ldsym == NULL); 350794536Sobrien amt = sizeof (struct internal_ldsym); 350894536Sobrien h->ldsym = (struct internal_ldsym *) bfd_zalloc (ldinfo->output_bfd, amt); 350984865Sobrien if (h->ldsym == NULL) 351084865Sobrien { 3511130561Sobrien ldinfo->failed = TRUE; 3512130561Sobrien return FALSE; 351384865Sobrien } 351484865Sobrien 351584865Sobrien if ((h->flags & XCOFF_IMPORT) != 0) 351684865Sobrien h->ldsym->l_ifile = h->ldindx; 351784865Sobrien 351884865Sobrien /* The first 3 symbol table indices are reserved to indicate the 351994536Sobrien data, text and bss sections. */ 352084865Sobrien h->ldindx = ldinfo->ldsym_count + 3; 352184865Sobrien 352284865Sobrien ++ldinfo->ldsym_count; 352384865Sobrien 3524130561Sobrien if (! bfd_xcoff_put_ldsymbol_name (ldinfo->output_bfd, ldinfo, 3525130561Sobrien h->ldsym, h->root.root.string)) 352684865Sobrien { 3527130561Sobrien return FALSE; 352884865Sobrien } 352984865Sobrien 353084865Sobrien h->flags |= XCOFF_BUILT_LDSYM; 353184865Sobrien 3532130561Sobrien return TRUE; 353384865Sobrien} 353484865Sobrien 353584865Sobrien/* Do the final link step. */ 353684865Sobrien 3537130561Sobrienbfd_boolean 353884865Sobrien_bfd_xcoff_bfd_final_link (abfd, info) 353984865Sobrien bfd *abfd; 354084865Sobrien struct bfd_link_info *info; 354184865Sobrien{ 354284865Sobrien bfd_size_type symesz; 354384865Sobrien struct xcoff_final_link_info finfo; 354484865Sobrien asection *o; 354584865Sobrien struct bfd_link_order *p; 354694536Sobrien bfd_size_type max_contents_size; 354794536Sobrien bfd_size_type max_sym_count; 354894536Sobrien bfd_size_type max_lineno_count; 354994536Sobrien bfd_size_type max_reloc_count; 355094536Sobrien bfd_size_type max_output_reloc_count; 355184865Sobrien file_ptr rel_filepos; 355284865Sobrien unsigned int relsz; 355384865Sobrien file_ptr line_filepos; 355484865Sobrien unsigned int linesz; 355584865Sobrien bfd *sub; 355684865Sobrien bfd_byte *external_relocs = NULL; 355784865Sobrien char strbuf[STRING_SIZE_SIZE]; 355894536Sobrien file_ptr pos; 355994536Sobrien bfd_size_type amt; 356084865Sobrien 356184865Sobrien if (info->shared) 356284865Sobrien abfd->flags |= DYNAMIC; 356384865Sobrien 356484865Sobrien symesz = bfd_coff_symesz (abfd); 356584865Sobrien 356684865Sobrien finfo.info = info; 356784865Sobrien finfo.output_bfd = abfd; 356884865Sobrien finfo.strtab = NULL; 356984865Sobrien finfo.section_info = NULL; 357084865Sobrien finfo.last_file_index = -1; 357184865Sobrien finfo.toc_symindx = -1; 357284865Sobrien finfo.internal_syms = NULL; 357384865Sobrien finfo.sym_indices = NULL; 357484865Sobrien finfo.outsyms = NULL; 357584865Sobrien finfo.linenos = NULL; 357684865Sobrien finfo.contents = NULL; 357784865Sobrien finfo.external_relocs = NULL; 357884865Sobrien 357994536Sobrien finfo.ldsym = (xcoff_hash_table (info)->loader_section->contents 358094536Sobrien + bfd_xcoff_ldhdrsz (abfd)); 358194536Sobrien finfo.ldrel = (xcoff_hash_table (info)->loader_section->contents 358294536Sobrien + bfd_xcoff_ldhdrsz(abfd) 358394536Sobrien + (xcoff_hash_table (info)->ldhdr.l_nsyms 358494536Sobrien * bfd_xcoff_ldsymsz(abfd))); 358584865Sobrien 358684865Sobrien xcoff_data (abfd)->coff.link_info = info; 358784865Sobrien 358884865Sobrien finfo.strtab = _bfd_stringtab_init (); 358984865Sobrien if (finfo.strtab == NULL) 359084865Sobrien goto error_return; 359184865Sobrien 359284865Sobrien /* Count the line number and relocation entries required for the 359384865Sobrien output file. Determine a few maximum sizes. */ 359484865Sobrien max_contents_size = 0; 359584865Sobrien max_lineno_count = 0; 359684865Sobrien max_reloc_count = 0; 359784865Sobrien for (o = abfd->sections; o != NULL; o = o->next) 359884865Sobrien { 359984865Sobrien o->reloc_count = 0; 360084865Sobrien o->lineno_count = 0; 360184865Sobrien for (p = o->link_order_head; p != NULL; p = p->next) 360284865Sobrien { 360384865Sobrien if (p->type == bfd_indirect_link_order) 360484865Sobrien { 360584865Sobrien asection *sec; 360684865Sobrien 360784865Sobrien sec = p->u.indirect.section; 360884865Sobrien 360984865Sobrien /* Mark all sections which are to be included in the 361084865Sobrien link. This will normally be every section. We need 361184865Sobrien to do this so that we can identify any sections which 361284865Sobrien the linker has decided to not include. */ 3613130561Sobrien sec->linker_mark = TRUE; 361484865Sobrien 361584865Sobrien if (info->strip == strip_none 361684865Sobrien || info->strip == strip_some) 361784865Sobrien o->lineno_count += sec->lineno_count; 361884865Sobrien 361984865Sobrien o->reloc_count += sec->reloc_count; 362084865Sobrien 362184865Sobrien if (sec->_raw_size > max_contents_size) 362284865Sobrien max_contents_size = sec->_raw_size; 362384865Sobrien if (sec->lineno_count > max_lineno_count) 362484865Sobrien max_lineno_count = sec->lineno_count; 362584865Sobrien if (coff_section_data (sec->owner, sec) != NULL 362684865Sobrien && xcoff_section_data (sec->owner, sec) != NULL 362784865Sobrien && (xcoff_section_data (sec->owner, sec)->lineno_count 362884865Sobrien > max_lineno_count)) 362984865Sobrien max_lineno_count = 363084865Sobrien xcoff_section_data (sec->owner, sec)->lineno_count; 363184865Sobrien if (sec->reloc_count > max_reloc_count) 363284865Sobrien max_reloc_count = sec->reloc_count; 363384865Sobrien } 363484865Sobrien else if (p->type == bfd_section_reloc_link_order 363584865Sobrien || p->type == bfd_symbol_reloc_link_order) 363684865Sobrien ++o->reloc_count; 363784865Sobrien } 363884865Sobrien } 363984865Sobrien 364084865Sobrien /* Compute the file positions for all the sections. */ 364184865Sobrien if (abfd->output_has_begun) 364284865Sobrien { 364384865Sobrien if (xcoff_hash_table (info)->file_align != 0) 364484865Sobrien abort (); 364584865Sobrien } 364684865Sobrien else 364784865Sobrien { 364884865Sobrien bfd_vma file_align; 364984865Sobrien 365084865Sobrien file_align = xcoff_hash_table (info)->file_align; 365184865Sobrien if (file_align != 0) 365284865Sobrien { 3653130561Sobrien bfd_boolean saw_contents; 365484865Sobrien int indx; 365584865Sobrien asection **op; 365684865Sobrien file_ptr sofar; 3657130561Sobrien 365884865Sobrien /* Insert .pad sections before every section which has 3659130561Sobrien contents and is loaded, if it is preceded by some other 3660130561Sobrien section which has contents and is loaded. */ 3661130561Sobrien saw_contents = TRUE; 366284865Sobrien for (op = &abfd->sections; *op != NULL; op = &(*op)->next) 366384865Sobrien { 366484865Sobrien if (strcmp ((*op)->name, ".pad") == 0) 3665130561Sobrien saw_contents = FALSE; 366684865Sobrien else if (((*op)->flags & SEC_HAS_CONTENTS) != 0 366784865Sobrien && ((*op)->flags & SEC_LOAD) != 0) 366884865Sobrien { 366984865Sobrien if (! saw_contents) 3670130561Sobrien saw_contents = TRUE; 367184865Sobrien else 367284865Sobrien { 367394536Sobrien asection *n, **st; 3674130561Sobrien 367594536Sobrien /* Create a pad section and place it before the section 3676130561Sobrien that needs padding. This requires unlinking and 367794536Sobrien relinking the bfd's section list. */ 3678130561Sobrien 367994536Sobrien st = abfd->section_tail; 368084865Sobrien n = bfd_make_section_anyway (abfd, ".pad"); 368184865Sobrien n->flags = SEC_HAS_CONTENTS; 3682130561Sobrien n->alignment_power = 0; 368394536Sobrien 368494536Sobrien BFD_ASSERT (*st == n); 368594536Sobrien bfd_section_list_remove (abfd, st); 368694536Sobrien bfd_section_list_insert (abfd, op, n); 368794536Sobrien 368894536Sobrien op = &n->next; 3689130561Sobrien saw_contents = FALSE; 369084865Sobrien } 369184865Sobrien } 369284865Sobrien } 3693130561Sobrien 369484865Sobrien /* Reset the section indices after inserting the new 3695130561Sobrien sections. */ 369684865Sobrien indx = 0; 369784865Sobrien for (o = abfd->sections; o != NULL; o = o->next) 369884865Sobrien { 369984865Sobrien ++indx; 370084865Sobrien o->target_index = indx; 370184865Sobrien } 370284865Sobrien BFD_ASSERT ((unsigned int) indx == abfd->section_count); 370384865Sobrien 370484865Sobrien /* Work out appropriate sizes for the .pad sections to force 3705130561Sobrien each section to land on a page boundary. This bit of 3706130561Sobrien code knows what compute_section_file_positions is going 3707130561Sobrien to do. */ 370884865Sobrien sofar = bfd_coff_filhsz (abfd); 370984865Sobrien sofar += bfd_coff_aoutsz (abfd); 371084865Sobrien sofar += abfd->section_count * bfd_coff_scnhsz (abfd); 371184865Sobrien for (o = abfd->sections; o != NULL; o = o->next) 371294536Sobrien if ((bfd_xcoff_is_reloc_count_overflow 371394536Sobrien (abfd, (bfd_vma) o->reloc_count)) 371494536Sobrien || (bfd_xcoff_is_lineno_count_overflow 371594536Sobrien (abfd, (bfd_vma) o->lineno_count))) 371694536Sobrien /* 64 does not overflow, need to check if 32 does */ 371784865Sobrien sofar += bfd_coff_scnhsz (abfd); 371884865Sobrien 371984865Sobrien for (o = abfd->sections; o != NULL; o = o->next) 372084865Sobrien { 372184865Sobrien if (strcmp (o->name, ".pad") == 0) 372284865Sobrien { 372384865Sobrien bfd_vma pageoff; 372484865Sobrien 372584865Sobrien BFD_ASSERT (o->_raw_size == 0); 372684865Sobrien pageoff = sofar & (file_align - 1); 372784865Sobrien if (pageoff != 0) 372884865Sobrien { 372984865Sobrien o->_raw_size = file_align - pageoff; 373084865Sobrien sofar += file_align - pageoff; 373184865Sobrien o->flags |= SEC_HAS_CONTENTS; 373284865Sobrien } 373384865Sobrien } 373484865Sobrien else 373584865Sobrien { 373684865Sobrien if ((o->flags & SEC_HAS_CONTENTS) != 0) 373784865Sobrien sofar += BFD_ALIGN (o->_raw_size, 373884865Sobrien 1 << o->alignment_power); 373984865Sobrien } 374084865Sobrien } 374184865Sobrien } 374284865Sobrien 374384865Sobrien if (! bfd_coff_compute_section_file_positions (abfd)) 374484865Sobrien goto error_return; 374584865Sobrien } 374684865Sobrien 374784865Sobrien /* Allocate space for the pointers we need to keep for the relocs. */ 374884865Sobrien { 374984865Sobrien unsigned int i; 375084865Sobrien 375184865Sobrien /* We use section_count + 1, rather than section_count, because 375284865Sobrien the target_index fields are 1 based. */ 375394536Sobrien amt = abfd->section_count + 1; 375494536Sobrien amt *= sizeof (struct xcoff_link_section_info); 375594536Sobrien finfo.section_info = (struct xcoff_link_section_info *) bfd_malloc (amt); 375684865Sobrien if (finfo.section_info == NULL) 375784865Sobrien goto error_return; 375884865Sobrien for (i = 0; i <= abfd->section_count; i++) 375984865Sobrien { 376084865Sobrien finfo.section_info[i].relocs = NULL; 376184865Sobrien finfo.section_info[i].rel_hashes = NULL; 376284865Sobrien finfo.section_info[i].toc_rel_hashes = NULL; 376384865Sobrien } 376484865Sobrien } 376584865Sobrien 376684865Sobrien /* Set the file positions for the relocs. */ 376784865Sobrien rel_filepos = obj_relocbase (abfd); 376884865Sobrien relsz = bfd_coff_relsz (abfd); 376984865Sobrien max_output_reloc_count = 0; 377084865Sobrien for (o = abfd->sections; o != NULL; o = o->next) 377184865Sobrien { 377284865Sobrien if (o->reloc_count == 0) 377384865Sobrien o->rel_filepos = 0; 377484865Sobrien else 377584865Sobrien { 377684865Sobrien /* A stripped file has no relocs. However, we still 3777130561Sobrien allocate the buffers, so that later code doesn't have to 3778130561Sobrien worry about whether we are stripping or not. */ 377984865Sobrien if (info->strip == strip_all) 378084865Sobrien o->rel_filepos = 0; 378184865Sobrien else 378284865Sobrien { 378384865Sobrien o->flags |= SEC_RELOC; 378484865Sobrien o->rel_filepos = rel_filepos; 378584865Sobrien rel_filepos += o->reloc_count * relsz; 378684865Sobrien } 378784865Sobrien 378884865Sobrien /* We don't know the indices of global symbols until we have 3789130561Sobrien written out all the local symbols. For each section in 3790130561Sobrien the output file, we keep an array of pointers to hash 3791130561Sobrien table entries. Each entry in the array corresponds to a 3792130561Sobrien reloc. When we find a reloc against a global symbol, we 3793130561Sobrien set the corresponding entry in this array so that we can 3794130561Sobrien fix up the symbol index after we have written out all the 3795130561Sobrien local symbols. 379684865Sobrien 379784865Sobrien Because of this problem, we also keep the relocs in 379884865Sobrien memory until the end of the link. This wastes memory. 379984865Sobrien We could backpatch the file later, I suppose, although it 380084865Sobrien would be slow. */ 380194536Sobrien amt = o->reloc_count; 380294536Sobrien amt *= sizeof (struct internal_reloc); 380384865Sobrien finfo.section_info[o->target_index].relocs = 380494536Sobrien (struct internal_reloc *) bfd_malloc (amt); 380594536Sobrien 380694536Sobrien amt = o->reloc_count; 380794536Sobrien amt *= sizeof (struct xcoff_link_hash_entry *); 380884865Sobrien finfo.section_info[o->target_index].rel_hashes = 380994536Sobrien (struct xcoff_link_hash_entry **) bfd_malloc (amt); 381094536Sobrien 381184865Sobrien if (finfo.section_info[o->target_index].relocs == NULL 381284865Sobrien || finfo.section_info[o->target_index].rel_hashes == NULL) 381384865Sobrien goto error_return; 381484865Sobrien 381584865Sobrien if (o->reloc_count > max_output_reloc_count) 381684865Sobrien max_output_reloc_count = o->reloc_count; 381784865Sobrien } 381884865Sobrien } 381984865Sobrien 382084865Sobrien /* We now know the size of the relocs, so we can determine the file 382184865Sobrien positions of the line numbers. */ 382284865Sobrien line_filepos = rel_filepos; 382384865Sobrien finfo.line_filepos = line_filepos; 382484865Sobrien linesz = bfd_coff_linesz (abfd); 382584865Sobrien for (o = abfd->sections; o != NULL; o = o->next) 382684865Sobrien { 382784865Sobrien if (o->lineno_count == 0) 382884865Sobrien o->line_filepos = 0; 382984865Sobrien else 383084865Sobrien { 383184865Sobrien o->line_filepos = line_filepos; 383284865Sobrien line_filepos += o->lineno_count * linesz; 383384865Sobrien } 383484865Sobrien 383584865Sobrien /* Reset the reloc and lineno counts, so that we can use them to 383684865Sobrien count the number of entries we have output so far. */ 383784865Sobrien o->reloc_count = 0; 383884865Sobrien o->lineno_count = 0; 383984865Sobrien } 384084865Sobrien 384184865Sobrien obj_sym_filepos (abfd) = line_filepos; 384284865Sobrien 384384865Sobrien /* Figure out the largest number of symbols in an input BFD. Take 384484865Sobrien the opportunity to clear the output_has_begun fields of all the 384584865Sobrien input BFD's. We want at least 6 symbols, since that is the 384684865Sobrien number which xcoff_write_global_symbol may need. */ 384784865Sobrien max_sym_count = 6; 384884865Sobrien for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) 384984865Sobrien { 385094536Sobrien bfd_size_type sz; 385184865Sobrien 3852130561Sobrien sub->output_has_begun = FALSE; 385384865Sobrien sz = obj_raw_syment_count (sub); 385484865Sobrien if (sz > max_sym_count) 385584865Sobrien max_sym_count = sz; 385684865Sobrien } 385784865Sobrien 385884865Sobrien /* Allocate some buffers used while linking. */ 385994536Sobrien amt = max_sym_count * sizeof (struct internal_syment); 386094536Sobrien finfo.internal_syms = (struct internal_syment *) bfd_malloc (amt); 386194536Sobrien 386294536Sobrien amt = max_sym_count * sizeof (long); 386394536Sobrien finfo.sym_indices = (long *) bfd_malloc (amt); 386494536Sobrien 386594536Sobrien amt = (max_sym_count + 1) * symesz; 386694536Sobrien finfo.outsyms = (bfd_byte *) bfd_malloc (amt); 386794536Sobrien 386894536Sobrien amt = max_lineno_count * bfd_coff_linesz (abfd); 386994536Sobrien finfo.linenos = (bfd_byte *) bfd_malloc (amt); 387094536Sobrien 387194536Sobrien amt = max_contents_size; 387294536Sobrien finfo.contents = (bfd_byte *) bfd_malloc (amt); 387394536Sobrien 387494536Sobrien amt = max_reloc_count * relsz; 387594536Sobrien finfo.external_relocs = (bfd_byte *) bfd_malloc (amt); 387694536Sobrien 387784865Sobrien if ((finfo.internal_syms == NULL && max_sym_count > 0) 387884865Sobrien || (finfo.sym_indices == NULL && max_sym_count > 0) 387984865Sobrien || finfo.outsyms == NULL 388084865Sobrien || (finfo.linenos == NULL && max_lineno_count > 0) 388184865Sobrien || (finfo.contents == NULL && max_contents_size > 0) 388284865Sobrien || (finfo.external_relocs == NULL && max_reloc_count > 0)) 388384865Sobrien goto error_return; 388484865Sobrien 388584865Sobrien obj_raw_syment_count (abfd) = 0; 388684865Sobrien xcoff_data (abfd)->toc = (bfd_vma) -1; 388784865Sobrien 388884865Sobrien /* We now know the position of everything in the file, except that 388984865Sobrien we don't know the size of the symbol table and therefore we don't 389084865Sobrien know where the string table starts. We just build the string 389184865Sobrien table in memory as we go along. We process all the relocations 389284865Sobrien for a single input file at once. */ 389384865Sobrien for (o = abfd->sections; o != NULL; o = o->next) 389484865Sobrien { 389584865Sobrien for (p = o->link_order_head; p != NULL; p = p->next) 389684865Sobrien { 389784865Sobrien if (p->type == bfd_indirect_link_order 389884865Sobrien && p->u.indirect.section->owner->xvec == abfd->xvec) 389984865Sobrien { 390084865Sobrien sub = p->u.indirect.section->owner; 390184865Sobrien if (! sub->output_has_begun) 390284865Sobrien { 390384865Sobrien if (! xcoff_link_input_bfd (&finfo, sub)) 390484865Sobrien goto error_return; 3905130561Sobrien sub->output_has_begun = TRUE; 390684865Sobrien } 390784865Sobrien } 390884865Sobrien else if (p->type == bfd_section_reloc_link_order 390984865Sobrien || p->type == bfd_symbol_reloc_link_order) 391084865Sobrien { 391184865Sobrien if (! xcoff_reloc_link_order (abfd, &finfo, o, p)) 391284865Sobrien goto error_return; 391384865Sobrien } 391484865Sobrien else 391584865Sobrien { 391684865Sobrien if (! _bfd_default_link_order (abfd, info, o, p)) 391784865Sobrien goto error_return; 391884865Sobrien } 391984865Sobrien } 392084865Sobrien } 392184865Sobrien 392294536Sobrien 392384865Sobrien /* Free up the buffers used by xcoff_link_input_bfd. */ 392484865Sobrien 392584865Sobrien if (finfo.internal_syms != NULL) 392684865Sobrien { 392784865Sobrien free (finfo.internal_syms); 392884865Sobrien finfo.internal_syms = NULL; 392984865Sobrien } 393084865Sobrien if (finfo.sym_indices != NULL) 393184865Sobrien { 393284865Sobrien free (finfo.sym_indices); 393384865Sobrien finfo.sym_indices = NULL; 393484865Sobrien } 393584865Sobrien if (finfo.linenos != NULL) 393684865Sobrien { 393784865Sobrien free (finfo.linenos); 393884865Sobrien finfo.linenos = NULL; 393984865Sobrien } 394084865Sobrien if (finfo.contents != NULL) 394184865Sobrien { 394284865Sobrien free (finfo.contents); 394384865Sobrien finfo.contents = NULL; 394484865Sobrien } 394584865Sobrien if (finfo.external_relocs != NULL) 394684865Sobrien { 394784865Sobrien free (finfo.external_relocs); 394884865Sobrien finfo.external_relocs = NULL; 394984865Sobrien } 395084865Sobrien 395184865Sobrien /* The value of the last C_FILE symbol is supposed to be -1. Write 395284865Sobrien it out again. */ 395384865Sobrien if (finfo.last_file_index != -1) 395484865Sobrien { 395594536Sobrien finfo.last_file.n_value = -(bfd_vma) 1; 395684865Sobrien bfd_coff_swap_sym_out (abfd, (PTR) &finfo.last_file, 395784865Sobrien (PTR) finfo.outsyms); 395894536Sobrien pos = obj_sym_filepos (abfd) + finfo.last_file_index * symesz; 395994536Sobrien if (bfd_seek (abfd, pos, SEEK_SET) != 0 396094536Sobrien || bfd_bwrite (finfo.outsyms, symesz, abfd) != symesz) 396184865Sobrien goto error_return; 396284865Sobrien } 396384865Sobrien 396484865Sobrien /* Write out all the global symbols which do not come from XCOFF 396584865Sobrien input files. */ 396684865Sobrien xcoff_link_hash_traverse (xcoff_hash_table (info), 396784865Sobrien xcoff_write_global_symbol, 396884865Sobrien (PTR) &finfo); 396984865Sobrien 397084865Sobrien if (finfo.outsyms != NULL) 397184865Sobrien { 397284865Sobrien free (finfo.outsyms); 397384865Sobrien finfo.outsyms = NULL; 397484865Sobrien } 397584865Sobrien 397684865Sobrien /* Now that we have written out all the global symbols, we know the 397784865Sobrien symbol indices to use for relocs against them, and we can finally 397884865Sobrien write out the relocs. */ 397994536Sobrien amt = max_output_reloc_count * relsz; 398094536Sobrien external_relocs = (bfd_byte *) bfd_malloc (amt); 398184865Sobrien if (external_relocs == NULL && max_output_reloc_count != 0) 398284865Sobrien goto error_return; 398384865Sobrien 398484865Sobrien for (o = abfd->sections; o != NULL; o = o->next) 398584865Sobrien { 398684865Sobrien struct internal_reloc *irel; 398784865Sobrien struct internal_reloc *irelend; 398884865Sobrien struct xcoff_link_hash_entry **rel_hash; 398984865Sobrien struct xcoff_toc_rel_hash *toc_rel_hash; 399084865Sobrien bfd_byte *erel; 399194536Sobrien bfd_size_type rel_size; 399284865Sobrien 399384865Sobrien /* A stripped file has no relocs. */ 399484865Sobrien if (info->strip == strip_all) 399584865Sobrien { 399684865Sobrien o->reloc_count = 0; 399784865Sobrien continue; 399884865Sobrien } 399984865Sobrien 400084865Sobrien if (o->reloc_count == 0) 400184865Sobrien continue; 400284865Sobrien 400384865Sobrien irel = finfo.section_info[o->target_index].relocs; 400484865Sobrien irelend = irel + o->reloc_count; 400584865Sobrien rel_hash = finfo.section_info[o->target_index].rel_hashes; 400684865Sobrien for (; irel < irelend; irel++, rel_hash++, erel += relsz) 400784865Sobrien { 400884865Sobrien if (*rel_hash != NULL) 400984865Sobrien { 401084865Sobrien if ((*rel_hash)->indx < 0) 401184865Sobrien { 401284865Sobrien if (! ((*info->callbacks->unattached_reloc) 401384865Sobrien (info, (*rel_hash)->root.root.string, 401484865Sobrien (bfd *) NULL, o, irel->r_vaddr))) 401584865Sobrien goto error_return; 401684865Sobrien (*rel_hash)->indx = 0; 401784865Sobrien } 401884865Sobrien irel->r_symndx = (*rel_hash)->indx; 401984865Sobrien } 402084865Sobrien } 402184865Sobrien 402284865Sobrien for (toc_rel_hash = finfo.section_info[o->target_index].toc_rel_hashes; 402384865Sobrien toc_rel_hash != NULL; 402484865Sobrien toc_rel_hash = toc_rel_hash->next) 402584865Sobrien { 402684865Sobrien if (toc_rel_hash->h->u.toc_indx < 0) 402784865Sobrien { 402884865Sobrien if (! ((*info->callbacks->unattached_reloc) 402984865Sobrien (info, toc_rel_hash->h->root.root.string, 403084865Sobrien (bfd *) NULL, o, toc_rel_hash->rel->r_vaddr))) 403184865Sobrien goto error_return; 403284865Sobrien toc_rel_hash->h->u.toc_indx = 0; 403384865Sobrien } 403484865Sobrien toc_rel_hash->rel->r_symndx = toc_rel_hash->h->u.toc_indx; 403584865Sobrien } 403684865Sobrien 403784865Sobrien /* XCOFF requires that the relocs be sorted by address. We tend 403894536Sobrien to produce them in the order in which their containing csects 403994536Sobrien appear in the symbol table, which is not necessarily by 404094536Sobrien address. So we sort them here. There may be a better way to 404194536Sobrien do this. */ 404284865Sobrien qsort ((PTR) finfo.section_info[o->target_index].relocs, 404384865Sobrien o->reloc_count, sizeof (struct internal_reloc), 404484865Sobrien xcoff_sort_relocs); 404584865Sobrien 404684865Sobrien irel = finfo.section_info[o->target_index].relocs; 404784865Sobrien irelend = irel + o->reloc_count; 404884865Sobrien erel = external_relocs; 404984865Sobrien for (; irel < irelend; irel++, rel_hash++, erel += relsz) 405084865Sobrien bfd_coff_swap_reloc_out (abfd, (PTR) irel, (PTR) erel); 405184865Sobrien 405294536Sobrien rel_size = relsz * o->reloc_count; 405384865Sobrien if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0 405494536Sobrien || bfd_bwrite ((PTR) external_relocs, rel_size, abfd) != rel_size) 405584865Sobrien goto error_return; 405684865Sobrien } 405784865Sobrien 405884865Sobrien if (external_relocs != NULL) 405984865Sobrien { 406084865Sobrien free (external_relocs); 406184865Sobrien external_relocs = NULL; 406284865Sobrien } 406384865Sobrien 406484865Sobrien /* Free up the section information. */ 406584865Sobrien if (finfo.section_info != NULL) 406684865Sobrien { 406784865Sobrien unsigned int i; 406884865Sobrien 406984865Sobrien for (i = 0; i < abfd->section_count; i++) 407084865Sobrien { 407184865Sobrien if (finfo.section_info[i].relocs != NULL) 407284865Sobrien free (finfo.section_info[i].relocs); 407384865Sobrien if (finfo.section_info[i].rel_hashes != NULL) 407484865Sobrien free (finfo.section_info[i].rel_hashes); 407584865Sobrien } 407684865Sobrien free (finfo.section_info); 407784865Sobrien finfo.section_info = NULL; 407884865Sobrien } 407984865Sobrien 408084865Sobrien /* Write out the loader section contents. */ 408184865Sobrien BFD_ASSERT ((bfd_byte *) finfo.ldrel 408284865Sobrien == (xcoff_hash_table (info)->loader_section->contents 408384865Sobrien + xcoff_hash_table (info)->ldhdr.l_impoff)); 408484865Sobrien o = xcoff_hash_table (info)->loader_section; 408594536Sobrien if (! bfd_set_section_contents (abfd, o->output_section, o->contents, 408694536Sobrien (file_ptr) o->output_offset, o->_raw_size)) 408784865Sobrien goto error_return; 408884865Sobrien 408984865Sobrien /* Write out the magic sections. */ 409084865Sobrien o = xcoff_hash_table (info)->linkage_section; 409184865Sobrien if (o->_raw_size > 0 409284865Sobrien && ! bfd_set_section_contents (abfd, o->output_section, o->contents, 409394536Sobrien (file_ptr) o->output_offset, 409494536Sobrien o->_raw_size)) 409584865Sobrien goto error_return; 409684865Sobrien o = xcoff_hash_table (info)->toc_section; 409784865Sobrien if (o->_raw_size > 0 409884865Sobrien && ! bfd_set_section_contents (abfd, o->output_section, o->contents, 409994536Sobrien (file_ptr) o->output_offset, 410094536Sobrien o->_raw_size)) 410184865Sobrien goto error_return; 410284865Sobrien o = xcoff_hash_table (info)->descriptor_section; 410384865Sobrien if (o->_raw_size > 0 410484865Sobrien && ! bfd_set_section_contents (abfd, o->output_section, o->contents, 410594536Sobrien (file_ptr) o->output_offset, 410694536Sobrien o->_raw_size)) 410784865Sobrien goto error_return; 410884865Sobrien 410984865Sobrien /* Write out the string table. */ 411094536Sobrien pos = obj_sym_filepos (abfd) + obj_raw_syment_count (abfd) * symesz; 411194536Sobrien if (bfd_seek (abfd, pos, SEEK_SET) != 0) 411284865Sobrien goto error_return; 411394536Sobrien H_PUT_32 (abfd, 411494536Sobrien _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE, 411594536Sobrien strbuf); 411694536Sobrien amt = STRING_SIZE_SIZE; 411794536Sobrien if (bfd_bwrite (strbuf, amt, abfd) != amt) 411884865Sobrien goto error_return; 411984865Sobrien if (! _bfd_stringtab_emit (abfd, finfo.strtab)) 412084865Sobrien goto error_return; 412184865Sobrien 412284865Sobrien _bfd_stringtab_free (finfo.strtab); 412384865Sobrien 412484865Sobrien /* Write out the debugging string table. */ 412584865Sobrien o = xcoff_hash_table (info)->debug_section; 412684865Sobrien if (o != NULL) 412784865Sobrien { 412884865Sobrien struct bfd_strtab_hash *debug_strtab; 412984865Sobrien 413084865Sobrien debug_strtab = xcoff_hash_table (info)->debug_strtab; 413184865Sobrien BFD_ASSERT (o->output_section->_raw_size - o->output_offset 413284865Sobrien >= _bfd_stringtab_size (debug_strtab)); 413394536Sobrien pos = o->output_section->filepos + o->output_offset; 413494536Sobrien if (bfd_seek (abfd, pos, SEEK_SET) != 0) 413584865Sobrien goto error_return; 413684865Sobrien if (! _bfd_stringtab_emit (abfd, debug_strtab)) 413784865Sobrien goto error_return; 413884865Sobrien } 413984865Sobrien 414084865Sobrien /* Setting bfd_get_symcount to 0 will cause write_object_contents to 414184865Sobrien not try to write out the symbols. */ 414284865Sobrien bfd_get_symcount (abfd) = 0; 414384865Sobrien 4144130561Sobrien return TRUE; 414584865Sobrien 414684865Sobrien error_return: 414784865Sobrien if (finfo.strtab != NULL) 414884865Sobrien _bfd_stringtab_free (finfo.strtab); 414994536Sobrien 415084865Sobrien if (finfo.section_info != NULL) 415184865Sobrien { 415284865Sobrien unsigned int i; 415384865Sobrien 415484865Sobrien for (i = 0; i < abfd->section_count; i++) 415584865Sobrien { 415684865Sobrien if (finfo.section_info[i].relocs != NULL) 415784865Sobrien free (finfo.section_info[i].relocs); 415884865Sobrien if (finfo.section_info[i].rel_hashes != NULL) 415984865Sobrien free (finfo.section_info[i].rel_hashes); 416084865Sobrien } 416184865Sobrien free (finfo.section_info); 416284865Sobrien } 416394536Sobrien 416484865Sobrien if (finfo.internal_syms != NULL) 416584865Sobrien free (finfo.internal_syms); 416684865Sobrien if (finfo.sym_indices != NULL) 416784865Sobrien free (finfo.sym_indices); 416884865Sobrien if (finfo.outsyms != NULL) 416984865Sobrien free (finfo.outsyms); 417084865Sobrien if (finfo.linenos != NULL) 417184865Sobrien free (finfo.linenos); 417284865Sobrien if (finfo.contents != NULL) 417384865Sobrien free (finfo.contents); 417484865Sobrien if (finfo.external_relocs != NULL) 417584865Sobrien free (finfo.external_relocs); 417684865Sobrien if (external_relocs != NULL) 417784865Sobrien free (external_relocs); 4178130561Sobrien return FALSE; 417984865Sobrien} 418084865Sobrien 418184865Sobrien/* Link an input file into the linker output file. This function 418284865Sobrien handles all the sections and relocations of the input file at once. */ 418384865Sobrien 4184130561Sobrienstatic bfd_boolean 418584865Sobrienxcoff_link_input_bfd (finfo, input_bfd) 418684865Sobrien struct xcoff_final_link_info *finfo; 418784865Sobrien bfd *input_bfd; 418884865Sobrien{ 418984865Sobrien bfd *output_bfd; 419084865Sobrien const char *strings; 419184865Sobrien bfd_size_type syment_base; 419284865Sobrien unsigned int n_tmask; 419384865Sobrien unsigned int n_btshft; 4194130561Sobrien bfd_boolean copy, hash; 419584865Sobrien bfd_size_type isymesz; 419684865Sobrien bfd_size_type osymesz; 419784865Sobrien bfd_size_type linesz; 419884865Sobrien bfd_byte *esym; 419984865Sobrien bfd_byte *esym_end; 420084865Sobrien struct xcoff_link_hash_entry **sym_hash; 420184865Sobrien struct internal_syment *isymp; 420284865Sobrien asection **csectpp; 420384865Sobrien unsigned long *debug_index; 420484865Sobrien long *indexp; 420584865Sobrien unsigned long output_index; 420684865Sobrien bfd_byte *outsym; 420784865Sobrien unsigned int incls; 420884865Sobrien asection *oline; 4209130561Sobrien bfd_boolean keep_syms; 421084865Sobrien asection *o; 421184865Sobrien 421284865Sobrien /* We can just skip DYNAMIC files, unless this is a static link. */ 421384865Sobrien if ((input_bfd->flags & DYNAMIC) != 0 421484865Sobrien && ! finfo->info->static_link) 4215130561Sobrien return TRUE; 421684865Sobrien 421784865Sobrien /* Move all the symbols to the output file. */ 421884865Sobrien 421984865Sobrien output_bfd = finfo->output_bfd; 422084865Sobrien strings = NULL; 422184865Sobrien syment_base = obj_raw_syment_count (output_bfd); 422284865Sobrien isymesz = bfd_coff_symesz (input_bfd); 422384865Sobrien osymesz = bfd_coff_symesz (output_bfd); 422484865Sobrien linesz = bfd_coff_linesz (input_bfd); 422584865Sobrien BFD_ASSERT (linesz == bfd_coff_linesz (output_bfd)); 422684865Sobrien 422784865Sobrien n_tmask = coff_data (input_bfd)->local_n_tmask; 422884865Sobrien n_btshft = coff_data (input_bfd)->local_n_btshft; 422984865Sobrien 423084865Sobrien /* Define macros so that ISFCN, et. al., macros work correctly. */ 423184865Sobrien#define N_TMASK n_tmask 423284865Sobrien#define N_BTSHFT n_btshft 423384865Sobrien 4234130561Sobrien copy = FALSE; 423584865Sobrien if (! finfo->info->keep_memory) 4236130561Sobrien copy = TRUE; 4237130561Sobrien hash = TRUE; 423884865Sobrien if ((output_bfd->flags & BFD_TRADITIONAL_FORMAT) != 0) 4239130561Sobrien hash = FALSE; 424084865Sobrien 424184865Sobrien if (! _bfd_coff_get_external_symbols (input_bfd)) 4242130561Sobrien return FALSE; 424384865Sobrien 424484865Sobrien esym = (bfd_byte *) obj_coff_external_syms (input_bfd); 424584865Sobrien esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz; 424684865Sobrien sym_hash = obj_xcoff_sym_hashes (input_bfd); 424784865Sobrien csectpp = xcoff_data (input_bfd)->csects; 424884865Sobrien debug_index = xcoff_data (input_bfd)->debug_indices; 424984865Sobrien isymp = finfo->internal_syms; 425084865Sobrien indexp = finfo->sym_indices; 425184865Sobrien output_index = syment_base; 425284865Sobrien outsym = finfo->outsyms; 425384865Sobrien incls = 0; 425484865Sobrien oline = NULL; 425584865Sobrien 425684865Sobrien while (esym < esym_end) 425784865Sobrien { 425894536Sobrien 425984865Sobrien struct internal_syment isym; 426084865Sobrien union internal_auxent aux; 426184865Sobrien int smtyp = 0; 4262130561Sobrien bfd_boolean skip; 4263130561Sobrien bfd_boolean require; 426484865Sobrien int add; 426584865Sobrien 426684865Sobrien bfd_coff_swap_sym_in (input_bfd, (PTR) esym, (PTR) isymp); 426784865Sobrien 426884865Sobrien /* If this is a C_EXT or C_HIDEXT symbol, we need the csect 4269130561Sobrien information. */ 427084865Sobrien if (isymp->n_sclass == C_EXT || isymp->n_sclass == C_HIDEXT) 427184865Sobrien { 427284865Sobrien BFD_ASSERT (isymp->n_numaux > 0); 427384865Sobrien bfd_coff_swap_aux_in (input_bfd, 427484865Sobrien (PTR) (esym + isymesz * isymp->n_numaux), 427584865Sobrien isymp->n_type, isymp->n_sclass, 427684865Sobrien isymp->n_numaux - 1, isymp->n_numaux, 427784865Sobrien (PTR) &aux); 427894536Sobrien 427984865Sobrien smtyp = SMTYP_SMTYP (aux.x_csect.x_smtyp); 428084865Sobrien } 428184865Sobrien 428284865Sobrien /* Make a copy of *isymp so that the relocate_section function 428384865Sobrien always sees the original values. This is more reliable than 428484865Sobrien always recomputing the symbol value even if we are stripping 428584865Sobrien the symbol. */ 428684865Sobrien isym = *isymp; 428784865Sobrien 428884865Sobrien /* If this symbol is in the .loader section, swap out the 4289130561Sobrien .loader symbol information. If this is an external symbol 4290130561Sobrien reference to a defined symbol, though, then wait until we get 4291130561Sobrien to the definition. */ 429284865Sobrien if (isym.n_sclass == C_EXT 429384865Sobrien && *sym_hash != NULL 429484865Sobrien && (*sym_hash)->ldsym != NULL 429584865Sobrien && (smtyp != XTY_ER 429684865Sobrien || (*sym_hash)->root.type == bfd_link_hash_undefined)) 429784865Sobrien { 429884865Sobrien struct xcoff_link_hash_entry *h; 429984865Sobrien struct internal_ldsym *ldsym; 430084865Sobrien 430184865Sobrien h = *sym_hash; 430284865Sobrien ldsym = h->ldsym; 430384865Sobrien if (isym.n_scnum > 0) 430484865Sobrien { 430584865Sobrien ldsym->l_scnum = (*csectpp)->output_section->target_index; 430684865Sobrien ldsym->l_value = (isym.n_value 430784865Sobrien + (*csectpp)->output_section->vma 430884865Sobrien + (*csectpp)->output_offset 430984865Sobrien - (*csectpp)->vma); 431084865Sobrien } 431184865Sobrien else 431284865Sobrien { 431384865Sobrien ldsym->l_scnum = isym.n_scnum; 431484865Sobrien ldsym->l_value = isym.n_value; 431584865Sobrien } 431684865Sobrien 431784865Sobrien ldsym->l_smtype = smtyp; 431884865Sobrien if (((h->flags & XCOFF_DEF_REGULAR) == 0 431984865Sobrien && (h->flags & XCOFF_DEF_DYNAMIC) != 0) 432084865Sobrien || (h->flags & XCOFF_IMPORT) != 0) 432184865Sobrien ldsym->l_smtype |= L_IMPORT; 432284865Sobrien if (((h->flags & XCOFF_DEF_REGULAR) != 0 432384865Sobrien && (h->flags & XCOFF_DEF_DYNAMIC) != 0) 432484865Sobrien || (h->flags & XCOFF_EXPORT) != 0) 432584865Sobrien ldsym->l_smtype |= L_EXPORT; 432684865Sobrien if ((h->flags & XCOFF_ENTRY) != 0) 432784865Sobrien ldsym->l_smtype |= L_ENTRY; 432884865Sobrien 432984865Sobrien ldsym->l_smclas = aux.x_csect.x_smclas; 433084865Sobrien 433184865Sobrien if (ldsym->l_ifile == (bfd_size_type) -1) 433284865Sobrien ldsym->l_ifile = 0; 433384865Sobrien else if (ldsym->l_ifile == 0) 433484865Sobrien { 433584865Sobrien if ((ldsym->l_smtype & L_IMPORT) == 0) 433684865Sobrien ldsym->l_ifile = 0; 433784865Sobrien else 433884865Sobrien { 433984865Sobrien bfd *impbfd; 434084865Sobrien 434184865Sobrien if (h->root.type == bfd_link_hash_defined 434284865Sobrien || h->root.type == bfd_link_hash_defweak) 434384865Sobrien impbfd = h->root.u.def.section->owner; 434484865Sobrien else if (h->root.type == bfd_link_hash_undefined 434584865Sobrien || h->root.type == bfd_link_hash_undefweak) 434684865Sobrien impbfd = h->root.u.undef.abfd; 434784865Sobrien else 434884865Sobrien impbfd = NULL; 434984865Sobrien 435084865Sobrien if (impbfd == NULL) 435184865Sobrien ldsym->l_ifile = 0; 435284865Sobrien else 435384865Sobrien { 435484865Sobrien BFD_ASSERT (impbfd->xvec == finfo->output_bfd->xvec); 435584865Sobrien ldsym->l_ifile = xcoff_data (impbfd)->import_file_id; 435684865Sobrien } 435784865Sobrien } 435884865Sobrien } 435984865Sobrien 436084865Sobrien ldsym->l_parm = 0; 436184865Sobrien 436284865Sobrien BFD_ASSERT (h->ldindx >= 0); 436394536Sobrien bfd_xcoff_swap_ldsym_out (finfo->output_bfd, ldsym, 436494536Sobrien (finfo->ldsym 436594536Sobrien + ((h->ldindx - 3) 436694536Sobrien * bfd_xcoff_ldsymsz (finfo->output_bfd)))); 436784865Sobrien h->ldsym = NULL; 436884865Sobrien 436984865Sobrien /* Fill in snentry now that we know the target_index. */ 437084865Sobrien if ((h->flags & XCOFF_ENTRY) != 0 437184865Sobrien && (h->root.type == bfd_link_hash_defined 437284865Sobrien || h->root.type == bfd_link_hash_defweak)) 437394536Sobrien { 437494536Sobrien xcoff_data (output_bfd)->snentry = 437594536Sobrien h->root.u.def.section->output_section->target_index; 437694536Sobrien } 437784865Sobrien } 437884865Sobrien 437984865Sobrien *indexp = -1; 438084865Sobrien 4381130561Sobrien skip = FALSE; 4382130561Sobrien require = FALSE; 438384865Sobrien add = 1 + isym.n_numaux; 438484865Sobrien 438584865Sobrien /* If we are skipping this csect, we want to skip this symbol. */ 438684865Sobrien if (*csectpp == NULL) 4387130561Sobrien skip = TRUE; 438884865Sobrien 438984865Sobrien /* If we garbage collected this csect, we want to skip this 4390130561Sobrien symbol. */ 439184865Sobrien if (! skip 439284865Sobrien && xcoff_hash_table (finfo->info)->gc 439384865Sobrien && ((*csectpp)->flags & SEC_MARK) == 0 439484865Sobrien && *csectpp != bfd_abs_section_ptr) 4395130561Sobrien skip = TRUE; 439684865Sobrien 439784865Sobrien /* An XCOFF linker always skips C_STAT symbols. */ 439884865Sobrien if (! skip 439984865Sobrien && isymp->n_sclass == C_STAT) 4400130561Sobrien skip = TRUE; 440184865Sobrien 440284865Sobrien /* We skip all but the first TOC anchor. */ 440384865Sobrien if (! skip 440484865Sobrien && isymp->n_sclass == C_HIDEXT 440584865Sobrien && aux.x_csect.x_smclas == XMC_TC0) 440684865Sobrien { 440784865Sobrien if (finfo->toc_symindx != -1) 4408130561Sobrien skip = TRUE; 440984865Sobrien else 441084865Sobrien { 441184865Sobrien bfd_vma tocval, tocend; 441284865Sobrien bfd *inp; 441384865Sobrien 441484865Sobrien tocval = ((*csectpp)->output_section->vma 441584865Sobrien + (*csectpp)->output_offset 441684865Sobrien + isym.n_value 441784865Sobrien - (*csectpp)->vma); 441884865Sobrien 441984865Sobrien /* We want to find out if tocval is a good value to use 4420130561Sobrien as the TOC anchor--that is, whether we can access all 4421130561Sobrien of the TOC using a 16 bit offset from tocval. This 4422130561Sobrien test assumes that the TOC comes at the end of the 4423130561Sobrien output section, as it does in the default linker 4424130561Sobrien script. */ 442584865Sobrien tocend = ((*csectpp)->output_section->vma 442684865Sobrien + (*csectpp)->output_section->_raw_size); 442784865Sobrien for (inp = finfo->info->input_bfds; 442884865Sobrien inp != NULL; 442984865Sobrien inp = inp->link_next) 443084865Sobrien { 443184865Sobrien 443284865Sobrien for (o = inp->sections; o != NULL; o = o->next) 443384865Sobrien if (strcmp (o->name, ".tocbss") == 0) 443484865Sobrien { 443584865Sobrien bfd_vma new_toc_end; 443684865Sobrien new_toc_end = (o->output_section->vma 443784865Sobrien + o->output_offset 443884865Sobrien + o->_cooked_size); 443984865Sobrien if (new_toc_end > tocend) 444084865Sobrien tocend = new_toc_end; 444184865Sobrien } 444284865Sobrien 444384865Sobrien } 444484865Sobrien 444584865Sobrien if (tocval + 0x10000 < tocend) 444684865Sobrien { 444784865Sobrien (*_bfd_error_handler) 444884865Sobrien (_("TOC overflow: 0x%lx > 0x10000; try -mminimal-toc when compiling"), 444984865Sobrien (unsigned long) (tocend - tocval)); 445084865Sobrien bfd_set_error (bfd_error_file_too_big); 4451130561Sobrien return FALSE; 445284865Sobrien } 445384865Sobrien 445484865Sobrien if (tocval + 0x8000 < tocend) 445584865Sobrien { 445684865Sobrien bfd_vma tocadd; 445784865Sobrien 445884865Sobrien tocadd = tocend - (tocval + 0x8000); 445984865Sobrien tocval += tocadd; 446084865Sobrien isym.n_value += tocadd; 446184865Sobrien } 446284865Sobrien 446384865Sobrien finfo->toc_symindx = output_index; 446484865Sobrien xcoff_data (finfo->output_bfd)->toc = tocval; 446584865Sobrien xcoff_data (finfo->output_bfd)->sntoc = 446684865Sobrien (*csectpp)->output_section->target_index; 4467130561Sobrien require = TRUE; 446894536Sobrien 446984865Sobrien } 447084865Sobrien } 447184865Sobrien 447284865Sobrien /* If we are stripping all symbols, we want to skip this one. */ 447384865Sobrien if (! skip 447484865Sobrien && finfo->info->strip == strip_all) 4475130561Sobrien skip = TRUE; 447684865Sobrien 447784865Sobrien /* We can skip resolved external references. */ 447884865Sobrien if (! skip 447984865Sobrien && isym.n_sclass == C_EXT 448084865Sobrien && smtyp == XTY_ER 448184865Sobrien && (*sym_hash)->root.type != bfd_link_hash_undefined) 4482130561Sobrien skip = TRUE; 448384865Sobrien 448484865Sobrien /* We can skip common symbols if they got defined somewhere 4485130561Sobrien else. */ 448684865Sobrien if (! skip 448784865Sobrien && isym.n_sclass == C_EXT 448884865Sobrien && smtyp == XTY_CM 448984865Sobrien && ((*sym_hash)->root.type != bfd_link_hash_common 449084865Sobrien || (*sym_hash)->root.u.c.p->section != *csectpp) 449184865Sobrien && ((*sym_hash)->root.type != bfd_link_hash_defined 449284865Sobrien || (*sym_hash)->root.u.def.section != *csectpp)) 4493130561Sobrien skip = TRUE; 449484865Sobrien 449584865Sobrien /* Skip local symbols if we are discarding them. */ 449684865Sobrien if (! skip 449784865Sobrien && finfo->info->discard == discard_all 449884865Sobrien && isym.n_sclass != C_EXT 449984865Sobrien && (isym.n_sclass != C_HIDEXT 450084865Sobrien || smtyp != XTY_SD)) 4501130561Sobrien skip = TRUE; 450284865Sobrien 450384865Sobrien /* If we stripping debugging symbols, and this is a debugging 4504130561Sobrien symbol, then skip it. */ 450584865Sobrien if (! skip 450684865Sobrien && finfo->info->strip == strip_debugger 450784865Sobrien && isym.n_scnum == N_DEBUG) 4508130561Sobrien skip = TRUE; 450984865Sobrien 451084865Sobrien /* If some symbols are stripped based on the name, work out the 451184865Sobrien name and decide whether to skip this symbol. We don't handle 451284865Sobrien this correctly for symbols whose names are in the .debug 451384865Sobrien section; to get it right we would need a new bfd_strtab_hash 451484865Sobrien function to return the string given the index. */ 451584865Sobrien if (! skip 451684865Sobrien && (finfo->info->strip == strip_some 451784865Sobrien || finfo->info->discard == discard_l) 451884865Sobrien && (debug_index == NULL || *debug_index == (unsigned long) -1)) 451984865Sobrien { 452084865Sobrien const char *name; 452184865Sobrien char buf[SYMNMLEN + 1]; 452284865Sobrien 452384865Sobrien name = _bfd_coff_internal_syment_name (input_bfd, &isym, buf); 452494536Sobrien 452584865Sobrien if (name == NULL) 4526130561Sobrien return FALSE; 452784865Sobrien 452884865Sobrien if ((finfo->info->strip == strip_some 4529130561Sobrien && (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE, 4530130561Sobrien FALSE) == NULL)) 453184865Sobrien || (finfo->info->discard == discard_l 453284865Sobrien && (isym.n_sclass != C_EXT 453384865Sobrien && (isym.n_sclass != C_HIDEXT 453484865Sobrien || smtyp != XTY_SD)) 453584865Sobrien && bfd_is_local_label_name (input_bfd, name))) 4536130561Sobrien skip = TRUE; 453784865Sobrien } 453884865Sobrien 453984865Sobrien /* We can not skip the first TOC anchor. */ 454084865Sobrien if (skip 454184865Sobrien && require 454284865Sobrien && finfo->info->strip != strip_all) 4543130561Sobrien skip = FALSE; 454484865Sobrien 454584865Sobrien /* We now know whether we are to skip this symbol or not. */ 454684865Sobrien if (! skip) 454784865Sobrien { 454884865Sobrien /* Adjust the symbol in order to output it. */ 454984865Sobrien 455084865Sobrien if (isym._n._n_n._n_zeroes == 0 455184865Sobrien && isym._n._n_n._n_offset != 0) 455284865Sobrien { 455384865Sobrien /* This symbol has a long name. Enter it in the string 455484865Sobrien table we are building. If *debug_index != -1, the 455584865Sobrien name has already been entered in the .debug section. */ 455684865Sobrien if (debug_index != NULL && *debug_index != (unsigned long) -1) 455784865Sobrien isym._n._n_n._n_offset = *debug_index; 455884865Sobrien else 455984865Sobrien { 456084865Sobrien const char *name; 456184865Sobrien bfd_size_type indx; 456284865Sobrien 456384865Sobrien name = _bfd_coff_internal_syment_name (input_bfd, &isym, 456484865Sobrien (char *) NULL); 456594536Sobrien 456684865Sobrien if (name == NULL) 4567130561Sobrien return FALSE; 456884865Sobrien indx = _bfd_stringtab_add (finfo->strtab, name, hash, copy); 456984865Sobrien if (indx == (bfd_size_type) -1) 4570130561Sobrien return FALSE; 457184865Sobrien isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx; 457284865Sobrien } 457384865Sobrien } 457484865Sobrien 457584865Sobrien if (isym.n_sclass != C_BSTAT 457684865Sobrien && isym.n_sclass != C_ESTAT 457784865Sobrien && isym.n_sclass != C_DECL 457884865Sobrien && isym.n_scnum > 0) 457984865Sobrien { 458084865Sobrien isym.n_scnum = (*csectpp)->output_section->target_index; 458184865Sobrien isym.n_value += ((*csectpp)->output_section->vma 458284865Sobrien + (*csectpp)->output_offset 458384865Sobrien - (*csectpp)->vma); 458484865Sobrien } 458584865Sobrien 458684865Sobrien /* The value of a C_FILE symbol is the symbol index of the 458784865Sobrien next C_FILE symbol. The value of the last C_FILE symbol 458884865Sobrien is -1. We try to get this right, below, just before we 458984865Sobrien write the symbols out, but in the general case we may 459084865Sobrien have to write the symbol out twice. */ 459184865Sobrien if (isym.n_sclass == C_FILE) 459284865Sobrien { 459384865Sobrien if (finfo->last_file_index != -1 459494536Sobrien && finfo->last_file.n_value != (bfd_vma) output_index) 459584865Sobrien { 459684865Sobrien /* We must correct the value of the last C_FILE entry. */ 459784865Sobrien finfo->last_file.n_value = output_index; 459884865Sobrien if ((bfd_size_type) finfo->last_file_index >= syment_base) 459984865Sobrien { 460084865Sobrien /* The last C_FILE symbol is in this input file. */ 460184865Sobrien bfd_coff_swap_sym_out (output_bfd, 460284865Sobrien (PTR) &finfo->last_file, 460384865Sobrien (PTR) (finfo->outsyms 460484865Sobrien + ((finfo->last_file_index 460584865Sobrien - syment_base) 460684865Sobrien * osymesz))); 460784865Sobrien } 460884865Sobrien else 460984865Sobrien { 461084865Sobrien /* We have already written out the last C_FILE 461184865Sobrien symbol. We need to write it out again. We 461284865Sobrien borrow *outsym temporarily. */ 461394536Sobrien file_ptr pos; 461494536Sobrien 461584865Sobrien bfd_coff_swap_sym_out (output_bfd, 461684865Sobrien (PTR) &finfo->last_file, 461784865Sobrien (PTR) outsym); 461894536Sobrien 461994536Sobrien pos = obj_sym_filepos (output_bfd); 462094536Sobrien pos += finfo->last_file_index * osymesz; 462194536Sobrien if (bfd_seek (output_bfd, pos, SEEK_SET) != 0 462294536Sobrien || (bfd_bwrite (outsym, osymesz, output_bfd) 462384865Sobrien != osymesz)) 4624130561Sobrien return FALSE; 462584865Sobrien } 462684865Sobrien } 462784865Sobrien 462884865Sobrien finfo->last_file_index = output_index; 462984865Sobrien finfo->last_file = isym; 463084865Sobrien } 463184865Sobrien 463284865Sobrien /* The value of a C_BINCL or C_EINCL symbol is a file offset 4633130561Sobrien into the line numbers. We update the symbol values when 4634130561Sobrien we handle the line numbers. */ 463584865Sobrien if (isym.n_sclass == C_BINCL 463684865Sobrien || isym.n_sclass == C_EINCL) 463784865Sobrien { 463884865Sobrien isym.n_value = finfo->line_filepos; 463984865Sobrien ++incls; 464084865Sobrien } 464184865Sobrien 464284865Sobrien /* Output the symbol. */ 464384865Sobrien 464484865Sobrien bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym); 464584865Sobrien 464684865Sobrien *indexp = output_index; 464784865Sobrien 464884865Sobrien if (isym.n_sclass == C_EXT) 464984865Sobrien { 465084865Sobrien long indx; 465184865Sobrien struct xcoff_link_hash_entry *h; 465284865Sobrien 465384865Sobrien indx = ((esym - (bfd_byte *) obj_coff_external_syms (input_bfd)) 465484865Sobrien / isymesz); 465584865Sobrien h = obj_xcoff_sym_hashes (input_bfd)[indx]; 465684865Sobrien BFD_ASSERT (h != NULL); 465784865Sobrien h->indx = output_index; 465884865Sobrien } 465984865Sobrien 466084865Sobrien /* If this is a symbol in the TOC which we may have merged 4661130561Sobrien (class XMC_TC), remember the symbol index of the TOC 4662130561Sobrien symbol. */ 466384865Sobrien if (isym.n_sclass == C_HIDEXT 466484865Sobrien && aux.x_csect.x_smclas == XMC_TC 466584865Sobrien && *sym_hash != NULL) 466684865Sobrien { 466784865Sobrien BFD_ASSERT (((*sym_hash)->flags & XCOFF_SET_TOC) == 0); 466884865Sobrien BFD_ASSERT ((*sym_hash)->toc_section != NULL); 466984865Sobrien (*sym_hash)->u.toc_indx = output_index; 467084865Sobrien } 467184865Sobrien 467284865Sobrien output_index += add; 467384865Sobrien outsym += add * osymesz; 467484865Sobrien } 467584865Sobrien 467684865Sobrien esym += add * isymesz; 467784865Sobrien isymp += add; 467884865Sobrien csectpp += add; 467984865Sobrien sym_hash += add; 468084865Sobrien if (debug_index != NULL) 468184865Sobrien debug_index += add; 468284865Sobrien ++indexp; 468384865Sobrien for (--add; add > 0; --add) 468484865Sobrien *indexp++ = -1; 468584865Sobrien } 468684865Sobrien 468784865Sobrien /* Fix up the aux entries and the C_BSTAT symbols. This must be 468884865Sobrien done in a separate pass, because we don't know the correct symbol 468984865Sobrien indices until we have already decided which symbols we are going 469084865Sobrien to keep. */ 469184865Sobrien 469284865Sobrien esym = (bfd_byte *) obj_coff_external_syms (input_bfd); 469384865Sobrien esym_end = esym + obj_raw_syment_count (input_bfd) * isymesz; 469484865Sobrien isymp = finfo->internal_syms; 469584865Sobrien indexp = finfo->sym_indices; 469684865Sobrien csectpp = xcoff_data (input_bfd)->csects; 469784865Sobrien outsym = finfo->outsyms; 469884865Sobrien while (esym < esym_end) 469984865Sobrien { 470084865Sobrien int add; 470184865Sobrien 470284865Sobrien add = 1 + isymp->n_numaux; 470384865Sobrien 470484865Sobrien if (*indexp < 0) 470584865Sobrien esym += add * isymesz; 470684865Sobrien else 470784865Sobrien { 470884865Sobrien int i; 470984865Sobrien 471084865Sobrien if (isymp->n_sclass == C_BSTAT) 471184865Sobrien { 471284865Sobrien struct internal_syment isym; 471384865Sobrien 471494536Sobrien bfd_vma indx; 471594536Sobrien 471684865Sobrien /* The value of a C_BSTAT symbol is the symbol table 4717130561Sobrien index of the containing csect. */ 471884865Sobrien bfd_coff_swap_sym_in (output_bfd, (PTR) outsym, (PTR) &isym); 471984865Sobrien indx = isym.n_value; 472084865Sobrien if (indx < obj_raw_syment_count (input_bfd)) 472184865Sobrien { 472284865Sobrien long symindx; 472384865Sobrien 472484865Sobrien symindx = finfo->sym_indices[indx]; 472584865Sobrien if (symindx < 0) 472684865Sobrien isym.n_value = 0; 472784865Sobrien else 472884865Sobrien isym.n_value = symindx; 472984865Sobrien bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, 473084865Sobrien (PTR) outsym); 473184865Sobrien } 473284865Sobrien } 473384865Sobrien 473484865Sobrien esym += isymesz; 473584865Sobrien outsym += osymesz; 473684865Sobrien 473784865Sobrien for (i = 0; i < isymp->n_numaux && esym < esym_end; i++) 473884865Sobrien { 473984865Sobrien union internal_auxent aux; 474084865Sobrien 474184865Sobrien bfd_coff_swap_aux_in (input_bfd, (PTR) esym, isymp->n_type, 474284865Sobrien isymp->n_sclass, i, isymp->n_numaux, 474384865Sobrien (PTR) &aux); 474484865Sobrien 474584865Sobrien if (isymp->n_sclass == C_FILE) 474684865Sobrien { 474784865Sobrien /* This is the file name (or some comment put in by 474884865Sobrien the compiler). If it is long, we must put it in 474984865Sobrien the string table. */ 475084865Sobrien if (aux.x_file.x_n.x_zeroes == 0 475184865Sobrien && aux.x_file.x_n.x_offset != 0) 475284865Sobrien { 475384865Sobrien const char *filename; 475484865Sobrien bfd_size_type indx; 475584865Sobrien 475684865Sobrien BFD_ASSERT (aux.x_file.x_n.x_offset 475784865Sobrien >= STRING_SIZE_SIZE); 475884865Sobrien if (strings == NULL) 475984865Sobrien { 476084865Sobrien strings = _bfd_coff_read_string_table (input_bfd); 476184865Sobrien if (strings == NULL) 4762130561Sobrien return FALSE; 476384865Sobrien } 476484865Sobrien filename = strings + aux.x_file.x_n.x_offset; 476584865Sobrien indx = _bfd_stringtab_add (finfo->strtab, filename, 476684865Sobrien hash, copy); 476784865Sobrien if (indx == (bfd_size_type) -1) 4768130561Sobrien return FALSE; 476984865Sobrien aux.x_file.x_n.x_offset = STRING_SIZE_SIZE + indx; 477084865Sobrien } 477184865Sobrien } 477284865Sobrien else if ((isymp->n_sclass == C_EXT 477384865Sobrien || isymp->n_sclass == C_HIDEXT) 477484865Sobrien && i + 1 == isymp->n_numaux) 477584865Sobrien { 477694536Sobrien 477784865Sobrien /* We don't support type checking. I don't know if 4778130561Sobrien anybody does. */ 477984865Sobrien aux.x_csect.x_parmhash = 0; 478084865Sobrien /* I don't think anybody uses these fields, but we'd 4781130561Sobrien better clobber them just in case. */ 478284865Sobrien aux.x_csect.x_stab = 0; 478384865Sobrien aux.x_csect.x_snstab = 0; 478494536Sobrien 478584865Sobrien if (SMTYP_SMTYP (aux.x_csect.x_smtyp) == XTY_LD) 478684865Sobrien { 478784865Sobrien unsigned long indx; 478884865Sobrien 478984865Sobrien indx = aux.x_csect.x_scnlen.l; 479084865Sobrien if (indx < obj_raw_syment_count (input_bfd)) 479184865Sobrien { 479284865Sobrien long symindx; 479384865Sobrien 479484865Sobrien symindx = finfo->sym_indices[indx]; 479584865Sobrien if (symindx < 0) 479694536Sobrien { 479794536Sobrien aux.x_csect.x_scnlen.l = 0; 479894536Sobrien } 479984865Sobrien else 480094536Sobrien { 480194536Sobrien aux.x_csect.x_scnlen.l = symindx; 480294536Sobrien } 480384865Sobrien } 480484865Sobrien } 480584865Sobrien } 480684865Sobrien else if (isymp->n_sclass != C_STAT || isymp->n_type != T_NULL) 480784865Sobrien { 480884865Sobrien unsigned long indx; 480984865Sobrien 481084865Sobrien if (ISFCN (isymp->n_type) 481184865Sobrien || ISTAG (isymp->n_sclass) 481284865Sobrien || isymp->n_sclass == C_BLOCK 481384865Sobrien || isymp->n_sclass == C_FCN) 481484865Sobrien { 481584865Sobrien indx = aux.x_sym.x_fcnary.x_fcn.x_endndx.l; 481684865Sobrien if (indx > 0 481784865Sobrien && indx < obj_raw_syment_count (input_bfd)) 481884865Sobrien { 481984865Sobrien /* We look forward through the symbol for 4820130561Sobrien the index of the next symbol we are going 4821130561Sobrien to include. I don't know if this is 4822130561Sobrien entirely right. */ 482384865Sobrien while (finfo->sym_indices[indx] < 0 482484865Sobrien && indx < obj_raw_syment_count (input_bfd)) 482584865Sobrien ++indx; 482684865Sobrien if (indx >= obj_raw_syment_count (input_bfd)) 482784865Sobrien indx = output_index; 482884865Sobrien else 482984865Sobrien indx = finfo->sym_indices[indx]; 483084865Sobrien aux.x_sym.x_fcnary.x_fcn.x_endndx.l = indx; 483194536Sobrien 483284865Sobrien } 483384865Sobrien } 483484865Sobrien 483584865Sobrien indx = aux.x_sym.x_tagndx.l; 483684865Sobrien if (indx > 0 && indx < obj_raw_syment_count (input_bfd)) 483784865Sobrien { 483884865Sobrien long symindx; 483984865Sobrien 484084865Sobrien symindx = finfo->sym_indices[indx]; 484184865Sobrien if (symindx < 0) 484284865Sobrien aux.x_sym.x_tagndx.l = 0; 484384865Sobrien else 484484865Sobrien aux.x_sym.x_tagndx.l = symindx; 484584865Sobrien } 484694536Sobrien 484784865Sobrien } 484884865Sobrien 484984865Sobrien /* Copy over the line numbers, unless we are stripping 485084865Sobrien them. We do this on a symbol by symbol basis in 485184865Sobrien order to more easily handle garbage collection. */ 485284865Sobrien if ((isymp->n_sclass == C_EXT 485384865Sobrien || isymp->n_sclass == C_HIDEXT) 485484865Sobrien && i == 0 485584865Sobrien && isymp->n_numaux > 1 485684865Sobrien && ISFCN (isymp->n_type) 485784865Sobrien && aux.x_sym.x_fcnary.x_fcn.x_lnnoptr != 0) 485884865Sobrien { 485984865Sobrien if (finfo->info->strip != strip_none 486084865Sobrien && finfo->info->strip != strip_some) 486184865Sobrien aux.x_sym.x_fcnary.x_fcn.x_lnnoptr = 0; 486284865Sobrien else 486384865Sobrien { 486484865Sobrien asection *enclosing; 486584865Sobrien unsigned int enc_count; 486694536Sobrien bfd_signed_vma linoff; 486784865Sobrien struct internal_lineno lin; 486884865Sobrien 486984865Sobrien o = *csectpp; 487084865Sobrien enclosing = xcoff_section_data (abfd, o)->enclosing; 487184865Sobrien enc_count = xcoff_section_data (abfd, o)->lineno_count; 487284865Sobrien if (oline != enclosing) 487384865Sobrien { 487494536Sobrien file_ptr pos = enclosing->line_filepos; 487594536Sobrien bfd_size_type amt = linesz * enc_count; 487694536Sobrien if (bfd_seek (input_bfd, pos, SEEK_SET) != 0 487794536Sobrien || (bfd_bread (finfo->linenos, amt, input_bfd) 487894536Sobrien != amt)) 4879130561Sobrien return FALSE; 488084865Sobrien oline = enclosing; 488184865Sobrien } 488284865Sobrien 488384865Sobrien linoff = (aux.x_sym.x_fcnary.x_fcn.x_lnnoptr 488484865Sobrien - enclosing->line_filepos); 488584865Sobrien 488684865Sobrien bfd_coff_swap_lineno_in (input_bfd, 488784865Sobrien (PTR) (finfo->linenos + linoff), 488884865Sobrien (PTR) &lin); 488984865Sobrien if (lin.l_lnno != 0 489084865Sobrien || ((bfd_size_type) lin.l_addr.l_symndx 489184865Sobrien != ((esym 489284865Sobrien - isymesz 489384865Sobrien - ((bfd_byte *) 489484865Sobrien obj_coff_external_syms (input_bfd))) 489584865Sobrien / isymesz))) 489684865Sobrien aux.x_sym.x_fcnary.x_fcn.x_lnnoptr = 0; 489784865Sobrien else 489884865Sobrien { 489984865Sobrien bfd_byte *linpend, *linp; 490084865Sobrien bfd_vma offset; 490184865Sobrien bfd_size_type count; 490284865Sobrien 490384865Sobrien lin.l_addr.l_symndx = *indexp; 490484865Sobrien bfd_coff_swap_lineno_out (output_bfd, (PTR) &lin, 490584865Sobrien (PTR) (finfo->linenos 490684865Sobrien + linoff)); 490784865Sobrien 490884865Sobrien linpend = (finfo->linenos 490984865Sobrien + enc_count * linesz); 491084865Sobrien offset = (o->output_section->vma 491184865Sobrien + o->output_offset 491284865Sobrien - o->vma); 491384865Sobrien for (linp = finfo->linenos + linoff + linesz; 491484865Sobrien linp < linpend; 491584865Sobrien linp += linesz) 491684865Sobrien { 491784865Sobrien bfd_coff_swap_lineno_in (input_bfd, (PTR) linp, 491884865Sobrien (PTR) &lin); 491984865Sobrien if (lin.l_lnno == 0) 492084865Sobrien break; 492184865Sobrien lin.l_addr.l_paddr += offset; 492284865Sobrien bfd_coff_swap_lineno_out (output_bfd, 492384865Sobrien (PTR) &lin, 492484865Sobrien (PTR) linp); 492584865Sobrien } 492684865Sobrien 492784865Sobrien count = (linp - (finfo->linenos + linoff)) / linesz; 492884865Sobrien 492984865Sobrien aux.x_sym.x_fcnary.x_fcn.x_lnnoptr = 493084865Sobrien (o->output_section->line_filepos 493184865Sobrien + o->output_section->lineno_count * linesz); 493284865Sobrien 493384865Sobrien if (bfd_seek (output_bfd, 493484865Sobrien aux.x_sym.x_fcnary.x_fcn.x_lnnoptr, 493584865Sobrien SEEK_SET) != 0 493694536Sobrien || (bfd_bwrite (finfo->linenos + linoff, 493794536Sobrien linesz * count, output_bfd) 493884865Sobrien != linesz * count)) 4939130561Sobrien return FALSE; 494084865Sobrien 494184865Sobrien o->output_section->lineno_count += count; 494284865Sobrien 494384865Sobrien if (incls > 0) 494484865Sobrien { 494584865Sobrien struct internal_syment *iisp, *iispend; 494684865Sobrien long *iindp; 494784865Sobrien bfd_byte *oos; 494884865Sobrien int iiadd; 494984865Sobrien 495084865Sobrien /* Update any C_BINCL or C_EINCL symbols 4951130561Sobrien that refer to a line number in the 4952130561Sobrien range we just output. */ 495384865Sobrien iisp = finfo->internal_syms; 495484865Sobrien iispend = (iisp 495584865Sobrien + obj_raw_syment_count (input_bfd)); 495684865Sobrien iindp = finfo->sym_indices; 495784865Sobrien oos = finfo->outsyms; 495884865Sobrien while (iisp < iispend) 495984865Sobrien { 496084865Sobrien if (*iindp >= 0 496184865Sobrien && (iisp->n_sclass == C_BINCL 496284865Sobrien || iisp->n_sclass == C_EINCL) 496384865Sobrien && ((bfd_size_type) iisp->n_value 496494536Sobrien >= (bfd_size_type)(enclosing->line_filepos + linoff)) 496584865Sobrien && ((bfd_size_type) iisp->n_value 496684865Sobrien < (enclosing->line_filepos 496784865Sobrien + enc_count * linesz))) 496884865Sobrien { 496984865Sobrien struct internal_syment iis; 497084865Sobrien 497184865Sobrien bfd_coff_swap_sym_in (output_bfd, 497284865Sobrien (PTR) oos, 497384865Sobrien (PTR) &iis); 497484865Sobrien iis.n_value = 497584865Sobrien (iisp->n_value 497684865Sobrien - enclosing->line_filepos 497784865Sobrien - linoff 497884865Sobrien + aux.x_sym.x_fcnary.x_fcn.x_lnnoptr); 497984865Sobrien bfd_coff_swap_sym_out (output_bfd, 498084865Sobrien (PTR) &iis, 498184865Sobrien (PTR) oos); 498284865Sobrien --incls; 498384865Sobrien } 498484865Sobrien 498584865Sobrien iiadd = 1 + iisp->n_numaux; 498684865Sobrien if (*iindp >= 0) 498784865Sobrien oos += iiadd * osymesz; 498884865Sobrien iisp += iiadd; 498984865Sobrien iindp += iiadd; 499084865Sobrien } 499184865Sobrien } 499284865Sobrien } 499384865Sobrien } 499484865Sobrien } 499584865Sobrien 499684865Sobrien bfd_coff_swap_aux_out (output_bfd, (PTR) &aux, isymp->n_type, 499784865Sobrien isymp->n_sclass, i, isymp->n_numaux, 499884865Sobrien (PTR) outsym); 499984865Sobrien outsym += osymesz; 500084865Sobrien esym += isymesz; 500184865Sobrien } 500284865Sobrien } 500384865Sobrien 500484865Sobrien indexp += add; 500584865Sobrien isymp += add; 500684865Sobrien csectpp += add; 500784865Sobrien } 500884865Sobrien 500984865Sobrien /* If we swapped out a C_FILE symbol, guess that the next C_FILE 501084865Sobrien symbol will be the first symbol in the next input file. In the 501184865Sobrien normal case, this will save us from writing out the C_FILE symbol 501284865Sobrien again. */ 501384865Sobrien if (finfo->last_file_index != -1 501484865Sobrien && (bfd_size_type) finfo->last_file_index >= syment_base) 501584865Sobrien { 501684865Sobrien finfo->last_file.n_value = output_index; 501784865Sobrien bfd_coff_swap_sym_out (output_bfd, (PTR) &finfo->last_file, 501884865Sobrien (PTR) (finfo->outsyms 501984865Sobrien + ((finfo->last_file_index - syment_base) 502084865Sobrien * osymesz))); 502184865Sobrien } 502284865Sobrien 502384865Sobrien /* Write the modified symbols to the output file. */ 502484865Sobrien if (outsym > finfo->outsyms) 502584865Sobrien { 502694536Sobrien file_ptr pos = obj_sym_filepos (output_bfd) + syment_base * osymesz; 502794536Sobrien bfd_size_type amt = outsym - finfo->outsyms; 502894536Sobrien if (bfd_seek (output_bfd, pos, SEEK_SET) != 0 502994536Sobrien || bfd_bwrite (finfo->outsyms, amt, output_bfd) != amt) 5030130561Sobrien return FALSE; 503184865Sobrien 503284865Sobrien BFD_ASSERT ((obj_raw_syment_count (output_bfd) 503384865Sobrien + (outsym - finfo->outsyms) / osymesz) 503484865Sobrien == output_index); 503584865Sobrien 503684865Sobrien obj_raw_syment_count (output_bfd) = output_index; 503784865Sobrien } 503884865Sobrien 503984865Sobrien /* Don't let the linker relocation routines discard the symbols. */ 504084865Sobrien keep_syms = obj_coff_keep_syms (input_bfd); 5041130561Sobrien obj_coff_keep_syms (input_bfd) = TRUE; 504284865Sobrien 504384865Sobrien /* Relocate the contents of each section. */ 504484865Sobrien for (o = input_bfd->sections; o != NULL; o = o->next) 504584865Sobrien { 504694536Sobrien 504784865Sobrien bfd_byte *contents; 504884865Sobrien 504984865Sobrien if (! o->linker_mark) 505084865Sobrien { 505184865Sobrien /* This section was omitted from the link. */ 505284865Sobrien continue; 505384865Sobrien } 505484865Sobrien 505584865Sobrien if ((o->flags & SEC_HAS_CONTENTS) == 0 505684865Sobrien || o->_raw_size == 0 505784865Sobrien || (o->flags & SEC_IN_MEMORY) != 0) 505884865Sobrien continue; 505984865Sobrien 506084865Sobrien /* We have set filepos correctly for the sections we created to 506194536Sobrien represent csects, so bfd_get_section_contents should work. */ 506284865Sobrien if (coff_section_data (input_bfd, o) != NULL 506384865Sobrien && coff_section_data (input_bfd, o)->contents != NULL) 506484865Sobrien contents = coff_section_data (input_bfd, o)->contents; 506594536Sobrien else { 506694536Sobrien if (! bfd_get_section_contents (input_bfd, o, finfo->contents, 506794536Sobrien (file_ptr) 0, o->_raw_size)) 5068130561Sobrien return FALSE; 506994536Sobrien contents = finfo->contents; 507094536Sobrien } 507184865Sobrien 507284865Sobrien if ((o->flags & SEC_RELOC) != 0) 507384865Sobrien { 507484865Sobrien int target_index; 507584865Sobrien struct internal_reloc *internal_relocs; 507684865Sobrien struct internal_reloc *irel; 507784865Sobrien bfd_vma offset; 507884865Sobrien struct internal_reloc *irelend; 507984865Sobrien struct xcoff_link_hash_entry **rel_hash; 508084865Sobrien long r_symndx; 508184865Sobrien 508284865Sobrien /* Read in the relocs. */ 508384865Sobrien target_index = o->output_section->target_index; 508484865Sobrien internal_relocs = (xcoff_read_internal_relocs 5085130561Sobrien (input_bfd, o, FALSE, finfo->external_relocs, 5086130561Sobrien TRUE, 508784865Sobrien (finfo->section_info[target_index].relocs 508884865Sobrien + o->output_section->reloc_count))); 508984865Sobrien if (internal_relocs == NULL) 5090130561Sobrien return FALSE; 509184865Sobrien 509284865Sobrien /* Call processor specific code to relocate the section 509394536Sobrien contents. */ 509484865Sobrien if (! bfd_coff_relocate_section (output_bfd, finfo->info, 509584865Sobrien input_bfd, o, 509684865Sobrien contents, 509784865Sobrien internal_relocs, 509884865Sobrien finfo->internal_syms, 509984865Sobrien xcoff_data (input_bfd)->csects)) 5100130561Sobrien return FALSE; 510184865Sobrien 510284865Sobrien offset = o->output_section->vma + o->output_offset - o->vma; 510384865Sobrien irel = internal_relocs; 510484865Sobrien irelend = irel + o->reloc_count; 510584865Sobrien rel_hash = (finfo->section_info[target_index].rel_hashes 510684865Sobrien + o->output_section->reloc_count); 510784865Sobrien for (; irel < irelend; irel++, rel_hash++) 510884865Sobrien { 510984865Sobrien struct xcoff_link_hash_entry *h = NULL; 511084865Sobrien struct internal_ldrel ldrel; 5111130561Sobrien bfd_boolean quiet; 511284865Sobrien 511384865Sobrien *rel_hash = NULL; 511484865Sobrien 511584865Sobrien /* Adjust the reloc address and symbol index. */ 511684865Sobrien 511784865Sobrien irel->r_vaddr += offset; 511884865Sobrien 511984865Sobrien r_symndx = irel->r_symndx; 512084865Sobrien 512184865Sobrien if (r_symndx == -1) 512284865Sobrien h = NULL; 512384865Sobrien else 512484865Sobrien h = obj_xcoff_sym_hashes (input_bfd)[r_symndx]; 512584865Sobrien 512684865Sobrien if (r_symndx != -1 && finfo->info->strip != strip_all) 512784865Sobrien { 512884865Sobrien if (h != NULL 512984865Sobrien && h->smclas != XMC_TD 513084865Sobrien && (irel->r_type == R_TOC 513184865Sobrien || irel->r_type == R_GL 513284865Sobrien || irel->r_type == R_TCL 513384865Sobrien || irel->r_type == R_TRL 513484865Sobrien || irel->r_type == R_TRLA)) 513584865Sobrien { 513684865Sobrien /* This is a TOC relative reloc with a symbol 513794536Sobrien attached. The symbol should be the one which 513894536Sobrien this reloc is for. We want to make this 513994536Sobrien reloc against the TOC address of the symbol, 514094536Sobrien not the symbol itself. */ 514184865Sobrien BFD_ASSERT (h->toc_section != NULL); 514284865Sobrien BFD_ASSERT ((h->flags & XCOFF_SET_TOC) == 0); 514384865Sobrien if (h->u.toc_indx != -1) 514484865Sobrien irel->r_symndx = h->u.toc_indx; 514584865Sobrien else 514684865Sobrien { 514784865Sobrien struct xcoff_toc_rel_hash *n; 514884865Sobrien struct xcoff_link_section_info *si; 514994536Sobrien bfd_size_type amt; 515084865Sobrien 515194536Sobrien amt = sizeof (struct xcoff_toc_rel_hash); 515284865Sobrien n = ((struct xcoff_toc_rel_hash *) 515394536Sobrien bfd_alloc (finfo->output_bfd, amt)); 515484865Sobrien if (n == NULL) 5155130561Sobrien return FALSE; 515684865Sobrien si = finfo->section_info + target_index; 515784865Sobrien n->next = si->toc_rel_hashes; 515884865Sobrien n->h = h; 515984865Sobrien n->rel = irel; 516084865Sobrien si->toc_rel_hashes = n; 516184865Sobrien } 516284865Sobrien } 516384865Sobrien else if (h != NULL) 516484865Sobrien { 516584865Sobrien /* This is a global symbol. */ 516684865Sobrien if (h->indx >= 0) 516784865Sobrien irel->r_symndx = h->indx; 516884865Sobrien else 516984865Sobrien { 517084865Sobrien /* This symbol is being written at the end 517184865Sobrien of the file, and we do not yet know the 517284865Sobrien symbol index. We save the pointer to the 517384865Sobrien hash table entry in the rel_hash list. 517484865Sobrien We set the indx field to -2 to indicate 517584865Sobrien that this symbol must not be stripped. */ 517684865Sobrien *rel_hash = h; 517784865Sobrien h->indx = -2; 517884865Sobrien } 517984865Sobrien } 518084865Sobrien else 518184865Sobrien { 518284865Sobrien long indx; 518384865Sobrien 518484865Sobrien indx = finfo->sym_indices[r_symndx]; 518584865Sobrien 518684865Sobrien if (indx == -1) 518784865Sobrien { 518884865Sobrien struct internal_syment *is; 518984865Sobrien 519084865Sobrien /* Relocations against a TC0 TOC anchor are 519184865Sobrien automatically transformed to be against 519284865Sobrien the TOC anchor in the output file. */ 519384865Sobrien is = finfo->internal_syms + r_symndx; 519484865Sobrien if (is->n_sclass == C_HIDEXT 519584865Sobrien && is->n_numaux > 0) 519684865Sobrien { 519784865Sobrien PTR auxptr; 519884865Sobrien union internal_auxent aux; 519984865Sobrien 520084865Sobrien auxptr = ((PTR) 520184865Sobrien (((bfd_byte *) 520284865Sobrien obj_coff_external_syms (input_bfd)) 520384865Sobrien + ((r_symndx + is->n_numaux) 520484865Sobrien * isymesz))); 520584865Sobrien bfd_coff_swap_aux_in (input_bfd, auxptr, 520684865Sobrien is->n_type, is->n_sclass, 520784865Sobrien is->n_numaux - 1, 520884865Sobrien is->n_numaux, 520984865Sobrien (PTR) &aux); 521084865Sobrien if (SMTYP_SMTYP (aux.x_csect.x_smtyp) == XTY_SD 521184865Sobrien && aux.x_csect.x_smclas == XMC_TC0) 521284865Sobrien indx = finfo->toc_symindx; 521384865Sobrien } 521484865Sobrien } 521584865Sobrien 521684865Sobrien if (indx != -1) 521784865Sobrien irel->r_symndx = indx; 521884865Sobrien else 521984865Sobrien { 522094536Sobrien 522184865Sobrien struct internal_syment *is; 522294536Sobrien 522384865Sobrien const char *name; 522484865Sobrien char buf[SYMNMLEN + 1]; 522584865Sobrien 522684865Sobrien /* This reloc is against a symbol we are 522784865Sobrien stripping. It would be possible to handle 522884865Sobrien this case, but I don't think it's worth it. */ 522984865Sobrien is = finfo->internal_syms + r_symndx; 523084865Sobrien 523184865Sobrien name = (_bfd_coff_internal_syment_name 523284865Sobrien (input_bfd, is, buf)); 523394536Sobrien 523484865Sobrien if (name == NULL) 5235130561Sobrien return FALSE; 523684865Sobrien 523784865Sobrien if (! ((*finfo->info->callbacks->unattached_reloc) 523884865Sobrien (finfo->info, name, input_bfd, o, 523984865Sobrien irel->r_vaddr))) 5240130561Sobrien return FALSE; 524184865Sobrien } 524284865Sobrien } 524384865Sobrien } 524484865Sobrien 5245130561Sobrien quiet = FALSE; 524684865Sobrien switch (irel->r_type) 524784865Sobrien { 524884865Sobrien default: 524984865Sobrien if (h == NULL 525084865Sobrien || h->root.type == bfd_link_hash_defined 525184865Sobrien || h->root.type == bfd_link_hash_defweak 525284865Sobrien || h->root.type == bfd_link_hash_common) 525384865Sobrien break; 525484865Sobrien /* Fall through. */ 525584865Sobrien case R_POS: 525684865Sobrien case R_NEG: 525784865Sobrien case R_RL: 525884865Sobrien case R_RLA: 525984865Sobrien /* This reloc needs to be copied into the .loader 526084865Sobrien section. */ 526184865Sobrien ldrel.l_vaddr = irel->r_vaddr; 526284865Sobrien if (r_symndx == -1) 526394536Sobrien ldrel.l_symndx = -(bfd_size_type ) 1; 526484865Sobrien else if (h == NULL 526584865Sobrien || (h->root.type == bfd_link_hash_defined 526684865Sobrien || h->root.type == bfd_link_hash_defweak 526784865Sobrien || h->root.type == bfd_link_hash_common)) 526884865Sobrien { 526984865Sobrien asection *sec; 527084865Sobrien 527184865Sobrien if (h == NULL) 527284865Sobrien sec = xcoff_data (input_bfd)->csects[r_symndx]; 527384865Sobrien else if (h->root.type == bfd_link_hash_common) 527484865Sobrien sec = h->root.u.c.p->section; 527584865Sobrien else 527684865Sobrien sec = h->root.u.def.section; 527784865Sobrien sec = sec->output_section; 527884865Sobrien 527984865Sobrien if (strcmp (sec->name, ".text") == 0) 528084865Sobrien ldrel.l_symndx = 0; 528184865Sobrien else if (strcmp (sec->name, ".data") == 0) 528284865Sobrien ldrel.l_symndx = 1; 528384865Sobrien else if (strcmp (sec->name, ".bss") == 0) 528484865Sobrien ldrel.l_symndx = 2; 528584865Sobrien else 528684865Sobrien { 528784865Sobrien (*_bfd_error_handler) 528884865Sobrien (_("%s: loader reloc in unrecognized section `%s'"), 528994536Sobrien bfd_archive_filename (input_bfd), 529084865Sobrien sec->name); 529184865Sobrien bfd_set_error (bfd_error_nonrepresentable_section); 5292130561Sobrien return FALSE; 529384865Sobrien } 529484865Sobrien } 529584865Sobrien else 529684865Sobrien { 5297130561Sobrien if (! finfo->info->relocatable 529884865Sobrien && (h->flags & XCOFF_DEF_DYNAMIC) == 0 529984865Sobrien && (h->flags & XCOFF_IMPORT) == 0) 530084865Sobrien { 530184865Sobrien /* We already called the undefined_symbol 530284865Sobrien callback for this relocation, in 530384865Sobrien _bfd_ppc_xcoff_relocate_section. Don't 530484865Sobrien issue any more warnings. */ 5305130561Sobrien quiet = TRUE; 530684865Sobrien } 530784865Sobrien if (h->ldindx < 0 && ! quiet) 530884865Sobrien { 530984865Sobrien (*_bfd_error_handler) 531084865Sobrien (_("%s: `%s' in loader reloc but not loader sym"), 531194536Sobrien bfd_archive_filename (input_bfd), 531284865Sobrien h->root.root.string); 531384865Sobrien bfd_set_error (bfd_error_bad_value); 5314130561Sobrien return FALSE; 531584865Sobrien } 531684865Sobrien ldrel.l_symndx = h->ldindx; 531784865Sobrien } 531884865Sobrien ldrel.l_rtype = (irel->r_size << 8) | irel->r_type; 531984865Sobrien ldrel.l_rsecnm = o->output_section->target_index; 532084865Sobrien if (xcoff_hash_table (finfo->info)->textro 532184865Sobrien && strcmp (o->output_section->name, ".text") == 0 532284865Sobrien && ! quiet) 532384865Sobrien { 532484865Sobrien (*_bfd_error_handler) 532584865Sobrien (_("%s: loader reloc in read-only section %s"), 532694536Sobrien bfd_archive_filename (input_bfd), 532784865Sobrien bfd_get_section_name (finfo->output_bfd, 532884865Sobrien o->output_section)); 532984865Sobrien bfd_set_error (bfd_error_invalid_operation); 5330130561Sobrien return FALSE; 533184865Sobrien } 533294536Sobrien bfd_xcoff_swap_ldrel_out (output_bfd, &ldrel, 533394536Sobrien finfo->ldrel); 533494536Sobrien 533594536Sobrien finfo->ldrel += bfd_xcoff_ldrelsz(output_bfd); 533684865Sobrien break; 533784865Sobrien 533884865Sobrien case R_TOC: 533984865Sobrien case R_GL: 534084865Sobrien case R_TCL: 534184865Sobrien case R_TRL: 534284865Sobrien case R_TRLA: 534384865Sobrien /* We should never need a .loader reloc for a TOC 534484865Sobrien relative reloc. */ 534584865Sobrien break; 534684865Sobrien } 534784865Sobrien } 534884865Sobrien 534984865Sobrien o->output_section->reloc_count += o->reloc_count; 535084865Sobrien } 535184865Sobrien 535284865Sobrien /* Write out the modified section contents. */ 535384865Sobrien if (! bfd_set_section_contents (output_bfd, o->output_section, 535494536Sobrien contents, (file_ptr) o->output_offset, 535584865Sobrien (o->_cooked_size != 0 535684865Sobrien ? o->_cooked_size 535784865Sobrien : o->_raw_size))) 5358130561Sobrien return FALSE; 535984865Sobrien } 536084865Sobrien 536184865Sobrien obj_coff_keep_syms (input_bfd) = keep_syms; 536284865Sobrien 536384865Sobrien if (! finfo->info->keep_memory) 536484865Sobrien { 536584865Sobrien if (! _bfd_coff_free_symbols (input_bfd)) 5366130561Sobrien return FALSE; 536784865Sobrien } 536884865Sobrien 5369130561Sobrien return TRUE; 537084865Sobrien} 537184865Sobrien 537284865Sobrien#undef N_TMASK 537384865Sobrien#undef N_BTSHFT 537484865Sobrien 537584865Sobrien/* Write out a non-XCOFF global symbol. */ 537684865Sobrien 537794536Sobrien 5378130561Sobrienstatic bfd_boolean 537994536Sobrienxcoff_write_global_symbol (h, inf) 538084865Sobrien struct xcoff_link_hash_entry *h; 538194536Sobrien PTR inf; 538284865Sobrien{ 538394536Sobrien struct xcoff_final_link_info *finfo = (struct xcoff_final_link_info *) inf; 538484865Sobrien bfd *output_bfd; 538584865Sobrien bfd_byte *outsym; 538684865Sobrien struct internal_syment isym; 538784865Sobrien union internal_auxent aux; 5388130561Sobrien bfd_boolean result; 538994536Sobrien file_ptr pos; 539094536Sobrien bfd_size_type amt; 539184865Sobrien 539284865Sobrien output_bfd = finfo->output_bfd; 539384865Sobrien outsym = finfo->outsyms; 539484865Sobrien 539594536Sobrien if (h->root.type == bfd_link_hash_warning) 539694536Sobrien { 539794536Sobrien h = (struct xcoff_link_hash_entry *) h->root.u.i.link; 539894536Sobrien if (h->root.type == bfd_link_hash_new) 5399130561Sobrien return TRUE; 540094536Sobrien } 540194536Sobrien 540284865Sobrien /* If this symbol was garbage collected, just skip it. */ 540384865Sobrien if (xcoff_hash_table (finfo->info)->gc 540484865Sobrien && (h->flags & XCOFF_MARK) == 0) 5405130561Sobrien return TRUE; 540684865Sobrien 540784865Sobrien /* If we need a .loader section entry, write it out. */ 540884865Sobrien if (h->ldsym != NULL) 540984865Sobrien { 541084865Sobrien struct internal_ldsym *ldsym; 541184865Sobrien bfd *impbfd; 541284865Sobrien 541384865Sobrien ldsym = h->ldsym; 541484865Sobrien 541584865Sobrien if (h->root.type == bfd_link_hash_undefined 541684865Sobrien || h->root.type == bfd_link_hash_undefweak) 541784865Sobrien { 541894536Sobrien 541984865Sobrien ldsym->l_value = 0; 542084865Sobrien ldsym->l_scnum = N_UNDEF; 542184865Sobrien ldsym->l_smtype = XTY_ER; 542284865Sobrien impbfd = h->root.u.undef.abfd; 542394536Sobrien 542484865Sobrien } 542584865Sobrien else if (h->root.type == bfd_link_hash_defined 542684865Sobrien || h->root.type == bfd_link_hash_defweak) 542784865Sobrien { 542894536Sobrien 542984865Sobrien asection *sec; 543084865Sobrien 543184865Sobrien sec = h->root.u.def.section; 543284865Sobrien ldsym->l_value = (sec->output_section->vma 543384865Sobrien + sec->output_offset 543484865Sobrien + h->root.u.def.value); 543584865Sobrien ldsym->l_scnum = sec->output_section->target_index; 543684865Sobrien ldsym->l_smtype = XTY_SD; 543784865Sobrien impbfd = sec->owner; 543894536Sobrien 543984865Sobrien } 544084865Sobrien else 544184865Sobrien abort (); 544284865Sobrien 544384865Sobrien if (((h->flags & XCOFF_DEF_REGULAR) == 0 544484865Sobrien && (h->flags & XCOFF_DEF_DYNAMIC) != 0) 544584865Sobrien || (h->flags & XCOFF_IMPORT) != 0) 544694536Sobrien { 544794536Sobrien /* Clear l_smtype 544894536Sobrien Import symbols are defined so the check above will make 544994536Sobrien the l_smtype XTY_SD. But this is not correct, it should 545094536Sobrien be cleared. */ 545194536Sobrien ldsym->l_smtype |= L_IMPORT; 545294536Sobrien } 545394536Sobrien 545484865Sobrien if (((h->flags & XCOFF_DEF_REGULAR) != 0 545584865Sobrien && (h->flags & XCOFF_DEF_DYNAMIC) != 0) 545684865Sobrien || (h->flags & XCOFF_EXPORT) != 0) 545794536Sobrien { 545894536Sobrien ldsym->l_smtype |= L_EXPORT; 545994536Sobrien } 546094536Sobrien 546184865Sobrien if ((h->flags & XCOFF_ENTRY) != 0) 546294536Sobrien { 546394536Sobrien ldsym->l_smtype |= L_ENTRY; 546494536Sobrien } 546584865Sobrien 546694536Sobrien if ((h->flags & XCOFF_RTINIT) != 0) 546794536Sobrien { 546894536Sobrien ldsym->l_smtype = XTY_SD; 546994536Sobrien } 547094536Sobrien 547184865Sobrien ldsym->l_smclas = h->smclas; 547284865Sobrien 547394536Sobrien if (ldsym->l_smtype & L_IMPORT) 547494536Sobrien { 547594536Sobrien if ((h->root.type == bfd_link_hash_defined 547694536Sobrien || h->root.type == bfd_link_hash_defweak) 547794536Sobrien && (h->root.u.def.value != 0)) 547894536Sobrien { 547994536Sobrien ldsym->l_smclas = XMC_XO; 548094536Sobrien } 548194536Sobrien else if ((h->flags & (XCOFF_SYSCALL32 | XCOFF_SYSCALL64)) == 548294536Sobrien (XCOFF_SYSCALL32 | XCOFF_SYSCALL64)) 548394536Sobrien { 548494536Sobrien ldsym->l_smclas = XMC_SV3264; 548594536Sobrien } 548694536Sobrien else if (h->flags & XCOFF_SYSCALL32) 548794536Sobrien { 548894536Sobrien ldsym->l_smclas = XMC_SV; 548994536Sobrien } 549094536Sobrien else if (h->flags & XCOFF_SYSCALL64) 549194536Sobrien { 549294536Sobrien ldsym->l_smclas = XMC_SV64; 549394536Sobrien } 549494536Sobrien } 549594536Sobrien 549694536Sobrien if (ldsym->l_ifile == -(bfd_size_type) 1) 549794536Sobrien { 549894536Sobrien ldsym->l_ifile = 0; 549994536Sobrien } 550084865Sobrien else if (ldsym->l_ifile == 0) 550184865Sobrien { 550284865Sobrien if ((ldsym->l_smtype & L_IMPORT) == 0) 550394536Sobrien { 550494536Sobrien ldsym->l_ifile = 0; 550594536Sobrien } 550684865Sobrien else if (impbfd == NULL) 550794536Sobrien { 550894536Sobrien ldsym->l_ifile = 0; 550994536Sobrien } 551084865Sobrien else 551184865Sobrien { 551284865Sobrien BFD_ASSERT (impbfd->xvec == output_bfd->xvec); 551384865Sobrien ldsym->l_ifile = xcoff_data (impbfd)->import_file_id; 551484865Sobrien } 551584865Sobrien } 551684865Sobrien 551784865Sobrien ldsym->l_parm = 0; 551884865Sobrien 551984865Sobrien BFD_ASSERT (h->ldindx >= 0); 552094536Sobrien 552194536Sobrien bfd_xcoff_swap_ldsym_out (output_bfd, ldsym, 552294536Sobrien (finfo->ldsym + 552394536Sobrien (h->ldindx - 3) 552494536Sobrien * bfd_xcoff_ldsymsz(finfo->output_bfd))); 552584865Sobrien h->ldsym = NULL; 552684865Sobrien } 552784865Sobrien 552884865Sobrien /* If this symbol needs global linkage code, write it out. */ 552984865Sobrien if (h->root.type == bfd_link_hash_defined 553084865Sobrien && (h->root.u.def.section 553184865Sobrien == xcoff_hash_table (finfo->info)->linkage_section)) 553284865Sobrien { 553384865Sobrien bfd_byte *p; 553484865Sobrien bfd_vma tocoff; 553584865Sobrien unsigned int i; 553684865Sobrien 553784865Sobrien p = h->root.u.def.section->contents + h->root.u.def.value; 553884865Sobrien 553984865Sobrien /* The first instruction in the global linkage code loads a 554094536Sobrien specific TOC element. */ 554184865Sobrien tocoff = (h->descriptor->toc_section->output_section->vma 554284865Sobrien + h->descriptor->toc_section->output_offset 554384865Sobrien - xcoff_data (output_bfd)->toc); 554494536Sobrien 554584865Sobrien if ((h->descriptor->flags & XCOFF_SET_TOC) != 0) 554694536Sobrien { 554794536Sobrien tocoff += h->descriptor->u.toc_offset; 554894536Sobrien } 554994536Sobrien 555094536Sobrien 555194536Sobrien /* The first instruction in the glink code needs to be 555294536Sobrien cooked to to hold the correct offset in the toc. The 555394536Sobrien rest are just output raw. */ 555494536Sobrien bfd_put_32 (output_bfd, 555594536Sobrien bfd_xcoff_glink_code(output_bfd, 0) | (tocoff & 0xffff), p); 555694536Sobrien 555794536Sobrien /* Start with i == 1 to get past the first instruction done above 555894536Sobrien The /4 is because the glink code is in bytes and we are going 555994536Sobrien 4 at a pop. */ 556094536Sobrien for (i = 1; i < bfd_xcoff_glink_code_size(output_bfd) / 4; i++) 556194536Sobrien { 556294536Sobrien bfd_put_32 (output_bfd, 556394536Sobrien (bfd_vma) bfd_xcoff_glink_code(output_bfd, i), 556494536Sobrien &p[4 * i]); 556594536Sobrien } 556684865Sobrien } 556784865Sobrien 556884865Sobrien /* If we created a TOC entry for this symbol, write out the required 556984865Sobrien relocs. */ 557084865Sobrien if ((h->flags & XCOFF_SET_TOC) != 0) 557184865Sobrien { 557284865Sobrien asection *tocsec; 557384865Sobrien asection *osec; 557484865Sobrien int oindx; 557584865Sobrien struct internal_reloc *irel; 557684865Sobrien struct internal_ldrel ldrel; 557784865Sobrien struct internal_syment irsym; 557884865Sobrien union internal_auxent iraux; 557984865Sobrien 558084865Sobrien tocsec = h->toc_section; 558184865Sobrien osec = tocsec->output_section; 558284865Sobrien oindx = osec->target_index; 558384865Sobrien irel = finfo->section_info[oindx].relocs + osec->reloc_count; 558484865Sobrien irel->r_vaddr = (osec->vma 558584865Sobrien + tocsec->output_offset 558684865Sobrien + h->u.toc_offset); 558794536Sobrien 558894536Sobrien 558984865Sobrien if (h->indx >= 0) 559094536Sobrien { 559194536Sobrien irel->r_symndx = h->indx; 559294536Sobrien } 559384865Sobrien else 559484865Sobrien { 559584865Sobrien h->indx = -2; 559684865Sobrien irel->r_symndx = obj_raw_syment_count (output_bfd); 559784865Sobrien } 559894536Sobrien 559994536Sobrien BFD_ASSERT (h->ldindx >= 0); 560094536Sobrien 560194536Sobrien /* Initialize the aux union here instead of closer to when it is 560294536Sobrien written out below because the length of the csect depends on 560394536Sobrien whether the output is 32 or 64 bit. */ 560494536Sobrien memset (&iraux, 0, sizeof iraux); 560594536Sobrien iraux.x_csect.x_smtyp = XTY_SD; 560694536Sobrien /* iraux.x_csect.x_scnlen.l = 4 or 8, see below */ 560794536Sobrien iraux.x_csect.x_smclas = XMC_TC; 560894536Sobrien 560994536Sobrien /* 32 bit uses a 32 bit R_POS to do the relocations 561094536Sobrien 64 bit uses a 64 bit R_POS to do the relocations 561194536Sobrien 561294536Sobrien Also needs to change the csect size : 4 for 32 bit, 8 for 64 bit 561394536Sobrien 561494536Sobrien Which one is determined by the backend. */ 561594536Sobrien if (bfd_xcoff_is_xcoff64 (output_bfd)) 561694536Sobrien { 561794536Sobrien irel->r_size = 63; 561894536Sobrien iraux.x_csect.x_scnlen.l = 8; 561994536Sobrien } 562094536Sobrien else if (bfd_xcoff_is_xcoff32 (output_bfd)) 562194536Sobrien { 562294536Sobrien irel->r_size = 31; 562394536Sobrien iraux.x_csect.x_scnlen.l = 4; 562494536Sobrien } 562594536Sobrien else 562694536Sobrien { 5627130561Sobrien return FALSE; 562894536Sobrien } 562984865Sobrien irel->r_type = R_POS; 563084865Sobrien finfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL; 563184865Sobrien ++osec->reloc_count; 563284865Sobrien 563384865Sobrien ldrel.l_vaddr = irel->r_vaddr; 563484865Sobrien ldrel.l_symndx = h->ldindx; 563594536Sobrien ldrel.l_rtype = (irel->r_size << 8) | R_POS; 563684865Sobrien ldrel.l_rsecnm = oindx; 563794536Sobrien bfd_xcoff_swap_ldrel_out (output_bfd, &ldrel, finfo->ldrel); 563894536Sobrien finfo->ldrel += bfd_xcoff_ldrelsz(output_bfd); 563984865Sobrien 564094536Sobrien /* We need to emit a symbol to define a csect which holds 564194536Sobrien the reloc. */ 564284865Sobrien if (finfo->info->strip != strip_all) 564384865Sobrien { 564494536Sobrien 564594536Sobrien result = bfd_xcoff_put_symbol_name (output_bfd, finfo->strtab, 564694536Sobrien &irsym, h->root.root.string); 5647130561Sobrien if (!result) 5648130561Sobrien return FALSE; 564984865Sobrien 565084865Sobrien irsym.n_value = irel->r_vaddr; 565184865Sobrien irsym.n_scnum = osec->target_index; 565284865Sobrien irsym.n_sclass = C_HIDEXT; 565384865Sobrien irsym.n_type = T_NULL; 565484865Sobrien irsym.n_numaux = 1; 565584865Sobrien 565684865Sobrien bfd_coff_swap_sym_out (output_bfd, (PTR) &irsym, (PTR) outsym); 565784865Sobrien outsym += bfd_coff_symesz (output_bfd); 565884865Sobrien 565994536Sobrien /* note : iraux is initialized above */ 566084865Sobrien bfd_coff_swap_aux_out (output_bfd, (PTR) &iraux, T_NULL, C_HIDEXT, 566184865Sobrien 0, 1, (PTR) outsym); 566284865Sobrien outsym += bfd_coff_auxesz (output_bfd); 566384865Sobrien 566484865Sobrien if (h->indx >= 0) 566584865Sobrien { 566684865Sobrien /* We aren't going to write out the symbols below, so we 566784865Sobrien need to write them out now. */ 566894536Sobrien pos = obj_sym_filepos (output_bfd); 566994536Sobrien pos += (obj_raw_syment_count (output_bfd) 567094536Sobrien * bfd_coff_symesz (output_bfd)); 567194536Sobrien amt = outsym - finfo->outsyms; 567294536Sobrien if (bfd_seek (output_bfd, pos, SEEK_SET) != 0 567394536Sobrien || bfd_bwrite (finfo->outsyms, amt, output_bfd) != amt) 5674130561Sobrien return FALSE; 567584865Sobrien obj_raw_syment_count (output_bfd) += 567684865Sobrien (outsym - finfo->outsyms) / bfd_coff_symesz (output_bfd); 567784865Sobrien 567884865Sobrien outsym = finfo->outsyms; 567984865Sobrien } 568084865Sobrien } 568184865Sobrien } 568284865Sobrien 568384865Sobrien /* If this symbol is a specially defined function descriptor, write 568484865Sobrien it out. The first word is the address of the function code 568584865Sobrien itself, the second word is the address of the TOC, and the third 568694536Sobrien word is zero. 568794536Sobrien 568894536Sobrien 32 bit vs 64 bit 568994536Sobrien The addresses for the 32 bit will take 4 bytes and the addresses 569094536Sobrien for 64 bit will take 8 bytes. Similar for the relocs. This type 569194536Sobrien of logic was also done above to create a TOC entry in 569294536Sobrien xcoff_write_global_symbol. */ 569384865Sobrien if ((h->flags & XCOFF_DESCRIPTOR) != 0 569484865Sobrien && h->root.type == bfd_link_hash_defined 569584865Sobrien && (h->root.u.def.section 569684865Sobrien == xcoff_hash_table (finfo->info)->descriptor_section)) 569784865Sobrien { 569884865Sobrien asection *sec; 569984865Sobrien asection *osec; 570084865Sobrien int oindx; 570184865Sobrien bfd_byte *p; 570284865Sobrien struct xcoff_link_hash_entry *hentry; 570384865Sobrien asection *esec; 570484865Sobrien struct internal_reloc *irel; 570584865Sobrien struct internal_ldrel ldrel; 570684865Sobrien asection *tsec; 570794536Sobrien unsigned int reloc_size, byte_size; 570884865Sobrien 570994536Sobrien if (bfd_xcoff_is_xcoff64 (output_bfd)) 571094536Sobrien { 571194536Sobrien reloc_size = 63; 571294536Sobrien byte_size = 8; 571394536Sobrien } 571494536Sobrien else if (bfd_xcoff_is_xcoff32 (output_bfd)) 571594536Sobrien { 571694536Sobrien reloc_size = 31; 571794536Sobrien byte_size = 4; 571894536Sobrien } 571994536Sobrien else 572094536Sobrien { 5721130561Sobrien return FALSE; 572294536Sobrien } 572394536Sobrien 572484865Sobrien sec = h->root.u.def.section; 572584865Sobrien osec = sec->output_section; 572684865Sobrien oindx = osec->target_index; 572784865Sobrien p = sec->contents + h->root.u.def.value; 572884865Sobrien 572984865Sobrien hentry = h->descriptor; 573084865Sobrien BFD_ASSERT (hentry != NULL 573184865Sobrien && (hentry->root.type == bfd_link_hash_defined 573284865Sobrien || hentry->root.type == bfd_link_hash_defweak)); 573384865Sobrien esec = hentry->root.u.def.section; 573484865Sobrien 573584865Sobrien irel = finfo->section_info[oindx].relocs + osec->reloc_count; 573684865Sobrien irel->r_vaddr = (osec->vma 573784865Sobrien + sec->output_offset 573884865Sobrien + h->root.u.def.value); 573984865Sobrien irel->r_symndx = esec->output_section->target_index; 574084865Sobrien irel->r_type = R_POS; 574194536Sobrien irel->r_size = reloc_size; 574284865Sobrien finfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL; 574384865Sobrien ++osec->reloc_count; 574484865Sobrien 574584865Sobrien ldrel.l_vaddr = irel->r_vaddr; 574684865Sobrien if (strcmp (esec->output_section->name, ".text") == 0) 574784865Sobrien ldrel.l_symndx = 0; 574884865Sobrien else if (strcmp (esec->output_section->name, ".data") == 0) 574984865Sobrien ldrel.l_symndx = 1; 575084865Sobrien else if (strcmp (esec->output_section->name, ".bss") == 0) 575184865Sobrien ldrel.l_symndx = 2; 575284865Sobrien else 575384865Sobrien { 575484865Sobrien (*_bfd_error_handler) 575584865Sobrien (_("%s: loader reloc in unrecognized section `%s'"), 575684865Sobrien bfd_get_filename (output_bfd), 575784865Sobrien esec->output_section->name); 575884865Sobrien bfd_set_error (bfd_error_nonrepresentable_section); 5759130561Sobrien return FALSE; 576084865Sobrien } 576194536Sobrien ldrel.l_rtype = (reloc_size << 8) | R_POS; 576284865Sobrien ldrel.l_rsecnm = oindx; 576394536Sobrien bfd_xcoff_swap_ldrel_out (output_bfd, &ldrel, finfo->ldrel); 576494536Sobrien finfo->ldrel += bfd_xcoff_ldrelsz(output_bfd); 576584865Sobrien 576694536Sobrien /* There are three items to write out, 576794536Sobrien the address of the code 576894536Sobrien the address of the toc anchor 576994536Sobrien the environment pointer. 577094536Sobrien We are ignoring the environment pointer. So set it to zero. */ 577194536Sobrien if (bfd_xcoff_is_xcoff64 (output_bfd)) 577294536Sobrien { 577394536Sobrien bfd_put_64 (output_bfd, 577494536Sobrien (esec->output_section->vma + esec->output_offset 577594536Sobrien + hentry->root.u.def.value), 577694536Sobrien p); 577794536Sobrien bfd_put_64 (output_bfd, xcoff_data (output_bfd)->toc, p + 8); 577894536Sobrien bfd_put_64 (output_bfd, (bfd_vma) 0, p + 16); 577994536Sobrien } 578094536Sobrien else 578194536Sobrien { 578294536Sobrien /* 32 bit backend 578394536Sobrien This logic was already called above so the error case where 578494536Sobrien the backend is neither has already been checked. */ 578594536Sobrien bfd_put_32 (output_bfd, 578694536Sobrien (esec->output_section->vma + esec->output_offset 578794536Sobrien + hentry->root.u.def.value), 578894536Sobrien p); 578994536Sobrien bfd_put_32 (output_bfd, xcoff_data (output_bfd)->toc, p + 4); 579094536Sobrien bfd_put_32 (output_bfd, (bfd_vma) 0, p + 8); 579194536Sobrien } 579284865Sobrien 579384865Sobrien tsec = coff_section_from_bfd_index (output_bfd, 579484865Sobrien xcoff_data (output_bfd)->sntoc); 579584865Sobrien 579684865Sobrien ++irel; 579784865Sobrien irel->r_vaddr = (osec->vma 579884865Sobrien + sec->output_offset 579984865Sobrien + h->root.u.def.value 580094536Sobrien + byte_size); 580184865Sobrien irel->r_symndx = tsec->output_section->target_index; 580284865Sobrien irel->r_type = R_POS; 580394536Sobrien irel->r_size = reloc_size; 580484865Sobrien finfo->section_info[oindx].rel_hashes[osec->reloc_count] = NULL; 580584865Sobrien ++osec->reloc_count; 580684865Sobrien 580784865Sobrien ldrel.l_vaddr = irel->r_vaddr; 580884865Sobrien if (strcmp (tsec->output_section->name, ".text") == 0) 580984865Sobrien ldrel.l_symndx = 0; 581084865Sobrien else if (strcmp (tsec->output_section->name, ".data") == 0) 581184865Sobrien ldrel.l_symndx = 1; 581284865Sobrien else if (strcmp (tsec->output_section->name, ".bss") == 0) 581384865Sobrien ldrel.l_symndx = 2; 581484865Sobrien else 581584865Sobrien { 581684865Sobrien (*_bfd_error_handler) 581784865Sobrien (_("%s: loader reloc in unrecognized section `%s'"), 581884865Sobrien bfd_get_filename (output_bfd), 581984865Sobrien tsec->output_section->name); 582084865Sobrien bfd_set_error (bfd_error_nonrepresentable_section); 5821130561Sobrien return FALSE; 582284865Sobrien } 582394536Sobrien ldrel.l_rtype = (reloc_size << 8) | R_POS; 582484865Sobrien ldrel.l_rsecnm = oindx; 582594536Sobrien bfd_xcoff_swap_ldrel_out (output_bfd, &ldrel, finfo->ldrel); 582694536Sobrien finfo->ldrel += bfd_xcoff_ldrelsz(output_bfd); 582784865Sobrien } 582884865Sobrien 582984865Sobrien if (h->indx >= 0 || finfo->info->strip == strip_all) 583084865Sobrien { 583184865Sobrien BFD_ASSERT (outsym == finfo->outsyms); 5832130561Sobrien return TRUE; 583384865Sobrien } 583484865Sobrien 583584865Sobrien if (h->indx != -2 583684865Sobrien && (finfo->info->strip == strip_all 583784865Sobrien || (finfo->info->strip == strip_some 583894536Sobrien && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string, 5839130561Sobrien FALSE, FALSE) == NULL))) 584084865Sobrien { 584184865Sobrien BFD_ASSERT (outsym == finfo->outsyms); 5842130561Sobrien return TRUE; 584384865Sobrien } 584484865Sobrien 584584865Sobrien if (h->indx != -2 584684865Sobrien && (h->flags & (XCOFF_REF_REGULAR | XCOFF_DEF_REGULAR)) == 0) 584784865Sobrien { 584884865Sobrien BFD_ASSERT (outsym == finfo->outsyms); 5849130561Sobrien return TRUE; 585084865Sobrien } 585184865Sobrien 585284865Sobrien memset (&aux, 0, sizeof aux); 585384865Sobrien 585484865Sobrien h->indx = obj_raw_syment_count (output_bfd); 585584865Sobrien 585694536Sobrien result = bfd_xcoff_put_symbol_name (output_bfd, finfo->strtab, &isym, 585794536Sobrien h->root.root.string); 5858130561Sobrien if (!result) 5859130561Sobrien return FALSE; 586084865Sobrien 586184865Sobrien if (h->root.type == bfd_link_hash_undefined 586284865Sobrien || h->root.type == bfd_link_hash_undefweak) 586384865Sobrien { 586484865Sobrien isym.n_value = 0; 586584865Sobrien isym.n_scnum = N_UNDEF; 586684865Sobrien isym.n_sclass = C_EXT; 586784865Sobrien aux.x_csect.x_smtyp = XTY_ER; 586884865Sobrien } 586984865Sobrien else if ((h->root.type == bfd_link_hash_defined 587084865Sobrien || h->root.type == bfd_link_hash_defweak) 587184865Sobrien && h->smclas == XMC_XO) 587284865Sobrien { 587384865Sobrien BFD_ASSERT (bfd_is_abs_section (h->root.u.def.section)); 587484865Sobrien isym.n_value = h->root.u.def.value; 587584865Sobrien isym.n_scnum = N_UNDEF; 587684865Sobrien isym.n_sclass = C_EXT; 587784865Sobrien aux.x_csect.x_smtyp = XTY_ER; 587884865Sobrien } 587984865Sobrien else if (h->root.type == bfd_link_hash_defined 588084865Sobrien || h->root.type == bfd_link_hash_defweak) 588184865Sobrien { 588284865Sobrien struct xcoff_link_size_list *l; 588384865Sobrien 588484865Sobrien isym.n_value = (h->root.u.def.section->output_section->vma 588584865Sobrien + h->root.u.def.section->output_offset 588684865Sobrien + h->root.u.def.value); 5887104834Sobrien if (bfd_is_abs_section (h->root.u.def.section->output_section)) 5888104834Sobrien isym.n_scnum = N_ABS; 5889104834Sobrien else 5890104834Sobrien isym.n_scnum = h->root.u.def.section->output_section->target_index; 589184865Sobrien isym.n_sclass = C_HIDEXT; 589284865Sobrien aux.x_csect.x_smtyp = XTY_SD; 589384865Sobrien 589484865Sobrien if ((h->flags & XCOFF_HAS_SIZE) != 0) 589584865Sobrien { 589684865Sobrien for (l = xcoff_hash_table (finfo->info)->size_list; 589784865Sobrien l != NULL; 589884865Sobrien l = l->next) 589984865Sobrien { 590084865Sobrien if (l->h == h) 590184865Sobrien { 590284865Sobrien aux.x_csect.x_scnlen.l = l->size; 590384865Sobrien break; 590484865Sobrien } 590584865Sobrien } 590684865Sobrien } 590784865Sobrien } 590884865Sobrien else if (h->root.type == bfd_link_hash_common) 590984865Sobrien { 591084865Sobrien isym.n_value = (h->root.u.c.p->section->output_section->vma 591184865Sobrien + h->root.u.c.p->section->output_offset); 591284865Sobrien isym.n_scnum = h->root.u.c.p->section->output_section->target_index; 591384865Sobrien isym.n_sclass = C_EXT; 591484865Sobrien aux.x_csect.x_smtyp = XTY_CM; 591584865Sobrien aux.x_csect.x_scnlen.l = h->root.u.c.size; 591684865Sobrien } 591784865Sobrien else 591884865Sobrien abort (); 591984865Sobrien 592084865Sobrien isym.n_type = T_NULL; 592184865Sobrien isym.n_numaux = 1; 592284865Sobrien 592384865Sobrien bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym); 592484865Sobrien outsym += bfd_coff_symesz (output_bfd); 592584865Sobrien 592684865Sobrien aux.x_csect.x_smclas = h->smclas; 592784865Sobrien bfd_coff_swap_aux_out (output_bfd, (PTR) &aux, T_NULL, isym.n_sclass, 0, 1, 592884865Sobrien (PTR) outsym); 592984865Sobrien outsym += bfd_coff_auxesz (output_bfd); 593084865Sobrien 593184865Sobrien if ((h->root.type == bfd_link_hash_defined 593284865Sobrien || h->root.type == bfd_link_hash_defweak) 593384865Sobrien && h->smclas != XMC_XO) 593484865Sobrien { 593584865Sobrien /* We just output an SD symbol. Now output an LD symbol. */ 593684865Sobrien 593784865Sobrien h->indx += 2; 593884865Sobrien 593984865Sobrien isym.n_sclass = C_EXT; 594084865Sobrien bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) outsym); 594184865Sobrien outsym += bfd_coff_symesz (output_bfd); 594284865Sobrien 594384865Sobrien aux.x_csect.x_smtyp = XTY_LD; 594484865Sobrien aux.x_csect.x_scnlen.l = obj_raw_syment_count (output_bfd); 594584865Sobrien bfd_coff_swap_aux_out (output_bfd, (PTR) &aux, T_NULL, C_EXT, 0, 1, 594684865Sobrien (PTR) outsym); 594784865Sobrien outsym += bfd_coff_auxesz (output_bfd); 594884865Sobrien } 594984865Sobrien 595094536Sobrien pos = obj_sym_filepos (output_bfd); 595194536Sobrien pos += obj_raw_syment_count (output_bfd) * bfd_coff_symesz (output_bfd); 595294536Sobrien amt = outsym - finfo->outsyms; 595394536Sobrien if (bfd_seek (output_bfd, pos, SEEK_SET) != 0 595494536Sobrien || bfd_bwrite (finfo->outsyms, amt, output_bfd) != amt) 5955130561Sobrien return FALSE; 595684865Sobrien obj_raw_syment_count (output_bfd) += 595784865Sobrien (outsym - finfo->outsyms) / bfd_coff_symesz (output_bfd); 595884865Sobrien 5959130561Sobrien return TRUE; 596084865Sobrien} 596184865Sobrien 596284865Sobrien/* Handle a link order which is supposed to generate a reloc. */ 596384865Sobrien 5964130561Sobrienstatic bfd_boolean 596584865Sobrienxcoff_reloc_link_order (output_bfd, finfo, output_section, link_order) 596684865Sobrien bfd *output_bfd; 596784865Sobrien struct xcoff_final_link_info *finfo; 596884865Sobrien asection *output_section; 596984865Sobrien struct bfd_link_order *link_order; 597084865Sobrien{ 597184865Sobrien reloc_howto_type *howto; 597284865Sobrien struct xcoff_link_hash_entry *h; 597384865Sobrien asection *hsec; 597484865Sobrien bfd_vma hval; 597584865Sobrien bfd_vma addend; 597684865Sobrien struct internal_reloc *irel; 597784865Sobrien struct xcoff_link_hash_entry **rel_hash_ptr; 597884865Sobrien struct internal_ldrel ldrel; 597984865Sobrien 598084865Sobrien if (link_order->type == bfd_section_reloc_link_order) 598184865Sobrien { 598284865Sobrien /* We need to somehow locate a symbol in the right section. The 5983130561Sobrien symbol must either have a value of zero, or we must adjust 5984130561Sobrien the addend by the value of the symbol. FIXME: Write this 5985130561Sobrien when we need it. The old linker couldn't handle this anyhow. */ 598684865Sobrien abort (); 598784865Sobrien } 598884865Sobrien 598984865Sobrien howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc); 599084865Sobrien if (howto == NULL) 599184865Sobrien { 599284865Sobrien bfd_set_error (bfd_error_bad_value); 5993130561Sobrien return FALSE; 599484865Sobrien } 599584865Sobrien 599684865Sobrien h = ((struct xcoff_link_hash_entry *) 599784865Sobrien bfd_wrapped_link_hash_lookup (output_bfd, finfo->info, 599884865Sobrien link_order->u.reloc.p->u.name, 5999130561Sobrien FALSE, FALSE, TRUE)); 600084865Sobrien if (h == NULL) 600184865Sobrien { 600284865Sobrien if (! ((*finfo->info->callbacks->unattached_reloc) 600384865Sobrien (finfo->info, link_order->u.reloc.p->u.name, (bfd *) NULL, 600484865Sobrien (asection *) NULL, (bfd_vma) 0))) 6005130561Sobrien return FALSE; 6006130561Sobrien return TRUE; 600784865Sobrien } 600884865Sobrien 600984865Sobrien if (h->root.type == bfd_link_hash_common) 601084865Sobrien { 601184865Sobrien hsec = h->root.u.c.p->section; 601284865Sobrien hval = 0; 601384865Sobrien } 601484865Sobrien else if (h->root.type == bfd_link_hash_defined 601584865Sobrien || h->root.type == bfd_link_hash_defweak) 601684865Sobrien { 601784865Sobrien hsec = h->root.u.def.section; 601884865Sobrien hval = h->root.u.def.value; 601984865Sobrien } 602084865Sobrien else 602184865Sobrien { 602284865Sobrien hsec = NULL; 602384865Sobrien hval = 0; 602484865Sobrien } 602584865Sobrien 602684865Sobrien addend = link_order->u.reloc.p->addend; 602784865Sobrien if (hsec != NULL) 602884865Sobrien addend += (hsec->output_section->vma 602984865Sobrien + hsec->output_offset 603084865Sobrien + hval); 603184865Sobrien 603284865Sobrien if (addend != 0) 603384865Sobrien { 603484865Sobrien bfd_size_type size; 603584865Sobrien bfd_byte *buf; 603684865Sobrien bfd_reloc_status_type rstat; 6037130561Sobrien bfd_boolean ok; 603884865Sobrien 603984865Sobrien size = bfd_get_reloc_size (howto); 604084865Sobrien buf = (bfd_byte *) bfd_zmalloc (size); 604184865Sobrien if (buf == NULL) 6042130561Sobrien return FALSE; 604384865Sobrien 604484865Sobrien rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf); 604584865Sobrien switch (rstat) 604684865Sobrien { 604784865Sobrien case bfd_reloc_ok: 604884865Sobrien break; 604984865Sobrien default: 605084865Sobrien case bfd_reloc_outofrange: 605184865Sobrien abort (); 605284865Sobrien case bfd_reloc_overflow: 605384865Sobrien if (! ((*finfo->info->callbacks->reloc_overflow) 605484865Sobrien (finfo->info, link_order->u.reloc.p->u.name, 605584865Sobrien howto->name, addend, (bfd *) NULL, (asection *) NULL, 605684865Sobrien (bfd_vma) 0))) 605784865Sobrien { 605884865Sobrien free (buf); 6059130561Sobrien return FALSE; 606084865Sobrien } 606184865Sobrien break; 606284865Sobrien } 606384865Sobrien ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf, 606484865Sobrien (file_ptr) link_order->offset, size); 606584865Sobrien free (buf); 606684865Sobrien if (! ok) 6067130561Sobrien return FALSE; 606884865Sobrien } 606984865Sobrien 607084865Sobrien /* Store the reloc information in the right place. It will get 607184865Sobrien swapped and written out at the end of the final_link routine. */ 607284865Sobrien 607384865Sobrien irel = (finfo->section_info[output_section->target_index].relocs 607484865Sobrien + output_section->reloc_count); 607584865Sobrien rel_hash_ptr = (finfo->section_info[output_section->target_index].rel_hashes 607684865Sobrien + output_section->reloc_count); 607784865Sobrien 607884865Sobrien memset (irel, 0, sizeof (struct internal_reloc)); 607984865Sobrien *rel_hash_ptr = NULL; 608084865Sobrien 608184865Sobrien irel->r_vaddr = output_section->vma + link_order->offset; 608284865Sobrien 608384865Sobrien if (h->indx >= 0) 608484865Sobrien irel->r_symndx = h->indx; 608584865Sobrien else 608684865Sobrien { 608784865Sobrien /* Set the index to -2 to force this symbol to get written out. */ 608884865Sobrien h->indx = -2; 608984865Sobrien *rel_hash_ptr = h; 609084865Sobrien irel->r_symndx = 0; 609184865Sobrien } 609284865Sobrien 609384865Sobrien irel->r_type = howto->type; 609484865Sobrien irel->r_size = howto->bitsize - 1; 609584865Sobrien if (howto->complain_on_overflow == complain_overflow_signed) 609684865Sobrien irel->r_size |= 0x80; 609784865Sobrien 609884865Sobrien ++output_section->reloc_count; 609984865Sobrien 610084865Sobrien /* Now output the reloc to the .loader section. */ 610184865Sobrien 610284865Sobrien ldrel.l_vaddr = irel->r_vaddr; 610384865Sobrien 610484865Sobrien if (hsec != NULL) 610584865Sobrien { 610684865Sobrien const char *secname; 610784865Sobrien 610884865Sobrien secname = hsec->output_section->name; 610984865Sobrien 611084865Sobrien if (strcmp (secname, ".text") == 0) 611184865Sobrien ldrel.l_symndx = 0; 611284865Sobrien else if (strcmp (secname, ".data") == 0) 611384865Sobrien ldrel.l_symndx = 1; 611484865Sobrien else if (strcmp (secname, ".bss") == 0) 611584865Sobrien ldrel.l_symndx = 2; 611684865Sobrien else 611784865Sobrien { 611884865Sobrien (*_bfd_error_handler) 611984865Sobrien (_("%s: loader reloc in unrecognized section `%s'"), 612084865Sobrien bfd_get_filename (output_bfd), secname); 612184865Sobrien bfd_set_error (bfd_error_nonrepresentable_section); 6122130561Sobrien return FALSE; 612384865Sobrien } 612484865Sobrien } 612584865Sobrien else 612684865Sobrien { 612784865Sobrien if (h->ldindx < 0) 612884865Sobrien { 612984865Sobrien (*_bfd_error_handler) 613084865Sobrien (_("%s: `%s' in loader reloc but not loader sym"), 613184865Sobrien bfd_get_filename (output_bfd), 613284865Sobrien h->root.root.string); 613384865Sobrien bfd_set_error (bfd_error_bad_value); 6134130561Sobrien return FALSE; 613584865Sobrien } 613684865Sobrien ldrel.l_symndx = h->ldindx; 613784865Sobrien } 613884865Sobrien 613984865Sobrien ldrel.l_rtype = (irel->r_size << 8) | irel->r_type; 614084865Sobrien ldrel.l_rsecnm = output_section->target_index; 614194536Sobrien bfd_xcoff_swap_ldrel_out (output_bfd, &ldrel, finfo->ldrel); 614294536Sobrien finfo->ldrel += bfd_xcoff_ldrelsz(output_bfd); 614384865Sobrien 6144130561Sobrien return TRUE; 614584865Sobrien} 614684865Sobrien 614784865Sobrien/* Sort relocs by VMA. This is called via qsort. */ 614884865Sobrien 614984865Sobrienstatic int 615084865Sobrienxcoff_sort_relocs (p1, p2) 615184865Sobrien const PTR p1; 615284865Sobrien const PTR p2; 615384865Sobrien{ 615484865Sobrien const struct internal_reloc *r1 = (const struct internal_reloc *) p1; 615584865Sobrien const struct internal_reloc *r2 = (const struct internal_reloc *) p2; 615684865Sobrien 615784865Sobrien if (r1->r_vaddr > r2->r_vaddr) 615884865Sobrien return 1; 615984865Sobrien else if (r1->r_vaddr < r2->r_vaddr) 616084865Sobrien return -1; 616184865Sobrien else 616284865Sobrien return 0; 616384865Sobrien} 616484865Sobrien 616584865Sobrien 616684865Sobrien 616784865Sobrien 6168