133965Sjdp/* Support for the generic parts of COFF, for BFD.
278828Sobrien   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3218822Sdim   2000, 2001, 2002, 2003, 2004, 2005, 2007
438889Sjdp   Free Software Foundation, Inc.
533965Sjdp   Written by Cygnus Support.
633965Sjdp
7218822Sdim   This file is part of BFD, the Binary File Descriptor library.
833965Sjdp
9218822Sdim   This program is free software; you can redistribute it and/or modify
10218822Sdim   it under the terms of the GNU General Public License as published by
11218822Sdim   the Free Software Foundation; either version 2 of the License, or
12218822Sdim   (at your option) any later version.
1333965Sjdp
14218822Sdim   This program is distributed in the hope that it will be useful,
15218822Sdim   but WITHOUT ANY WARRANTY; without even the implied warranty of
16218822Sdim   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17218822Sdim   GNU General Public License for more details.
1833965Sjdp
19218822Sdim   You should have received a copy of the GNU General Public License
20218822Sdim   along with this program; if not, write to the Free Software
21218822Sdim   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
2233965Sjdp
2333965Sjdp/* Most of this hacked by  Steve Chamberlain, sac@cygnus.com.
2433965Sjdp   Split out of coffcode.h by Ian Taylor, ian@cygnus.com.  */
2533965Sjdp
2633965Sjdp/* This file contains COFF code that is not dependent on any
2733965Sjdp   particular COFF target.  There is only one version of this file in
2833965Sjdp   libbfd.a, so no target specific code may be put in here.  Or, to
2933965Sjdp   put it another way,
3033965Sjdp
3133965Sjdp   ********** DO NOT PUT TARGET SPECIFIC CODE IN THIS FILE **********
3233965Sjdp
3333965Sjdp   If you need to add some target specific behaviour, add a new hook
3433965Sjdp   function to bfd_coff_backend_data.
3533965Sjdp
3633965Sjdp   Some of these functions are also called by the ECOFF routines.
3733965Sjdp   Those functions may not use any COFF specific information, such as
3833965Sjdp   coff_data (abfd).  */
3933965Sjdp
40218822Sdim#include "sysdep.h"
4133965Sjdp#include "bfd.h"
4233965Sjdp#include "libbfd.h"
4333965Sjdp#include "coff/internal.h"
4433965Sjdp#include "libcoff.h"
4533965Sjdp
4633965Sjdp/* Take a section header read from a coff file (in HOST byte order),
4733965Sjdp   and make a BFD "section" out of it.  This is used by ECOFF.  */
48218822Sdim
49130561Sobrienstatic bfd_boolean
50218822Sdimmake_a_section_from_file (bfd *abfd,
51218822Sdim			  struct internal_scnhdr *hdr,
52218822Sdim			  unsigned int target_index)
5333965Sjdp{
5433965Sjdp  asection *return_section;
5533965Sjdp  char *name;
56130561Sobrien  bfd_boolean result = TRUE;
5789857Sobrien  flagword flags;
5833965Sjdp
5933965Sjdp  name = NULL;
6033965Sjdp
6133965Sjdp  /* Handle long section names as in PE.  */
6233965Sjdp  if (bfd_coff_long_section_names (abfd)
6333965Sjdp      && hdr->s_name[0] == '/')
6433965Sjdp    {
6533965Sjdp      char buf[SCNNMLEN];
6633965Sjdp      long strindex;
6733965Sjdp      char *p;
6833965Sjdp      const char *strings;
6933965Sjdp
7033965Sjdp      memcpy (buf, hdr->s_name + 1, SCNNMLEN - 1);
7133965Sjdp      buf[SCNNMLEN - 1] = '\0';
7233965Sjdp      strindex = strtol (buf, &p, 10);
7333965Sjdp      if (*p == '\0' && strindex >= 0)
7433965Sjdp	{
7533965Sjdp	  strings = _bfd_coff_read_string_table (abfd);
7633965Sjdp	  if (strings == NULL)
77130561Sobrien	    return FALSE;
7833965Sjdp	  /* FIXME: For extra safety, we should make sure that
7933965Sjdp             strindex does not run us past the end, but right now we
8033965Sjdp             don't know the length of the string table.  */
8133965Sjdp	  strings += strindex;
8289857Sobrien	  name = bfd_alloc (abfd, (bfd_size_type) strlen (strings) + 1);
8333965Sjdp	  if (name == NULL)
84130561Sobrien	    return FALSE;
8533965Sjdp	  strcpy (name, strings);
8633965Sjdp	}
8733965Sjdp    }
8833965Sjdp
8933965Sjdp  if (name == NULL)
9033965Sjdp    {
9133965Sjdp      /* Assorted wastage to null-terminate the name, thanks AT&T! */
9289857Sobrien      name = bfd_alloc (abfd, (bfd_size_type) sizeof (hdr->s_name) + 1);
9333965Sjdp      if (name == NULL)
94130561Sobrien	return FALSE;
9533965Sjdp      strncpy (name, (char *) &hdr->s_name[0], sizeof (hdr->s_name));
9633965Sjdp      name[sizeof (hdr->s_name)] = 0;
9733965Sjdp    }
9833965Sjdp
9933965Sjdp  return_section = bfd_make_section_anyway (abfd, name);
10033965Sjdp  if (return_section == NULL)
101130561Sobrien    return FALSE;
10233965Sjdp
10333965Sjdp  return_section->vma = hdr->s_vaddr;
10433965Sjdp  return_section->lma = hdr->s_paddr;
105218822Sdim  return_section->size = hdr->s_size;
10633965Sjdp  return_section->filepos = hdr->s_scnptr;
10733965Sjdp  return_section->rel_filepos = hdr->s_relptr;
10833965Sjdp  return_section->reloc_count = hdr->s_nreloc;
10933965Sjdp
11033965Sjdp  bfd_coff_set_alignment_hook (abfd, return_section, hdr);
11133965Sjdp
11233965Sjdp  return_section->line_filepos = hdr->s_lnnoptr;
11333965Sjdp
11433965Sjdp  return_section->lineno_count = hdr->s_nlnno;
11533965Sjdp  return_section->userdata = NULL;
116218822Sdim  return_section->next = NULL;
11733965Sjdp  return_section->target_index = target_index;
11833965Sjdp
11989857Sobrien  if (! bfd_coff_styp_to_sec_flags_hook (abfd, hdr, name, return_section,
12089857Sobrien					 & flags))
121130561Sobrien    result = FALSE;
12289857Sobrien
12389857Sobrien  return_section->flags = flags;
12489857Sobrien
12533965Sjdp  /* At least on i386-coff, the line number count for a shared library
12633965Sjdp     section must be ignored.  */
12733965Sjdp  if ((return_section->flags & SEC_COFF_SHARED_LIBRARY) != 0)
12833965Sjdp    return_section->lineno_count = 0;
12933965Sjdp
13033965Sjdp  if (hdr->s_nreloc != 0)
13133965Sjdp    return_section->flags |= SEC_RELOC;
132218822Sdim  /* FIXME: should this check 'hdr->s_size > 0'.  */
13333965Sjdp  if (hdr->s_scnptr != 0)
13433965Sjdp    return_section->flags |= SEC_HAS_CONTENTS;
13589857Sobrien
13689857Sobrien  return result;
13733965Sjdp}
13833965Sjdp
13933965Sjdp/* Read in a COFF object and make it into a BFD.  This is used by
14033965Sjdp   ECOFF as well.  */
14133965Sjdp
14233965Sjdpstatic const bfd_target *
143218822Sdimcoff_real_object_p (bfd *abfd,
144218822Sdim		    unsigned nscns,
145218822Sdim		    struct internal_filehdr *internal_f,
146218822Sdim		    struct internal_aouthdr *internal_a)
14733965Sjdp{
14833965Sjdp  flagword oflags = abfd->flags;
14933965Sjdp  bfd_vma ostart = bfd_get_start_address (abfd);
150218822Sdim  void * tdata;
151218822Sdim  void * tdata_save;
152218822Sdim  bfd_size_type readsize;	/* Length of file_info.  */
15333965Sjdp  unsigned int scnhsz;
15433965Sjdp  char *external_sections;
15533965Sjdp
15633965Sjdp  if (!(internal_f->f_flags & F_RELFLG))
15733965Sjdp    abfd->flags |= HAS_RELOC;
15833965Sjdp  if ((internal_f->f_flags & F_EXEC))
15933965Sjdp    abfd->flags |= EXEC_P;
16033965Sjdp  if (!(internal_f->f_flags & F_LNNO))
16133965Sjdp    abfd->flags |= HAS_LINENO;
16233965Sjdp  if (!(internal_f->f_flags & F_LSYMS))
16333965Sjdp    abfd->flags |= HAS_LOCALS;
16433965Sjdp
16533965Sjdp  /* FIXME: How can we set D_PAGED correctly?  */
16633965Sjdp  if ((internal_f->f_flags & F_EXEC) != 0)
16733965Sjdp    abfd->flags |= D_PAGED;
16833965Sjdp
16933965Sjdp  bfd_get_symcount (abfd) = internal_f->f_nsyms;
17033965Sjdp  if (internal_f->f_nsyms)
17133965Sjdp    abfd->flags |= HAS_SYMS;
17233965Sjdp
17333965Sjdp  if (internal_a != (struct internal_aouthdr *) NULL)
17433965Sjdp    bfd_get_start_address (abfd) = internal_a->entry;
17533965Sjdp  else
17633965Sjdp    bfd_get_start_address (abfd) = 0;
17733965Sjdp
17833965Sjdp  /* Set up the tdata area.  ECOFF uses its own routine, and overrides
17933965Sjdp     abfd->flags.  */
180104834Sobrien  tdata_save = abfd->tdata.any;
181218822Sdim  tdata = bfd_coff_mkobject_hook (abfd, (void *) internal_f, (void *) internal_a);
18233965Sjdp  if (tdata == NULL)
183104834Sobrien    goto fail2;
18433965Sjdp
18533965Sjdp  scnhsz = bfd_coff_scnhsz (abfd);
18689857Sobrien  readsize = (bfd_size_type) nscns * scnhsz;
187218822Sdim  external_sections = bfd_alloc (abfd, readsize);
18833965Sjdp  if (!external_sections)
18933965Sjdp    goto fail;
19033965Sjdp
191218822Sdim  if (bfd_bread ((void *) external_sections, readsize, abfd) != readsize)
19233965Sjdp    goto fail;
19333965Sjdp
19460484Sobrien  /* Set the arch/mach *before* swapping in sections; section header swapping
19577298Sobrien     may depend on arch/mach info.  */
196218822Sdim  if (! bfd_coff_set_arch_mach_hook (abfd, (void *) internal_f))
19760484Sobrien    goto fail;
19860484Sobrien
199130561Sobrien  /* Now copy data as required; construct all asections etc.  */
20033965Sjdp  if (nscns != 0)
20133965Sjdp    {
20233965Sjdp      unsigned int i;
20333965Sjdp      for (i = 0; i < nscns; i++)
20433965Sjdp	{
20533965Sjdp	  struct internal_scnhdr tmp;
20633965Sjdp	  bfd_coff_swap_scnhdr_in (abfd,
207218822Sdim				   (void *) (external_sections + i * scnhsz),
208218822Sdim				   (void *) & tmp);
20933965Sjdp	  if (! make_a_section_from_file (abfd, &tmp, i + 1))
21033965Sjdp	    goto fail;
21133965Sjdp	}
21233965Sjdp    }
21333965Sjdp
21433965Sjdp  return abfd->xvec;
21533965Sjdp
21633965Sjdp fail:
21733965Sjdp  bfd_release (abfd, tdata);
218104834Sobrien fail2:
219104834Sobrien  abfd->tdata.any = tdata_save;
22033965Sjdp  abfd->flags = oflags;
22133965Sjdp  bfd_get_start_address (abfd) = ostart;
22233965Sjdp  return (const bfd_target *) NULL;
22333965Sjdp}
22433965Sjdp
22533965Sjdp/* Turn a COFF file into a BFD, but fail with bfd_error_wrong_format if it is
22633965Sjdp   not a COFF file.  This is also used by ECOFF.  */
22733965Sjdp
22833965Sjdpconst bfd_target *
229218822Sdimcoff_object_p (bfd *abfd)
23033965Sjdp{
23189857Sobrien  bfd_size_type filhsz;
23289857Sobrien  bfd_size_type aoutsz;
23389857Sobrien  unsigned int nscns;
234218822Sdim  void * filehdr;
23533965Sjdp  struct internal_filehdr internal_f;
23633965Sjdp  struct internal_aouthdr internal_a;
23733965Sjdp
238218822Sdim  /* Figure out how much to read.  */
23933965Sjdp  filhsz = bfd_coff_filhsz (abfd);
24033965Sjdp  aoutsz = bfd_coff_aoutsz (abfd);
24133965Sjdp
24233965Sjdp  filehdr = bfd_alloc (abfd, filhsz);
24333965Sjdp  if (filehdr == NULL)
244104834Sobrien    return NULL;
24589857Sobrien  if (bfd_bread (filehdr, filhsz, abfd) != filhsz)
24633965Sjdp    {
24733965Sjdp      if (bfd_get_error () != bfd_error_system_call)
24833965Sjdp	bfd_set_error (bfd_error_wrong_format);
249104834Sobrien      bfd_release (abfd, filehdr);
250104834Sobrien      return NULL;
25133965Sjdp    }
25233965Sjdp  bfd_coff_swap_filehdr_in (abfd, filehdr, &internal_f);
25333965Sjdp  bfd_release (abfd, filehdr);
25433965Sjdp
25589857Sobrien  /* The XCOFF format has two sizes for the f_opthdr.  SMALL_AOUTSZ
25689857Sobrien     (less than aoutsz) used in object files and AOUTSZ (equal to
25789857Sobrien     aoutsz) in executables.  The bfd_coff_swap_aouthdr_in function
25889857Sobrien     expects this header to be aoutsz bytes in length, so we use that
25989857Sobrien     value in the call to bfd_alloc below.  But we must be careful to
26089857Sobrien     only read in f_opthdr bytes in the call to bfd_bread.  We should
26189857Sobrien     also attempt to catch corrupt or non-COFF binaries with a strange
26289857Sobrien     value for f_opthdr.  */
263104834Sobrien  if (! bfd_coff_bad_format_hook (abfd, &internal_f)
26489857Sobrien      || internal_f.f_opthdr > aoutsz)
26533965Sjdp    {
26633965Sjdp      bfd_set_error (bfd_error_wrong_format);
267104834Sobrien      return NULL;
26833965Sjdp    }
26933965Sjdp  nscns = internal_f.f_nscns;
27033965Sjdp
27133965Sjdp  if (internal_f.f_opthdr)
27233965Sjdp    {
273218822Sdim      void * opthdr;
27433965Sjdp
27533965Sjdp      opthdr = bfd_alloc (abfd, aoutsz);
27633965Sjdp      if (opthdr == NULL)
277104834Sobrien	return NULL;
27889857Sobrien      if (bfd_bread (opthdr, (bfd_size_type) internal_f.f_opthdr, abfd)
27938889Sjdp	  != internal_f.f_opthdr)
28033965Sjdp	{
281104834Sobrien	  bfd_release (abfd, opthdr);
282104834Sobrien	  return NULL;
28333965Sjdp	}
284218822Sdim      bfd_coff_swap_aouthdr_in (abfd, opthdr, (void *) &internal_a);
285104834Sobrien      bfd_release (abfd, opthdr);
28633965Sjdp    }
28733965Sjdp
28833965Sjdp  return coff_real_object_p (abfd, nscns, &internal_f,
28933965Sjdp			     (internal_f.f_opthdr != 0
29033965Sjdp			      ? &internal_a
29133965Sjdp			      : (struct internal_aouthdr *) NULL));
29233965Sjdp}
29333965Sjdp
29433965Sjdp/* Get the BFD section from a COFF symbol section number.  */
29533965Sjdp
29633965Sjdpasection *
297218822Sdimcoff_section_from_bfd_index (bfd *abfd, int index)
29833965Sjdp{
299130561Sobrien  struct bfd_section *answer = abfd->sections;
30033965Sjdp
30133965Sjdp  if (index == N_ABS)
30233965Sjdp    return bfd_abs_section_ptr;
30333965Sjdp  if (index == N_UNDEF)
30433965Sjdp    return bfd_und_section_ptr;
30533965Sjdp  if (index == N_DEBUG)
30633965Sjdp    return bfd_abs_section_ptr;
30733965Sjdp
30833965Sjdp  while (answer)
30933965Sjdp    {
31033965Sjdp      if (answer->target_index == index)
31133965Sjdp	return answer;
31233965Sjdp      answer = answer->next;
31333965Sjdp    }
31433965Sjdp
31533965Sjdp  /* We should not reach this point, but the SCO 3.2v4 /lib/libc_s.a
31633965Sjdp     has a bad symbol table in biglitpow.o.  */
31733965Sjdp  return bfd_und_section_ptr;
31833965Sjdp}
31933965Sjdp
32033965Sjdp/* Get the upper bound of a COFF symbol table.  */
32133965Sjdp
32233965Sjdplong
323218822Sdimcoff_get_symtab_upper_bound (bfd *abfd)
32433965Sjdp{
32533965Sjdp  if (!bfd_coff_slurp_symbol_table (abfd))
32633965Sjdp    return -1;
32733965Sjdp
32833965Sjdp  return (bfd_get_symcount (abfd) + 1) * (sizeof (coff_symbol_type *));
32933965Sjdp}
33033965Sjdp
33133965Sjdp/* Canonicalize a COFF symbol table.  */
33233965Sjdp
33333965Sjdplong
334218822Sdimcoff_canonicalize_symtab (bfd *abfd, asymbol **alocation)
33533965Sjdp{
33633965Sjdp  unsigned int counter;
33733965Sjdp  coff_symbol_type *symbase;
33833965Sjdp  coff_symbol_type **location = (coff_symbol_type **) alocation;
33933965Sjdp
34033965Sjdp  if (!bfd_coff_slurp_symbol_table (abfd))
34133965Sjdp    return -1;
34233965Sjdp
34333965Sjdp  symbase = obj_symbols (abfd);
34433965Sjdp  counter = bfd_get_symcount (abfd);
34533965Sjdp  while (counter-- > 0)
34633965Sjdp    *location++ = symbase++;
34733965Sjdp
34833965Sjdp  *location = NULL;
34933965Sjdp
35033965Sjdp  return bfd_get_symcount (abfd);
35133965Sjdp}
35233965Sjdp
35333965Sjdp/* Get the name of a symbol.  The caller must pass in a buffer of size
35433965Sjdp   >= SYMNMLEN + 1.  */
35533965Sjdp
35633965Sjdpconst char *
357218822Sdim_bfd_coff_internal_syment_name (bfd *abfd,
358218822Sdim				const struct internal_syment *sym,
359218822Sdim				char *buf)
36033965Sjdp{
36133965Sjdp  /* FIXME: It's not clear this will work correctly if sizeof
36233965Sjdp     (_n_zeroes) != 4.  */
36333965Sjdp  if (sym->_n._n_n._n_zeroes != 0
36433965Sjdp      || sym->_n._n_n._n_offset == 0)
36533965Sjdp    {
36633965Sjdp      memcpy (buf, sym->_n._n_name, SYMNMLEN);
36733965Sjdp      buf[SYMNMLEN] = '\0';
36833965Sjdp      return buf;
36933965Sjdp    }
37033965Sjdp  else
37133965Sjdp    {
37233965Sjdp      const char *strings;
37333965Sjdp
37433965Sjdp      BFD_ASSERT (sym->_n._n_n._n_offset >= STRING_SIZE_SIZE);
37533965Sjdp      strings = obj_coff_strings (abfd);
37633965Sjdp      if (strings == NULL)
37733965Sjdp	{
37833965Sjdp	  strings = _bfd_coff_read_string_table (abfd);
37933965Sjdp	  if (strings == NULL)
38033965Sjdp	    return NULL;
38133965Sjdp	}
38233965Sjdp      return strings + sym->_n._n_n._n_offset;
38333965Sjdp    }
38433965Sjdp}
38533965Sjdp
38633965Sjdp/* Read in and swap the relocs.  This returns a buffer holding the
387130561Sobrien   relocs for section SEC in file ABFD.  If CACHE is TRUE and
38833965Sjdp   INTERNAL_RELOCS is NULL, the relocs read in will be saved in case
38933965Sjdp   the function is called again.  If EXTERNAL_RELOCS is not NULL, it
39033965Sjdp   is a buffer large enough to hold the unswapped relocs.  If
39133965Sjdp   INTERNAL_RELOCS is not NULL, it is a buffer large enough to hold
392130561Sobrien   the swapped relocs.  If REQUIRE_INTERNAL is TRUE, then the return
39333965Sjdp   value must be INTERNAL_RELOCS.  The function returns NULL on error.  */
39433965Sjdp
39533965Sjdpstruct internal_reloc *
396218822Sdim_bfd_coff_read_internal_relocs (bfd *abfd,
397218822Sdim				asection *sec,
398218822Sdim				bfd_boolean cache,
399218822Sdim				bfd_byte *external_relocs,
400218822Sdim				bfd_boolean require_internal,
401218822Sdim				struct internal_reloc *internal_relocs)
40233965Sjdp{
40333965Sjdp  bfd_size_type relsz;
40433965Sjdp  bfd_byte *free_external = NULL;
40533965Sjdp  struct internal_reloc *free_internal = NULL;
40633965Sjdp  bfd_byte *erel;
40733965Sjdp  bfd_byte *erel_end;
40833965Sjdp  struct internal_reloc *irel;
40989857Sobrien  bfd_size_type amt;
41033965Sjdp
41133965Sjdp  if (coff_section_data (abfd, sec) != NULL
41233965Sjdp      && coff_section_data (abfd, sec)->relocs != NULL)
41333965Sjdp    {
41433965Sjdp      if (! require_internal)
41533965Sjdp	return coff_section_data (abfd, sec)->relocs;
41633965Sjdp      memcpy (internal_relocs, coff_section_data (abfd, sec)->relocs,
41733965Sjdp	      sec->reloc_count * sizeof (struct internal_reloc));
41833965Sjdp      return internal_relocs;
41933965Sjdp    }
42033965Sjdp
42133965Sjdp  relsz = bfd_coff_relsz (abfd);
42233965Sjdp
42389857Sobrien  amt = sec->reloc_count * relsz;
42433965Sjdp  if (external_relocs == NULL)
42533965Sjdp    {
426218822Sdim      free_external = bfd_malloc (amt);
42733965Sjdp      if (free_external == NULL && sec->reloc_count > 0)
42833965Sjdp	goto error_return;
42933965Sjdp      external_relocs = free_external;
43033965Sjdp    }
43133965Sjdp
43233965Sjdp  if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0
43389857Sobrien      || bfd_bread (external_relocs, amt, abfd) != amt)
43433965Sjdp    goto error_return;
43533965Sjdp
43633965Sjdp  if (internal_relocs == NULL)
43733965Sjdp    {
43889857Sobrien      amt = sec->reloc_count;
43989857Sobrien      amt *= sizeof (struct internal_reloc);
440218822Sdim      free_internal = bfd_malloc (amt);
44133965Sjdp      if (free_internal == NULL && sec->reloc_count > 0)
44233965Sjdp	goto error_return;
44333965Sjdp      internal_relocs = free_internal;
44433965Sjdp    }
44533965Sjdp
44633965Sjdp  /* Swap in the relocs.  */
44733965Sjdp  erel = external_relocs;
44833965Sjdp  erel_end = erel + relsz * sec->reloc_count;
44933965Sjdp  irel = internal_relocs;
45033965Sjdp  for (; erel < erel_end; erel += relsz, irel++)
451218822Sdim    bfd_coff_swap_reloc_in (abfd, (void *) erel, (void *) irel);
45233965Sjdp
45333965Sjdp  if (free_external != NULL)
45433965Sjdp    {
45533965Sjdp      free (free_external);
45633965Sjdp      free_external = NULL;
45733965Sjdp    }
45833965Sjdp
45933965Sjdp  if (cache && free_internal != NULL)
46033965Sjdp    {
46133965Sjdp      if (coff_section_data (abfd, sec) == NULL)
46233965Sjdp	{
46389857Sobrien	  amt = sizeof (struct coff_section_tdata);
464218822Sdim	  sec->used_by_bfd = bfd_zalloc (abfd, amt);
46533965Sjdp	  if (sec->used_by_bfd == NULL)
46633965Sjdp	    goto error_return;
46733965Sjdp	  coff_section_data (abfd, sec)->contents = NULL;
46833965Sjdp	}
46933965Sjdp      coff_section_data (abfd, sec)->relocs = free_internal;
47033965Sjdp    }
47133965Sjdp
47233965Sjdp  return internal_relocs;
47333965Sjdp
47433965Sjdp error_return:
47533965Sjdp  if (free_external != NULL)
47633965Sjdp    free (free_external);
47733965Sjdp  if (free_internal != NULL)
47833965Sjdp    free (free_internal);
47933965Sjdp  return NULL;
48033965Sjdp}
48133965Sjdp
48233965Sjdp/* Set lineno_count for the output sections of a COFF file.  */
48333965Sjdp
48433965Sjdpint
485218822Sdimcoff_count_linenumbers (bfd *abfd)
48633965Sjdp{
48733965Sjdp  unsigned int limit = bfd_get_symcount (abfd);
48833965Sjdp  unsigned int i;
48933965Sjdp  int total = 0;
49033965Sjdp  asymbol **p;
49133965Sjdp  asection *s;
49233965Sjdp
49333965Sjdp  if (limit == 0)
49433965Sjdp    {
49533965Sjdp      /* This may be from the backend linker, in which case the
49633965Sjdp         lineno_count in the sections is correct.  */
49733965Sjdp      for (s = abfd->sections; s != NULL; s = s->next)
49833965Sjdp	total += s->lineno_count;
49933965Sjdp      return total;
50033965Sjdp    }
50133965Sjdp
50233965Sjdp  for (s = abfd->sections; s != NULL; s = s->next)
50333965Sjdp    BFD_ASSERT (s->lineno_count == 0);
50433965Sjdp
50533965Sjdp  for (p = abfd->outsymbols, i = 0; i < limit; i++, p++)
50633965Sjdp    {
50733965Sjdp      asymbol *q_maybe = *p;
50833965Sjdp
50977298Sobrien      if (bfd_family_coff (bfd_asymbol_bfd (q_maybe)))
51033965Sjdp	{
51133965Sjdp	  coff_symbol_type *q = coffsymbol (q_maybe);
51233965Sjdp
51333965Sjdp	  /* The AIX 4.1 compiler can sometimes generate line numbers
51433965Sjdp             attached to debugging symbols.  We try to simply ignore
51533965Sjdp             those here.  */
51633965Sjdp	  if (q->lineno != NULL
51733965Sjdp	      && q->symbol.section->owner != NULL)
51833965Sjdp	    {
51933965Sjdp	      /* This symbol has line numbers.  Increment the owning
52033965Sjdp	         section's linenumber count.  */
52133965Sjdp	      alent *l = q->lineno;
52233965Sjdp
52389857Sobrien	      do
52433965Sjdp		{
52589857Sobrien		  asection * sec = q->symbol.section->output_section;
526130561Sobrien
52789857Sobrien		  /* Do not try to update fields in read-only sections.  */
52889857Sobrien		  if (! bfd_is_const_section (sec))
52989857Sobrien		    sec->lineno_count ++;
53089857Sobrien
53133965Sjdp		  ++total;
53233965Sjdp		  ++l;
53333965Sjdp		}
53489857Sobrien	      while (l->line_number != 0);
53533965Sjdp	    }
53633965Sjdp	}
53733965Sjdp    }
53833965Sjdp
53933965Sjdp  return total;
54033965Sjdp}
54133965Sjdp
54233965Sjdp/* Takes a bfd and a symbol, returns a pointer to the coff specific
54333965Sjdp   area of the symbol if there is one.  */
54433965Sjdp
54533965Sjdpcoff_symbol_type *
546218822Sdimcoff_symbol_from (bfd *ignore_abfd ATTRIBUTE_UNUSED,
547218822Sdim		  asymbol *symbol)
54833965Sjdp{
54977298Sobrien  if (!bfd_family_coff (bfd_asymbol_bfd (symbol)))
55033965Sjdp    return (coff_symbol_type *) NULL;
55133965Sjdp
55233965Sjdp  if (bfd_asymbol_bfd (symbol)->tdata.coff_obj_data == (coff_data_type *) NULL)
55333965Sjdp    return (coff_symbol_type *) NULL;
55433965Sjdp
55533965Sjdp  return (coff_symbol_type *) symbol;
55633965Sjdp}
55733965Sjdp
55833965Sjdpstatic void
559218822Sdimfixup_symbol_value (bfd *abfd,
560218822Sdim		    coff_symbol_type *coff_symbol_ptr,
561218822Sdim		    struct internal_syment *syment)
56233965Sjdp{
563218822Sdim  /* Normalize the symbol flags.  */
56433965Sjdp  if (bfd_is_com_section (coff_symbol_ptr->symbol.section))
56533965Sjdp    {
566218822Sdim      /* A common symbol is undefined with a value.  */
56733965Sjdp      syment->n_scnum = N_UNDEF;
56833965Sjdp      syment->n_value = coff_symbol_ptr->symbol.value;
56933965Sjdp    }
57060484Sobrien  else if ((coff_symbol_ptr->symbol.flags & BSF_DEBUGGING) != 0
57160484Sobrien	   && (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING_RELOC) == 0)
57233965Sjdp    {
57333965Sjdp      syment->n_value = coff_symbol_ptr->symbol.value;
57433965Sjdp    }
57533965Sjdp  else if (bfd_is_und_section (coff_symbol_ptr->symbol.section))
57633965Sjdp    {
57733965Sjdp      syment->n_scnum = N_UNDEF;
57833965Sjdp      syment->n_value = 0;
57933965Sjdp    }
58060484Sobrien  /* FIXME: Do we need to handle the absolute section here?  */
58133965Sjdp  else
58233965Sjdp    {
58333965Sjdp      if (coff_symbol_ptr->symbol.section)
58433965Sjdp	{
58533965Sjdp	  syment->n_scnum =
58633965Sjdp	    coff_symbol_ptr->symbol.section->output_section->target_index;
58733965Sjdp
58838889Sjdp	  syment->n_value = (coff_symbol_ptr->symbol.value
58938889Sjdp			     + coff_symbol_ptr->symbol.section->output_offset);
59038889Sjdp	  if (! obj_pe (abfd))
59177298Sobrien            {
59277298Sobrien              syment->n_value += (syment->n_sclass == C_STATLAB)
59377298Sobrien                ? coff_symbol_ptr->symbol.section->output_section->lma
59477298Sobrien                : coff_symbol_ptr->symbol.section->output_section->vma;
59577298Sobrien            }
59633965Sjdp	}
59733965Sjdp      else
59833965Sjdp	{
59933965Sjdp	  BFD_ASSERT (0);
60033965Sjdp	  /* This can happen, but I don't know why yet (steve@cygnus.com) */
60133965Sjdp	  syment->n_scnum = N_ABS;
60233965Sjdp	  syment->n_value = coff_symbol_ptr->symbol.value;
60333965Sjdp	}
60433965Sjdp    }
60533965Sjdp}
60633965Sjdp
60733965Sjdp/* Run through all the symbols in the symbol table and work out what
60833965Sjdp   their indexes into the symbol table will be when output.
60933965Sjdp
61033965Sjdp   Coff requires that each C_FILE symbol points to the next one in the
61133965Sjdp   chain, and that the last one points to the first external symbol. We
61233965Sjdp   do that here too.  */
61333965Sjdp
614130561Sobrienbfd_boolean
615218822Sdimcoff_renumber_symbols (bfd *bfd_ptr, int *first_undef)
61633965Sjdp{
61733965Sjdp  unsigned int symbol_count = bfd_get_symcount (bfd_ptr);
61833965Sjdp  asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
61933965Sjdp  unsigned int native_index = 0;
620218822Sdim  struct internal_syment *last_file = NULL;
62133965Sjdp  unsigned int symbol_index;
62233965Sjdp
62333965Sjdp  /* COFF demands that undefined symbols come after all other symbols.
62433965Sjdp     Since we don't need to impose this extra knowledge on all our
62533965Sjdp     client programs, deal with that here.  Sort the symbol table;
62633965Sjdp     just move the undefined symbols to the end, leaving the rest
62733965Sjdp     alone.  The O'Reilly book says that defined global symbols come
62833965Sjdp     at the end before the undefined symbols, so we do that here as
62933965Sjdp     well.  */
63033965Sjdp  /* @@ Do we have some condition we could test for, so we don't always
63133965Sjdp     have to do this?  I don't think relocatability is quite right, but
63233965Sjdp     I'm not certain.  [raeburn:19920508.1711EST]  */
63333965Sjdp  {
63433965Sjdp    asymbol **newsyms;
63533965Sjdp    unsigned int i;
63689857Sobrien    bfd_size_type amt;
63733965Sjdp
63889857Sobrien    amt = sizeof (asymbol *) * ((bfd_size_type) symbol_count + 1);
639218822Sdim    newsyms = bfd_alloc (bfd_ptr, amt);
64033965Sjdp    if (!newsyms)
641130561Sobrien      return FALSE;
64233965Sjdp    bfd_ptr->outsymbols = newsyms;
64333965Sjdp    for (i = 0; i < symbol_count; i++)
64433965Sjdp      if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) != 0
64533965Sjdp	  || (!bfd_is_und_section (symbol_ptr_ptr[i]->section)
64633965Sjdp	      && !bfd_is_com_section (symbol_ptr_ptr[i]->section)
64760484Sobrien	      && ((symbol_ptr_ptr[i]->flags & BSF_FUNCTION) != 0
64860484Sobrien		  || ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_WEAK))
64960484Sobrien		      == 0))))
65033965Sjdp	*newsyms++ = symbol_ptr_ptr[i];
65133965Sjdp
65233965Sjdp    for (i = 0; i < symbol_count; i++)
65333965Sjdp      if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) == 0
65433965Sjdp	  && !bfd_is_und_section (symbol_ptr_ptr[i]->section)
65533965Sjdp	  && (bfd_is_com_section (symbol_ptr_ptr[i]->section)
65660484Sobrien	      || ((symbol_ptr_ptr[i]->flags & BSF_FUNCTION) == 0
65760484Sobrien		  && ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_WEAK))
65860484Sobrien		      != 0))))
65933965Sjdp	*newsyms++ = symbol_ptr_ptr[i];
66033965Sjdp
66133965Sjdp    *first_undef = newsyms - bfd_ptr->outsymbols;
66233965Sjdp
66333965Sjdp    for (i = 0; i < symbol_count; i++)
66433965Sjdp      if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) == 0
66533965Sjdp	  && bfd_is_und_section (symbol_ptr_ptr[i]->section))
66633965Sjdp	*newsyms++ = symbol_ptr_ptr[i];
66733965Sjdp    *newsyms = (asymbol *) NULL;
66833965Sjdp    symbol_ptr_ptr = bfd_ptr->outsymbols;
66933965Sjdp  }
67033965Sjdp
67133965Sjdp  for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
67233965Sjdp    {
67333965Sjdp      coff_symbol_type *coff_symbol_ptr = coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]);
67477298Sobrien      symbol_ptr_ptr[symbol_index]->udata.i = symbol_index;
67533965Sjdp      if (coff_symbol_ptr && coff_symbol_ptr->native)
67633965Sjdp	{
67733965Sjdp	  combined_entry_type *s = coff_symbol_ptr->native;
67833965Sjdp	  int i;
67933965Sjdp
68033965Sjdp	  if (s->u.syment.n_sclass == C_FILE)
68133965Sjdp	    {
682218822Sdim	      if (last_file != NULL)
68333965Sjdp		last_file->n_value = native_index;
68433965Sjdp	      last_file = &(s->u.syment);
68533965Sjdp	    }
68633965Sjdp	  else
687218822Sdim	    /* Modify the symbol values according to their section and
688218822Sdim	       type.  */
689218822Sdim	    fixup_symbol_value (bfd_ptr, coff_symbol_ptr, &(s->u.syment));
69033965Sjdp
69133965Sjdp	  for (i = 0; i < s->u.syment.n_numaux + 1; i++)
69233965Sjdp	    s[i].offset = native_index++;
69333965Sjdp	}
69433965Sjdp      else
695218822Sdim	native_index++;
69633965Sjdp    }
697218822Sdim
69833965Sjdp  obj_conv_table_size (bfd_ptr) = native_index;
69933965Sjdp
700130561Sobrien  return TRUE;
70133965Sjdp}
70233965Sjdp
70333965Sjdp/* Run thorough the symbol table again, and fix it so that all
70433965Sjdp   pointers to entries are changed to the entries' index in the output
70533965Sjdp   symbol table.  */
70633965Sjdp
70733965Sjdpvoid
708218822Sdimcoff_mangle_symbols (bfd *bfd_ptr)
70933965Sjdp{
71033965Sjdp  unsigned int symbol_count = bfd_get_symcount (bfd_ptr);
71133965Sjdp  asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
71233965Sjdp  unsigned int symbol_index;
71333965Sjdp
71433965Sjdp  for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
71533965Sjdp    {
71633965Sjdp      coff_symbol_type *coff_symbol_ptr =
71733965Sjdp      coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]);
71833965Sjdp
71933965Sjdp      if (coff_symbol_ptr && coff_symbol_ptr->native)
72033965Sjdp	{
72133965Sjdp	  int i;
72233965Sjdp	  combined_entry_type *s = coff_symbol_ptr->native;
72333965Sjdp
72433965Sjdp	  if (s->fix_value)
72533965Sjdp	    {
72633965Sjdp	      /* FIXME: We should use a union here.  */
72733965Sjdp	      s->u.syment.n_value =
72889857Sobrien		(bfd_vma)((combined_entry_type *)
72989857Sobrien			  ((unsigned long) s->u.syment.n_value))->offset;
73033965Sjdp	      s->fix_value = 0;
73133965Sjdp	    }
73233965Sjdp	  if (s->fix_line)
73333965Sjdp	    {
73433965Sjdp	      /* The value is the offset into the line number entries
73533965Sjdp                 for the symbol's section.  On output, the symbol's
73633965Sjdp                 section should be N_DEBUG.  */
73733965Sjdp	      s->u.syment.n_value =
73833965Sjdp		(coff_symbol_ptr->symbol.section->output_section->line_filepos
73933965Sjdp		 + s->u.syment.n_value * bfd_coff_linesz (bfd_ptr));
74033965Sjdp	      coff_symbol_ptr->symbol.section =
74133965Sjdp		coff_section_from_bfd_index (bfd_ptr, N_DEBUG);
74233965Sjdp	      BFD_ASSERT (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING);
74333965Sjdp	    }
74433965Sjdp	  for (i = 0; i < s->u.syment.n_numaux; i++)
74533965Sjdp	    {
74633965Sjdp	      combined_entry_type *a = s + i + 1;
74733965Sjdp	      if (a->fix_tag)
74833965Sjdp		{
74933965Sjdp		  a->u.auxent.x_sym.x_tagndx.l =
75033965Sjdp		    a->u.auxent.x_sym.x_tagndx.p->offset;
75133965Sjdp		  a->fix_tag = 0;
75233965Sjdp		}
75333965Sjdp	      if (a->fix_end)
75433965Sjdp		{
75533965Sjdp		  a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l =
75633965Sjdp		    a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p->offset;
75733965Sjdp		  a->fix_end = 0;
75833965Sjdp		}
75933965Sjdp	      if (a->fix_scnlen)
76033965Sjdp		{
76133965Sjdp		  a->u.auxent.x_csect.x_scnlen.l =
76233965Sjdp		    a->u.auxent.x_csect.x_scnlen.p->offset;
76333965Sjdp		  a->fix_scnlen = 0;
76433965Sjdp		}
76533965Sjdp	    }
76633965Sjdp	}
76733965Sjdp    }
76833965Sjdp}
76933965Sjdp
77033965Sjdpstatic void
771218822Sdimcoff_fix_symbol_name (bfd *abfd,
772218822Sdim		      asymbol *symbol,
773218822Sdim		      combined_entry_type *native,
774218822Sdim		      bfd_size_type *string_size_p,
775218822Sdim		      asection **debug_string_section_p,
776218822Sdim		      bfd_size_type *debug_string_size_p)
77733965Sjdp{
77833965Sjdp  unsigned int name_length;
77933965Sjdp  union internal_auxent *auxent;
78033965Sjdp  char *name = (char *) (symbol->name);
78133965Sjdp
782218822Sdim  if (name == NULL)
78333965Sjdp    {
784218822Sdim      /* COFF symbols always have names, so we'll make one up.  */
78533965Sjdp      symbol->name = "strange";
78633965Sjdp      name = (char *) symbol->name;
78733965Sjdp    }
78833965Sjdp  name_length = strlen (name);
78933965Sjdp
79033965Sjdp  if (native->u.syment.n_sclass == C_FILE
79133965Sjdp      && native->u.syment.n_numaux > 0)
79233965Sjdp    {
79360484Sobrien      unsigned int filnmlen;
79460484Sobrien
79577298Sobrien      if (bfd_coff_force_symnames_in_strings (abfd))
79677298Sobrien	{
79777298Sobrien          native->u.syment._n._n_n._n_offset =
79877298Sobrien	      (*string_size_p + STRING_SIZE_SIZE);
79977298Sobrien	  native->u.syment._n._n_n._n_zeroes = 0;
80077298Sobrien	  *string_size_p += 6;  /* strlen(".file") + 1 */
80177298Sobrien	}
80277298Sobrien      else
80377298Sobrien  	strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN);
80477298Sobrien
80533965Sjdp      auxent = &(native + 1)->u.auxent;
80633965Sjdp
80760484Sobrien      filnmlen = bfd_coff_filnmlen (abfd);
80860484Sobrien
80933965Sjdp      if (bfd_coff_long_filenames (abfd))
81033965Sjdp	{
81160484Sobrien	  if (name_length <= filnmlen)
812218822Sdim	    strncpy (auxent->x_file.x_fname, name, filnmlen);
81333965Sjdp	  else
81433965Sjdp	    {
81533965Sjdp	      auxent->x_file.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE;
81633965Sjdp	      auxent->x_file.x_n.x_zeroes = 0;
81733965Sjdp	      *string_size_p += name_length + 1;
81833965Sjdp	    }
81933965Sjdp	}
82033965Sjdp      else
82133965Sjdp	{
82260484Sobrien	  strncpy (auxent->x_file.x_fname, name, filnmlen);
82360484Sobrien	  if (name_length > filnmlen)
82460484Sobrien	    name[filnmlen] = '\0';
82533965Sjdp	}
82633965Sjdp    }
82733965Sjdp  else
82833965Sjdp    {
82977298Sobrien      if (name_length <= SYMNMLEN && !bfd_coff_force_symnames_in_strings (abfd))
830218822Sdim	/* This name will fit into the symbol neatly.  */
831218822Sdim	strncpy (native->u.syment._n._n_name, symbol->name, SYMNMLEN);
832218822Sdim
83333965Sjdp      else if (!bfd_coff_symname_in_debug (abfd, &native->u.syment))
83433965Sjdp	{
83533965Sjdp	  native->u.syment._n._n_n._n_offset = (*string_size_p
83633965Sjdp						+ STRING_SIZE_SIZE);
83733965Sjdp	  native->u.syment._n._n_n._n_zeroes = 0;
83833965Sjdp	  *string_size_p += name_length + 1;
83933965Sjdp	}
84033965Sjdp      else
84133965Sjdp	{
84289857Sobrien	  file_ptr filepos;
84377298Sobrien	  bfd_byte buf[4];
84477298Sobrien	  int prefix_len = bfd_coff_debug_string_prefix_length (abfd);
84533965Sjdp
84633965Sjdp	  /* This name should be written into the .debug section.  For
84733965Sjdp	     some reason each name is preceded by a two byte length
84833965Sjdp	     and also followed by a null byte.  FIXME: We assume that
84933965Sjdp	     the .debug section has already been created, and that it
85033965Sjdp	     is large enough.  */
85133965Sjdp	  if (*debug_string_section_p == (asection *) NULL)
85233965Sjdp	    *debug_string_section_p = bfd_get_section_by_name (abfd, ".debug");
85333965Sjdp	  filepos = bfd_tell (abfd);
85477298Sobrien	  if (prefix_len == 4)
85589857Sobrien	    bfd_put_32 (abfd, (bfd_vma) (name_length + 1), buf);
85677298Sobrien	  else
85789857Sobrien	    bfd_put_16 (abfd, (bfd_vma) (name_length + 1), buf);
85877298Sobrien
85933965Sjdp	  if (!bfd_set_section_contents (abfd,
86033965Sjdp					 *debug_string_section_p,
861218822Sdim					 (void *) buf,
86233965Sjdp					 (file_ptr) *debug_string_size_p,
86377298Sobrien					 (bfd_size_type) prefix_len)
86433965Sjdp	      || !bfd_set_section_contents (abfd,
86533965Sjdp					    *debug_string_section_p,
866218822Sdim					    (void *) symbol->name,
86789857Sobrien					    (file_ptr) (*debug_string_size_p
86889857Sobrien							+ prefix_len),
86933965Sjdp					    (bfd_size_type) name_length + 1))
87033965Sjdp	    abort ();
87133965Sjdp	  if (bfd_seek (abfd, filepos, SEEK_SET) != 0)
87233965Sjdp	    abort ();
87377298Sobrien	  native->u.syment._n._n_n._n_offset =
87477298Sobrien	      *debug_string_size_p + prefix_len;
87533965Sjdp	  native->u.syment._n._n_n._n_zeroes = 0;
87677298Sobrien	  *debug_string_size_p += name_length + 1 + prefix_len;
87733965Sjdp	}
87833965Sjdp    }
87933965Sjdp}
88033965Sjdp
88133965Sjdp/* We need to keep track of the symbol index so that when we write out
88233965Sjdp   the relocs we can get the index for a symbol.  This method is a
88333965Sjdp   hack.  FIXME.  */
88433965Sjdp
88533965Sjdp#define set_index(symbol, idx)	((symbol)->udata.i = (idx))
88633965Sjdp
88733965Sjdp/* Write a symbol out to a COFF file.  */
88833965Sjdp
889130561Sobrienstatic bfd_boolean
890218822Sdimcoff_write_symbol (bfd *abfd,
891218822Sdim		   asymbol *symbol,
892218822Sdim		   combined_entry_type *native,
893218822Sdim		   bfd_vma *written,
894218822Sdim		   bfd_size_type *string_size_p,
895218822Sdim		   asection **debug_string_section_p,
896218822Sdim		   bfd_size_type *debug_string_size_p)
89733965Sjdp{
89833965Sjdp  unsigned int numaux = native->u.syment.n_numaux;
89933965Sjdp  int type = native->u.syment.n_type;
90033965Sjdp  int class = native->u.syment.n_sclass;
901218822Sdim  void * buf;
90233965Sjdp  bfd_size_type symesz;
90333965Sjdp
90433965Sjdp  if (native->u.syment.n_sclass == C_FILE)
90533965Sjdp    symbol->flags |= BSF_DEBUGGING;
90633965Sjdp
90733965Sjdp  if (symbol->flags & BSF_DEBUGGING
90833965Sjdp      && bfd_is_abs_section (symbol->section))
909218822Sdim    native->u.syment.n_scnum = N_DEBUG;
910218822Sdim
91133965Sjdp  else if (bfd_is_abs_section (symbol->section))
912218822Sdim    native->u.syment.n_scnum = N_ABS;
913218822Sdim
91433965Sjdp  else if (bfd_is_und_section (symbol->section))
915218822Sdim    native->u.syment.n_scnum = N_UNDEF;
916218822Sdim
91733965Sjdp  else
918218822Sdim    native->u.syment.n_scnum =
919218822Sdim      symbol->section->output_section->target_index;
92033965Sjdp
92133965Sjdp  coff_fix_symbol_name (abfd, symbol, native, string_size_p,
92233965Sjdp			debug_string_section_p, debug_string_size_p);
92333965Sjdp
92433965Sjdp  symesz = bfd_coff_symesz (abfd);
92533965Sjdp  buf = bfd_alloc (abfd, symesz);
92633965Sjdp  if (!buf)
927130561Sobrien    return FALSE;
92833965Sjdp  bfd_coff_swap_sym_out (abfd, &native->u.syment, buf);
92989857Sobrien  if (bfd_bwrite (buf, symesz, abfd) != symesz)
930130561Sobrien    return FALSE;
93133965Sjdp  bfd_release (abfd, buf);
93233965Sjdp
93333965Sjdp  if (native->u.syment.n_numaux > 0)
93433965Sjdp    {
93533965Sjdp      bfd_size_type auxesz;
93633965Sjdp      unsigned int j;
93733965Sjdp
93833965Sjdp      auxesz = bfd_coff_auxesz (abfd);
93933965Sjdp      buf = bfd_alloc (abfd, auxesz);
94033965Sjdp      if (!buf)
941130561Sobrien	return FALSE;
94233965Sjdp      for (j = 0; j < native->u.syment.n_numaux; j++)
94333965Sjdp	{
94433965Sjdp	  bfd_coff_swap_aux_out (abfd,
94533965Sjdp				 &((native + j + 1)->u.auxent),
946218822Sdim				 type, class, (int) j,
94733965Sjdp				 native->u.syment.n_numaux,
94833965Sjdp				 buf);
94989857Sobrien	  if (bfd_bwrite (buf, auxesz, abfd) != auxesz)
950130561Sobrien	    return FALSE;
95133965Sjdp	}
95233965Sjdp      bfd_release (abfd, buf);
95333965Sjdp    }
95433965Sjdp
95533965Sjdp  /* Store the index for use when we write out the relocs.  */
95633965Sjdp  set_index (symbol, *written);
95733965Sjdp
95833965Sjdp  *written += numaux + 1;
959130561Sobrien  return TRUE;
96033965Sjdp}
96133965Sjdp
96233965Sjdp/* Write out a symbol to a COFF file that does not come from a COFF
96333965Sjdp   file originally.  This symbol may have been created by the linker,
96433965Sjdp   or we may be linking a non COFF file to a COFF file.  */
96533965Sjdp
966130561Sobrienstatic bfd_boolean
967218822Sdimcoff_write_alien_symbol (bfd *abfd,
968218822Sdim			 asymbol *symbol,
969218822Sdim			 bfd_vma *written,
970218822Sdim			 bfd_size_type *string_size_p,
971218822Sdim			 asection **debug_string_section_p,
972218822Sdim			 bfd_size_type *debug_string_size_p)
97333965Sjdp{
97433965Sjdp  combined_entry_type *native;
97533965Sjdp  combined_entry_type dummy;
97633965Sjdp
97733965Sjdp  native = &dummy;
97833965Sjdp  native->u.syment.n_type = T_NULL;
97933965Sjdp  native->u.syment.n_flags = 0;
98033965Sjdp  if (bfd_is_und_section (symbol->section))
98133965Sjdp    {
98233965Sjdp      native->u.syment.n_scnum = N_UNDEF;
98333965Sjdp      native->u.syment.n_value = symbol->value;
98433965Sjdp    }
98533965Sjdp  else if (bfd_is_com_section (symbol->section))
98633965Sjdp    {
98733965Sjdp      native->u.syment.n_scnum = N_UNDEF;
98833965Sjdp      native->u.syment.n_value = symbol->value;
98933965Sjdp    }
99033965Sjdp  else if (symbol->flags & BSF_DEBUGGING)
99133965Sjdp    {
99233965Sjdp      /* There isn't much point to writing out a debugging symbol
99333965Sjdp         unless we are prepared to convert it into COFF debugging
99433965Sjdp         format.  So, we just ignore them.  We must clobber the symbol
99533965Sjdp         name to keep it from being put in the string table.  */
99633965Sjdp      symbol->name = "";
997130561Sobrien      return TRUE;
99833965Sjdp    }
99933965Sjdp  else
100033965Sjdp    {
100133965Sjdp      native->u.syment.n_scnum =
100233965Sjdp	symbol->section->output_section->target_index;
100333965Sjdp      native->u.syment.n_value = (symbol->value
100433965Sjdp				  + symbol->section->output_offset);
100538889Sjdp      if (! obj_pe (abfd))
100638889Sjdp	native->u.syment.n_value += symbol->section->output_section->vma;
100733965Sjdp
100889857Sobrien      /* Copy the any flags from the file header into the symbol.
100933965Sjdp         FIXME: Why?  */
101033965Sjdp      {
101133965Sjdp	coff_symbol_type *c = coff_symbol_from (abfd, symbol);
101233965Sjdp	if (c != (coff_symbol_type *) NULL)
101333965Sjdp	  native->u.syment.n_flags = bfd_asymbol_bfd (&c->symbol)->flags;
101433965Sjdp      }
101533965Sjdp    }
101633965Sjdp
101733965Sjdp  native->u.syment.n_type = 0;
101833965Sjdp  if (symbol->flags & BSF_LOCAL)
101933965Sjdp    native->u.syment.n_sclass = C_STAT;
102060484Sobrien  else if (symbol->flags & BSF_WEAK)
102160484Sobrien    native->u.syment.n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT;
102233965Sjdp  else
102333965Sjdp    native->u.syment.n_sclass = C_EXT;
102433965Sjdp  native->u.syment.n_numaux = 0;
102533965Sjdp
102633965Sjdp  return coff_write_symbol (abfd, symbol, native, written, string_size_p,
102733965Sjdp			    debug_string_section_p, debug_string_size_p);
102833965Sjdp}
102933965Sjdp
103033965Sjdp/* Write a native symbol to a COFF file.  */
103133965Sjdp
1032130561Sobrienstatic bfd_boolean
1033218822Sdimcoff_write_native_symbol (bfd *abfd,
1034218822Sdim			  coff_symbol_type *symbol,
1035218822Sdim			  bfd_vma *written,
1036218822Sdim			  bfd_size_type *string_size_p,
1037218822Sdim			  asection **debug_string_section_p,
1038218822Sdim			  bfd_size_type *debug_string_size_p)
103933965Sjdp{
104033965Sjdp  combined_entry_type *native = symbol->native;
104133965Sjdp  alent *lineno = symbol->lineno;
104233965Sjdp
104333965Sjdp  /* If this symbol has an associated line number, we must store the
104433965Sjdp     symbol index in the line number field.  We also tag the auxent to
104533965Sjdp     point to the right place in the lineno table.  */
104633965Sjdp  if (lineno && !symbol->done_lineno && symbol->symbol.section->owner != NULL)
104733965Sjdp    {
104833965Sjdp      unsigned int count = 0;
1049218822Sdim
105033965Sjdp      lineno[count].u.offset = *written;
105133965Sjdp      if (native->u.syment.n_numaux)
105233965Sjdp	{
105333965Sjdp	  union internal_auxent *a = &((native + 1)->u.auxent);
105433965Sjdp
105533965Sjdp	  a->x_sym.x_fcnary.x_fcn.x_lnnoptr =
105633965Sjdp	    symbol->symbol.section->output_section->moving_line_filepos;
105733965Sjdp	}
105833965Sjdp
105933965Sjdp      /* Count and relocate all other linenumbers.  */
106033965Sjdp      count++;
106133965Sjdp      while (lineno[count].line_number != 0)
106233965Sjdp	{
106333965Sjdp	  lineno[count].u.offset +=
106433965Sjdp	    (symbol->symbol.section->output_section->vma
106533965Sjdp	     + symbol->symbol.section->output_offset);
106633965Sjdp	  count++;
106733965Sjdp	}
1068130561Sobrien      symbol->done_lineno = TRUE;
106933965Sjdp
107089857Sobrien      if (! bfd_is_const_section (symbol->symbol.section->output_section))
107189857Sobrien	symbol->symbol.section->output_section->moving_line_filepos +=
107289857Sobrien	  count * bfd_coff_linesz (abfd);
107333965Sjdp    }
107433965Sjdp
107533965Sjdp  return coff_write_symbol (abfd, &(symbol->symbol), native, written,
107633965Sjdp			    string_size_p, debug_string_section_p,
107733965Sjdp			    debug_string_size_p);
107833965Sjdp}
107933965Sjdp
108033965Sjdp/* Write out the COFF symbols.  */
108133965Sjdp
1082130561Sobrienbfd_boolean
1083218822Sdimcoff_write_symbols (bfd *abfd)
108433965Sjdp{
108533965Sjdp  bfd_size_type string_size;
108633965Sjdp  asection *debug_string_section;
108733965Sjdp  bfd_size_type debug_string_size;
108833965Sjdp  unsigned int i;
108933965Sjdp  unsigned int limit = bfd_get_symcount (abfd);
1090218822Sdim  bfd_vma written = 0;
109133965Sjdp  asymbol **p;
109233965Sjdp
109333965Sjdp  string_size = 0;
109433965Sjdp  debug_string_section = NULL;
109533965Sjdp  debug_string_size = 0;
109633965Sjdp
109733965Sjdp  /* If this target supports long section names, they must be put into
109833965Sjdp     the string table.  This is supported by PE.  This code must
109933965Sjdp     handle section names just as they are handled in
110033965Sjdp     coff_write_object_contents.  */
110133965Sjdp  if (bfd_coff_long_section_names (abfd))
110233965Sjdp    {
110333965Sjdp      asection *o;
110433965Sjdp
110533965Sjdp      for (o = abfd->sections; o != NULL; o = o->next)
110633965Sjdp	{
110733965Sjdp	  size_t len;
110833965Sjdp
110933965Sjdp	  len = strlen (o->name);
111033965Sjdp	  if (len > SCNNMLEN)
111133965Sjdp	    string_size += len + 1;
111233965Sjdp	}
111333965Sjdp    }
111433965Sjdp
1115218822Sdim  /* Seek to the right place.  */
111633965Sjdp  if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0)
1117130561Sobrien    return FALSE;
111833965Sjdp
1119218822Sdim  /* Output all the symbols we have.  */
112033965Sjdp  written = 0;
112133965Sjdp  for (p = abfd->outsymbols, i = 0; i < limit; i++, p++)
112233965Sjdp    {
112333965Sjdp      asymbol *symbol = *p;
112433965Sjdp      coff_symbol_type *c_symbol = coff_symbol_from (abfd, symbol);
112533965Sjdp
112633965Sjdp      if (c_symbol == (coff_symbol_type *) NULL
112733965Sjdp	  || c_symbol->native == (combined_entry_type *) NULL)
112833965Sjdp	{
112933965Sjdp	  if (!coff_write_alien_symbol (abfd, symbol, &written, &string_size,
113033965Sjdp					&debug_string_section,
113133965Sjdp					&debug_string_size))
1132130561Sobrien	    return FALSE;
113333965Sjdp	}
113433965Sjdp      else
113533965Sjdp	{
113633965Sjdp	  if (!coff_write_native_symbol (abfd, c_symbol, &written,
113733965Sjdp					 &string_size, &debug_string_section,
113833965Sjdp					 &debug_string_size))
1139130561Sobrien	    return FALSE;
114033965Sjdp	}
114133965Sjdp    }
114233965Sjdp
114333965Sjdp  obj_raw_syment_count (abfd) = written;
114433965Sjdp
1145218822Sdim  /* Now write out strings.  */
114633965Sjdp  if (string_size != 0)
114733965Sjdp    {
114833965Sjdp      unsigned int size = string_size + STRING_SIZE_SIZE;
114933965Sjdp      bfd_byte buffer[STRING_SIZE_SIZE];
115033965Sjdp
115133965Sjdp#if STRING_SIZE_SIZE == 4
115289857Sobrien      H_PUT_32 (abfd, size, buffer);
115333965Sjdp#else
115489857Sobrien #error Change H_PUT_32
115533965Sjdp#endif
1156218822Sdim      if (bfd_bwrite ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd)
115789857Sobrien	  != sizeof (buffer))
1158130561Sobrien	return FALSE;
115933965Sjdp
116033965Sjdp      /* Handle long section names.  This code must handle section
116133965Sjdp	 names just as they are handled in coff_write_object_contents.  */
116233965Sjdp      if (bfd_coff_long_section_names (abfd))
116333965Sjdp	{
116433965Sjdp	  asection *o;
116533965Sjdp
116633965Sjdp	  for (o = abfd->sections; o != NULL; o = o->next)
116733965Sjdp	    {
116833965Sjdp	      size_t len;
116933965Sjdp
117033965Sjdp	      len = strlen (o->name);
117133965Sjdp	      if (len > SCNNMLEN)
117233965Sjdp		{
117389857Sobrien		  if (bfd_bwrite (o->name, (bfd_size_type) (len + 1), abfd)
117489857Sobrien		      != len + 1)
1175130561Sobrien		    return FALSE;
117633965Sjdp		}
117733965Sjdp	    }
117833965Sjdp	}
117933965Sjdp
118033965Sjdp      for (p = abfd->outsymbols, i = 0;
118133965Sjdp	   i < limit;
118233965Sjdp	   i++, p++)
118333965Sjdp	{
118433965Sjdp	  asymbol *q = *p;
118533965Sjdp	  size_t name_length = strlen (q->name);
118633965Sjdp	  coff_symbol_type *c_symbol = coff_symbol_from (abfd, q);
118733965Sjdp	  size_t maxlen;
118833965Sjdp
118933965Sjdp	  /* Figure out whether the symbol name should go in the string
119033965Sjdp	     table.  Symbol names that are short enough are stored
119133965Sjdp	     directly in the syment structure.  File names permit a
119233965Sjdp	     different, longer, length in the syment structure.  On
119333965Sjdp	     XCOFF, some symbol names are stored in the .debug section
119433965Sjdp	     rather than in the string table.  */
119533965Sjdp
119633965Sjdp	  if (c_symbol == NULL
119733965Sjdp	      || c_symbol->native == NULL)
1198218822Sdim	    /* This is not a COFF symbol, so it certainly is not a
1199218822Sdim	       file name, nor does it go in the .debug section.  */
1200218822Sdim	    maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN;
1201218822Sdim
120233965Sjdp	  else if (bfd_coff_symname_in_debug (abfd,
120333965Sjdp					      &c_symbol->native->u.syment))
1204218822Sdim	    /* This symbol name is in the XCOFF .debug section.
1205218822Sdim	       Don't write it into the string table.  */
1206218822Sdim	    maxlen = name_length;
1207218822Sdim
120833965Sjdp	  else if (c_symbol->native->u.syment.n_sclass == C_FILE
120933965Sjdp		   && c_symbol->native->u.syment.n_numaux > 0)
121077298Sobrien	    {
121177298Sobrien	      if (bfd_coff_force_symnames_in_strings (abfd))
121289857Sobrien		{
121389857Sobrien		  if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6)
1214130561Sobrien		    return FALSE;
121589857Sobrien		}
121677298Sobrien	      maxlen = bfd_coff_filnmlen (abfd);
121777298Sobrien	    }
121833965Sjdp	  else
121977298Sobrien	    maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN;
122033965Sjdp
122133965Sjdp	  if (name_length > maxlen)
122233965Sjdp	    {
1223218822Sdim	      if (bfd_bwrite ((void *) (q->name), (bfd_size_type) name_length + 1,
122489857Sobrien			     abfd) != name_length + 1)
1225130561Sobrien		return FALSE;
122633965Sjdp	    }
122733965Sjdp	}
122833965Sjdp    }
122933965Sjdp  else
123033965Sjdp    {
123133965Sjdp      /* We would normally not write anything here, but we'll write
123233965Sjdp         out 4 so that any stupid coff reader which tries to read the
123333965Sjdp         string table even when there isn't one won't croak.  */
123433965Sjdp      unsigned int size = STRING_SIZE_SIZE;
123533965Sjdp      bfd_byte buffer[STRING_SIZE_SIZE];
123633965Sjdp
123733965Sjdp#if STRING_SIZE_SIZE == 4
123889857Sobrien      H_PUT_32 (abfd, size, buffer);
123933965Sjdp#else
124089857Sobrien #error Change H_PUT_32
124133965Sjdp#endif
1242218822Sdim      if (bfd_bwrite ((void *) buffer, (bfd_size_type) STRING_SIZE_SIZE, abfd)
124333965Sjdp	  != STRING_SIZE_SIZE)
1244130561Sobrien	return FALSE;
124533965Sjdp    }
124633965Sjdp
124733965Sjdp  /* Make sure the .debug section was created to be the correct size.
124833965Sjdp     We should create it ourselves on the fly, but we don't because
124933965Sjdp     BFD won't let us write to any section until we know how large all
125033965Sjdp     the sections are.  We could still do it by making another pass
125133965Sjdp     over the symbols.  FIXME.  */
125233965Sjdp  BFD_ASSERT (debug_string_size == 0
125333965Sjdp	      || (debug_string_section != (asection *) NULL
125433965Sjdp		  && (BFD_ALIGN (debug_string_size,
125533965Sjdp				 1 << debug_string_section->alignment_power)
1256218822Sdim		      == debug_string_section->size)));
125733965Sjdp
1258130561Sobrien  return TRUE;
125933965Sjdp}
126033965Sjdp
1261130561Sobrienbfd_boolean
1262218822Sdimcoff_write_linenumbers (bfd *abfd)
126333965Sjdp{
126433965Sjdp  asection *s;
126533965Sjdp  bfd_size_type linesz;
1266218822Sdim  void * buff;
126733965Sjdp
126833965Sjdp  linesz = bfd_coff_linesz (abfd);
126933965Sjdp  buff = bfd_alloc (abfd, linesz);
127033965Sjdp  if (!buff)
1271130561Sobrien    return FALSE;
127233965Sjdp  for (s = abfd->sections; s != (asection *) NULL; s = s->next)
127333965Sjdp    {
127433965Sjdp      if (s->lineno_count)
127533965Sjdp	{
127633965Sjdp	  asymbol **q = abfd->outsymbols;
127733965Sjdp	  if (bfd_seek (abfd, s->line_filepos, SEEK_SET) != 0)
1278130561Sobrien	    return FALSE;
1279218822Sdim	  /* Find all the linenumbers in this section.  */
128033965Sjdp	  while (*q)
128133965Sjdp	    {
128233965Sjdp	      asymbol *p = *q;
128333965Sjdp	      if (p->section->output_section == s)
128433965Sjdp		{
128533965Sjdp		  alent *l =
128633965Sjdp		  BFD_SEND (bfd_asymbol_bfd (p), _get_lineno,
128733965Sjdp			    (bfd_asymbol_bfd (p), p));
128833965Sjdp		  if (l)
128933965Sjdp		    {
1290218822Sdim		      /* Found a linenumber entry, output.  */
129133965Sjdp		      struct internal_lineno out;
1292218822Sdim		      memset ((void *) & out, 0, sizeof (out));
129333965Sjdp		      out.l_lnno = 0;
129433965Sjdp		      out.l_addr.l_symndx = l->u.offset;
129533965Sjdp		      bfd_coff_swap_lineno_out (abfd, &out, buff);
129689857Sobrien		      if (bfd_bwrite (buff, (bfd_size_type) linesz, abfd)
129789857Sobrien			  != linesz)
1298130561Sobrien			return FALSE;
129933965Sjdp		      l++;
130033965Sjdp		      while (l->line_number)
130133965Sjdp			{
130233965Sjdp			  out.l_lnno = l->line_number;
130333965Sjdp			  out.l_addr.l_symndx = l->u.offset;
130433965Sjdp			  bfd_coff_swap_lineno_out (abfd, &out, buff);
130589857Sobrien			  if (bfd_bwrite (buff, (bfd_size_type) linesz, abfd)
130689857Sobrien			      != linesz)
1307130561Sobrien			    return FALSE;
130833965Sjdp			  l++;
130933965Sjdp			}
131033965Sjdp		    }
131133965Sjdp		}
131233965Sjdp	      q++;
131333965Sjdp	    }
131433965Sjdp	}
131533965Sjdp    }
131633965Sjdp  bfd_release (abfd, buff);
1317130561Sobrien  return TRUE;
131833965Sjdp}
131933965Sjdp
132033965Sjdpalent *
1321218822Sdimcoff_get_lineno (bfd *ignore_abfd ATTRIBUTE_UNUSED, asymbol *symbol)
132233965Sjdp{
132333965Sjdp  return coffsymbol (symbol)->lineno;
132433965Sjdp}
132533965Sjdp
132633965Sjdp/* This function transforms the offsets into the symbol table into
132733965Sjdp   pointers to syments.  */
132833965Sjdp
132933965Sjdpstatic void
1330218822Sdimcoff_pointerize_aux (bfd *abfd,
1331218822Sdim		     combined_entry_type *table_base,
1332218822Sdim		     combined_entry_type *symbol,
1333218822Sdim		     unsigned int indaux,
1334218822Sdim		     combined_entry_type *auxent)
133533965Sjdp{
133638889Sjdp  unsigned int type = symbol->u.syment.n_type;
133738889Sjdp  unsigned int class = symbol->u.syment.n_sclass;
133833965Sjdp
133933965Sjdp  if (coff_backend_info (abfd)->_bfd_coff_pointerize_aux_hook)
134033965Sjdp    {
134133965Sjdp      if ((*coff_backend_info (abfd)->_bfd_coff_pointerize_aux_hook)
134233965Sjdp	  (abfd, table_base, symbol, indaux, auxent))
134333965Sjdp	return;
134433965Sjdp    }
134533965Sjdp
1346218822Sdim  /* Don't bother if this is a file or a section.  */
134733965Sjdp  if (class == C_STAT && type == T_NULL)
134833965Sjdp    return;
134933965Sjdp  if (class == C_FILE)
135033965Sjdp    return;
135133965Sjdp
1352218822Sdim  /* Otherwise patch up.  */
1353218822Sdim#define N_TMASK coff_data  (abfd)->local_n_tmask
135433965Sjdp#define N_BTSHFT coff_data (abfd)->local_n_btshft
1355218822Sdim
135633965Sjdp  if ((ISFCN (type) || ISTAG (class) || class == C_BLOCK || class == C_FCN)
135733965Sjdp      && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l > 0)
135833965Sjdp    {
135933965Sjdp      auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p =
136033965Sjdp	table_base + auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l;
136133965Sjdp      auxent->fix_end = 1;
136233965Sjdp    }
136333965Sjdp  /* A negative tagndx is meaningless, but the SCO 3.2v4 cc can
136433965Sjdp     generate one, so we must be careful to ignore it.  */
136533965Sjdp  if (auxent->u.auxent.x_sym.x_tagndx.l > 0)
136633965Sjdp    {
136733965Sjdp      auxent->u.auxent.x_sym.x_tagndx.p =
136833965Sjdp	table_base + auxent->u.auxent.x_sym.x_tagndx.l;
136933965Sjdp      auxent->fix_tag = 1;
137033965Sjdp    }
137133965Sjdp}
137233965Sjdp
137333965Sjdp/* Allocate space for the ".debug" section, and read it.
137433965Sjdp   We did not read the debug section until now, because
137577298Sobrien   we didn't want to go to the trouble until someone needed it.  */
137633965Sjdp
137733965Sjdpstatic char *
1378218822Sdimbuild_debug_section (bfd *abfd)
137933965Sjdp{
138033965Sjdp  char *debug_section;
138189857Sobrien  file_ptr position;
138289857Sobrien  bfd_size_type sec_size;
138333965Sjdp
138433965Sjdp  asection *sect = bfd_get_section_by_name (abfd, ".debug");
138533965Sjdp
138633965Sjdp  if (!sect)
138733965Sjdp    {
138833965Sjdp      bfd_set_error (bfd_error_no_debug_section);
138933965Sjdp      return NULL;
139033965Sjdp    }
139133965Sjdp
1392218822Sdim  sec_size = sect->size;
1393218822Sdim  debug_section = bfd_alloc (abfd, sec_size);
139433965Sjdp  if (debug_section == NULL)
139533965Sjdp    return NULL;
139633965Sjdp
139777298Sobrien  /* Seek to the beginning of the `.debug' section and read it.
139833965Sjdp     Save the current position first; it is needed by our caller.
139933965Sjdp     Then read debug section and reset the file pointer.  */
140033965Sjdp
140133965Sjdp  position = bfd_tell (abfd);
140233965Sjdp  if (bfd_seek (abfd, sect->filepos, SEEK_SET) != 0
140389857Sobrien      || bfd_bread (debug_section, sec_size, abfd) != sec_size
140433965Sjdp      || bfd_seek (abfd, position, SEEK_SET) != 0)
140533965Sjdp    return NULL;
140633965Sjdp  return debug_section;
140733965Sjdp}
140833965Sjdp
140933965Sjdp/* Return a pointer to a malloc'd copy of 'name'.  'name' may not be
141033965Sjdp   \0-terminated, but will not exceed 'maxlen' characters.  The copy *will*
141133965Sjdp   be \0-terminated.  */
1412218822Sdim
141333965Sjdpstatic char *
1414218822Sdimcopy_name (bfd *abfd, char *name, size_t maxlen)
141533965Sjdp{
141689857Sobrien  size_t len;
141733965Sjdp  char *newname;
141833965Sjdp
141933965Sjdp  for (len = 0; len < maxlen; ++len)
1420218822Sdim    if (name[len] == '\0')
1421218822Sdim      break;
142233965Sjdp
1423218822Sdim  if ((newname = bfd_alloc (abfd, (bfd_size_type) len + 1)) == NULL)
1424218822Sdim    return NULL;
1425218822Sdim
142633965Sjdp  strncpy (newname, name, len);
142733965Sjdp  newname[len] = '\0';
142833965Sjdp  return newname;
142933965Sjdp}
143033965Sjdp
143133965Sjdp/* Read in the external symbols.  */
143233965Sjdp
1433130561Sobrienbfd_boolean
1434218822Sdim_bfd_coff_get_external_symbols (bfd *abfd)
143533965Sjdp{
143633965Sjdp  bfd_size_type symesz;
143789857Sobrien  bfd_size_type size;
1438218822Sdim  void * syms;
143933965Sjdp
144033965Sjdp  if (obj_coff_external_syms (abfd) != NULL)
1441130561Sobrien    return TRUE;
144233965Sjdp
144333965Sjdp  symesz = bfd_coff_symesz (abfd);
144433965Sjdp
144533965Sjdp  size = obj_raw_syment_count (abfd) * symesz;
144633965Sjdp
1447218822Sdim  syms = bfd_malloc (size);
144833965Sjdp  if (syms == NULL && size != 0)
1449130561Sobrien    return FALSE;
145033965Sjdp
145133965Sjdp  if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
145289857Sobrien      || bfd_bread (syms, size, abfd) != size)
145333965Sjdp    {
145433965Sjdp      if (syms != NULL)
145533965Sjdp	free (syms);
1456130561Sobrien      return FALSE;
145733965Sjdp    }
145833965Sjdp
145933965Sjdp  obj_coff_external_syms (abfd) = syms;
146033965Sjdp
1461130561Sobrien  return TRUE;
146233965Sjdp}
146333965Sjdp
146433965Sjdp/* Read in the external strings.  The strings are not loaded until
146533965Sjdp   they are needed.  This is because we have no simple way of
146633965Sjdp   detecting a missing string table in an archive.  */
146733965Sjdp
146833965Sjdpconst char *
1469218822Sdim_bfd_coff_read_string_table (bfd *abfd)
147033965Sjdp{
147133965Sjdp  char extstrsize[STRING_SIZE_SIZE];
147289857Sobrien  bfd_size_type strsize;
147333965Sjdp  char *strings;
147489857Sobrien  file_ptr pos;
147533965Sjdp
147633965Sjdp  if (obj_coff_strings (abfd) != NULL)
147733965Sjdp    return obj_coff_strings (abfd);
147833965Sjdp
147933965Sjdp  if (obj_sym_filepos (abfd) == 0)
148033965Sjdp    {
148133965Sjdp      bfd_set_error (bfd_error_no_symbols);
148233965Sjdp      return NULL;
148333965Sjdp    }
148433965Sjdp
148589857Sobrien  pos = obj_sym_filepos (abfd);
148689857Sobrien  pos += obj_raw_syment_count (abfd) * bfd_coff_symesz (abfd);
148789857Sobrien  if (bfd_seek (abfd, pos, SEEK_SET) != 0)
148833965Sjdp    return NULL;
148977298Sobrien
149089857Sobrien  if (bfd_bread (extstrsize, (bfd_size_type) sizeof extstrsize, abfd)
149189857Sobrien      != sizeof extstrsize)
149233965Sjdp    {
149333965Sjdp      if (bfd_get_error () != bfd_error_file_truncated)
149433965Sjdp	return NULL;
149533965Sjdp
149633965Sjdp      /* There is no string table.  */
149733965Sjdp      strsize = STRING_SIZE_SIZE;
149833965Sjdp    }
149933965Sjdp  else
150033965Sjdp    {
150133965Sjdp#if STRING_SIZE_SIZE == 4
150289857Sobrien      strsize = H_GET_32 (abfd, extstrsize);
150333965Sjdp#else
150489857Sobrien #error Change H_GET_32
150533965Sjdp#endif
150633965Sjdp    }
150733965Sjdp
150833965Sjdp  if (strsize < STRING_SIZE_SIZE)
150933965Sjdp    {
151033965Sjdp      (*_bfd_error_handler)
1511218822Sdim	(_("%B: bad string table size %lu"), abfd, (unsigned long) strsize);
151233965Sjdp      bfd_set_error (bfd_error_bad_value);
151333965Sjdp      return NULL;
151433965Sjdp    }
151533965Sjdp
1516218822Sdim  strings = bfd_malloc (strsize);
151733965Sjdp  if (strings == NULL)
151833965Sjdp    return NULL;
151933965Sjdp
152089857Sobrien  if (bfd_bread (strings + STRING_SIZE_SIZE, strsize - STRING_SIZE_SIZE, abfd)
152133965Sjdp      != strsize - STRING_SIZE_SIZE)
152233965Sjdp    {
152333965Sjdp      free (strings);
152433965Sjdp      return NULL;
152533965Sjdp    }
152633965Sjdp
152733965Sjdp  obj_coff_strings (abfd) = strings;
152833965Sjdp
152933965Sjdp  return strings;
153033965Sjdp}
153133965Sjdp
153233965Sjdp/* Free up the external symbols and strings read from a COFF file.  */
153333965Sjdp
1534130561Sobrienbfd_boolean
1535218822Sdim_bfd_coff_free_symbols (bfd *abfd)
153633965Sjdp{
153733965Sjdp  if (obj_coff_external_syms (abfd) != NULL
153833965Sjdp      && ! obj_coff_keep_syms (abfd))
153933965Sjdp    {
154033965Sjdp      free (obj_coff_external_syms (abfd));
154133965Sjdp      obj_coff_external_syms (abfd) = NULL;
154233965Sjdp    }
154333965Sjdp  if (obj_coff_strings (abfd) != NULL
154433965Sjdp      && ! obj_coff_keep_strings (abfd))
154533965Sjdp    {
154633965Sjdp      free (obj_coff_strings (abfd));
154733965Sjdp      obj_coff_strings (abfd) = NULL;
154833965Sjdp    }
1549130561Sobrien  return TRUE;
155033965Sjdp}
155133965Sjdp
155233965Sjdp/* Read a symbol table into freshly bfd_allocated memory, swap it, and
155333965Sjdp   knit the symbol names into a normalized form.  By normalized here I
155433965Sjdp   mean that all symbols have an n_offset pointer that points to a null-
155533965Sjdp   terminated string.  */
155633965Sjdp
155733965Sjdpcombined_entry_type *
1558218822Sdimcoff_get_normalized_symtab (bfd *abfd)
155933965Sjdp{
156033965Sjdp  combined_entry_type *internal;
156133965Sjdp  combined_entry_type *internal_ptr;
156233965Sjdp  combined_entry_type *symbol_ptr;
156333965Sjdp  combined_entry_type *internal_end;
156489857Sobrien  size_t symesz;
156533965Sjdp  char *raw_src;
156633965Sjdp  char *raw_end;
156733965Sjdp  const char *string_table = NULL;
156833965Sjdp  char *debug_section = NULL;
156989857Sobrien  bfd_size_type size;
157033965Sjdp
157133965Sjdp  if (obj_raw_syments (abfd) != NULL)
157233965Sjdp    return obj_raw_syments (abfd);
157333965Sjdp
157433965Sjdp  size = obj_raw_syment_count (abfd) * sizeof (combined_entry_type);
1575218822Sdim  internal = bfd_zalloc (abfd, size);
157633965Sjdp  if (internal == NULL && size != 0)
157733965Sjdp    return NULL;
157833965Sjdp  internal_end = internal + obj_raw_syment_count (abfd);
157933965Sjdp
158033965Sjdp  if (! _bfd_coff_get_external_symbols (abfd))
158133965Sjdp    return NULL;
158233965Sjdp
158333965Sjdp  raw_src = (char *) obj_coff_external_syms (abfd);
158433965Sjdp
1585218822Sdim  /* Mark the end of the symbols.  */
158633965Sjdp  symesz = bfd_coff_symesz (abfd);
158733965Sjdp  raw_end = (char *) raw_src + obj_raw_syment_count (abfd) * symesz;
158833965Sjdp
158933965Sjdp  /* FIXME SOMEDAY.  A string table size of zero is very weird, but
159033965Sjdp     probably possible.  If one shows up, it will probably kill us.  */
159133965Sjdp
1592218822Sdim  /* Swap all the raw entries.  */
159333965Sjdp  for (internal_ptr = internal;
159433965Sjdp       raw_src < raw_end;
159533965Sjdp       raw_src += symesz, internal_ptr++)
159633965Sjdp    {
159733965Sjdp
159833965Sjdp      unsigned int i;
1599218822Sdim      bfd_coff_swap_sym_in (abfd, (void *) raw_src,
1600218822Sdim			    (void *) & internal_ptr->u.syment);
160133965Sjdp      symbol_ptr = internal_ptr;
160233965Sjdp
160333965Sjdp      for (i = 0;
160433965Sjdp	   i < symbol_ptr->u.syment.n_numaux;
160533965Sjdp	   i++)
160633965Sjdp	{
160733965Sjdp	  internal_ptr++;
160833965Sjdp	  raw_src += symesz;
1609218822Sdim	  bfd_coff_swap_aux_in (abfd, (void *) raw_src,
161033965Sjdp				symbol_ptr->u.syment.n_type,
161133965Sjdp				symbol_ptr->u.syment.n_sclass,
161289857Sobrien				(int) i, symbol_ptr->u.syment.n_numaux,
161333965Sjdp				&(internal_ptr->u.auxent));
161433965Sjdp	  coff_pointerize_aux (abfd, internal, symbol_ptr, i,
161533965Sjdp			       internal_ptr);
161633965Sjdp	}
161733965Sjdp    }
161833965Sjdp
161933965Sjdp  /* Free the raw symbols, but not the strings (if we have them).  */
1620130561Sobrien  obj_coff_keep_strings (abfd) = TRUE;
162133965Sjdp  if (! _bfd_coff_free_symbols (abfd))
162233965Sjdp    return NULL;
162333965Sjdp
162433965Sjdp  for (internal_ptr = internal; internal_ptr < internal_end;
162533965Sjdp       internal_ptr++)
162633965Sjdp    {
162733965Sjdp      if (internal_ptr->u.syment.n_sclass == C_FILE
162833965Sjdp	  && internal_ptr->u.syment.n_numaux > 0)
162933965Sjdp	{
1630218822Sdim	  /* Make a file symbol point to the name in the auxent, since
1631218822Sdim	     the text ".file" is redundant.  */
163233965Sjdp	  if ((internal_ptr + 1)->u.auxent.x_file.x_n.x_zeroes == 0)
163333965Sjdp	    {
1634218822Sdim	      /* The filename is a long one, point into the string table.  */
163533965Sjdp	      if (string_table == NULL)
163633965Sjdp		{
163733965Sjdp		  string_table = _bfd_coff_read_string_table (abfd);
163833965Sjdp		  if (string_table == NULL)
163933965Sjdp		    return NULL;
164033965Sjdp		}
164133965Sjdp
164233965Sjdp	      internal_ptr->u.syment._n._n_n._n_offset =
164333965Sjdp		((long)
164433965Sjdp		 (string_table
164533965Sjdp		  + (internal_ptr + 1)->u.auxent.x_file.x_n.x_offset));
164633965Sjdp	    }
164733965Sjdp	  else
164833965Sjdp	    {
164960484Sobrien	      /* Ordinary short filename, put into memory anyway.  The
165060484Sobrien                 Microsoft PE tools sometimes store a filename in
165160484Sobrien                 multiple AUX entries.  */
165260484Sobrien	      if (internal_ptr->u.syment.n_numaux > 1
165360484Sobrien		  && coff_data (abfd)->pe)
1654218822Sdim		internal_ptr->u.syment._n._n_n._n_offset =
1655218822Sdim		  ((long)
1656218822Sdim		   copy_name (abfd,
1657218822Sdim			      (internal_ptr + 1)->u.auxent.x_file.x_fname,
1658218822Sdim			      internal_ptr->u.syment.n_numaux * symesz));
165960484Sobrien	      else
1660218822Sdim		internal_ptr->u.syment._n._n_n._n_offset =
1661218822Sdim		  ((long)
1662218822Sdim		   copy_name (abfd,
1663218822Sdim			      (internal_ptr + 1)->u.auxent.x_file.x_fname,
1664218822Sdim			      (size_t) bfd_coff_filnmlen (abfd)));
166533965Sjdp	    }
166633965Sjdp	}
166733965Sjdp      else
166833965Sjdp	{
166933965Sjdp	  if (internal_ptr->u.syment._n._n_n._n_zeroes != 0)
167033965Sjdp	    {
167133965Sjdp	      /* This is a "short" name.  Make it long.  */
167289857Sobrien	      size_t i;
167389857Sobrien	      char *newstring;
167433965Sjdp
1675218822Sdim	      /* Find the length of this string without walking into memory
167633965Sjdp	         that isn't ours.  */
167733965Sjdp	      for (i = 0; i < 8; ++i)
167889857Sobrien		if (internal_ptr->u.syment._n._n_name[i] == '\0')
167989857Sobrien		  break;
168033965Sjdp
1681218822Sdim	      newstring = bfd_zalloc (abfd, (bfd_size_type) (i + 1));
168289857Sobrien	      if (newstring == NULL)
1683218822Sdim		return NULL;
168489857Sobrien	      strncpy (newstring, internal_ptr->u.syment._n._n_name, i);
168533965Sjdp	      internal_ptr->u.syment._n._n_n._n_offset = (long int) newstring;
168633965Sjdp	      internal_ptr->u.syment._n._n_n._n_zeroes = 0;
168733965Sjdp	    }
168833965Sjdp	  else if (internal_ptr->u.syment._n._n_n._n_offset == 0)
168933965Sjdp	    internal_ptr->u.syment._n._n_n._n_offset = (long int) "";
169033965Sjdp	  else if (!bfd_coff_symname_in_debug (abfd, &internal_ptr->u.syment))
169133965Sjdp	    {
169233965Sjdp	      /* Long name already.  Point symbol at the string in the
169333965Sjdp                 table.  */
169433965Sjdp	      if (string_table == NULL)
169533965Sjdp		{
169633965Sjdp		  string_table = _bfd_coff_read_string_table (abfd);
169733965Sjdp		  if (string_table == NULL)
169833965Sjdp		    return NULL;
169933965Sjdp		}
170033965Sjdp	      internal_ptr->u.syment._n._n_n._n_offset =
170133965Sjdp		((long int)
170233965Sjdp		 (string_table
170333965Sjdp		  + internal_ptr->u.syment._n._n_n._n_offset));
170433965Sjdp	    }
170533965Sjdp	  else
170633965Sjdp	    {
170733965Sjdp	      /* Long name in debug section.  Very similar.  */
170833965Sjdp	      if (debug_section == NULL)
170933965Sjdp		debug_section = build_debug_section (abfd);
171033965Sjdp	      internal_ptr->u.syment._n._n_n._n_offset = (long int)
171133965Sjdp		(debug_section + internal_ptr->u.syment._n._n_n._n_offset);
171233965Sjdp	    }
171333965Sjdp	}
171433965Sjdp      internal_ptr += internal_ptr->u.syment.n_numaux;
171533965Sjdp    }
171633965Sjdp
171733965Sjdp  obj_raw_syments (abfd) = internal;
171833965Sjdp  BFD_ASSERT (obj_raw_syment_count (abfd)
171933965Sjdp	      == (unsigned int) (internal_ptr - internal));
172033965Sjdp
1721218822Sdim  return internal;
1722218822Sdim}
172333965Sjdp
172433965Sjdplong
1725218822Sdimcoff_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
172633965Sjdp{
172733965Sjdp  if (bfd_get_format (abfd) != bfd_object)
172833965Sjdp    {
172933965Sjdp      bfd_set_error (bfd_error_invalid_operation);
173033965Sjdp      return -1;
173133965Sjdp    }
173233965Sjdp  return (asect->reloc_count + 1) * sizeof (arelent *);
173333965Sjdp}
173433965Sjdp
173533965Sjdpasymbol *
1736218822Sdimcoff_make_empty_symbol (bfd *abfd)
173733965Sjdp{
173889857Sobrien  bfd_size_type amt = sizeof (coff_symbol_type);
1739218822Sdim  coff_symbol_type *new = bfd_zalloc (abfd, amt);
1740218822Sdim
174133965Sjdp  if (new == NULL)
1742218822Sdim    return NULL;
174333965Sjdp  new->symbol.section = 0;
174433965Sjdp  new->native = 0;
1745218822Sdim  new->lineno = NULL;
1746130561Sobrien  new->done_lineno = FALSE;
174733965Sjdp  new->symbol.the_bfd = abfd;
1748218822Sdim
1749218822Sdim  return & new->symbol;
175033965Sjdp}
175133965Sjdp
175233965Sjdp/* Make a debugging symbol.  */
175333965Sjdp
175433965Sjdpasymbol *
1755218822Sdimcoff_bfd_make_debug_symbol (bfd *abfd,
1756218822Sdim			    void * ptr ATTRIBUTE_UNUSED,
1757218822Sdim			    unsigned long sz ATTRIBUTE_UNUSED)
175833965Sjdp{
175989857Sobrien  bfd_size_type amt = sizeof (coff_symbol_type);
1760218822Sdim  coff_symbol_type *new = bfd_alloc (abfd, amt);
1761218822Sdim
176233965Sjdp  if (new == NULL)
1763218822Sdim    return NULL;
176433965Sjdp  /* @@ The 10 is a guess at a plausible maximum number of aux entries
176533965Sjdp     (but shouldn't be a constant).  */
176689857Sobrien  amt = sizeof (combined_entry_type) * 10;
1767218822Sdim  new->native = bfd_zalloc (abfd, amt);
176833965Sjdp  if (!new->native)
1769218822Sdim    return NULL;
177033965Sjdp  new->symbol.section = bfd_abs_section_ptr;
177133965Sjdp  new->symbol.flags = BSF_DEBUGGING;
1772218822Sdim  new->lineno = NULL;
1773130561Sobrien  new->done_lineno = FALSE;
177433965Sjdp  new->symbol.the_bfd = abfd;
1775218822Sdim
1776218822Sdim  return & new->symbol;
177733965Sjdp}
177833965Sjdp
177933965Sjdpvoid
1780218822Sdimcoff_get_symbol_info (bfd *abfd, asymbol *symbol, symbol_info *ret)
178133965Sjdp{
178233965Sjdp  bfd_symbol_info (symbol, ret);
1783218822Sdim
178433965Sjdp  if (coffsymbol (symbol)->native != NULL
178533965Sjdp      && coffsymbol (symbol)->native->fix_value)
1786218822Sdim    ret->value = coffsymbol (symbol)->native->u.syment.n_value -
1787218822Sdim      (unsigned long) obj_raw_syments (abfd);
178833965Sjdp}
178933965Sjdp
179033965Sjdp/* Return the COFF syment for a symbol.  */
179133965Sjdp
1792130561Sobrienbfd_boolean
1793218822Sdimbfd_coff_get_syment (bfd *abfd,
1794218822Sdim		     asymbol *symbol,
1795218822Sdim		     struct internal_syment *psyment)
179633965Sjdp{
179733965Sjdp  coff_symbol_type *csym;
179833965Sjdp
179933965Sjdp  csym = coff_symbol_from (abfd, symbol);
180033965Sjdp  if (csym == NULL || csym->native == NULL)
180133965Sjdp    {
180233965Sjdp      bfd_set_error (bfd_error_invalid_operation);
1803130561Sobrien      return FALSE;
180433965Sjdp    }
180533965Sjdp
180633965Sjdp  *psyment = csym->native->u.syment;
180733965Sjdp
180833965Sjdp  if (csym->native->fix_value)
180989857Sobrien    psyment->n_value = psyment->n_value -
181089857Sobrien      (unsigned long) obj_raw_syments (abfd);
181133965Sjdp
181233965Sjdp  /* FIXME: We should handle fix_line here.  */
181333965Sjdp
1814130561Sobrien  return TRUE;
181533965Sjdp}
181633965Sjdp
181733965Sjdp/* Return the COFF auxent for a symbol.  */
181833965Sjdp
1819130561Sobrienbfd_boolean
1820218822Sdimbfd_coff_get_auxent (bfd *abfd,
1821218822Sdim		     asymbol *symbol,
1822218822Sdim		     int indx,
1823218822Sdim		     union internal_auxent *pauxent)
182433965Sjdp{
182533965Sjdp  coff_symbol_type *csym;
182633965Sjdp  combined_entry_type *ent;
182733965Sjdp
182833965Sjdp  csym = coff_symbol_from (abfd, symbol);
182933965Sjdp
183033965Sjdp  if (csym == NULL
183133965Sjdp      || csym->native == NULL
183233965Sjdp      || indx >= csym->native->u.syment.n_numaux)
183333965Sjdp    {
183433965Sjdp      bfd_set_error (bfd_error_invalid_operation);
1835130561Sobrien      return FALSE;
183633965Sjdp    }
183733965Sjdp
183833965Sjdp  ent = csym->native + indx + 1;
183933965Sjdp
184033965Sjdp  *pauxent = ent->u.auxent;
184133965Sjdp
184233965Sjdp  if (ent->fix_tag)
184333965Sjdp    pauxent->x_sym.x_tagndx.l =
184433965Sjdp      ((combined_entry_type *) pauxent->x_sym.x_tagndx.p
184533965Sjdp       - obj_raw_syments (abfd));
184633965Sjdp
184733965Sjdp  if (ent->fix_end)
184833965Sjdp    pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l =
184933965Sjdp      ((combined_entry_type *) pauxent->x_sym.x_fcnary.x_fcn.x_endndx.p
185033965Sjdp       - obj_raw_syments (abfd));
185133965Sjdp
185233965Sjdp  if (ent->fix_scnlen)
185333965Sjdp    pauxent->x_csect.x_scnlen.l =
185433965Sjdp      ((combined_entry_type *) pauxent->x_csect.x_scnlen.p
185533965Sjdp       - obj_raw_syments (abfd));
185633965Sjdp
1857130561Sobrien  return TRUE;
185833965Sjdp}
185933965Sjdp
186033965Sjdp/* Print out information about COFF symbol.  */
186133965Sjdp
186233965Sjdpvoid
1863218822Sdimcoff_print_symbol (bfd *abfd,
1864218822Sdim		   void * filep,
1865218822Sdim		   asymbol *symbol,
1866218822Sdim		   bfd_print_symbol_type how)
186733965Sjdp{
1868218822Sdim  FILE * file = (FILE *) filep;
186933965Sjdp
187033965Sjdp  switch (how)
187133965Sjdp    {
187233965Sjdp    case bfd_print_symbol_name:
187333965Sjdp      fprintf (file, "%s", symbol->name);
187433965Sjdp      break;
187533965Sjdp
187633965Sjdp    case bfd_print_symbol_more:
187733965Sjdp      fprintf (file, "coff %s %s",
187833965Sjdp	       coffsymbol (symbol)->native ? "n" : "g",
187933965Sjdp	       coffsymbol (symbol)->lineno ? "l" : " ");
188033965Sjdp      break;
188133965Sjdp
188233965Sjdp    case bfd_print_symbol_all:
188333965Sjdp      if (coffsymbol (symbol)->native)
188433965Sjdp	{
188589857Sobrien	  bfd_vma val;
188633965Sjdp	  unsigned int aux;
188733965Sjdp	  combined_entry_type *combined = coffsymbol (symbol)->native;
188833965Sjdp	  combined_entry_type *root = obj_raw_syments (abfd);
188933965Sjdp	  struct lineno_cache_entry *l = coffsymbol (symbol)->lineno;
189033965Sjdp
189133965Sjdp	  fprintf (file, "[%3ld]", (long) (combined - root));
189233965Sjdp
189333965Sjdp	  if (! combined->fix_value)
189489857Sobrien	    val = (bfd_vma) combined->u.syment.n_value;
189533965Sjdp	  else
189689857Sobrien	    val = combined->u.syment.n_value - (unsigned long) root;
189733965Sjdp
1898218822Sdim	  fprintf (file, "(sec %2d)(fl 0x%02x)(ty %3x)(scl %3d) (nx %d) 0x",
189933965Sjdp		   combined->u.syment.n_scnum,
190033965Sjdp		   combined->u.syment.n_flags,
190133965Sjdp		   combined->u.syment.n_type,
190233965Sjdp		   combined->u.syment.n_sclass,
1903218822Sdim		   combined->u.syment.n_numaux);
1904218822Sdim#ifdef BFD64
1905218822Sdim	  /* fprintf_vma() on a 64-bit enabled host will always print a 64-bit
1906218822Sdim	     value, but really we want to display the address in the target's
1907218822Sdim	     address size.  Since we do not have a field in the bfd structure
1908218822Sdim	     to tell us this, we take a guess, based on the target's name.  */
1909218822Sdim	  if (strstr (bfd_get_target (abfd), "64") == NULL)
1910218822Sdim	    fprintf (file, "%08lx", (unsigned long) (val & 0xffffffff));
1911218822Sdim	  else
191289857Sobrien#endif
1913218822Sdim	    fprintf_vma (file, val);
1914218822Sdim	  fprintf (file, " %s", symbol->name);
191533965Sjdp
191633965Sjdp	  for (aux = 0; aux < combined->u.syment.n_numaux; aux++)
191733965Sjdp	    {
191833965Sjdp	      combined_entry_type *auxp = combined + aux + 1;
191933965Sjdp	      long tagndx;
192033965Sjdp
192133965Sjdp	      if (auxp->fix_tag)
192233965Sjdp		tagndx = auxp->u.auxent.x_sym.x_tagndx.p - root;
192333965Sjdp	      else
192433965Sjdp		tagndx = auxp->u.auxent.x_sym.x_tagndx.l;
192533965Sjdp
192633965Sjdp	      fprintf (file, "\n");
192733965Sjdp
192833965Sjdp	      if (bfd_coff_print_aux (abfd, file, root, combined, auxp, aux))
192933965Sjdp		continue;
193033965Sjdp
193133965Sjdp	      switch (combined->u.syment.n_sclass)
193233965Sjdp		{
193333965Sjdp		case C_FILE:
193433965Sjdp		  fprintf (file, "File ");
193533965Sjdp		  break;
193633965Sjdp
193733965Sjdp		case C_STAT:
193833965Sjdp		  if (combined->u.syment.n_type == T_NULL)
1939218822Sdim		    /* Probably a section symbol ?  */
194033965Sjdp		    {
194133965Sjdp		      fprintf (file, "AUX scnlen 0x%lx nreloc %d nlnno %d",
194233965Sjdp			       (long) auxp->u.auxent.x_scn.x_scnlen,
194333965Sjdp			       auxp->u.auxent.x_scn.x_nreloc,
194433965Sjdp			       auxp->u.auxent.x_scn.x_nlinno);
194533965Sjdp		      if (auxp->u.auxent.x_scn.x_checksum != 0
194633965Sjdp			  || auxp->u.auxent.x_scn.x_associated != 0
194733965Sjdp			  || auxp->u.auxent.x_scn.x_comdat != 0)
194833965Sjdp			fprintf (file, " checksum 0x%lx assoc %d comdat %d",
194933965Sjdp				 auxp->u.auxent.x_scn.x_checksum,
195033965Sjdp				 auxp->u.auxent.x_scn.x_associated,
195133965Sjdp				 auxp->u.auxent.x_scn.x_comdat);
195233965Sjdp		      break;
195333965Sjdp		    }
1954218822Sdim		    /* Otherwise fall through.  */
195560484Sobrien		case C_EXT:
195660484Sobrien		  if (ISFCN (combined->u.syment.n_type))
195760484Sobrien		    {
195889857Sobrien		      long next, llnos;
195989857Sobrien
196089857Sobrien		      if (auxp->fix_end)
196189857Sobrien			next = (auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p
196289857Sobrien			       - root);
196389857Sobrien		      else
196489857Sobrien			next = auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l;
196589857Sobrien		      llnos = auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_lnnoptr;
196660484Sobrien		      fprintf (file,
196789857Sobrien			       "AUX tagndx %ld ttlsiz 0x%lx lnnos %ld next %ld",
196889857Sobrien			       tagndx, auxp->u.auxent.x_sym.x_misc.x_fsize,
196989857Sobrien			       llnos, next);
197060484Sobrien		      break;
197160484Sobrien		    }
1972218822Sdim		  /* Otherwise fall through.  */
197333965Sjdp		default:
197433965Sjdp		  fprintf (file, "AUX lnno %d size 0x%x tagndx %ld",
197533965Sjdp			   auxp->u.auxent.x_sym.x_misc.x_lnsz.x_lnno,
197633965Sjdp			   auxp->u.auxent.x_sym.x_misc.x_lnsz.x_size,
197733965Sjdp			   tagndx);
197833965Sjdp		  if (auxp->fix_end)
197933965Sjdp		    fprintf (file, " endndx %ld",
198033965Sjdp			     ((long)
198133965Sjdp			      (auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p
198233965Sjdp			       - root)));
198333965Sjdp		  break;
198433965Sjdp		}
198533965Sjdp	    }
198633965Sjdp
198733965Sjdp	  if (l)
198833965Sjdp	    {
198933965Sjdp	      fprintf (file, "\n%s :", l->u.sym->name);
199033965Sjdp	      l++;
199133965Sjdp	      while (l->line_number)
199233965Sjdp		{
1993218822Sdim		  fprintf (file, "\n%4d : ", l->line_number);
1994218822Sdim		  fprintf_vma (file, l->u.offset + symbol->section->vma);
199533965Sjdp		  l++;
199633965Sjdp		}
199733965Sjdp	    }
199833965Sjdp	}
199933965Sjdp      else
200033965Sjdp	{
2001218822Sdim	  bfd_print_symbol_vandf (abfd, (void *) file, symbol);
200233965Sjdp	  fprintf (file, " %-5s %s %s %s",
200333965Sjdp		   symbol->section->name,
200433965Sjdp		   coffsymbol (symbol)->native ? "n" : "g",
200533965Sjdp		   coffsymbol (symbol)->lineno ? "l" : " ",
200633965Sjdp		   symbol->name);
200733965Sjdp	}
200833965Sjdp    }
200933965Sjdp}
201033965Sjdp
201133965Sjdp/* Return whether a symbol name implies a local symbol.  In COFF,
201233965Sjdp   local symbols generally start with ``.L''.  Most targets use this
201333965Sjdp   function for the is_local_label_name entry point, but some may
201433965Sjdp   override it.  */
201533965Sjdp
2016130561Sobrienbfd_boolean
2017218822Sdim_bfd_coff_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
2018218822Sdim			       const char *name)
201933965Sjdp{
2020130561Sobrien  return name[0] == '.' && name[1] == 'L';
202133965Sjdp}
202233965Sjdp
202360484Sobrien/* Provided a BFD, a section and an offset (in bytes, not octets) into the
202460484Sobrien   section, calculate and return the name of the source file and the line
202560484Sobrien   nearest to the wanted location.  */
202677298Sobrien
2027130561Sobrienbfd_boolean
2028218822Sdimcoff_find_nearest_line (bfd *abfd,
2029218822Sdim			asection *section,
2030218822Sdim			asymbol **symbols,
2031218822Sdim			bfd_vma offset,
2032218822Sdim			const char **filename_ptr,
2033218822Sdim			const char **functionname_ptr,
2034218822Sdim			unsigned int *line_ptr)
203533965Sjdp{
2036130561Sobrien  bfd_boolean found;
203733965Sjdp  unsigned int i;
203833965Sjdp  unsigned int line_base;
203933965Sjdp  coff_data_type *cof = coff_data (abfd);
2040218822Sdim  /* Run through the raw syments if available.  */
204133965Sjdp  combined_entry_type *p;
204233965Sjdp  combined_entry_type *pend;
204333965Sjdp  alent *l;
204433965Sjdp  struct coff_section_tdata *sec_data;
204589857Sobrien  bfd_size_type amt;
204633965Sjdp
204733965Sjdp  /* Before looking through the symbol table, try to use a .stab
204833965Sjdp     section to find the information.  */
204933965Sjdp  if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
205033965Sjdp					     &found, filename_ptr,
205133965Sjdp					     functionname_ptr, line_ptr,
205277298Sobrien					     &coff_data(abfd)->line_info))
2053130561Sobrien    return FALSE;
205477298Sobrien
205533965Sjdp  if (found)
2056130561Sobrien    return TRUE;
205733965Sjdp
205877298Sobrien  /* Also try examining DWARF2 debugging information.  */
205977298Sobrien  if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
206077298Sobrien				     filename_ptr, functionname_ptr,
206177298Sobrien				     line_ptr, 0,
206277298Sobrien				     &coff_data(abfd)->dwarf2_find_line_info))
2063130561Sobrien    return TRUE;
206477298Sobrien
206533965Sjdp  *filename_ptr = 0;
206633965Sjdp  *functionname_ptr = 0;
206733965Sjdp  *line_ptr = 0;
206833965Sjdp
2069218822Sdim  /* Don't try and find line numbers in a non coff file.  */
207077298Sobrien  if (!bfd_family_coff (abfd))
2071130561Sobrien    return FALSE;
207233965Sjdp
207333965Sjdp  if (cof == NULL)
2074130561Sobrien    return FALSE;
207533965Sjdp
207633965Sjdp  /* Find the first C_FILE symbol.  */
207733965Sjdp  p = cof->raw_syments;
207838889Sjdp  if (!p)
2079130561Sobrien    return FALSE;
208038889Sjdp
208133965Sjdp  pend = p + cof->raw_syment_count;
208233965Sjdp  while (p < pend)
208333965Sjdp    {
208433965Sjdp      if (p->u.syment.n_sclass == C_FILE)
208533965Sjdp	break;
208633965Sjdp      p += 1 + p->u.syment.n_numaux;
208733965Sjdp    }
208833965Sjdp
208933965Sjdp  if (p < pend)
209033965Sjdp    {
209138889Sjdp      bfd_vma sec_vma;
209233965Sjdp      bfd_vma maxdiff;
209333965Sjdp
209433965Sjdp      /* Look through the C_FILE symbols to find the best one.  */
209538889Sjdp      sec_vma = bfd_get_section_vma (abfd, section);
209633965Sjdp      *filename_ptr = (char *) p->u.syment._n._n_n._n_offset;
209733965Sjdp      maxdiff = (bfd_vma) 0 - (bfd_vma) 1;
209833965Sjdp      while (1)
209933965Sjdp	{
210033965Sjdp	  combined_entry_type *p2;
210133965Sjdp
210233965Sjdp	  for (p2 = p + 1 + p->u.syment.n_numaux;
210333965Sjdp	       p2 < pend;
210433965Sjdp	       p2 += 1 + p2->u.syment.n_numaux)
210533965Sjdp	    {
210633965Sjdp	      if (p2->u.syment.n_scnum > 0
210733965Sjdp		  && (section
210833965Sjdp		      == coff_section_from_bfd_index (abfd,
210933965Sjdp						      p2->u.syment.n_scnum)))
211033965Sjdp		break;
211133965Sjdp	      if (p2->u.syment.n_sclass == C_FILE)
211233965Sjdp		{
211333965Sjdp		  p2 = pend;
211433965Sjdp		  break;
211533965Sjdp		}
211633965Sjdp	    }
211733965Sjdp
211860484Sobrien	  /* We use <= MAXDIFF here so that if we get a zero length
211960484Sobrien             file, we actually use the next file entry.  */
212033965Sjdp	  if (p2 < pend
212138889Sjdp	      && offset + sec_vma >= (bfd_vma) p2->u.syment.n_value
212260484Sobrien	      && offset + sec_vma - (bfd_vma) p2->u.syment.n_value <= maxdiff)
212333965Sjdp	    {
212433965Sjdp	      *filename_ptr = (char *) p->u.syment._n._n_n._n_offset;
212538889Sjdp	      maxdiff = offset + sec_vma - p2->u.syment.n_value;
212633965Sjdp	    }
212733965Sjdp
212833965Sjdp	  /* Avoid endless loops on erroneous files by ensuring that
212933965Sjdp	     we always move forward in the file.  */
213089857Sobrien	  if (p >= cof->raw_syments + p->u.syment.n_value)
213133965Sjdp	    break;
213233965Sjdp
213333965Sjdp	  p = cof->raw_syments + p->u.syment.n_value;
213433965Sjdp	  if (p > pend || p->u.syment.n_sclass != C_FILE)
213533965Sjdp	    break;
213633965Sjdp	}
213733965Sjdp    }
213833965Sjdp
2139218822Sdim  /* Now wander though the raw linenumbers of the section.  */
2140218822Sdim  /* If we have been called on this section before, and th. e offset we
214133965Sjdp     want is further down then we can prime the lookup loop.  */
214233965Sjdp  sec_data = coff_section_data (abfd, section);
214333965Sjdp  if (sec_data != NULL
214433965Sjdp      && sec_data->i > 0
214533965Sjdp      && offset >= sec_data->offset)
214633965Sjdp    {
214733965Sjdp      i = sec_data->i;
214833965Sjdp      *functionname_ptr = sec_data->function;
214933965Sjdp      line_base = sec_data->line_base;
215033965Sjdp    }
215133965Sjdp  else
215233965Sjdp    {
215333965Sjdp      i = 0;
215433965Sjdp      line_base = 0;
215533965Sjdp    }
215633965Sjdp
215733965Sjdp  if (section->lineno != NULL)
215833965Sjdp    {
215960484Sobrien      bfd_vma last_value = 0;
216060484Sobrien
216133965Sjdp      l = &section->lineno[i];
216233965Sjdp
216333965Sjdp      for (; i < section->lineno_count; i++)
216433965Sjdp	{
216533965Sjdp	  if (l->line_number == 0)
216633965Sjdp	    {
2167218822Sdim	      /* Get the symbol this line number points at.  */
216833965Sjdp	      coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym);
216933965Sjdp	      if (coff->symbol.value > offset)
217033965Sjdp		break;
217133965Sjdp	      *functionname_ptr = coff->symbol.name;
217260484Sobrien	      last_value = coff->symbol.value;
217333965Sjdp	      if (coff->native)
217433965Sjdp		{
217533965Sjdp		  combined_entry_type *s = coff->native;
217633965Sjdp		  s = s + 1 + s->u.syment.n_numaux;
217733965Sjdp
217833965Sjdp		  /* In XCOFF a debugging symbol can follow the
217933965Sjdp		     function symbol.  */
218033965Sjdp		  if (s->u.syment.n_scnum == N_DEBUG)
218133965Sjdp		    s = s + 1 + s->u.syment.n_numaux;
218233965Sjdp
218333965Sjdp		  /* S should now point to the .bf of the function.  */
218433965Sjdp		  if (s->u.syment.n_numaux)
218533965Sjdp		    {
218633965Sjdp		      /* The linenumber is stored in the auxent.  */
218733965Sjdp		      union internal_auxent *a = &((s + 1)->u.auxent);
218833965Sjdp		      line_base = a->x_sym.x_misc.x_lnsz.x_lnno;
218933965Sjdp		      *line_ptr = line_base;
219033965Sjdp		    }
219133965Sjdp		}
219233965Sjdp	    }
219333965Sjdp	  else
219433965Sjdp	    {
219538889Sjdp	      if (l->u.offset > offset)
219633965Sjdp		break;
219733965Sjdp	      *line_ptr = l->line_number + line_base - 1;
219833965Sjdp	    }
219933965Sjdp	  l++;
220033965Sjdp	}
220160484Sobrien
220260484Sobrien      /* If we fell off the end of the loop, then assume that this
220360484Sobrien	 symbol has no line number info.  Otherwise, symbols with no
220460484Sobrien	 line number info get reported with the line number of the
220560484Sobrien	 last line of the last symbol which does have line number
220660484Sobrien	 info.  We use 0x100 as a slop to account for cases where the
220760484Sobrien	 last line has executable code.  */
220860484Sobrien      if (i >= section->lineno_count
220960484Sobrien	  && last_value != 0
221060484Sobrien	  && offset - last_value > 0x100)
221160484Sobrien	{
221260484Sobrien	  *functionname_ptr = NULL;
221360484Sobrien	  *line_ptr = 0;
221460484Sobrien	}
221533965Sjdp    }
221633965Sjdp
221733965Sjdp  /* Cache the results for the next call.  */
221833965Sjdp  if (sec_data == NULL && section->owner == abfd)
221933965Sjdp    {
222089857Sobrien      amt = sizeof (struct coff_section_tdata);
2221218822Sdim      section->used_by_bfd = bfd_zalloc (abfd, amt);
222233965Sjdp      sec_data = (struct coff_section_tdata *) section->used_by_bfd;
222333965Sjdp    }
222433965Sjdp  if (sec_data != NULL)
222533965Sjdp    {
222633965Sjdp      sec_data->offset = offset;
222733965Sjdp      sec_data->i = i;
222833965Sjdp      sec_data->function = *functionname_ptr;
222933965Sjdp      sec_data->line_base = line_base;
223033965Sjdp    }
223133965Sjdp
2232130561Sobrien  return TRUE;
223333965Sjdp}
223433965Sjdp
2235218822Sdimbfd_boolean
2236218822Sdimcoff_find_inliner_info (bfd *abfd,
2237218822Sdim			const char **filename_ptr,
2238218822Sdim			const char **functionname_ptr,
2239218822Sdim			unsigned int *line_ptr)
2240218822Sdim{
2241218822Sdim  bfd_boolean found;
2242218822Sdim
2243218822Sdim  found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr,
2244218822Sdim					 functionname_ptr, line_ptr,
2245218822Sdim					 &coff_data(abfd)->dwarf2_find_line_info);
2246218822Sdim  return (found);
2247218822Sdim}
2248218822Sdim
224933965Sjdpint
2250218822Sdimcoff_sizeof_headers (bfd *abfd, struct bfd_link_info *info)
225133965Sjdp{
225233965Sjdp  size_t size;
225333965Sjdp
2254218822Sdim  if (!info->relocatable)
2255218822Sdim    size = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
225633965Sjdp  else
2257218822Sdim    size = bfd_coff_filhsz (abfd);
225833965Sjdp
225933965Sjdp  size += abfd->section_count * bfd_coff_scnhsz (abfd);
226033965Sjdp  return size;
226133965Sjdp}
226260484Sobrien
226360484Sobrien/* Change the class of a coff symbol held by BFD.  */
2264218822Sdim
2265130561Sobrienbfd_boolean
2266218822Sdimbfd_coff_set_symbol_class (bfd *         abfd,
2267218822Sdim			   asymbol *     symbol,
2268218822Sdim			   unsigned int  class)
226960484Sobrien{
227060484Sobrien  coff_symbol_type * csym;
227160484Sobrien
227260484Sobrien  csym = coff_symbol_from (abfd, symbol);
227360484Sobrien  if (csym == NULL)
227460484Sobrien    {
227560484Sobrien      bfd_set_error (bfd_error_invalid_operation);
2276130561Sobrien      return FALSE;
227760484Sobrien    }
227860484Sobrien  else if (csym->native == NULL)
227960484Sobrien    {
228060484Sobrien      /* This is an alien symbol which no native coff backend data.
228160484Sobrien	 We cheat here by creating a fake native entry for it and
228260484Sobrien	 then filling in the class.  This code is based on that in
228360484Sobrien	 coff_write_alien_symbol().  */
228477298Sobrien
228560484Sobrien      combined_entry_type * native;
228689857Sobrien      bfd_size_type amt = sizeof (* native);
228760484Sobrien
2288218822Sdim      native = bfd_zalloc (abfd, amt);
228960484Sobrien      if (native == NULL)
2290130561Sobrien	return FALSE;
229160484Sobrien
229260484Sobrien      native->u.syment.n_type   = T_NULL;
229360484Sobrien      native->u.syment.n_sclass = class;
229477298Sobrien
229560484Sobrien      if (bfd_is_und_section (symbol->section))
229660484Sobrien	{
229760484Sobrien	  native->u.syment.n_scnum = N_UNDEF;
229860484Sobrien	  native->u.syment.n_value = symbol->value;
229960484Sobrien	}
230060484Sobrien      else if (bfd_is_com_section (symbol->section))
230160484Sobrien	{
230260484Sobrien	  native->u.syment.n_scnum = N_UNDEF;
230360484Sobrien	  native->u.syment.n_value = symbol->value;
230460484Sobrien	}
230560484Sobrien      else
230660484Sobrien	{
230760484Sobrien	  native->u.syment.n_scnum =
230860484Sobrien	    symbol->section->output_section->target_index;
230960484Sobrien	  native->u.syment.n_value = (symbol->value
231060484Sobrien				      + symbol->section->output_offset);
231160484Sobrien	  if (! obj_pe (abfd))
231260484Sobrien	    native->u.syment.n_value += symbol->section->output_section->vma;
231377298Sobrien
231489857Sobrien	  /* Copy the any flags from the file header into the symbol.
231560484Sobrien	     FIXME: Why?  */
231660484Sobrien	  native->u.syment.n_flags = bfd_asymbol_bfd (& csym->symbol)->flags;
231760484Sobrien	}
231877298Sobrien
231960484Sobrien      csym->native = native;
232060484Sobrien    }
232160484Sobrien  else
2322218822Sdim    csym->native->u.syment.n_sclass = class;
232377298Sobrien
2324130561Sobrien  return TRUE;
232560484Sobrien}
2326218822Sdim
2327218822Sdimstruct coff_comdat_info *
2328218822Sdimbfd_coff_get_comdat_section (bfd *abfd, struct bfd_section *sec)
2329218822Sdim{
2330218822Sdim  if (bfd_get_flavour (abfd) == bfd_target_coff_flavour
2331218822Sdim      && coff_section_data (abfd, sec) != NULL)
2332218822Sdim    return coff_section_data (abfd, sec)->comdat;
2333218822Sdim  else
2334218822Sdim    return NULL;
2335218822Sdim}
2336