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