133965Sjdp/* ELF executable support for BFD.
233965Sjdp
3130563Sobrien   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
4218822Sdim   2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
533965Sjdp
6130563Sobrien   This file is part of BFD, the Binary File Descriptor library.
733965Sjdp
8130563Sobrien   This program is free software; you can redistribute it and/or modify
9130563Sobrien   it under the terms of the GNU General Public License as published by
10130563Sobrien   the Free Software Foundation; either version 2 of the License, or
11130563Sobrien   (at your option) any later version.
1233965Sjdp
13130563Sobrien   This program is distributed in the hope that it will be useful,
14130563Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
15130563Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16130563Sobrien   GNU General Public License for more details.
1733965Sjdp
18130563Sobrien   You should have received a copy of the GNU General Public License
19130563Sobrien   along with this program; if not, write to the Free Software
20218822Sdim   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
2191047Sobrien
22130563Sobrien
2359160Sobrien/* $FreeBSD$ */
2459160Sobrien
2533965Sjdp
26218822Sdim/*
27218822SdimSECTION
2833965Sjdp	ELF backends
2933965Sjdp
3033965Sjdp	BFD support for ELF formats is being worked on.
3133965Sjdp	Currently, the best supported back ends are for sparc and i386
3233965Sjdp	(running svr4 or Solaris 2).
3333965Sjdp
3433965Sjdp	Documentation of the internals of the support code still needs
3533965Sjdp	to be written.  The code is changing quickly enough that we
3691047Sobrien	haven't bothered yet.  */
3733965Sjdp
3877301Sobrien/* For sparc64-cross-sparc32.  */
3977301Sobrien#define _SYSCALL32
40218822Sdim#include "sysdep.h"
4133965Sjdp#include "bfd.h"
4233965Sjdp#include "bfdlink.h"
4333965Sjdp#include "libbfd.h"
4433965Sjdp#define ARCH_SIZE 0
4533965Sjdp#include "elf-bfd.h"
4689860Sobrien#include "libiberty.h"
4733965Sjdp
48130563Sobrienstatic int elf_sort_sections (const void *, const void *);
49130563Sobrienstatic bfd_boolean assign_file_positions_except_relocs (bfd *, struct bfd_link_info *);
50130563Sobrienstatic bfd_boolean prep_headers (bfd *);
51130563Sobrienstatic bfd_boolean swap_out_syms (bfd *, struct bfd_strtab_hash **, int) ;
52130563Sobrienstatic bfd_boolean elfcore_read_notes (bfd *, file_ptr, bfd_size_type) ;
5333965Sjdp
5433965Sjdp/* Swap version information in and out.  The version information is
5533965Sjdp   currently size independent.  If that ever changes, this code will
5633965Sjdp   need to move into elfcode.h.  */
5733965Sjdp
5833965Sjdp/* Swap in a Verdef structure.  */
5933965Sjdp
6033965Sjdpvoid
61130563Sobrien_bfd_elf_swap_verdef_in (bfd *abfd,
62130563Sobrien			 const Elf_External_Verdef *src,
63130563Sobrien			 Elf_Internal_Verdef *dst)
6433965Sjdp{
6589860Sobrien  dst->vd_version = H_GET_16 (abfd, src->vd_version);
6689860Sobrien  dst->vd_flags   = H_GET_16 (abfd, src->vd_flags);
6789860Sobrien  dst->vd_ndx     = H_GET_16 (abfd, src->vd_ndx);
6889860Sobrien  dst->vd_cnt     = H_GET_16 (abfd, src->vd_cnt);
6989860Sobrien  dst->vd_hash    = H_GET_32 (abfd, src->vd_hash);
7089860Sobrien  dst->vd_aux     = H_GET_32 (abfd, src->vd_aux);
7189860Sobrien  dst->vd_next    = H_GET_32 (abfd, src->vd_next);
7233965Sjdp}
7333965Sjdp
7433965Sjdp/* Swap out a Verdef structure.  */
7533965Sjdp
7633965Sjdpvoid
77130563Sobrien_bfd_elf_swap_verdef_out (bfd *abfd,
78130563Sobrien			  const Elf_Internal_Verdef *src,
79130563Sobrien			  Elf_External_Verdef *dst)
8033965Sjdp{
8189860Sobrien  H_PUT_16 (abfd, src->vd_version, dst->vd_version);
8289860Sobrien  H_PUT_16 (abfd, src->vd_flags, dst->vd_flags);
8389860Sobrien  H_PUT_16 (abfd, src->vd_ndx, dst->vd_ndx);
8489860Sobrien  H_PUT_16 (abfd, src->vd_cnt, dst->vd_cnt);
8589860Sobrien  H_PUT_32 (abfd, src->vd_hash, dst->vd_hash);
8689860Sobrien  H_PUT_32 (abfd, src->vd_aux, dst->vd_aux);
8789860Sobrien  H_PUT_32 (abfd, src->vd_next, dst->vd_next);
8833965Sjdp}
8933965Sjdp
9033965Sjdp/* Swap in a Verdaux structure.  */
9133965Sjdp
9233965Sjdpvoid
93130563Sobrien_bfd_elf_swap_verdaux_in (bfd *abfd,
94130563Sobrien			  const Elf_External_Verdaux *src,
95130563Sobrien			  Elf_Internal_Verdaux *dst)
9633965Sjdp{
9789860Sobrien  dst->vda_name = H_GET_32 (abfd, src->vda_name);
9889860Sobrien  dst->vda_next = H_GET_32 (abfd, src->vda_next);
9933965Sjdp}
10033965Sjdp
10133965Sjdp/* Swap out a Verdaux structure.  */
10233965Sjdp
10333965Sjdpvoid
104130563Sobrien_bfd_elf_swap_verdaux_out (bfd *abfd,
105130563Sobrien			   const Elf_Internal_Verdaux *src,
106130563Sobrien			   Elf_External_Verdaux *dst)
10733965Sjdp{
10889860Sobrien  H_PUT_32 (abfd, src->vda_name, dst->vda_name);
10989860Sobrien  H_PUT_32 (abfd, src->vda_next, dst->vda_next);
11033965Sjdp}
11133965Sjdp
11233965Sjdp/* Swap in a Verneed structure.  */
11333965Sjdp
11433965Sjdpvoid
115130563Sobrien_bfd_elf_swap_verneed_in (bfd *abfd,
116130563Sobrien			  const Elf_External_Verneed *src,
117130563Sobrien			  Elf_Internal_Verneed *dst)
11833965Sjdp{
11989860Sobrien  dst->vn_version = H_GET_16 (abfd, src->vn_version);
12089860Sobrien  dst->vn_cnt     = H_GET_16 (abfd, src->vn_cnt);
12189860Sobrien  dst->vn_file    = H_GET_32 (abfd, src->vn_file);
12289860Sobrien  dst->vn_aux     = H_GET_32 (abfd, src->vn_aux);
12389860Sobrien  dst->vn_next    = H_GET_32 (abfd, src->vn_next);
12433965Sjdp}
12533965Sjdp
12633965Sjdp/* Swap out a Verneed structure.  */
12733965Sjdp
12833965Sjdpvoid
129130563Sobrien_bfd_elf_swap_verneed_out (bfd *abfd,
130130563Sobrien			   const Elf_Internal_Verneed *src,
131130563Sobrien			   Elf_External_Verneed *dst)
13233965Sjdp{
13389860Sobrien  H_PUT_16 (abfd, src->vn_version, dst->vn_version);
13489860Sobrien  H_PUT_16 (abfd, src->vn_cnt, dst->vn_cnt);
13589860Sobrien  H_PUT_32 (abfd, src->vn_file, dst->vn_file);
13689860Sobrien  H_PUT_32 (abfd, src->vn_aux, dst->vn_aux);
13789860Sobrien  H_PUT_32 (abfd, src->vn_next, dst->vn_next);
13833965Sjdp}
13933965Sjdp
14033965Sjdp/* Swap in a Vernaux structure.  */
14133965Sjdp
14233965Sjdpvoid
143130563Sobrien_bfd_elf_swap_vernaux_in (bfd *abfd,
144130563Sobrien			  const Elf_External_Vernaux *src,
145130563Sobrien			  Elf_Internal_Vernaux *dst)
14633965Sjdp{
14789860Sobrien  dst->vna_hash  = H_GET_32 (abfd, src->vna_hash);
14889860Sobrien  dst->vna_flags = H_GET_16 (abfd, src->vna_flags);
14989860Sobrien  dst->vna_other = H_GET_16 (abfd, src->vna_other);
15089860Sobrien  dst->vna_name  = H_GET_32 (abfd, src->vna_name);
15189860Sobrien  dst->vna_next  = H_GET_32 (abfd, src->vna_next);
15233965Sjdp}
15333965Sjdp
15433965Sjdp/* Swap out a Vernaux structure.  */
15533965Sjdp
15633965Sjdpvoid
157130563Sobrien_bfd_elf_swap_vernaux_out (bfd *abfd,
158130563Sobrien			   const Elf_Internal_Vernaux *src,
159130563Sobrien			   Elf_External_Vernaux *dst)
16033965Sjdp{
16189860Sobrien  H_PUT_32 (abfd, src->vna_hash, dst->vna_hash);
16289860Sobrien  H_PUT_16 (abfd, src->vna_flags, dst->vna_flags);
16389860Sobrien  H_PUT_16 (abfd, src->vna_other, dst->vna_other);
16489860Sobrien  H_PUT_32 (abfd, src->vna_name, dst->vna_name);
16589860Sobrien  H_PUT_32 (abfd, src->vna_next, dst->vna_next);
16633965Sjdp}
16733965Sjdp
16833965Sjdp/* Swap in a Versym structure.  */
16933965Sjdp
17033965Sjdpvoid
171130563Sobrien_bfd_elf_swap_versym_in (bfd *abfd,
172130563Sobrien			 const Elf_External_Versym *src,
173130563Sobrien			 Elf_Internal_Versym *dst)
17433965Sjdp{
17589860Sobrien  dst->vs_vers = H_GET_16 (abfd, src->vs_vers);
17633965Sjdp}
17733965Sjdp
17833965Sjdp/* Swap out a Versym structure.  */
17933965Sjdp
18033965Sjdpvoid
181130563Sobrien_bfd_elf_swap_versym_out (bfd *abfd,
182130563Sobrien			  const Elf_Internal_Versym *src,
183130563Sobrien			  Elf_External_Versym *dst)
18433965Sjdp{
18589860Sobrien  H_PUT_16 (abfd, src->vs_vers, dst->vs_vers);
18633965Sjdp}
18733965Sjdp
18833965Sjdp/* Standard ELF hash function.  Do not change this function; you will
18960508Sobrien   cause invalid hash tables to be generated.  */
19060508Sobrien
19133965Sjdpunsigned long
192130563Sobrienbfd_elf_hash (const char *namearg)
19333965Sjdp{
19460508Sobrien  const unsigned char *name = (const unsigned char *) namearg;
19533965Sjdp  unsigned long h = 0;
19633965Sjdp  unsigned long g;
19733965Sjdp  int ch;
19833965Sjdp
19933965Sjdp  while ((ch = *name++) != '\0')
20033965Sjdp    {
20133965Sjdp      h = (h << 4) + ch;
20233965Sjdp      if ((g = (h & 0xf0000000)) != 0)
20333965Sjdp	{
20433965Sjdp	  h ^= g >> 24;
20560508Sobrien	  /* The ELF ABI says `h &= ~g', but this is equivalent in
20660508Sobrien	     this case and on some machines one insn instead of two.  */
20760508Sobrien	  h ^= g;
20833965Sjdp	}
20933965Sjdp    }
210130563Sobrien  return h & 0xffffffff;
21133965Sjdp}
21233965Sjdp
213218822Sdim/* DT_GNU_HASH hash function.  Do not change this function; you will
214218822Sdim   cause invalid hash tables to be generated.  */
21533965Sjdp
216218822Sdimunsigned long
217218822Sdimbfd_elf_gnu_hash (const char *namearg)
21833965Sjdp{
219218822Sdim  const unsigned char *name = (const unsigned char *) namearg;
220218822Sdim  unsigned long h = 5381;
221218822Sdim  unsigned char ch;
22233965Sjdp
223218822Sdim  while ((ch = *name++) != '\0')
224218822Sdim    h = (h << 5) + h + ch;
225218822Sdim  return h & 0xffffffff;
22633965Sjdp}
22733965Sjdp
228130563Sobrienbfd_boolean
229130563Sobrienbfd_elf_mkobject (bfd *abfd)
23033965Sjdp{
231218822Sdim  if (abfd->tdata.any == NULL)
232218822Sdim    {
233218822Sdim      abfd->tdata.any = bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
234218822Sdim      if (abfd->tdata.any == NULL)
235218822Sdim	return FALSE;
236218822Sdim    }
23733965Sjdp
238218822Sdim  elf_tdata (abfd)->program_header_size = (bfd_size_type) -1;
239218822Sdim
240130563Sobrien  return TRUE;
24133965Sjdp}
24233965Sjdp
243130563Sobrienbfd_boolean
244130563Sobrienbfd_elf_mkcorefile (bfd *abfd)
24560508Sobrien{
24677301Sobrien  /* I think this can be done just like an object file.  */
24760508Sobrien  return bfd_elf_mkobject (abfd);
24860508Sobrien}
24960508Sobrien
25033965Sjdpchar *
251130563Sobrienbfd_elf_get_str_section (bfd *abfd, unsigned int shindex)
25233965Sjdp{
25333965Sjdp  Elf_Internal_Shdr **i_shdrp;
254218822Sdim  bfd_byte *shstrtab = NULL;
25589860Sobrien  file_ptr offset;
25689860Sobrien  bfd_size_type shstrtabsize;
25733965Sjdp
25833965Sjdp  i_shdrp = elf_elfsections (abfd);
259218822Sdim  if (i_shdrp == 0
260218822Sdim      || shindex >= elf_numsections (abfd)
261218822Sdim      || i_shdrp[shindex] == 0)
262218822Sdim    return NULL;
26333965Sjdp
264218822Sdim  shstrtab = i_shdrp[shindex]->contents;
26533965Sjdp  if (shstrtab == NULL)
26633965Sjdp    {
26777301Sobrien      /* No cached one, attempt to read, and cache what we read.  */
26833965Sjdp      offset = i_shdrp[shindex]->sh_offset;
26933965Sjdp      shstrtabsize = i_shdrp[shindex]->sh_size;
270218822Sdim
271218822Sdim      /* Allocate and clear an extra byte at the end, to prevent crashes
272218822Sdim	 in case the string table is not terminated.  */
273218822Sdim      if (shstrtabsize + 1 == 0
274218822Sdim	  || (shstrtab = bfd_alloc (abfd, shstrtabsize + 1)) == NULL
275218822Sdim	  || bfd_seek (abfd, offset, SEEK_SET) != 0)
276218822Sdim	shstrtab = NULL;
277218822Sdim      else if (bfd_bread (shstrtab, shstrtabsize, abfd) != shstrtabsize)
278218822Sdim	{
279218822Sdim	  if (bfd_get_error () != bfd_error_system_call)
280218822Sdim	    bfd_set_error (bfd_error_file_truncated);
281218822Sdim	  shstrtab = NULL;
282218822Sdim	}
283218822Sdim      else
284218822Sdim	shstrtab[shstrtabsize] = '\0';
285130563Sobrien      i_shdrp[shindex]->contents = shstrtab;
28633965Sjdp    }
287218822Sdim  return (char *) shstrtab;
28833965Sjdp}
28933965Sjdp
29033965Sjdpchar *
291130563Sobrienbfd_elf_string_from_elf_section (bfd *abfd,
292130563Sobrien				 unsigned int shindex,
293130563Sobrien				 unsigned int strindex)
29433965Sjdp{
29533965Sjdp  Elf_Internal_Shdr *hdr;
29633965Sjdp
29733965Sjdp  if (strindex == 0)
29833965Sjdp    return "";
29933965Sjdp
300218822Sdim  if (elf_elfsections (abfd) == NULL || shindex >= elf_numsections (abfd))
301218822Sdim    return NULL;
302218822Sdim
30333965Sjdp  hdr = elf_elfsections (abfd)[shindex];
30433965Sjdp
30533965Sjdp  if (hdr->contents == NULL
30633965Sjdp      && bfd_elf_get_str_section (abfd, shindex) == NULL)
30733965Sjdp    return NULL;
30833965Sjdp
30938891Sjdp  if (strindex >= hdr->sh_size)
31038891Sjdp    {
311218822Sdim      unsigned int shstrndx = elf_elfheader(abfd)->e_shstrndx;
31238891Sjdp      (*_bfd_error_handler)
313218822Sdim	(_("%B: invalid string offset %u >= %lu for section `%s'"),
314218822Sdim	 abfd, strindex, (unsigned long) hdr->sh_size,
315218822Sdim	 (shindex == shstrndx && strindex == hdr->sh_name
31638891Sjdp	  ? ".shstrtab"
317218822Sdim	  : bfd_elf_string_from_elf_section (abfd, shstrndx, hdr->sh_name)));
31838891Sjdp      return "";
31938891Sjdp    }
32038891Sjdp
32133965Sjdp  return ((char *) hdr->contents) + strindex;
32233965Sjdp}
32333965Sjdp
324104838Sobrien/* Read and convert symbols to internal format.
325104838Sobrien   SYMCOUNT specifies the number of symbols to read, starting from
326104838Sobrien   symbol SYMOFFSET.  If any of INTSYM_BUF, EXTSYM_BUF or EXTSHNDX_BUF
327104838Sobrien   are non-NULL, they are used to store the internal symbols, external
328104838Sobrien   symbols, and symbol section index extensions, respectively.  */
329104838Sobrien
330104838SobrienElf_Internal_Sym *
331130563Sobrienbfd_elf_get_elf_syms (bfd *ibfd,
332130563Sobrien		      Elf_Internal_Shdr *symtab_hdr,
333130563Sobrien		      size_t symcount,
334130563Sobrien		      size_t symoffset,
335130563Sobrien		      Elf_Internal_Sym *intsym_buf,
336130563Sobrien		      void *extsym_buf,
337130563Sobrien		      Elf_External_Sym_Shndx *extshndx_buf)
338104838Sobrien{
339104838Sobrien  Elf_Internal_Shdr *shndx_hdr;
340130563Sobrien  void *alloc_ext;
341104838Sobrien  const bfd_byte *esym;
342104838Sobrien  Elf_External_Sym_Shndx *alloc_extshndx;
343104838Sobrien  Elf_External_Sym_Shndx *shndx;
344104838Sobrien  Elf_Internal_Sym *isym;
345104838Sobrien  Elf_Internal_Sym *isymend;
346130563Sobrien  const struct elf_backend_data *bed;
347104838Sobrien  size_t extsym_size;
348104838Sobrien  bfd_size_type amt;
349104838Sobrien  file_ptr pos;
350104838Sobrien
351104838Sobrien  if (symcount == 0)
352104838Sobrien    return intsym_buf;
353104838Sobrien
354104838Sobrien  /* Normal syms might have section extension entries.  */
355104838Sobrien  shndx_hdr = NULL;
356104838Sobrien  if (symtab_hdr == &elf_tdata (ibfd)->symtab_hdr)
357104838Sobrien    shndx_hdr = &elf_tdata (ibfd)->symtab_shndx_hdr;
358104838Sobrien
359104838Sobrien  /* Read the symbols.  */
360104838Sobrien  alloc_ext = NULL;
361104838Sobrien  alloc_extshndx = NULL;
362104838Sobrien  bed = get_elf_backend_data (ibfd);
363104838Sobrien  extsym_size = bed->s->sizeof_sym;
364104838Sobrien  amt = symcount * extsym_size;
365104838Sobrien  pos = symtab_hdr->sh_offset + symoffset * extsym_size;
366104838Sobrien  if (extsym_buf == NULL)
367104838Sobrien    {
368218822Sdim      alloc_ext = bfd_malloc2 (symcount, extsym_size);
369104838Sobrien      extsym_buf = alloc_ext;
370104838Sobrien    }
371104838Sobrien  if (extsym_buf == NULL
372104838Sobrien      || bfd_seek (ibfd, pos, SEEK_SET) != 0
373104838Sobrien      || bfd_bread (extsym_buf, amt, ibfd) != amt)
374104838Sobrien    {
375104838Sobrien      intsym_buf = NULL;
376104838Sobrien      goto out;
377104838Sobrien    }
378104838Sobrien
379104838Sobrien  if (shndx_hdr == NULL || shndx_hdr->sh_size == 0)
380104838Sobrien    extshndx_buf = NULL;
381104838Sobrien  else
382104838Sobrien    {
383104838Sobrien      amt = symcount * sizeof (Elf_External_Sym_Shndx);
384104838Sobrien      pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx);
385104838Sobrien      if (extshndx_buf == NULL)
386104838Sobrien	{
387218822Sdim	  alloc_extshndx = bfd_malloc2 (symcount,
388218822Sdim					sizeof (Elf_External_Sym_Shndx));
389104838Sobrien	  extshndx_buf = alloc_extshndx;
390104838Sobrien	}
391104838Sobrien      if (extshndx_buf == NULL
392104838Sobrien	  || bfd_seek (ibfd, pos, SEEK_SET) != 0
393104838Sobrien	  || bfd_bread (extshndx_buf, amt, ibfd) != amt)
394104838Sobrien	{
395104838Sobrien	  intsym_buf = NULL;
396104838Sobrien	  goto out;
397104838Sobrien	}
398104838Sobrien    }
399104838Sobrien
400104838Sobrien  if (intsym_buf == NULL)
401104838Sobrien    {
402218822Sdim      intsym_buf = bfd_malloc2 (symcount, sizeof (Elf_Internal_Sym));
403104838Sobrien      if (intsym_buf == NULL)
404104838Sobrien	goto out;
405104838Sobrien    }
406104838Sobrien
407104838Sobrien  /* Convert the symbols to internal form.  */
408104838Sobrien  isymend = intsym_buf + symcount;
409104838Sobrien  for (esym = extsym_buf, isym = intsym_buf, shndx = extshndx_buf;
410104838Sobrien       isym < isymend;
411104838Sobrien       esym += extsym_size, isym++, shndx = shndx != NULL ? shndx + 1 : NULL)
412218822Sdim    if (!(*bed->s->swap_symbol_in) (ibfd, esym, shndx, isym))
413218822Sdim      {
414218822Sdim	symoffset += (esym - (bfd_byte *) extsym_buf) / extsym_size;
415218822Sdim	(*_bfd_error_handler) (_("%B symbol number %lu references "
416218822Sdim				 "nonexistent SHT_SYMTAB_SHNDX section"),
417218822Sdim			       ibfd, (unsigned long) symoffset);
418218822Sdim	intsym_buf = NULL;
419218822Sdim	goto out;
420218822Sdim      }
421104838Sobrien
422104838Sobrien out:
423104838Sobrien  if (alloc_ext != NULL)
424104838Sobrien    free (alloc_ext);
425104838Sobrien  if (alloc_extshndx != NULL)
426104838Sobrien    free (alloc_extshndx);
427104838Sobrien
428104838Sobrien  return intsym_buf;
429104838Sobrien}
430104838Sobrien
431130563Sobrien/* Look up a symbol name.  */
432130563Sobrienconst char *
433218822Sdimbfd_elf_sym_name (bfd *abfd,
434218822Sdim		  Elf_Internal_Shdr *symtab_hdr,
435218822Sdim		  Elf_Internal_Sym *isym,
436218822Sdim		  asection *sym_sec)
437130563Sobrien{
438218822Sdim  const char *name;
439130563Sobrien  unsigned int iname = isym->st_name;
440218822Sdim  unsigned int shindex = symtab_hdr->sh_link;
441218822Sdim
442218822Sdim  if (iname == 0 && ELF_ST_TYPE (isym->st_info) == STT_SECTION
443218822Sdim      /* Check for a bogus st_shndx to avoid crashing.  */
444218822Sdim      && isym->st_shndx < elf_numsections (abfd)
445218822Sdim      && !(isym->st_shndx >= SHN_LORESERVE && isym->st_shndx <= SHN_HIRESERVE))
446130563Sobrien    {
447130563Sobrien      iname = elf_elfsections (abfd)[isym->st_shndx]->sh_name;
448130563Sobrien      shindex = elf_elfheader (abfd)->e_shstrndx;
449130563Sobrien    }
450130563Sobrien
451218822Sdim  name = bfd_elf_string_from_elf_section (abfd, shindex, iname);
452218822Sdim  if (name == NULL)
453218822Sdim    name = "(null)";
454218822Sdim  else if (sym_sec && *name == '\0')
455218822Sdim    name = bfd_section_name (abfd, sym_sec);
456218822Sdim
457218822Sdim  return name;
458130563Sobrien}
459130563Sobrien
46089860Sobrien/* Elf_Internal_Shdr->contents is an array of these for SHT_GROUP
46189860Sobrien   sections.  The first element is the flags, the rest are section
46289860Sobrien   pointers.  */
46389860Sobrien
46489860Sobrientypedef union elf_internal_group {
46589860Sobrien  Elf_Internal_Shdr *shdr;
46689860Sobrien  unsigned int flags;
46789860Sobrien} Elf_Internal_Group;
46889860Sobrien
469104838Sobrien/* Return the name of the group signature symbol.  Why isn't the
470104838Sobrien   signature just a string?  */
471104838Sobrien
472104838Sobrienstatic const char *
473130563Sobriengroup_signature (bfd *abfd, Elf_Internal_Shdr *ghdr)
474104838Sobrien{
475104838Sobrien  Elf_Internal_Shdr *hdr;
476104838Sobrien  unsigned char esym[sizeof (Elf64_External_Sym)];
477104838Sobrien  Elf_External_Sym_Shndx eshndx;
478104838Sobrien  Elf_Internal_Sym isym;
479104838Sobrien
480218822Sdim  /* First we need to ensure the symbol table is available.  Make sure
481218822Sdim     that it is a symbol table section.  */
482218822Sdim  hdr = elf_elfsections (abfd) [ghdr->sh_link];
483218822Sdim  if (hdr->sh_type != SHT_SYMTAB
484218822Sdim      || ! bfd_section_from_shdr (abfd, ghdr->sh_link))
485104838Sobrien    return NULL;
486104838Sobrien
487104838Sobrien  /* Go read the symbol.  */
488104838Sobrien  hdr = &elf_tdata (abfd)->symtab_hdr;
489104838Sobrien  if (bfd_elf_get_elf_syms (abfd, hdr, 1, ghdr->sh_info,
490104838Sobrien			    &isym, esym, &eshndx) == NULL)
491104838Sobrien    return NULL;
492104838Sobrien
493218822Sdim  return bfd_elf_sym_name (abfd, hdr, &isym, NULL);
494104838Sobrien}
495104838Sobrien
49689860Sobrien/* Set next_in_group list pointer, and group name for NEWSECT.  */
49789860Sobrien
498130563Sobrienstatic bfd_boolean
499130563Sobriensetup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
50089860Sobrien{
50189860Sobrien  unsigned int num_group = elf_tdata (abfd)->num_group;
50289860Sobrien
50389860Sobrien  /* If num_group is zero, read in all SHT_GROUP sections.  The count
50489860Sobrien     is set to -1 if there are no SHT_GROUP sections.  */
50589860Sobrien  if (num_group == 0)
50689860Sobrien    {
50789860Sobrien      unsigned int i, shnum;
50889860Sobrien
50989860Sobrien      /* First count the number of groups.  If we have a SHT_GROUP
51089860Sobrien	 section with just a flag word (ie. sh_size is 4), ignore it.  */
51189860Sobrien      shnum = elf_numsections (abfd);
51289860Sobrien      num_group = 0;
513218822Sdim
514218822Sdim#define IS_VALID_GROUP_SECTION_HEADER(shdr)		\
515218822Sdim	(   (shdr)->sh_type == SHT_GROUP		\
516218822Sdim	 && (shdr)->sh_size >= (2 * GRP_ENTRY_SIZE)	\
517218822Sdim	 && (shdr)->sh_entsize == GRP_ENTRY_SIZE	\
518218822Sdim	 && ((shdr)->sh_size % GRP_ENTRY_SIZE) == 0)
519218822Sdim
52089860Sobrien      for (i = 0; i < shnum; i++)
52189860Sobrien	{
52289860Sobrien	  Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
523218822Sdim
524218822Sdim	  if (IS_VALID_GROUP_SECTION_HEADER (shdr))
52589860Sobrien	    num_group += 1;
52689860Sobrien	}
52789860Sobrien
52889860Sobrien      if (num_group == 0)
52989860Sobrien	{
530218822Sdim	  num_group = (unsigned) -1;
531218822Sdim	  elf_tdata (abfd)->num_group = num_group;
532218822Sdim	}
533218822Sdim      else
534218822Sdim	{
53589860Sobrien	  /* We keep a list of elf section headers for group sections,
53689860Sobrien	     so we can find them quickly.  */
537218822Sdim	  bfd_size_type amt;
538218822Sdim
539218822Sdim	  elf_tdata (abfd)->num_group = num_group;
540218822Sdim	  elf_tdata (abfd)->group_sect_ptr
541218822Sdim	    = bfd_alloc2 (abfd, num_group, sizeof (Elf_Internal_Shdr *));
54289860Sobrien	  if (elf_tdata (abfd)->group_sect_ptr == NULL)
543130563Sobrien	    return FALSE;
54489860Sobrien
54589860Sobrien	  num_group = 0;
54689860Sobrien	  for (i = 0; i < shnum; i++)
54789860Sobrien	    {
54889860Sobrien	      Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
549218822Sdim
550218822Sdim	      if (IS_VALID_GROUP_SECTION_HEADER (shdr))
55189860Sobrien		{
55289860Sobrien		  unsigned char *src;
55389860Sobrien		  Elf_Internal_Group *dest;
55489860Sobrien
55589860Sobrien		  /* Add to list of sections.  */
55689860Sobrien		  elf_tdata (abfd)->group_sect_ptr[num_group] = shdr;
55789860Sobrien		  num_group += 1;
55889860Sobrien
55989860Sobrien		  /* Read the raw contents.  */
56089860Sobrien		  BFD_ASSERT (sizeof (*dest) >= 4);
56189860Sobrien		  amt = shdr->sh_size * sizeof (*dest) / 4;
562218822Sdim		  shdr->contents = bfd_alloc2 (abfd, shdr->sh_size,
563218822Sdim					       sizeof (*dest) / 4);
564218822Sdim		  /* PR binutils/4110: Handle corrupt group headers.  */
565218822Sdim		  if (shdr->contents == NULL)
566218822Sdim		    {
567218822Sdim		      _bfd_error_handler
568218822Sdim			(_("%B: Corrupt size field in group section header: 0x%lx"), abfd, shdr->sh_size);
569218822Sdim		      bfd_set_error (bfd_error_bad_value);
570218822Sdim		      return FALSE;
571218822Sdim		    }
572218822Sdim
573218822Sdim		  memset (shdr->contents, 0, amt);
574218822Sdim
575218822Sdim		  if (bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0
57689860Sobrien		      || (bfd_bread (shdr->contents, shdr->sh_size, abfd)
57789860Sobrien			  != shdr->sh_size))
578130563Sobrien		    return FALSE;
57989860Sobrien
58089860Sobrien		  /* Translate raw contents, a flag word followed by an
58189860Sobrien		     array of elf section indices all in target byte order,
58289860Sobrien		     to the flag word followed by an array of elf section
58389860Sobrien		     pointers.  */
58489860Sobrien		  src = shdr->contents + shdr->sh_size;
58589860Sobrien		  dest = (Elf_Internal_Group *) (shdr->contents + amt);
58689860Sobrien		  while (1)
58789860Sobrien		    {
58889860Sobrien		      unsigned int idx;
58989860Sobrien
59089860Sobrien		      src -= 4;
59189860Sobrien		      --dest;
59289860Sobrien		      idx = H_GET_32 (abfd, src);
59389860Sobrien		      if (src == shdr->contents)
59489860Sobrien			{
59589860Sobrien			  dest->flags = idx;
596104838Sobrien			  if (shdr->bfd_section != NULL && (idx & GRP_COMDAT))
597104838Sobrien			    shdr->bfd_section->flags
598104838Sobrien			      |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
59989860Sobrien			  break;
60089860Sobrien			}
60189860Sobrien		      if (idx >= shnum)
60289860Sobrien			{
60389860Sobrien			  ((*_bfd_error_handler)
604218822Sdim			   (_("%B: invalid SHT_GROUP entry"), abfd));
60589860Sobrien			  idx = 0;
60689860Sobrien			}
60789860Sobrien		      dest->shdr = elf_elfsections (abfd)[idx];
60889860Sobrien		    }
60989860Sobrien		}
61089860Sobrien	    }
61189860Sobrien	}
61289860Sobrien    }
61389860Sobrien
61489860Sobrien  if (num_group != (unsigned) -1)
61589860Sobrien    {
61689860Sobrien      unsigned int i;
61789860Sobrien
61889860Sobrien      for (i = 0; i < num_group; i++)
61989860Sobrien	{
62089860Sobrien	  Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
62189860Sobrien	  Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents;
62289860Sobrien	  unsigned int n_elt = shdr->sh_size / 4;
62389860Sobrien
62489860Sobrien	  /* Look through this group's sections to see if current
62589860Sobrien	     section is a member.  */
62689860Sobrien	  while (--n_elt != 0)
62789860Sobrien	    if ((++idx)->shdr == hdr)
62889860Sobrien	      {
62989860Sobrien		asection *s = NULL;
63089860Sobrien
63189860Sobrien		/* We are a member of this group.  Go looking through
63289860Sobrien		   other members to see if any others are linked via
63389860Sobrien		   next_in_group.  */
63489860Sobrien		idx = (Elf_Internal_Group *) shdr->contents;
63589860Sobrien		n_elt = shdr->sh_size / 4;
63689860Sobrien		while (--n_elt != 0)
63789860Sobrien		  if ((s = (++idx)->shdr->bfd_section) != NULL
63889860Sobrien		      && elf_next_in_group (s) != NULL)
63989860Sobrien		    break;
64089860Sobrien		if (n_elt != 0)
64189860Sobrien		  {
64289860Sobrien		    /* Snarf the group name from other member, and
64389860Sobrien		       insert current section in circular list.  */
64489860Sobrien		    elf_group_name (newsect) = elf_group_name (s);
64589860Sobrien		    elf_next_in_group (newsect) = elf_next_in_group (s);
64689860Sobrien		    elf_next_in_group (s) = newsect;
64789860Sobrien		  }
64889860Sobrien		else
64989860Sobrien		  {
65089860Sobrien		    const char *gname;
65189860Sobrien
652104838Sobrien		    gname = group_signature (abfd, shdr);
653104838Sobrien		    if (gname == NULL)
654130563Sobrien		      return FALSE;
65589860Sobrien		    elf_group_name (newsect) = gname;
65689860Sobrien
65789860Sobrien		    /* Start a circular list with one element.  */
65889860Sobrien		    elf_next_in_group (newsect) = newsect;
65989860Sobrien		  }
660104838Sobrien
661104838Sobrien		/* If the group section has been created, point to the
662104838Sobrien		   new member.  */
66389860Sobrien		if (shdr->bfd_section != NULL)
66489860Sobrien		  elf_next_in_group (shdr->bfd_section) = newsect;
665104838Sobrien
66689860Sobrien		i = num_group - 1;
66789860Sobrien		break;
66889860Sobrien	      }
66989860Sobrien	}
67089860Sobrien    }
67189860Sobrien
67289860Sobrien  if (elf_group_name (newsect) == NULL)
67389860Sobrien    {
674218822Sdim      (*_bfd_error_handler) (_("%B: no group info for section %A"),
675218822Sdim			     abfd, newsect);
67689860Sobrien    }
677130563Sobrien  return TRUE;
67889860Sobrien}
67989860Sobrien
680130563Sobrienbfd_boolean
681218822Sdim_bfd_elf_setup_sections (bfd *abfd)
682104838Sobrien{
683218822Sdim  unsigned int i;
684218822Sdim  unsigned int num_group = elf_tdata (abfd)->num_group;
685218822Sdim  bfd_boolean result = TRUE;
686218822Sdim  asection *s;
687104838Sobrien
688218822Sdim  /* Process SHF_LINK_ORDER.  */
689218822Sdim  for (s = abfd->sections; s != NULL; s = s->next)
690104838Sobrien    {
691218822Sdim      Elf_Internal_Shdr *this_hdr = &elf_section_data (s)->this_hdr;
692218822Sdim      if ((this_hdr->sh_flags & SHF_LINK_ORDER) != 0)
693218822Sdim	{
694218822Sdim	  unsigned int elfsec = this_hdr->sh_link;
695218822Sdim	  /* FIXME: The old Intel compiler and old strip/objcopy may
696218822Sdim	     not set the sh_link or sh_info fields.  Hence we could
697218822Sdim	     get the situation where elfsec is 0.  */
698218822Sdim	  if (elfsec == 0)
699218822Sdim	    {
700218822Sdim	      const struct elf_backend_data *bed
701218822Sdim		= get_elf_backend_data (abfd);
702218822Sdim	      if (bed->link_order_error_handler)
703218822Sdim		bed->link_order_error_handler
704218822Sdim		  (_("%B: warning: sh_link not set for section `%A'"),
705218822Sdim		   abfd, s);
706218822Sdim	    }
707218822Sdim	  else
708218822Sdim	    {
709218822Sdim	      asection *link;
710218822Sdim
711218822Sdim	      this_hdr = elf_elfsections (abfd)[elfsec];
712218822Sdim
713218822Sdim	      /* PR 1991, 2008:
714218822Sdim		 Some strip/objcopy may leave an incorrect value in
715218822Sdim		 sh_link.  We don't want to proceed.  */
716218822Sdim	      link = this_hdr->bfd_section;
717218822Sdim	      if (link == NULL)
718218822Sdim		{
719218822Sdim		  (*_bfd_error_handler)
720218822Sdim		    (_("%B: sh_link [%d] in section `%A' is incorrect"),
721218822Sdim		     s->owner, s, elfsec);
722218822Sdim		  result = FALSE;
723218822Sdim		}
724218822Sdim
725218822Sdim	      elf_linked_to_section (s) = link;
726218822Sdim	    }
727218822Sdim	}
728104838Sobrien    }
729218822Sdim
730218822Sdim  /* Process section groups.  */
731218822Sdim  if (num_group == (unsigned) -1)
732218822Sdim    return result;
733218822Sdim
734218822Sdim  for (i = 0; i < num_group; i++)
735218822Sdim    {
736218822Sdim      Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
737218822Sdim      Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents;
738218822Sdim      unsigned int n_elt = shdr->sh_size / 4;
739218822Sdim
740218822Sdim      while (--n_elt != 0)
741218822Sdim	if ((++idx)->shdr->bfd_section)
742218822Sdim	  elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section;
743218822Sdim	else if (idx->shdr->sh_type == SHT_RELA
744218822Sdim		 || idx->shdr->sh_type == SHT_REL)
745218822Sdim	  /* We won't include relocation sections in section groups in
746218822Sdim	     output object files. We adjust the group section size here
747218822Sdim	     so that relocatable link will work correctly when
748218822Sdim	     relocation sections are in section group in input object
749218822Sdim	     files.  */
750218822Sdim	  shdr->bfd_section->size -= 4;
751218822Sdim	else
752218822Sdim	  {
753218822Sdim	    /* There are some unknown sections in the group.  */
754218822Sdim	    (*_bfd_error_handler)
755218822Sdim	      (_("%B: unknown [%d] section `%s' in group [%s]"),
756218822Sdim	       abfd,
757218822Sdim	       (unsigned int) idx->shdr->sh_type,
758218822Sdim	       bfd_elf_string_from_elf_section (abfd,
759218822Sdim						(elf_elfheader (abfd)
760218822Sdim						 ->e_shstrndx),
761218822Sdim						idx->shdr->sh_name),
762218822Sdim	       shdr->bfd_section->name);
763218822Sdim	    result = FALSE;
764218822Sdim	  }
765218822Sdim    }
766218822Sdim  return result;
767104838Sobrien}
768104838Sobrien
769218822Sdimbfd_boolean
770218822Sdimbfd_elf_is_group_section (bfd *abfd ATTRIBUTE_UNUSED, const asection *sec)
771218822Sdim{
772218822Sdim  return elf_next_in_group (sec) != NULL;
773218822Sdim}
774218822Sdim
77533965Sjdp/* Make a BFD section from an ELF section.  We store a pointer to the
77633965Sjdp   BFD section in the bfd_section field of the header.  */
77733965Sjdp
778130563Sobrienbfd_boolean
779130563Sobrien_bfd_elf_make_section_from_shdr (bfd *abfd,
780130563Sobrien				 Elf_Internal_Shdr *hdr,
781218822Sdim				 const char *name,
782218822Sdim				 int shindex)
78333965Sjdp{
78433965Sjdp  asection *newsect;
78533965Sjdp  flagword flags;
786130563Sobrien  const struct elf_backend_data *bed;
78733965Sjdp
78833965Sjdp  if (hdr->bfd_section != NULL)
78933965Sjdp    {
79033965Sjdp      BFD_ASSERT (strcmp (name,
79133965Sjdp			  bfd_get_section_name (abfd, hdr->bfd_section)) == 0);
792130563Sobrien      return TRUE;
79333965Sjdp    }
79433965Sjdp
79533965Sjdp  newsect = bfd_make_section_anyway (abfd, name);
79633965Sjdp  if (newsect == NULL)
797130563Sobrien    return FALSE;
79833965Sjdp
799218822Sdim  hdr->bfd_section = newsect;
800218822Sdim  elf_section_data (newsect)->this_hdr = *hdr;
801218822Sdim  elf_section_data (newsect)->this_idx = shindex;
802218822Sdim
803130563Sobrien  /* Always use the real type/flags.  */
804130563Sobrien  elf_section_type (newsect) = hdr->sh_type;
805130563Sobrien  elf_section_flags (newsect) = hdr->sh_flags;
806130563Sobrien
80733965Sjdp  newsect->filepos = hdr->sh_offset;
80833965Sjdp
80933965Sjdp  if (! bfd_set_section_vma (abfd, newsect, hdr->sh_addr)
81033965Sjdp      || ! bfd_set_section_size (abfd, newsect, hdr->sh_size)
81133965Sjdp      || ! bfd_set_section_alignment (abfd, newsect,
81289860Sobrien				      bfd_log2 ((bfd_vma) hdr->sh_addralign)))
813130563Sobrien    return FALSE;
81433965Sjdp
81533965Sjdp  flags = SEC_NO_FLAGS;
81633965Sjdp  if (hdr->sh_type != SHT_NOBITS)
81733965Sjdp    flags |= SEC_HAS_CONTENTS;
81889860Sobrien  if (hdr->sh_type == SHT_GROUP)
81989860Sobrien    flags |= SEC_GROUP | SEC_EXCLUDE;
82033965Sjdp  if ((hdr->sh_flags & SHF_ALLOC) != 0)
82133965Sjdp    {
82233965Sjdp      flags |= SEC_ALLOC;
82333965Sjdp      if (hdr->sh_type != SHT_NOBITS)
82433965Sjdp	flags |= SEC_LOAD;
82533965Sjdp    }
82633965Sjdp  if ((hdr->sh_flags & SHF_WRITE) == 0)
82733965Sjdp    flags |= SEC_READONLY;
82833965Sjdp  if ((hdr->sh_flags & SHF_EXECINSTR) != 0)
82933965Sjdp    flags |= SEC_CODE;
83033965Sjdp  else if ((flags & SEC_LOAD) != 0)
83133965Sjdp    flags |= SEC_DATA;
83289860Sobrien  if ((hdr->sh_flags & SHF_MERGE) != 0)
83389860Sobrien    {
83489860Sobrien      flags |= SEC_MERGE;
83589860Sobrien      newsect->entsize = hdr->sh_entsize;
83689860Sobrien      if ((hdr->sh_flags & SHF_STRINGS) != 0)
83789860Sobrien	flags |= SEC_STRINGS;
83889860Sobrien    }
83989860Sobrien  if (hdr->sh_flags & SHF_GROUP)
84089860Sobrien    if (!setup_group (abfd, hdr, newsect))
841130563Sobrien      return FALSE;
842104838Sobrien  if ((hdr->sh_flags & SHF_TLS) != 0)
843104838Sobrien    flags |= SEC_THREAD_LOCAL;
84433965Sjdp
845218822Sdim  if ((flags & SEC_ALLOC) == 0)
84677301Sobrien    {
847218822Sdim      /* The debugging sections appear to be recognized only by name,
848218822Sdim	 not any sort of flag.  Their SEC_ALLOC bits are cleared.  */
849218822Sdim      static const struct
850218822Sdim	{
851218822Sdim	  const char *name;
852218822Sdim	  int len;
853218822Sdim	} debug_sections [] =
854218822Sdim	{
855218822Sdim	  { STRING_COMMA_LEN ("debug") },	/* 'd' */
856218822Sdim	  { NULL,		 0  },	/* 'e' */
857218822Sdim	  { NULL,		 0  },	/* 'f' */
858218822Sdim	  { STRING_COMMA_LEN ("gnu.linkonce.wi.") },	/* 'g' */
859218822Sdim	  { NULL,		 0  },	/* 'h' */
860218822Sdim	  { NULL,		 0  },	/* 'i' */
861218822Sdim	  { NULL,		 0  },	/* 'j' */
862218822Sdim	  { NULL,		 0  },	/* 'k' */
863218822Sdim	  { STRING_COMMA_LEN ("line") },	/* 'l' */
864218822Sdim	  { NULL,		 0  },	/* 'm' */
865218822Sdim	  { NULL,		 0  },	/* 'n' */
866218822Sdim	  { NULL,		 0  },	/* 'o' */
867218822Sdim	  { NULL,		 0  },	/* 'p' */
868218822Sdim	  { NULL,		 0  },	/* 'q' */
869218822Sdim	  { NULL,		 0  },	/* 'r' */
870218822Sdim	  { STRING_COMMA_LEN ("stab") }	/* 's' */
871218822Sdim	};
87233965Sjdp
873218822Sdim      if (name [0] == '.')
874218822Sdim	{
875218822Sdim	  int i = name [1] - 'd';
876218822Sdim	  if (i >= 0
877218822Sdim	      && i < (int) ARRAY_SIZE (debug_sections)
878218822Sdim	      && debug_sections [i].name != NULL
879218822Sdim	      && strncmp (&name [1], debug_sections [i].name,
880218822Sdim			  debug_sections [i].len) == 0)
881218822Sdim	    flags |= SEC_DEBUGGING;
882218822Sdim	}
883218822Sdim    }
88477301Sobrien
88533965Sjdp  /* As a GNU extension, if the name begins with .gnu.linkonce, we
88633965Sjdp     only link a single copy of the section.  This is used to support
88733965Sjdp     g++.  g++ will emit each template expansion in its own section.
88833965Sjdp     The symbols will be defined as weak, so that multiple definitions
88933965Sjdp     are permitted.  The GNU linker extension is to actually discard
89033965Sjdp     all but one of the sections.  */
891218822Sdim  if (CONST_STRNEQ (name, ".gnu.linkonce")
892104838Sobrien      && elf_next_in_group (newsect) == NULL)
89333965Sjdp    flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
89433965Sjdp
89577301Sobrien  bed = get_elf_backend_data (abfd);
89677301Sobrien  if (bed->elf_backend_section_flags)
89777301Sobrien    if (! bed->elf_backend_section_flags (&flags, hdr))
898130563Sobrien      return FALSE;
89977301Sobrien
90033965Sjdp  if (! bfd_set_section_flags (abfd, newsect, flags))
901130563Sobrien    return FALSE;
90233965Sjdp
90333965Sjdp  if ((flags & SEC_ALLOC) != 0)
90433965Sjdp    {
90533965Sjdp      Elf_Internal_Phdr *phdr;
90633965Sjdp      unsigned int i;
90733965Sjdp
90860508Sobrien      /* Look through the phdrs to see if we need to adjust the lma.
909218822Sdim	 If all the p_paddr fields are zero, we ignore them, since
910218822Sdim	 some ELF linkers produce such output.  */
91133965Sjdp      phdr = elf_tdata (abfd)->phdr;
91233965Sjdp      for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
91333965Sjdp	{
91460508Sobrien	  if (phdr->p_paddr != 0)
91560508Sobrien	    break;
91660508Sobrien	}
91760508Sobrien      if (i < elf_elfheader (abfd)->e_phnum)
91860508Sobrien	{
91960508Sobrien	  phdr = elf_tdata (abfd)->phdr;
92060508Sobrien	  for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
92133965Sjdp	    {
92289860Sobrien	      /* This section is part of this segment if its file
92389860Sobrien		 offset plus size lies within the segment's memory
92489860Sobrien		 span and, if the section is loaded, the extent of the
925104838Sobrien		 loaded data lies within the extent of the segment.
92694542Sobrien
92794542Sobrien		 Note - we used to check the p_paddr field as well, and
92894542Sobrien		 refuse to set the LMA if it was 0.  This is wrong
92994542Sobrien		 though, as a perfectly valid initialised segment can
93094542Sobrien		 have a p_paddr of zero.  Some architectures, eg ARM,
931218822Sdim		 place special significance on the address 0 and
932218822Sdim		 executables need to be able to have a segment which
933218822Sdim		 covers this address.  */
93460508Sobrien	      if (phdr->p_type == PT_LOAD
93589860Sobrien		  && (bfd_vma) hdr->sh_offset >= phdr->p_offset
93689860Sobrien		  && (hdr->sh_offset + hdr->sh_size
93789860Sobrien		      <= phdr->p_offset + phdr->p_memsz)
93860508Sobrien		  && ((flags & SEC_LOAD) == 0
93994542Sobrien		      || (hdr->sh_offset + hdr->sh_size
94094542Sobrien			  <= phdr->p_offset + phdr->p_filesz)))
94160508Sobrien		{
94294542Sobrien		  if ((flags & SEC_LOAD) == 0)
94394542Sobrien		    newsect->lma = (phdr->p_paddr
94494542Sobrien				    + hdr->sh_addr - phdr->p_vaddr);
94594542Sobrien		  else
94694542Sobrien		    /* We used to use the same adjustment for SEC_LOAD
94794542Sobrien		       sections, but that doesn't work if the segment
94894542Sobrien		       is packed with code from multiple VMAs.
94994542Sobrien		       Instead we calculate the section LMA based on
95094542Sobrien		       the segment LMA.  It is assumed that the
95194542Sobrien		       segment will contain sections with contiguous
95294542Sobrien		       LMAs, even if the VMAs are not.  */
95394542Sobrien		    newsect->lma = (phdr->p_paddr
95494542Sobrien				    + hdr->sh_offset - phdr->p_offset);
95594542Sobrien
95694542Sobrien		  /* With contiguous segments, we can't tell from file
95794542Sobrien		     offsets whether a section with zero size should
95894542Sobrien		     be placed at the end of one segment or the
95994542Sobrien		     beginning of the next.  Decide based on vaddr.  */
96094542Sobrien		  if (hdr->sh_addr >= phdr->p_vaddr
96194542Sobrien		      && (hdr->sh_addr + hdr->sh_size
96294542Sobrien			  <= phdr->p_vaddr + phdr->p_memsz))
96394542Sobrien		    break;
96460508Sobrien		}
96533965Sjdp	    }
96633965Sjdp	}
96733965Sjdp    }
96833965Sjdp
969130563Sobrien  return TRUE;
97033965Sjdp}
97133965Sjdp
97233965Sjdp/*
97333965SjdpINTERNAL_FUNCTION
97433965Sjdp	bfd_elf_find_section
97533965Sjdp
97633965SjdpSYNOPSIS
97733965Sjdp	struct elf_internal_shdr *bfd_elf_find_section (bfd *abfd, char *name);
97833965Sjdp
97933965SjdpDESCRIPTION
98033965Sjdp	Helper functions for GDB to locate the string tables.
98133965Sjdp	Since BFD hides string tables from callers, GDB needs to use an
98233965Sjdp	internal hook to find them.  Sun's .stabstr, in particular,
98333965Sjdp	isn't even pointed to by the .stab section, so ordinary
98433965Sjdp	mechanisms wouldn't work to find it, even if we had some.
98533965Sjdp*/
98633965Sjdp
98733965Sjdpstruct elf_internal_shdr *
988130563Sobrienbfd_elf_find_section (bfd *abfd, char *name)
98933965Sjdp{
99033965Sjdp  Elf_Internal_Shdr **i_shdrp;
99133965Sjdp  char *shstrtab;
99233965Sjdp  unsigned int max;
99333965Sjdp  unsigned int i;
99433965Sjdp
99533965Sjdp  i_shdrp = elf_elfsections (abfd);
99633965Sjdp  if (i_shdrp != NULL)
99733965Sjdp    {
99889860Sobrien      shstrtab = bfd_elf_get_str_section (abfd,
99989860Sobrien					  elf_elfheader (abfd)->e_shstrndx);
100033965Sjdp      if (shstrtab != NULL)
100133965Sjdp	{
100289860Sobrien	  max = elf_numsections (abfd);
100333965Sjdp	  for (i = 1; i < max; i++)
100433965Sjdp	    if (!strcmp (&shstrtab[i_shdrp[i]->sh_name], name))
100533965Sjdp	      return i_shdrp[i];
100633965Sjdp	}
100733965Sjdp    }
100833965Sjdp  return 0;
100933965Sjdp}
101033965Sjdp
101133965Sjdpconst char *const bfd_elf_section_type_names[] = {
101233965Sjdp  "SHT_NULL", "SHT_PROGBITS", "SHT_SYMTAB", "SHT_STRTAB",
101333965Sjdp  "SHT_RELA", "SHT_HASH", "SHT_DYNAMIC", "SHT_NOTE",
101433965Sjdp  "SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM",
101533965Sjdp};
101633965Sjdp
1017130563Sobrien/* ELF relocs are against symbols.  If we are producing relocatable
101833965Sjdp   output, and the reloc is against an external symbol, and nothing
101933965Sjdp   has given us any additional addend, the resulting reloc will also
102033965Sjdp   be against the same symbol.  In such a case, we don't want to
102133965Sjdp   change anything about the way the reloc is handled, since it will
102233965Sjdp   all be done at final link time.  Rather than put special case code
102333965Sjdp   into bfd_perform_relocation, all the reloc types use this howto
102433965Sjdp   function.  It just short circuits the reloc if producing
1025130563Sobrien   relocatable output against an external symbol.  */
102633965Sjdp
102733965Sjdpbfd_reloc_status_type
1028130563Sobrienbfd_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED,
1029130563Sobrien		       arelent *reloc_entry,
1030130563Sobrien		       asymbol *symbol,
1031130563Sobrien		       void *data ATTRIBUTE_UNUSED,
1032130563Sobrien		       asection *input_section,
1033130563Sobrien		       bfd *output_bfd,
1034130563Sobrien		       char **error_message ATTRIBUTE_UNUSED)
103533965Sjdp{
1036130563Sobrien  if (output_bfd != NULL
103733965Sjdp      && (symbol->flags & BSF_SECTION_SYM) == 0
103833965Sjdp      && (! reloc_entry->howto->partial_inplace
103933965Sjdp	  || reloc_entry->addend == 0))
104033965Sjdp    {
104133965Sjdp      reloc_entry->address += input_section->output_offset;
104233965Sjdp      return bfd_reloc_ok;
104333965Sjdp    }
104433965Sjdp
104533965Sjdp  return bfd_reloc_continue;
104633965Sjdp}
104733965Sjdp
104889860Sobrien/* Make sure sec_info_type is cleared if sec_info is cleared too.  */
104989860Sobrien
105089860Sobrienstatic void
1051130563Sobrienmerge_sections_remove_hook (bfd *abfd ATTRIBUTE_UNUSED,
1052130563Sobrien			    asection *sec)
105389860Sobrien{
1054130563Sobrien  BFD_ASSERT (sec->sec_info_type == ELF_INFO_TYPE_MERGE);
1055130563Sobrien  sec->sec_info_type = ELF_INFO_TYPE_NONE;
105689860Sobrien}
105789860Sobrien
105889860Sobrien/* Finish SHF_MERGE section merging.  */
105989860Sobrien
1060130563Sobrienbfd_boolean
1061130563Sobrien_bfd_elf_merge_sections (bfd *abfd, struct bfd_link_info *info)
106289860Sobrien{
1063218822Sdim  bfd *ibfd;
1064218822Sdim  asection *sec;
1065218822Sdim
1066130563Sobrien  if (!is_elf_hash_table (info->hash))
1067130563Sobrien    return FALSE;
1068218822Sdim
1069218822Sdim  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
1070218822Sdim    if ((ibfd->flags & DYNAMIC) == 0)
1071218822Sdim      for (sec = ibfd->sections; sec != NULL; sec = sec->next)
1072218822Sdim	if ((sec->flags & SEC_MERGE) != 0
1073218822Sdim	    && !bfd_is_abs_section (sec->output_section))
1074218822Sdim	  {
1075218822Sdim	    struct bfd_elf_section_data *secdata;
1076218822Sdim
1077218822Sdim	    secdata = elf_section_data (sec);
1078218822Sdim	    if (! _bfd_add_merge_section (abfd,
1079218822Sdim					  &elf_hash_table (info)->merge_info,
1080218822Sdim					  sec, &secdata->sec_info))
1081218822Sdim	      return FALSE;
1082218822Sdim	    else if (secdata->sec_info)
1083218822Sdim	      sec->sec_info_type = ELF_INFO_TYPE_MERGE;
1084218822Sdim	  }
1085218822Sdim
1086218822Sdim  if (elf_hash_table (info)->merge_info != NULL)
1087218822Sdim    _bfd_merge_sections (abfd, info, elf_hash_table (info)->merge_info,
108889860Sobrien			 merge_sections_remove_hook);
1089130563Sobrien  return TRUE;
109089860Sobrien}
1091104838Sobrien
1092104838Sobrienvoid
1093130563Sobrien_bfd_elf_link_just_syms (asection *sec, struct bfd_link_info *info)
1094104838Sobrien{
1095104838Sobrien  sec->output_section = bfd_abs_section_ptr;
1096104838Sobrien  sec->output_offset = sec->vma;
1097130563Sobrien  if (!is_elf_hash_table (info->hash))
1098104838Sobrien    return;
1099104838Sobrien
1100130563Sobrien  sec->sec_info_type = ELF_INFO_TYPE_JUST_SYMS;
1101104838Sobrien}
110289860Sobrien
110389860Sobrien/* Copy the program header and other data from one object module to
110489860Sobrien   another.  */
110589860Sobrien
1106130563Sobrienbfd_boolean
1107130563Sobrien_bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
110889860Sobrien{
110989860Sobrien  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
111089860Sobrien      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1111130563Sobrien    return TRUE;
111289860Sobrien
111389860Sobrien  BFD_ASSERT (!elf_flags_init (obfd)
111489860Sobrien	      || (elf_elfheader (obfd)->e_flags
111589860Sobrien		  == elf_elfheader (ibfd)->e_flags));
111689860Sobrien
111789860Sobrien  elf_gp (obfd) = elf_gp (ibfd);
111889860Sobrien  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
1119130563Sobrien  elf_flags_init (obfd) = TRUE;
1120218822Sdim
1121218822Sdim  /* Copy object attributes.  */
1122218822Sdim  _bfd_elf_copy_obj_attributes (ibfd, obfd);
1123218822Sdim
1124130563Sobrien  return TRUE;
112589860Sobrien}
112689860Sobrien
1127218822Sdimstatic const char *
1128218822Sdimget_segment_type (unsigned int p_type)
1129218822Sdim{
1130218822Sdim  const char *pt;
1131218822Sdim  switch (p_type)
1132218822Sdim    {
1133218822Sdim    case PT_NULL: pt = "NULL"; break;
1134218822Sdim    case PT_LOAD: pt = "LOAD"; break;
1135218822Sdim    case PT_DYNAMIC: pt = "DYNAMIC"; break;
1136218822Sdim    case PT_INTERP: pt = "INTERP"; break;
1137218822Sdim    case PT_NOTE: pt = "NOTE"; break;
1138218822Sdim    case PT_SHLIB: pt = "SHLIB"; break;
1139218822Sdim    case PT_PHDR: pt = "PHDR"; break;
1140218822Sdim    case PT_TLS: pt = "TLS"; break;
1141218822Sdim    case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break;
1142218822Sdim    case PT_GNU_STACK: pt = "STACK"; break;
1143218822Sdim    case PT_GNU_RELRO: pt = "RELRO"; break;
1144218822Sdim    default: pt = NULL; break;
1145218822Sdim    }
1146218822Sdim  return pt;
1147218822Sdim}
1148218822Sdim
114933965Sjdp/* Print out the program headers.  */
115033965Sjdp
1151130563Sobrienbfd_boolean
1152130563Sobrien_bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
115333965Sjdp{
1154130563Sobrien  FILE *f = farg;
115533965Sjdp  Elf_Internal_Phdr *p;
115633965Sjdp  asection *s;
115733965Sjdp  bfd_byte *dynbuf = NULL;
115833965Sjdp
115933965Sjdp  p = elf_tdata (abfd)->phdr;
116033965Sjdp  if (p != NULL)
116133965Sjdp    {
116233965Sjdp      unsigned int i, c;
116333965Sjdp
116460508Sobrien      fprintf (f, _("\nProgram Header:\n"));
116533965Sjdp      c = elf_elfheader (abfd)->e_phnum;
116633965Sjdp      for (i = 0; i < c; i++, p++)
116733965Sjdp	{
1168218822Sdim	  const char *pt = get_segment_type (p->p_type);
116933965Sjdp	  char buf[20];
117033965Sjdp
1171218822Sdim	  if (pt == NULL)
117233965Sjdp	    {
1173218822Sdim	      sprintf (buf, "0x%lx", p->p_type);
1174218822Sdim	      pt = buf;
117533965Sjdp	    }
117689860Sobrien	  fprintf (f, "%8s off    0x", pt);
117789860Sobrien	  bfd_fprintf_vma (abfd, f, p->p_offset);
117833965Sjdp	  fprintf (f, " vaddr 0x");
117989860Sobrien	  bfd_fprintf_vma (abfd, f, p->p_vaddr);
118033965Sjdp	  fprintf (f, " paddr 0x");
118189860Sobrien	  bfd_fprintf_vma (abfd, f, p->p_paddr);
118233965Sjdp	  fprintf (f, " align 2**%u\n", bfd_log2 (p->p_align));
118333965Sjdp	  fprintf (f, "         filesz 0x");
118489860Sobrien	  bfd_fprintf_vma (abfd, f, p->p_filesz);
118533965Sjdp	  fprintf (f, " memsz 0x");
118689860Sobrien	  bfd_fprintf_vma (abfd, f, p->p_memsz);
118733965Sjdp	  fprintf (f, " flags %c%c%c",
118833965Sjdp		   (p->p_flags & PF_R) != 0 ? 'r' : '-',
118933965Sjdp		   (p->p_flags & PF_W) != 0 ? 'w' : '-',
119033965Sjdp		   (p->p_flags & PF_X) != 0 ? 'x' : '-');
119189860Sobrien	  if ((p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X)) != 0)
119289860Sobrien	    fprintf (f, " %lx", p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X));
119333965Sjdp	  fprintf (f, "\n");
119433965Sjdp	}
119533965Sjdp    }
119633965Sjdp
119733965Sjdp  s = bfd_get_section_by_name (abfd, ".dynamic");
119833965Sjdp  if (s != NULL)
119933965Sjdp    {
120033965Sjdp      int elfsec;
120189860Sobrien      unsigned long shlink;
120233965Sjdp      bfd_byte *extdyn, *extdynend;
120333965Sjdp      size_t extdynsize;
1204130563Sobrien      void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
120533965Sjdp
120660508Sobrien      fprintf (f, _("\nDynamic Section:\n"));
120733965Sjdp
1208218822Sdim      if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
120933965Sjdp	goto error_return;
121033965Sjdp
121133965Sjdp      elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
121233965Sjdp      if (elfsec == -1)
121333965Sjdp	goto error_return;
121489860Sobrien      shlink = elf_elfsections (abfd)[elfsec]->sh_link;
121533965Sjdp
121633965Sjdp      extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
121733965Sjdp      swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
121833965Sjdp
121933965Sjdp      extdyn = dynbuf;
1220218822Sdim      extdynend = extdyn + s->size;
122133965Sjdp      for (; extdyn < extdynend; extdyn += extdynsize)
122233965Sjdp	{
122333965Sjdp	  Elf_Internal_Dyn dyn;
122433965Sjdp	  const char *name;
122533965Sjdp	  char ab[20];
1226130563Sobrien	  bfd_boolean stringp;
122733965Sjdp
1228130563Sobrien	  (*swap_dyn_in) (abfd, extdyn, &dyn);
122933965Sjdp
123033965Sjdp	  if (dyn.d_tag == DT_NULL)
123133965Sjdp	    break;
123233965Sjdp
1233130563Sobrien	  stringp = FALSE;
123433965Sjdp	  switch (dyn.d_tag)
123533965Sjdp	    {
123633965Sjdp	    default:
123733965Sjdp	      sprintf (ab, "0x%lx", (unsigned long) dyn.d_tag);
123833965Sjdp	      name = ab;
123933965Sjdp	      break;
124033965Sjdp
1241130563Sobrien	    case DT_NEEDED: name = "NEEDED"; stringp = TRUE; break;
124233965Sjdp	    case DT_PLTRELSZ: name = "PLTRELSZ"; break;
124333965Sjdp	    case DT_PLTGOT: name = "PLTGOT"; break;
124433965Sjdp	    case DT_HASH: name = "HASH"; break;
124533965Sjdp	    case DT_STRTAB: name = "STRTAB"; break;
124633965Sjdp	    case DT_SYMTAB: name = "SYMTAB"; break;
124733965Sjdp	    case DT_RELA: name = "RELA"; break;
124833965Sjdp	    case DT_RELASZ: name = "RELASZ"; break;
124933965Sjdp	    case DT_RELAENT: name = "RELAENT"; break;
125033965Sjdp	    case DT_STRSZ: name = "STRSZ"; break;
125133965Sjdp	    case DT_SYMENT: name = "SYMENT"; break;
125233965Sjdp	    case DT_INIT: name = "INIT"; break;
125333965Sjdp	    case DT_FINI: name = "FINI"; break;
1254130563Sobrien	    case DT_SONAME: name = "SONAME"; stringp = TRUE; break;
1255130563Sobrien	    case DT_RPATH: name = "RPATH"; stringp = TRUE; break;
125633965Sjdp	    case DT_SYMBOLIC: name = "SYMBOLIC"; break;
125733965Sjdp	    case DT_REL: name = "REL"; break;
125833965Sjdp	    case DT_RELSZ: name = "RELSZ"; break;
125933965Sjdp	    case DT_RELENT: name = "RELENT"; break;
126033965Sjdp	    case DT_PLTREL: name = "PLTREL"; break;
126133965Sjdp	    case DT_DEBUG: name = "DEBUG"; break;
126233965Sjdp	    case DT_TEXTREL: name = "TEXTREL"; break;
126333965Sjdp	    case DT_JMPREL: name = "JMPREL"; break;
126477301Sobrien	    case DT_BIND_NOW: name = "BIND_NOW"; break;
126577301Sobrien	    case DT_INIT_ARRAY: name = "INIT_ARRAY"; break;
126677301Sobrien	    case DT_FINI_ARRAY: name = "FINI_ARRAY"; break;
126777301Sobrien	    case DT_INIT_ARRAYSZ: name = "INIT_ARRAYSZ"; break;
126877301Sobrien	    case DT_FINI_ARRAYSZ: name = "FINI_ARRAYSZ"; break;
1269130563Sobrien	    case DT_RUNPATH: name = "RUNPATH"; stringp = TRUE; break;
127077301Sobrien	    case DT_FLAGS: name = "FLAGS"; break;
127177301Sobrien	    case DT_PREINIT_ARRAY: name = "PREINIT_ARRAY"; break;
127277301Sobrien	    case DT_PREINIT_ARRAYSZ: name = "PREINIT_ARRAYSZ"; break;
127377301Sobrien	    case DT_CHECKSUM: name = "CHECKSUM"; break;
127477301Sobrien	    case DT_PLTPADSZ: name = "PLTPADSZ"; break;
127577301Sobrien	    case DT_MOVEENT: name = "MOVEENT"; break;
127677301Sobrien	    case DT_MOVESZ: name = "MOVESZ"; break;
127777301Sobrien	    case DT_FEATURE: name = "FEATURE"; break;
127877301Sobrien	    case DT_POSFLAG_1: name = "POSFLAG_1"; break;
127977301Sobrien	    case DT_SYMINSZ: name = "SYMINSZ"; break;
128077301Sobrien	    case DT_SYMINENT: name = "SYMINENT"; break;
1281130563Sobrien	    case DT_CONFIG: name = "CONFIG"; stringp = TRUE; break;
1282130563Sobrien	    case DT_DEPAUDIT: name = "DEPAUDIT"; stringp = TRUE; break;
1283130563Sobrien	    case DT_AUDIT: name = "AUDIT"; stringp = TRUE; break;
128477301Sobrien	    case DT_PLTPAD: name = "PLTPAD"; break;
128577301Sobrien	    case DT_MOVETAB: name = "MOVETAB"; break;
128677301Sobrien	    case DT_SYMINFO: name = "SYMINFO"; break;
128777301Sobrien	    case DT_RELACOUNT: name = "RELACOUNT"; break;
128877301Sobrien	    case DT_RELCOUNT: name = "RELCOUNT"; break;
128977301Sobrien	    case DT_FLAGS_1: name = "FLAGS_1"; break;
129033965Sjdp	    case DT_VERSYM: name = "VERSYM"; break;
129133965Sjdp	    case DT_VERDEF: name = "VERDEF"; break;
129233965Sjdp	    case DT_VERDEFNUM: name = "VERDEFNUM"; break;
129333965Sjdp	    case DT_VERNEED: name = "VERNEED"; break;
129433965Sjdp	    case DT_VERNEEDNUM: name = "VERNEEDNUM"; break;
1295130563Sobrien	    case DT_AUXILIARY: name = "AUXILIARY"; stringp = TRUE; break;
129677301Sobrien	    case DT_USED: name = "USED"; break;
1297130563Sobrien	    case DT_FILTER: name = "FILTER"; stringp = TRUE; break;
1298218822Sdim	    case DT_GNU_HASH: name = "GNU_HASH"; break;
129933965Sjdp	    }
130033965Sjdp
130133965Sjdp	  fprintf (f, "  %-11s ", name);
130233965Sjdp	  if (! stringp)
130333965Sjdp	    fprintf (f, "0x%lx", (unsigned long) dyn.d_un.d_val);
130433965Sjdp	  else
130533965Sjdp	    {
130633965Sjdp	      const char *string;
130789860Sobrien	      unsigned int tagv = dyn.d_un.d_val;
130833965Sjdp
130989860Sobrien	      string = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
131033965Sjdp	      if (string == NULL)
131133965Sjdp		goto error_return;
131233965Sjdp	      fprintf (f, "%s", string);
131333965Sjdp	    }
131433965Sjdp	  fprintf (f, "\n");
131533965Sjdp	}
131633965Sjdp
131733965Sjdp      free (dynbuf);
131833965Sjdp      dynbuf = NULL;
131933965Sjdp    }
132033965Sjdp
132133965Sjdp  if ((elf_dynverdef (abfd) != 0 && elf_tdata (abfd)->verdef == NULL)
132233965Sjdp      || (elf_dynverref (abfd) != 0 && elf_tdata (abfd)->verref == NULL))
132333965Sjdp    {
1324218822Sdim      if (! _bfd_elf_slurp_version_tables (abfd, FALSE))
1325130563Sobrien	return FALSE;
132633965Sjdp    }
132733965Sjdp
132833965Sjdp  if (elf_dynverdef (abfd) != 0)
132933965Sjdp    {
133033965Sjdp      Elf_Internal_Verdef *t;
133133965Sjdp
133260508Sobrien      fprintf (f, _("\nVersion definitions:\n"));
133333965Sjdp      for (t = elf_tdata (abfd)->verdef; t != NULL; t = t->vd_nextdef)
133433965Sjdp	{
133533965Sjdp	  fprintf (f, "%d 0x%2.2x 0x%8.8lx %s\n", t->vd_ndx,
1336218822Sdim		   t->vd_flags, t->vd_hash,
1337218822Sdim		   t->vd_nodename ? t->vd_nodename : "<corrupt>");
1338218822Sdim	  if (t->vd_auxptr != NULL && t->vd_auxptr->vda_nextptr != NULL)
133933965Sjdp	    {
134033965Sjdp	      Elf_Internal_Verdaux *a;
134133965Sjdp
134233965Sjdp	      fprintf (f, "\t");
134333965Sjdp	      for (a = t->vd_auxptr->vda_nextptr;
134433965Sjdp		   a != NULL;
134533965Sjdp		   a = a->vda_nextptr)
1346218822Sdim		fprintf (f, "%s ",
1347218822Sdim			 a->vda_nodename ? a->vda_nodename : "<corrupt>");
134833965Sjdp	      fprintf (f, "\n");
134933965Sjdp	    }
135033965Sjdp	}
135133965Sjdp    }
135233965Sjdp
135333965Sjdp  if (elf_dynverref (abfd) != 0)
135433965Sjdp    {
135533965Sjdp      Elf_Internal_Verneed *t;
135633965Sjdp
135760508Sobrien      fprintf (f, _("\nVersion References:\n"));
135833965Sjdp      for (t = elf_tdata (abfd)->verref; t != NULL; t = t->vn_nextref)
135933965Sjdp	{
136033965Sjdp	  Elf_Internal_Vernaux *a;
136133965Sjdp
1362218822Sdim	  fprintf (f, _("  required from %s:\n"),
1363218822Sdim		   t->vn_filename ? t->vn_filename : "<corrupt>");
136433965Sjdp	  for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
136533965Sjdp	    fprintf (f, "    0x%8.8lx 0x%2.2x %2.2d %s\n", a->vna_hash,
1366218822Sdim		     a->vna_flags, a->vna_other,
1367218822Sdim		     a->vna_nodename ? a->vna_nodename : "<corrupt>");
136833965Sjdp	}
136933965Sjdp    }
137033965Sjdp
1371130563Sobrien  return TRUE;
137233965Sjdp
137333965Sjdp error_return:
137433965Sjdp  if (dynbuf != NULL)
137533965Sjdp    free (dynbuf);
1376130563Sobrien  return FALSE;
137733965Sjdp}
137833965Sjdp
137933965Sjdp/* Display ELF-specific fields of a symbol.  */
138033965Sjdp
138133965Sjdpvoid
1382130563Sobrienbfd_elf_print_symbol (bfd *abfd,
1383130563Sobrien		      void *filep,
1384130563Sobrien		      asymbol *symbol,
1385130563Sobrien		      bfd_print_symbol_type how)
138633965Sjdp{
1387130563Sobrien  FILE *file = filep;
138833965Sjdp  switch (how)
138933965Sjdp    {
139033965Sjdp    case bfd_print_symbol_name:
139133965Sjdp      fprintf (file, "%s", symbol->name);
139233965Sjdp      break;
139333965Sjdp    case bfd_print_symbol_more:
139433965Sjdp      fprintf (file, "elf ");
139589860Sobrien      bfd_fprintf_vma (abfd, file, symbol->value);
139633965Sjdp      fprintf (file, " %lx", (long) symbol->flags);
139733965Sjdp      break;
139833965Sjdp    case bfd_print_symbol_all:
139933965Sjdp      {
140078831Sobrien	const char *section_name;
140178831Sobrien	const char *name = NULL;
1402130563Sobrien	const struct elf_backend_data *bed;
140360508Sobrien	unsigned char st_other;
140489860Sobrien	bfd_vma val;
140577301Sobrien
140633965Sjdp	section_name = symbol->section ? symbol->section->name : "(*none*)";
140760508Sobrien
140860508Sobrien	bed = get_elf_backend_data (abfd);
140960508Sobrien	if (bed->elf_backend_print_symbol_all)
141077301Sobrien	  name = (*bed->elf_backend_print_symbol_all) (abfd, filep, symbol);
141160508Sobrien
141260508Sobrien	if (name == NULL)
141360508Sobrien	  {
141477301Sobrien	    name = symbol->name;
1415130563Sobrien	    bfd_print_symbol_vandf (abfd, file, symbol);
141660508Sobrien	  }
141760508Sobrien
141833965Sjdp	fprintf (file, " %s\t", section_name);
141933965Sjdp	/* Print the "other" value for a symbol.  For common symbols,
142033965Sjdp	   we've already printed the size; now print the alignment.
142133965Sjdp	   For other symbols, we have no specified alignment, and
142233965Sjdp	   we've printed the address; now print the size.  */
142389860Sobrien	if (bfd_is_com_section (symbol->section))
142489860Sobrien	  val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value;
142589860Sobrien	else
142689860Sobrien	  val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_size;
142789860Sobrien	bfd_fprintf_vma (abfd, file, val);
142833965Sjdp
142933965Sjdp	/* If we have version information, print it.  */
143033965Sjdp	if (elf_tdata (abfd)->dynversym_section != 0
143133965Sjdp	    && (elf_tdata (abfd)->dynverdef_section != 0
143233965Sjdp		|| elf_tdata (abfd)->dynverref_section != 0))
143333965Sjdp	  {
143433965Sjdp	    unsigned int vernum;
143533965Sjdp	    const char *version_string;
143633965Sjdp
143733965Sjdp	    vernum = ((elf_symbol_type *) symbol)->version & VERSYM_VERSION;
143833965Sjdp
143933965Sjdp	    if (vernum == 0)
144033965Sjdp	      version_string = "";
144133965Sjdp	    else if (vernum == 1)
144233965Sjdp	      version_string = "Base";
144333965Sjdp	    else if (vernum <= elf_tdata (abfd)->cverdefs)
144433965Sjdp	      version_string =
144533965Sjdp		elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
144633965Sjdp	    else
144733965Sjdp	      {
144833965Sjdp		Elf_Internal_Verneed *t;
144933965Sjdp
145033965Sjdp		version_string = "";
145133965Sjdp		for (t = elf_tdata (abfd)->verref;
145233965Sjdp		     t != NULL;
145333965Sjdp		     t = t->vn_nextref)
145433965Sjdp		  {
145533965Sjdp		    Elf_Internal_Vernaux *a;
145633965Sjdp
145733965Sjdp		    for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
145833965Sjdp		      {
145933965Sjdp			if (a->vna_other == vernum)
146033965Sjdp			  {
146133965Sjdp			    version_string = a->vna_nodename;
146233965Sjdp			    break;
146333965Sjdp			  }
146433965Sjdp		      }
146533965Sjdp		  }
146633965Sjdp	      }
146733965Sjdp
146833965Sjdp	    if ((((elf_symbol_type *) symbol)->version & VERSYM_HIDDEN) == 0)
146933965Sjdp	      fprintf (file, "  %-11s", version_string);
147033965Sjdp	    else
147133965Sjdp	      {
147233965Sjdp		int i;
147333965Sjdp
147433965Sjdp		fprintf (file, " (%s)", version_string);
147533965Sjdp		for (i = 10 - strlen (version_string); i > 0; --i)
147633965Sjdp		  putc (' ', file);
147733965Sjdp	      }
147833965Sjdp	  }
147933965Sjdp
148033965Sjdp	/* If the st_other field is not zero, print it.  */
148160508Sobrien	st_other = ((elf_symbol_type *) symbol)->internal_elf_sym.st_other;
148277301Sobrien
148360508Sobrien	switch (st_other)
148460508Sobrien	  {
148560508Sobrien	  case 0: break;
148660508Sobrien	  case STV_INTERNAL:  fprintf (file, " .internal");  break;
148760508Sobrien	  case STV_HIDDEN:    fprintf (file, " .hidden");    break;
148860508Sobrien	  case STV_PROTECTED: fprintf (file, " .protected"); break;
148960508Sobrien	  default:
149060508Sobrien	    /* Some other non-defined flags are also present, so print
149160508Sobrien	       everything hex.  */
149260508Sobrien	    fprintf (file, " 0x%02x", (unsigned int) st_other);
149360508Sobrien	  }
149433965Sjdp
149560508Sobrien	fprintf (file, " %s", name);
149633965Sjdp      }
149733965Sjdp      break;
149833965Sjdp    }
149933965Sjdp}
150033965Sjdp
150133965Sjdp/* Create an entry in an ELF linker hash table.  */
150233965Sjdp
150333965Sjdpstruct bfd_hash_entry *
1504130563Sobrien_bfd_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
1505130563Sobrien			    struct bfd_hash_table *table,
1506130563Sobrien			    const char *string)
150733965Sjdp{
150833965Sjdp  /* Allocate the structure if it has not already been allocated by a
150933965Sjdp     subclass.  */
151089860Sobrien  if (entry == NULL)
151189860Sobrien    {
151289860Sobrien      entry = bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry));
151389860Sobrien      if (entry == NULL)
151489860Sobrien	return entry;
151589860Sobrien    }
151633965Sjdp
151733965Sjdp  /* Call the allocation method of the superclass.  */
151889860Sobrien  entry = _bfd_link_hash_newfunc (entry, table, string);
151989860Sobrien  if (entry != NULL)
152033965Sjdp    {
152189860Sobrien      struct elf_link_hash_entry *ret = (struct elf_link_hash_entry *) entry;
152289860Sobrien      struct elf_link_hash_table *htab = (struct elf_link_hash_table *) table;
152389860Sobrien
152433965Sjdp      /* Set local fields.  */
152533965Sjdp      ret->indx = -1;
152633965Sjdp      ret->dynindx = -1;
1527218822Sdim      ret->got = htab->init_got_refcount;
1528218822Sdim      ret->plt = htab->init_plt_refcount;
1529218822Sdim      memset (&ret->size, 0, (sizeof (struct elf_link_hash_entry)
1530218822Sdim			      - offsetof (struct elf_link_hash_entry, size)));
153133965Sjdp      /* Assume that we have been called by a non-ELF symbol reader.
1532218822Sdim	 This flag is then reset by the code which reads an ELF input
1533218822Sdim	 file.  This ensures that a symbol created by a non-ELF symbol
1534218822Sdim	 reader will have the flag set correctly.  */
1535218822Sdim      ret->non_elf = 1;
153633965Sjdp    }
153733965Sjdp
153889860Sobrien  return entry;
153933965Sjdp}
154033965Sjdp
154160508Sobrien/* Copy data from an indirect symbol to its direct symbol, hiding the
154289860Sobrien   old indirect symbol.  Also used for copying flags to a weakdef.  */
154360508Sobrien
154460508Sobrienvoid
1545218822Sdim_bfd_elf_link_hash_copy_indirect (struct bfd_link_info *info,
1546130563Sobrien				  struct elf_link_hash_entry *dir,
1547130563Sobrien				  struct elf_link_hash_entry *ind)
154860508Sobrien{
1549218822Sdim  struct elf_link_hash_table *htab;
155089860Sobrien
155160508Sobrien  /* Copy down any references that we may have already seen to the
155260508Sobrien     symbol which just became indirect.  */
155360508Sobrien
1554218822Sdim  dir->ref_dynamic |= ind->ref_dynamic;
1555218822Sdim  dir->ref_regular |= ind->ref_regular;
1556218822Sdim  dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
1557218822Sdim  dir->non_got_ref |= ind->non_got_ref;
1558218822Sdim  dir->needs_plt |= ind->needs_plt;
1559218822Sdim  dir->pointer_equality_needed |= ind->pointer_equality_needed;
156060508Sobrien
156189860Sobrien  if (ind->root.type != bfd_link_hash_indirect)
156289860Sobrien    return;
156389860Sobrien
156489860Sobrien  /* Copy over the global and procedure linkage table refcount entries.
156560508Sobrien     These may have been already set up by a check_relocs routine.  */
1566218822Sdim  htab = elf_hash_table (info);
1567218822Sdim  if (ind->got.refcount > htab->init_got_refcount.refcount)
156860508Sobrien    {
1569218822Sdim      if (dir->got.refcount < 0)
1570218822Sdim	dir->got.refcount = 0;
1571218822Sdim      dir->got.refcount += ind->got.refcount;
1572218822Sdim      ind->got.refcount = htab->init_got_refcount.refcount;
157360508Sobrien    }
157460508Sobrien
1575218822Sdim  if (ind->plt.refcount > htab->init_plt_refcount.refcount)
157660508Sobrien    {
1577218822Sdim      if (dir->plt.refcount < 0)
1578218822Sdim	dir->plt.refcount = 0;
1579218822Sdim      dir->plt.refcount += ind->plt.refcount;
1580218822Sdim      ind->plt.refcount = htab->init_plt_refcount.refcount;
158160508Sobrien    }
158260508Sobrien
1583218822Sdim  if (ind->dynindx != -1)
158460508Sobrien    {
1585218822Sdim      if (dir->dynindx != -1)
1586218822Sdim	_bfd_elf_strtab_delref (htab->dynstr, dir->dynstr_index);
158760508Sobrien      dir->dynindx = ind->dynindx;
158860508Sobrien      dir->dynstr_index = ind->dynstr_index;
158960508Sobrien      ind->dynindx = -1;
159060508Sobrien      ind->dynstr_index = 0;
159160508Sobrien    }
159260508Sobrien}
159360508Sobrien
159460508Sobrienvoid
1595130563Sobrien_bfd_elf_link_hash_hide_symbol (struct bfd_link_info *info,
1596130563Sobrien				struct elf_link_hash_entry *h,
1597130563Sobrien				bfd_boolean force_local)
159860508Sobrien{
1599218822Sdim  h->plt = elf_hash_table (info)->init_plt_offset;
1600218822Sdim  h->needs_plt = 0;
160189860Sobrien  if (force_local)
160289860Sobrien    {
1603218822Sdim      h->forced_local = 1;
160489860Sobrien      if (h->dynindx != -1)
160589860Sobrien	{
160689860Sobrien	  h->dynindx = -1;
160789860Sobrien	  _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
160889860Sobrien				  h->dynstr_index);
160989860Sobrien	}
161089860Sobrien    }
161160508Sobrien}
161260508Sobrien
161333965Sjdp/* Initialize an ELF linker hash table.  */
161433965Sjdp
1615130563Sobrienbfd_boolean
1616130563Sobrien_bfd_elf_link_hash_table_init
1617130563Sobrien  (struct elf_link_hash_table *table,
1618130563Sobrien   bfd *abfd,
1619130563Sobrien   struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
1620130563Sobrien				      struct bfd_hash_table *,
1621218822Sdim				      const char *),
1622218822Sdim   unsigned int entsize)
162333965Sjdp{
1624130563Sobrien  bfd_boolean ret;
1625218822Sdim  int can_refcount = get_elf_backend_data (abfd)->can_refcount;
162689860Sobrien
1627218822Sdim  memset (table, 0, sizeof * table);
1628218822Sdim  table->init_got_refcount.refcount = can_refcount - 1;
1629218822Sdim  table->init_plt_refcount.refcount = can_refcount - 1;
1630218822Sdim  table->init_got_offset.offset = -(bfd_vma) 1;
1631218822Sdim  table->init_plt_offset.offset = -(bfd_vma) 1;
163233965Sjdp  /* The first dynamic symbol is a dummy.  */
163333965Sjdp  table->dynsymcount = 1;
1634130563Sobrien
1635218822Sdim  ret = _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize);
163689860Sobrien  table->root.type = bfd_link_elf_hash_table;
163789860Sobrien
163889860Sobrien  return ret;
163933965Sjdp}
164033965Sjdp
164133965Sjdp/* Create an ELF linker hash table.  */
164233965Sjdp
164333965Sjdpstruct bfd_link_hash_table *
1644130563Sobrien_bfd_elf_link_hash_table_create (bfd *abfd)
164533965Sjdp{
164633965Sjdp  struct elf_link_hash_table *ret;
164789860Sobrien  bfd_size_type amt = sizeof (struct elf_link_hash_table);
164833965Sjdp
1649130563Sobrien  ret = bfd_malloc (amt);
1650130563Sobrien  if (ret == NULL)
165133965Sjdp    return NULL;
165233965Sjdp
1653218822Sdim  if (! _bfd_elf_link_hash_table_init (ret, abfd, _bfd_elf_link_hash_newfunc,
1654218822Sdim				       sizeof (struct elf_link_hash_entry)))
165533965Sjdp    {
1656104838Sobrien      free (ret);
165733965Sjdp      return NULL;
165833965Sjdp    }
165933965Sjdp
166033965Sjdp  return &ret->root;
166133965Sjdp}
166233965Sjdp
166333965Sjdp/* This is a hook for the ELF emulation code in the generic linker to
166433965Sjdp   tell the backend linker what file name to use for the DT_NEEDED
1665130563Sobrien   entry for a dynamic object.  */
166633965Sjdp
166733965Sjdpvoid
1668130563Sobrienbfd_elf_set_dt_needed_name (bfd *abfd, const char *name)
166933965Sjdp{
167033965Sjdp  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
167133965Sjdp      && bfd_get_format (abfd) == bfd_object)
167233965Sjdp    elf_dt_name (abfd) = name;
167333965Sjdp}
167433965Sjdp
1675218822Sdimint
1676218822Sdimbfd_elf_get_dyn_lib_class (bfd *abfd)
1677218822Sdim{
1678218822Sdim  int lib_class;
1679218822Sdim  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
1680218822Sdim      && bfd_get_format (abfd) == bfd_object)
1681218822Sdim    lib_class = elf_dyn_lib_class (abfd);
1682218822Sdim  else
1683218822Sdim    lib_class = 0;
1684218822Sdim  return lib_class;
1685218822Sdim}
1686218822Sdim
168777301Sobrienvoid
1688218822Sdimbfd_elf_set_dyn_lib_class (bfd *abfd, enum dynamic_lib_link_class lib_class)
168977301Sobrien{
169077301Sobrien  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
169177301Sobrien      && bfd_get_format (abfd) == bfd_object)
1692130563Sobrien    elf_dyn_lib_class (abfd) = lib_class;
169377301Sobrien}
169477301Sobrien
169533965Sjdp/* Get the list of DT_NEEDED entries for a link.  This is a hook for
169660508Sobrien   the linker ELF emulation code.  */
169733965Sjdp
169833965Sjdpstruct bfd_link_needed_list *
1699130563Sobrienbfd_elf_get_needed_list (bfd *abfd ATTRIBUTE_UNUSED,
1700130563Sobrien			 struct bfd_link_info *info)
170133965Sjdp{
1702130563Sobrien  if (! is_elf_hash_table (info->hash))
170333965Sjdp    return NULL;
170433965Sjdp  return elf_hash_table (info)->needed;
170533965Sjdp}
170633965Sjdp
170777301Sobrien/* Get the list of DT_RPATH/DT_RUNPATH entries for a link.  This is a
170877301Sobrien   hook for the linker ELF emulation code.  */
170977301Sobrien
171077301Sobrienstruct bfd_link_needed_list *
1711130563Sobrienbfd_elf_get_runpath_list (bfd *abfd ATTRIBUTE_UNUSED,
1712130563Sobrien			  struct bfd_link_info *info)
171377301Sobrien{
1714130563Sobrien  if (! is_elf_hash_table (info->hash))
171577301Sobrien    return NULL;
171677301Sobrien  return elf_hash_table (info)->runpath;
171777301Sobrien}
171877301Sobrien
171933965Sjdp/* Get the name actually used for a dynamic object for a link.  This
172033965Sjdp   is the SONAME entry if there is one.  Otherwise, it is the string
172133965Sjdp   passed to bfd_elf_set_dt_needed_name, or it is the filename.  */
172233965Sjdp
172333965Sjdpconst char *
1724130563Sobrienbfd_elf_get_dt_soname (bfd *abfd)
172533965Sjdp{
172633965Sjdp  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
172733965Sjdp      && bfd_get_format (abfd) == bfd_object)
172833965Sjdp    return elf_dt_name (abfd);
172933965Sjdp  return NULL;
173033965Sjdp}
173138891Sjdp
173238891Sjdp/* Get the list of DT_NEEDED entries from a BFD.  This is a hook for
173338891Sjdp   the ELF linker emulation code.  */
173438891Sjdp
1735130563Sobrienbfd_boolean
1736130563Sobrienbfd_elf_get_bfd_needed_list (bfd *abfd,
1737130563Sobrien			     struct bfd_link_needed_list **pneeded)
173838891Sjdp{
173938891Sjdp  asection *s;
174038891Sjdp  bfd_byte *dynbuf = NULL;
174138891Sjdp  int elfsec;
174289860Sobrien  unsigned long shlink;
174338891Sjdp  bfd_byte *extdyn, *extdynend;
174438891Sjdp  size_t extdynsize;
1745130563Sobrien  void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
174638891Sjdp
174738891Sjdp  *pneeded = NULL;
174838891Sjdp
174938891Sjdp  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour
175038891Sjdp      || bfd_get_format (abfd) != bfd_object)
1751130563Sobrien    return TRUE;
175238891Sjdp
175338891Sjdp  s = bfd_get_section_by_name (abfd, ".dynamic");
1754218822Sdim  if (s == NULL || s->size == 0)
1755130563Sobrien    return TRUE;
175638891Sjdp
1757218822Sdim  if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
175838891Sjdp    goto error_return;
175938891Sjdp
176038891Sjdp  elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
176138891Sjdp  if (elfsec == -1)
176238891Sjdp    goto error_return;
176338891Sjdp
176489860Sobrien  shlink = elf_elfsections (abfd)[elfsec]->sh_link;
176538891Sjdp
176638891Sjdp  extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
176738891Sjdp  swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
176838891Sjdp
176938891Sjdp  extdyn = dynbuf;
1770218822Sdim  extdynend = extdyn + s->size;
177138891Sjdp  for (; extdyn < extdynend; extdyn += extdynsize)
177238891Sjdp    {
177338891Sjdp      Elf_Internal_Dyn dyn;
177438891Sjdp
1775130563Sobrien      (*swap_dyn_in) (abfd, extdyn, &dyn);
177638891Sjdp
177738891Sjdp      if (dyn.d_tag == DT_NULL)
177838891Sjdp	break;
177938891Sjdp
178038891Sjdp      if (dyn.d_tag == DT_NEEDED)
178138891Sjdp	{
178238891Sjdp	  const char *string;
178338891Sjdp	  struct bfd_link_needed_list *l;
178489860Sobrien	  unsigned int tagv = dyn.d_un.d_val;
178589860Sobrien	  bfd_size_type amt;
178638891Sjdp
178789860Sobrien	  string = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
178838891Sjdp	  if (string == NULL)
178938891Sjdp	    goto error_return;
179038891Sjdp
179189860Sobrien	  amt = sizeof *l;
1792130563Sobrien	  l = bfd_alloc (abfd, amt);
179338891Sjdp	  if (l == NULL)
179438891Sjdp	    goto error_return;
179538891Sjdp
179638891Sjdp	  l->by = abfd;
179738891Sjdp	  l->name = string;
179838891Sjdp	  l->next = *pneeded;
179938891Sjdp	  *pneeded = l;
180038891Sjdp	}
180138891Sjdp    }
180238891Sjdp
180338891Sjdp  free (dynbuf);
180438891Sjdp
1805130563Sobrien  return TRUE;
180638891Sjdp
180738891Sjdp error_return:
180838891Sjdp  if (dynbuf != NULL)
180938891Sjdp    free (dynbuf);
1810130563Sobrien  return FALSE;
181138891Sjdp}
181233965Sjdp
181333965Sjdp/* Allocate an ELF string table--force the first byte to be zero.  */
181433965Sjdp
181533965Sjdpstruct bfd_strtab_hash *
1816130563Sobrien_bfd_elf_stringtab_init (void)
181733965Sjdp{
181833965Sjdp  struct bfd_strtab_hash *ret;
181933965Sjdp
182033965Sjdp  ret = _bfd_stringtab_init ();
182133965Sjdp  if (ret != NULL)
182233965Sjdp    {
182333965Sjdp      bfd_size_type loc;
182433965Sjdp
1825130563Sobrien      loc = _bfd_stringtab_add (ret, "", TRUE, FALSE);
182633965Sjdp      BFD_ASSERT (loc == 0 || loc == (bfd_size_type) -1);
182733965Sjdp      if (loc == (bfd_size_type) -1)
182833965Sjdp	{
182933965Sjdp	  _bfd_stringtab_free (ret);
183033965Sjdp	  ret = NULL;
183133965Sjdp	}
183233965Sjdp    }
183333965Sjdp  return ret;
183433965Sjdp}
183533965Sjdp
183633965Sjdp/* ELF .o/exec file reading */
183733965Sjdp
183877301Sobrien/* Create a new bfd section from an ELF section header.  */
183933965Sjdp
1840130563Sobrienbfd_boolean
1841130563Sobrienbfd_section_from_shdr (bfd *abfd, unsigned int shindex)
184233965Sjdp{
184333965Sjdp  Elf_Internal_Shdr *hdr = elf_elfsections (abfd)[shindex];
184433965Sjdp  Elf_Internal_Ehdr *ehdr = elf_elfheader (abfd);
1845130563Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
1846104838Sobrien  const char *name;
184733965Sjdp
1848218822Sdim  name = bfd_elf_string_from_elf_section (abfd,
1849218822Sdim					  elf_elfheader (abfd)->e_shstrndx,
1850218822Sdim					  hdr->sh_name);
1851218822Sdim  if (name == NULL)
1852218822Sdim    return FALSE;
185333965Sjdp
185433965Sjdp  switch (hdr->sh_type)
185533965Sjdp    {
185633965Sjdp    case SHT_NULL:
185733965Sjdp      /* Inactive section. Throw it away.  */
1858130563Sobrien      return TRUE;
185933965Sjdp
186033965Sjdp    case SHT_PROGBITS:	/* Normal section with contents.  */
186133965Sjdp    case SHT_NOBITS:	/* .bss section.  */
186233965Sjdp    case SHT_HASH:	/* .hash section.  */
186333965Sjdp    case SHT_NOTE:	/* .note section.  */
186494542Sobrien    case SHT_INIT_ARRAY:	/* .init_array section.  */
186594542Sobrien    case SHT_FINI_ARRAY:	/* .fini_array section.  */
186694542Sobrien    case SHT_PREINIT_ARRAY:	/* .preinit_array section.  */
1867218822Sdim    case SHT_GNU_LIBLIST:	/* .gnu.liblist section.  */
1868218822Sdim    case SHT_GNU_HASH:		/* .gnu.hash section.  */
1869218822Sdim      return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
187033965Sjdp
1871104838Sobrien    case SHT_DYNAMIC:	/* Dynamic linking information.  */
1872218822Sdim      if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
1873130563Sobrien	return FALSE;
1874218822Sdim      if (hdr->sh_link > elf_numsections (abfd)
1875218822Sdim	  || elf_elfsections (abfd)[hdr->sh_link] == NULL)
1876218822Sdim	return FALSE;
1877104838Sobrien      if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB)
1878104838Sobrien	{
1879104838Sobrien	  Elf_Internal_Shdr *dynsymhdr;
1880104838Sobrien
1881104838Sobrien	  /* The shared libraries distributed with hpux11 have a bogus
1882104838Sobrien	     sh_link field for the ".dynamic" section.  Find the
1883104838Sobrien	     string table for the ".dynsym" section instead.  */
1884104838Sobrien	  if (elf_dynsymtab (abfd) != 0)
1885104838Sobrien	    {
1886104838Sobrien	      dynsymhdr = elf_elfsections (abfd)[elf_dynsymtab (abfd)];
1887104838Sobrien	      hdr->sh_link = dynsymhdr->sh_link;
1888104838Sobrien	    }
1889104838Sobrien	  else
1890104838Sobrien	    {
1891104838Sobrien	      unsigned int i, num_sec;
1892104838Sobrien
1893104838Sobrien	      num_sec = elf_numsections (abfd);
1894104838Sobrien	      for (i = 1; i < num_sec; i++)
1895104838Sobrien		{
1896104838Sobrien		  dynsymhdr = elf_elfsections (abfd)[i];
1897104838Sobrien		  if (dynsymhdr->sh_type == SHT_DYNSYM)
1898104838Sobrien		    {
1899104838Sobrien		      hdr->sh_link = dynsymhdr->sh_link;
1900104838Sobrien		      break;
1901104838Sobrien		    }
1902104838Sobrien		}
1903104838Sobrien	    }
1904104838Sobrien	}
1905104838Sobrien      break;
1906104838Sobrien
190733965Sjdp    case SHT_SYMTAB:		/* A symbol table */
190833965Sjdp      if (elf_onesymtab (abfd) == shindex)
1909130563Sobrien	return TRUE;
191033965Sjdp
1911218822Sdim      if (hdr->sh_entsize != bed->s->sizeof_sym)
1912218822Sdim	return FALSE;
191333965Sjdp      BFD_ASSERT (elf_onesymtab (abfd) == 0);
191433965Sjdp      elf_onesymtab (abfd) = shindex;
191533965Sjdp      elf_tdata (abfd)->symtab_hdr = *hdr;
191633965Sjdp      elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->symtab_hdr;
191733965Sjdp      abfd->flags |= HAS_SYMS;
191833965Sjdp
191933965Sjdp      /* Sometimes a shared object will map in the symbol table.  If
1920218822Sdim	 SHF_ALLOC is set, and this is a shared object, then we also
1921218822Sdim	 treat this section as a BFD section.  We can not base the
1922218822Sdim	 decision purely on SHF_ALLOC, because that flag is sometimes
1923218822Sdim	 set in a relocatable object file, which would confuse the
1924218822Sdim	 linker.  */
192533965Sjdp      if ((hdr->sh_flags & SHF_ALLOC) != 0
192633965Sjdp	  && (abfd->flags & DYNAMIC) != 0
1927218822Sdim	  && ! _bfd_elf_make_section_from_shdr (abfd, hdr, name,
1928218822Sdim						shindex))
1929130563Sobrien	return FALSE;
193033965Sjdp
1931218822Sdim      /* Go looking for SHT_SYMTAB_SHNDX too, since if there is one we
1932218822Sdim	 can't read symbols without that section loaded as well.  It
1933218822Sdim	 is most likely specified by the next section header.  */
1934218822Sdim      if (elf_elfsections (abfd)[elf_symtab_shndx (abfd)]->sh_link != shindex)
1935218822Sdim	{
1936218822Sdim	  unsigned int i, num_sec;
1937218822Sdim
1938218822Sdim	  num_sec = elf_numsections (abfd);
1939218822Sdim	  for (i = shindex + 1; i < num_sec; i++)
1940218822Sdim	    {
1941218822Sdim	      Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
1942218822Sdim	      if (hdr2->sh_type == SHT_SYMTAB_SHNDX
1943218822Sdim		  && hdr2->sh_link == shindex)
1944218822Sdim		break;
1945218822Sdim	    }
1946218822Sdim	  if (i == num_sec)
1947218822Sdim	    for (i = 1; i < shindex; i++)
1948218822Sdim	      {
1949218822Sdim		Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
1950218822Sdim		if (hdr2->sh_type == SHT_SYMTAB_SHNDX
1951218822Sdim		    && hdr2->sh_link == shindex)
1952218822Sdim		  break;
1953218822Sdim	      }
1954218822Sdim	  if (i != shindex)
1955218822Sdim	    return bfd_section_from_shdr (abfd, i);
1956218822Sdim	}
1957130563Sobrien      return TRUE;
195833965Sjdp
195933965Sjdp    case SHT_DYNSYM:		/* A dynamic symbol table */
196033965Sjdp      if (elf_dynsymtab (abfd) == shindex)
1961130563Sobrien	return TRUE;
196233965Sjdp
1963218822Sdim      if (hdr->sh_entsize != bed->s->sizeof_sym)
1964218822Sdim	return FALSE;
196533965Sjdp      BFD_ASSERT (elf_dynsymtab (abfd) == 0);
196633965Sjdp      elf_dynsymtab (abfd) = shindex;
196733965Sjdp      elf_tdata (abfd)->dynsymtab_hdr = *hdr;
196833965Sjdp      elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->dynsymtab_hdr;
196933965Sjdp      abfd->flags |= HAS_SYMS;
197033965Sjdp
197133965Sjdp      /* Besides being a symbol table, we also treat this as a regular
197233965Sjdp	 section, so that objcopy can handle it.  */
1973218822Sdim      return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
197433965Sjdp
197589860Sobrien    case SHT_SYMTAB_SHNDX:	/* Symbol section indices when >64k sections */
197689860Sobrien      if (elf_symtab_shndx (abfd) == shindex)
1977130563Sobrien	return TRUE;
197889860Sobrien
1979218822Sdim      BFD_ASSERT (elf_symtab_shndx (abfd) == 0);
198089860Sobrien      elf_symtab_shndx (abfd) = shindex;
198189860Sobrien      elf_tdata (abfd)->symtab_shndx_hdr = *hdr;
198289860Sobrien      elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->symtab_shndx_hdr;
1983130563Sobrien      return TRUE;
198489860Sobrien
198533965Sjdp    case SHT_STRTAB:		/* A string table */
198633965Sjdp      if (hdr->bfd_section != NULL)
1987130563Sobrien	return TRUE;
198833965Sjdp      if (ehdr->e_shstrndx == shindex)
198933965Sjdp	{
199033965Sjdp	  elf_tdata (abfd)->shstrtab_hdr = *hdr;
199133965Sjdp	  elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->shstrtab_hdr;
1992130563Sobrien	  return TRUE;
199333965Sjdp	}
1994218822Sdim      if (elf_elfsections (abfd)[elf_onesymtab (abfd)]->sh_link == shindex)
1995218822Sdim	{
1996218822Sdim	symtab_strtab:
1997218822Sdim	  elf_tdata (abfd)->strtab_hdr = *hdr;
1998218822Sdim	  elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->strtab_hdr;
1999218822Sdim	  return TRUE;
2000218822Sdim	}
2001218822Sdim      if (elf_elfsections (abfd)[elf_dynsymtab (abfd)]->sh_link == shindex)
2002218822Sdim	{
2003218822Sdim	dynsymtab_strtab:
2004218822Sdim	  elf_tdata (abfd)->dynstrtab_hdr = *hdr;
2005218822Sdim	  hdr = &elf_tdata (abfd)->dynstrtab_hdr;
2006218822Sdim	  elf_elfsections (abfd)[shindex] = hdr;
2007218822Sdim	  /* We also treat this as a regular section, so that objcopy
2008218822Sdim	     can handle it.  */
2009218822Sdim	  return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
2010218822Sdim						  shindex);
2011218822Sdim	}
201233965Sjdp
2013218822Sdim      /* If the string table isn't one of the above, then treat it as a
2014218822Sdim	 regular section.  We need to scan all the headers to be sure,
2015218822Sdim	 just in case this strtab section appeared before the above.  */
2016218822Sdim      if (elf_onesymtab (abfd) == 0 || elf_dynsymtab (abfd) == 0)
2017218822Sdim	{
2018218822Sdim	  unsigned int i, num_sec;
201933965Sjdp
2020218822Sdim	  num_sec = elf_numsections (abfd);
2021218822Sdim	  for (i = 1; i < num_sec; i++)
2022218822Sdim	    {
2023218822Sdim	      Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
2024218822Sdim	      if (hdr2->sh_link == shindex)
2025218822Sdim		{
2026218822Sdim		  /* Prevent endless recursion on broken objects.  */
2027218822Sdim		  if (i == shindex)
2028218822Sdim		    return FALSE;
2029218822Sdim		  if (! bfd_section_from_shdr (abfd, i))
2030218822Sdim		    return FALSE;
2031218822Sdim		  if (elf_onesymtab (abfd) == i)
2032218822Sdim		    goto symtab_strtab;
2033218822Sdim		  if (elf_dynsymtab (abfd) == i)
2034218822Sdim		    goto dynsymtab_strtab;
2035218822Sdim		}
2036218822Sdim	    }
2037218822Sdim	}
2038218822Sdim      return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
203933965Sjdp
204033965Sjdp    case SHT_REL:
204133965Sjdp    case SHT_RELA:
204233965Sjdp      /* *These* do a lot of work -- but build no sections!  */
204333965Sjdp      {
204433965Sjdp	asection *target_sect;
204533965Sjdp	Elf_Internal_Shdr *hdr2;
204689860Sobrien	unsigned int num_sec = elf_numsections (abfd);
204733965Sjdp
2048218822Sdim	if (hdr->sh_entsize
2049218822Sdim	    != (bfd_size_type) (hdr->sh_type == SHT_REL
2050218822Sdim				? bed->s->sizeof_rel : bed->s->sizeof_rela))
2051218822Sdim	  return FALSE;
2052218822Sdim
205360508Sobrien	/* Check for a bogus link to avoid crashing.  */
205489860Sobrien	if ((hdr->sh_link >= SHN_LORESERVE && hdr->sh_link <= SHN_HIRESERVE)
205589860Sobrien	    || hdr->sh_link >= num_sec)
205660508Sobrien	  {
205760508Sobrien	    ((*_bfd_error_handler)
2058218822Sdim	     (_("%B: invalid link %lu for reloc section %s (index %u)"),
2059218822Sdim	      abfd, hdr->sh_link, name, shindex));
2060218822Sdim	    return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
2061218822Sdim						    shindex);
206260508Sobrien	  }
206360508Sobrien
206433965Sjdp	/* For some incomprehensible reason Oracle distributes
206533965Sjdp	   libraries for Solaris in which some of the objects have
206633965Sjdp	   bogus sh_link fields.  It would be nice if we could just
206733965Sjdp	   reject them, but, unfortunately, some people need to use
206833965Sjdp	   them.  We scan through the section headers; if we find only
206933965Sjdp	   one suitable symbol table, we clobber the sh_link to point
207033965Sjdp	   to it.  I hope this doesn't break anything.  */
207133965Sjdp	if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_SYMTAB
207233965Sjdp	    && elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_DYNSYM)
207333965Sjdp	  {
207489860Sobrien	    unsigned int scan;
207533965Sjdp	    int found;
207633965Sjdp
207733965Sjdp	    found = 0;
207889860Sobrien	    for (scan = 1; scan < num_sec; scan++)
207933965Sjdp	      {
208033965Sjdp		if (elf_elfsections (abfd)[scan]->sh_type == SHT_SYMTAB
208133965Sjdp		    || elf_elfsections (abfd)[scan]->sh_type == SHT_DYNSYM)
208233965Sjdp		  {
208333965Sjdp		    if (found != 0)
208433965Sjdp		      {
208533965Sjdp			found = 0;
208633965Sjdp			break;
208733965Sjdp		      }
208833965Sjdp		    found = scan;
208933965Sjdp		  }
209033965Sjdp	      }
209133965Sjdp	    if (found != 0)
209233965Sjdp	      hdr->sh_link = found;
209333965Sjdp	  }
209433965Sjdp
209533965Sjdp	/* Get the symbol table.  */
2096218822Sdim	if ((elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_SYMTAB
2097218822Sdim	     || elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_DYNSYM)
209833965Sjdp	    && ! bfd_section_from_shdr (abfd, hdr->sh_link))
2099130563Sobrien	  return FALSE;
210033965Sjdp
210133965Sjdp	/* If this reloc section does not use the main symbol table we
210233965Sjdp	   don't treat it as a reloc section.  BFD can't adequately
210333965Sjdp	   represent such a section, so at least for now, we don't
210477301Sobrien	   try.  We just present it as a normal section.  We also
210577301Sobrien	   can't use it as a reloc section if it points to the null
2106218822Sdim	   section, an invalid section, or another reloc section.  */
2107218822Sdim	if (hdr->sh_link != elf_onesymtab (abfd)
2108218822Sdim	    || hdr->sh_info == SHN_UNDEF
2109218822Sdim	    || (hdr->sh_info >= SHN_LORESERVE && hdr->sh_info <= SHN_HIRESERVE)
2110218822Sdim	    || hdr->sh_info >= num_sec
2111218822Sdim	    || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL
2112218822Sdim	    || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA)
2113218822Sdim	  return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
2114218822Sdim						  shindex);
211533965Sjdp
211633965Sjdp	if (! bfd_section_from_shdr (abfd, hdr->sh_info))
2117130563Sobrien	  return FALSE;
211833965Sjdp	target_sect = bfd_section_from_elf_index (abfd, hdr->sh_info);
211933965Sjdp	if (target_sect == NULL)
2120130563Sobrien	  return FALSE;
212133965Sjdp
212233965Sjdp	if ((target_sect->flags & SEC_RELOC) == 0
212333965Sjdp	    || target_sect->reloc_count == 0)
212433965Sjdp	  hdr2 = &elf_section_data (target_sect)->rel_hdr;
212533965Sjdp	else
212633965Sjdp	  {
212789860Sobrien	    bfd_size_type amt;
212833965Sjdp	    BFD_ASSERT (elf_section_data (target_sect)->rel_hdr2 == NULL);
212989860Sobrien	    amt = sizeof (*hdr2);
2130130563Sobrien	    hdr2 = bfd_alloc (abfd, amt);
213133965Sjdp	    elf_section_data (target_sect)->rel_hdr2 = hdr2;
213233965Sjdp	  }
213333965Sjdp	*hdr2 = *hdr;
213433965Sjdp	elf_elfsections (abfd)[shindex] = hdr2;
213578831Sobrien	target_sect->reloc_count += NUM_SHDR_ENTRIES (hdr);
213633965Sjdp	target_sect->flags |= SEC_RELOC;
213733965Sjdp	target_sect->relocation = NULL;
213833965Sjdp	target_sect->rel_filepos = hdr->sh_offset;
213960508Sobrien	/* In the section to which the relocations apply, mark whether
214060508Sobrien	   its relocations are of the REL or RELA variety.  */
214160508Sobrien	if (hdr->sh_size != 0)
2142130563Sobrien	  target_sect->use_rela_p = hdr->sh_type == SHT_RELA;
214333965Sjdp	abfd->flags |= HAS_RELOC;
2144130563Sobrien	return TRUE;
214533965Sjdp      }
214633965Sjdp
214733965Sjdp    case SHT_GNU_verdef:
214833965Sjdp      elf_dynverdef (abfd) = shindex;
214933965Sjdp      elf_tdata (abfd)->dynverdef_hdr = *hdr;
2150218822Sdim      return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
215133965Sjdp
215233965Sjdp    case SHT_GNU_versym:
2153218822Sdim      if (hdr->sh_entsize != sizeof (Elf_External_Versym))
2154218822Sdim	return FALSE;
215533965Sjdp      elf_dynversym (abfd) = shindex;
215633965Sjdp      elf_tdata (abfd)->dynversym_hdr = *hdr;
2157218822Sdim      return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
215833965Sjdp
215933965Sjdp    case SHT_GNU_verneed:
216033965Sjdp      elf_dynverref (abfd) = shindex;
216133965Sjdp      elf_tdata (abfd)->dynverref_hdr = *hdr;
2162218822Sdim      return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
216333965Sjdp
216433965Sjdp    case SHT_SHLIB:
2165130563Sobrien      return TRUE;
216633965Sjdp
216789860Sobrien    case SHT_GROUP:
2168104838Sobrien      /* We need a BFD section for objcopy and relocatable linking,
2169104838Sobrien	 and it's handy to have the signature available as the section
2170104838Sobrien	 name.  */
2171218822Sdim      if (! IS_VALID_GROUP_SECTION_HEADER (hdr))
2172218822Sdim	return FALSE;
2173104838Sobrien      name = group_signature (abfd, hdr);
2174104838Sobrien      if (name == NULL)
2175130563Sobrien	return FALSE;
2176218822Sdim      if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
2177130563Sobrien	return FALSE;
217889860Sobrien      if (hdr->contents != NULL)
217989860Sobrien	{
218089860Sobrien	  Elf_Internal_Group *idx = (Elf_Internal_Group *) hdr->contents;
2181218822Sdim	  unsigned int n_elt = hdr->sh_size / GRP_ENTRY_SIZE;
218289860Sobrien	  asection *s;
218389860Sobrien
2184104838Sobrien	  if (idx->flags & GRP_COMDAT)
2185104838Sobrien	    hdr->bfd_section->flags
2186104838Sobrien	      |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
2187104838Sobrien
2188218822Sdim	  /* We try to keep the same section order as it comes in.  */
2189218822Sdim	  idx += n_elt;
219089860Sobrien	  while (--n_elt != 0)
2191218822Sdim	    {
2192218822Sdim	      --idx;
2193218822Sdim
2194218822Sdim	      if (idx->shdr != NULL
2195218822Sdim		  && (s = idx->shdr->bfd_section) != NULL
2196218822Sdim		  && elf_next_in_group (s) != NULL)
2197218822Sdim		{
2198218822Sdim		  elf_next_in_group (hdr->bfd_section) = s;
2199218822Sdim		  break;
2200218822Sdim		}
2201218822Sdim	    }
220289860Sobrien	}
220389860Sobrien      break;
220489860Sobrien
220533965Sjdp    default:
2206218822Sdim      /* Possibly an attributes section.  */
2207218822Sdim      if (hdr->sh_type == SHT_GNU_ATTRIBUTES
2208218822Sdim	  || hdr->sh_type == bed->obj_attrs_section_type)
2209218822Sdim	{
2210218822Sdim	  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
2211218822Sdim	    return FALSE;
2212218822Sdim	  _bfd_elf_parse_attributes (abfd, hdr);
2213218822Sdim	  return TRUE;
2214218822Sdim	}
2215218822Sdim
221633965Sjdp      /* Check for any processor-specific section types.  */
2217218822Sdim      if (bed->elf_backend_section_from_shdr (abfd, hdr, name, shindex))
2218218822Sdim	return TRUE;
2219218822Sdim
2220218822Sdim      if (hdr->sh_type >= SHT_LOUSER && hdr->sh_type <= SHT_HIUSER)
2221218822Sdim	{
2222218822Sdim	  if ((hdr->sh_flags & SHF_ALLOC) != 0)
2223218822Sdim	    /* FIXME: How to properly handle allocated section reserved
2224218822Sdim	       for applications?  */
2225218822Sdim	    (*_bfd_error_handler)
2226218822Sdim	      (_("%B: don't know how to handle allocated, application "
2227218822Sdim		 "specific section `%s' [0x%8x]"),
2228218822Sdim	       abfd, name, hdr->sh_type);
2229218822Sdim	  else
2230218822Sdim	    /* Allow sections reserved for applications.  */
2231218822Sdim	    return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
2232218822Sdim						    shindex);
2233218822Sdim	}
2234218822Sdim      else if (hdr->sh_type >= SHT_LOPROC
2235218822Sdim	       && hdr->sh_type <= SHT_HIPROC)
2236218822Sdim	/* FIXME: We should handle this section.  */
2237218822Sdim	(*_bfd_error_handler)
2238218822Sdim	  (_("%B: don't know how to handle processor specific section "
2239218822Sdim	     "`%s' [0x%8x]"),
2240218822Sdim	   abfd, name, hdr->sh_type);
2241218822Sdim      else if (hdr->sh_type >= SHT_LOOS && hdr->sh_type <= SHT_HIOS)
2242218822Sdim	{
2243218822Sdim	  /* Unrecognised OS-specific sections.  */
2244218822Sdim	  if ((hdr->sh_flags & SHF_OS_NONCONFORMING) != 0)
2245218822Sdim	    /* SHF_OS_NONCONFORMING indicates that special knowledge is
2246218822Sdim	       required to correctly process the section and the file should
2247218822Sdim	       be rejected with an error message.  */
2248218822Sdim	    (*_bfd_error_handler)
2249218822Sdim	      (_("%B: don't know how to handle OS specific section "
2250218822Sdim		 "`%s' [0x%8x]"),
2251218822Sdim	       abfd, name, hdr->sh_type);
2252218822Sdim	  else
2253218822Sdim	    /* Otherwise it should be processed.  */
2254218822Sdim	    return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
2255218822Sdim	}
2256218822Sdim      else
2257218822Sdim	/* FIXME: We should handle this section.  */
2258218822Sdim	(*_bfd_error_handler)
2259218822Sdim	  (_("%B: don't know how to handle section `%s' [0x%8x]"),
2260218822Sdim	   abfd, name, hdr->sh_type);
2261218822Sdim
2262218822Sdim      return FALSE;
226333965Sjdp    }
226433965Sjdp
2265130563Sobrien  return TRUE;
226633965Sjdp}
226733965Sjdp
226889860Sobrien/* Return the section for the local symbol specified by ABFD, R_SYMNDX.
226989860Sobrien   Return SEC for sections that have no elf section, and NULL on error.  */
227089860Sobrien
227189860Sobrienasection *
2272130563Sobrienbfd_section_from_r_symndx (bfd *abfd,
2273130563Sobrien			   struct sym_sec_cache *cache,
2274130563Sobrien			   asection *sec,
2275130563Sobrien			   unsigned long r_symndx)
227689860Sobrien{
227789860Sobrien  Elf_Internal_Shdr *symtab_hdr;
2278104838Sobrien  unsigned char esym[sizeof (Elf64_External_Sym)];
2279104838Sobrien  Elf_External_Sym_Shndx eshndx;
2280104838Sobrien  Elf_Internal_Sym isym;
228189860Sobrien  unsigned int ent = r_symndx % LOCAL_SYM_CACHE_SIZE;
228289860Sobrien
228389860Sobrien  if (cache->abfd == abfd && cache->indx[ent] == r_symndx)
228489860Sobrien    return cache->sec[ent];
228589860Sobrien
228689860Sobrien  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2287104838Sobrien  if (bfd_elf_get_elf_syms (abfd, symtab_hdr, 1, r_symndx,
2288104838Sobrien			    &isym, esym, &eshndx) == NULL)
228989860Sobrien    return NULL;
229089860Sobrien
229189860Sobrien  if (cache->abfd != abfd)
229289860Sobrien    {
229389860Sobrien      memset (cache->indx, -1, sizeof (cache->indx));
229489860Sobrien      cache->abfd = abfd;
229589860Sobrien    }
229689860Sobrien  cache->indx[ent] = r_symndx;
229789860Sobrien  cache->sec[ent] = sec;
2298130563Sobrien  if ((isym.st_shndx != SHN_UNDEF && isym.st_shndx < SHN_LORESERVE)
2299130563Sobrien      || isym.st_shndx > SHN_HIRESERVE)
230089860Sobrien    {
230189860Sobrien      asection *s;
2302104838Sobrien      s = bfd_section_from_elf_index (abfd, isym.st_shndx);
230389860Sobrien      if (s != NULL)
230489860Sobrien	cache->sec[ent] = s;
230589860Sobrien    }
230689860Sobrien  return cache->sec[ent];
230789860Sobrien}
230889860Sobrien
230933965Sjdp/* Given an ELF section number, retrieve the corresponding BFD
231033965Sjdp   section.  */
231133965Sjdp
231233965Sjdpasection *
2313130563Sobrienbfd_section_from_elf_index (bfd *abfd, unsigned int index)
231433965Sjdp{
231589860Sobrien  if (index >= elf_numsections (abfd))
231633965Sjdp    return NULL;
231733965Sjdp  return elf_elfsections (abfd)[index]->bfd_section;
231833965Sjdp}
231933965Sjdp
2320218822Sdimstatic const struct bfd_elf_special_section special_sections_b[] =
232133965Sjdp{
2322218822Sdim  { STRING_COMMA_LEN (".bss"), -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
2323218822Sdim  { NULL,                   0,  0, 0,            0 }
2324130563Sobrien};
2325130563Sobrien
2326218822Sdimstatic const struct bfd_elf_special_section special_sections_c[] =
2327130563Sobrien{
2328218822Sdim  { STRING_COMMA_LEN (".comment"), 0, SHT_PROGBITS, 0 },
2329218822Sdim  { NULL,                       0, 0, 0,            0 }
2330218822Sdim};
2331218822Sdim
2332218822Sdimstatic const struct bfd_elf_special_section special_sections_d[] =
2333218822Sdim{
2334218822Sdim  { STRING_COMMA_LEN (".data"),         -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
2335218822Sdim  { STRING_COMMA_LEN (".data1"),         0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
2336218822Sdim  { STRING_COMMA_LEN (".debug"),         0, SHT_PROGBITS, 0 },
2337218822Sdim  { STRING_COMMA_LEN (".debug_line"),    0, SHT_PROGBITS, 0 },
2338218822Sdim  { STRING_COMMA_LEN (".debug_info"),    0, SHT_PROGBITS, 0 },
2339218822Sdim  { STRING_COMMA_LEN (".debug_abbrev"),  0, SHT_PROGBITS, 0 },
2340218822Sdim  { STRING_COMMA_LEN (".debug_aranges"), 0, SHT_PROGBITS, 0 },
2341218822Sdim  { STRING_COMMA_LEN (".dynamic"),       0, SHT_DYNAMIC,  SHF_ALLOC },
2342218822Sdim  { STRING_COMMA_LEN (".dynstr"),        0, SHT_STRTAB,   SHF_ALLOC },
2343218822Sdim  { STRING_COMMA_LEN (".dynsym"),        0, SHT_DYNSYM,   SHF_ALLOC },
2344218822Sdim  { NULL,                      0,        0, 0,            0 }
2345218822Sdim};
2346218822Sdim
2347218822Sdimstatic const struct bfd_elf_special_section special_sections_f[] =
2348218822Sdim{
2349218822Sdim  { STRING_COMMA_LEN (".fini"),       0, SHT_PROGBITS,   SHF_ALLOC + SHF_EXECINSTR },
2350218822Sdim  { STRING_COMMA_LEN (".fini_array"), 0, SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE },
2351218822Sdim  { NULL,                          0, 0, 0,              0 }
2352218822Sdim};
2353218822Sdim
2354218822Sdimstatic const struct bfd_elf_special_section special_sections_g[] =
2355218822Sdim{
2356218822Sdim  { STRING_COMMA_LEN (".gnu.linkonce.b"), -2, SHT_NOBITS,      SHF_ALLOC + SHF_WRITE },
2357218822Sdim  { STRING_COMMA_LEN (".got"),             0, SHT_PROGBITS,    SHF_ALLOC + SHF_WRITE },
2358218822Sdim  { STRING_COMMA_LEN (".gnu.version"),     0, SHT_GNU_versym,  0 },
2359218822Sdim  { STRING_COMMA_LEN (".gnu.version_d"),   0, SHT_GNU_verdef,  0 },
2360218822Sdim  { STRING_COMMA_LEN (".gnu.version_r"),   0, SHT_GNU_verneed, 0 },
2361218822Sdim  { STRING_COMMA_LEN (".gnu.liblist"),     0, SHT_GNU_LIBLIST, SHF_ALLOC },
2362218822Sdim  { STRING_COMMA_LEN (".gnu.conflict"),    0, SHT_RELA,        SHF_ALLOC },
2363218822Sdim  { STRING_COMMA_LEN (".gnu.hash"),        0, SHT_GNU_HASH,    SHF_ALLOC },
2364218822Sdim  { NULL,                        0,        0, 0,               0 }
2365218822Sdim};
2366218822Sdim
2367218822Sdimstatic const struct bfd_elf_special_section special_sections_h[] =
2368218822Sdim{
2369218822Sdim  { STRING_COMMA_LEN (".hash"), 0, SHT_HASH,     SHF_ALLOC },
2370218822Sdim  { NULL,                    0, 0, 0,            0 }
2371218822Sdim};
2372218822Sdim
2373218822Sdimstatic const struct bfd_elf_special_section special_sections_i[] =
2374218822Sdim{
2375218822Sdim  { STRING_COMMA_LEN (".init"),       0, SHT_PROGBITS,   SHF_ALLOC + SHF_EXECINSTR },
2376218822Sdim  { STRING_COMMA_LEN (".init_array"), 0, SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE },
2377218822Sdim  { STRING_COMMA_LEN (".interp"),     0, SHT_PROGBITS,   0 },
2378218822Sdim  { NULL,                      0,     0, 0,              0 }
2379218822Sdim};
2380218822Sdim
2381218822Sdimstatic const struct bfd_elf_special_section special_sections_l[] =
2382218822Sdim{
2383218822Sdim  { STRING_COMMA_LEN (".line"), 0, SHT_PROGBITS, 0 },
2384218822Sdim  { NULL,                    0, 0, 0,            0 }
2385218822Sdim};
2386218822Sdim
2387218822Sdimstatic const struct bfd_elf_special_section special_sections_n[] =
2388218822Sdim{
2389218822Sdim  { STRING_COMMA_LEN (".note.GNU-stack"), 0, SHT_PROGBITS, 0 },
2390218822Sdim  { STRING_COMMA_LEN (".note"),          -1, SHT_NOTE,     0 },
2391218822Sdim  { NULL,                    0,           0, 0,            0 }
2392218822Sdim};
2393218822Sdim
2394218822Sdimstatic const struct bfd_elf_special_section special_sections_p[] =
2395218822Sdim{
2396218822Sdim  { STRING_COMMA_LEN (".preinit_array"), 0, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE },
2397218822Sdim  { STRING_COMMA_LEN (".plt"),           0, SHT_PROGBITS,      SHF_ALLOC + SHF_EXECINSTR },
2398218822Sdim  { NULL,                   0,           0, 0,                 0 }
2399218822Sdim};
2400218822Sdim
2401218822Sdimstatic const struct bfd_elf_special_section special_sections_r[] =
2402218822Sdim{
2403218822Sdim  { STRING_COMMA_LEN (".rodata"), -2, SHT_PROGBITS, SHF_ALLOC },
2404218822Sdim  { STRING_COMMA_LEN (".rodata1"), 0, SHT_PROGBITS, SHF_ALLOC },
2405218822Sdim  { STRING_COMMA_LEN (".rela"),   -1, SHT_RELA,     0 },
2406218822Sdim  { STRING_COMMA_LEN (".rel"),    -1, SHT_REL,      0 },
2407218822Sdim  { NULL,                   0,     0, 0,            0 }
2408218822Sdim};
2409218822Sdim
2410218822Sdimstatic const struct bfd_elf_special_section special_sections_s[] =
2411218822Sdim{
2412218822Sdim  { STRING_COMMA_LEN (".shstrtab"), 0, SHT_STRTAB, 0 },
2413218822Sdim  { STRING_COMMA_LEN (".strtab"),   0, SHT_STRTAB, 0 },
2414218822Sdim  { STRING_COMMA_LEN (".symtab"),   0, SHT_SYMTAB, 0 },
2415218822Sdim  /* See struct bfd_elf_special_section declaration for the semantics of
2416218822Sdim     this special case where .prefix_length != strlen (.prefix).  */
2417218822Sdim  { ".stabstr",			5,  3, SHT_STRTAB, 0 },
2418218822Sdim  { NULL,                       0,  0, 0,          0 }
2419218822Sdim};
2420218822Sdim
2421218822Sdimstatic const struct bfd_elf_special_section special_sections_t[] =
2422218822Sdim{
2423218822Sdim  { STRING_COMMA_LEN (".text"),  -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
2424218822Sdim  { STRING_COMMA_LEN (".tbss"),  -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_TLS },
2425218822Sdim  { STRING_COMMA_LEN (".tdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS },
2426218822Sdim  { NULL,                     0,  0, 0,            0 }
2427218822Sdim};
2428218822Sdim
2429218822Sdimstatic const struct bfd_elf_special_section *special_sections[] =
2430218822Sdim{
2431218822Sdim  special_sections_b,		/* 'b' */
2432218822Sdim  special_sections_c,		/* 'b' */
2433218822Sdim  special_sections_d,		/* 'd' */
2434218822Sdim  NULL,				/* 'e' */
2435218822Sdim  special_sections_f,		/* 'f' */
2436218822Sdim  special_sections_g,		/* 'g' */
2437218822Sdim  special_sections_h,		/* 'h' */
2438218822Sdim  special_sections_i,		/* 'i' */
2439218822Sdim  NULL,				/* 'j' */
2440218822Sdim  NULL,				/* 'k' */
2441218822Sdim  special_sections_l,		/* 'l' */
2442218822Sdim  NULL,				/* 'm' */
2443218822Sdim  special_sections_n,		/* 'n' */
2444218822Sdim  NULL,				/* 'o' */
2445218822Sdim  special_sections_p,		/* 'p' */
2446218822Sdim  NULL,				/* 'q' */
2447218822Sdim  special_sections_r,		/* 'r' */
2448218822Sdim  special_sections_s,		/* 's' */
2449218822Sdim  special_sections_t,		/* 't' */
2450218822Sdim};
2451218822Sdim
2452218822Sdimconst struct bfd_elf_special_section *
2453218822Sdim_bfd_elf_get_special_section (const char *name,
2454218822Sdim			      const struct bfd_elf_special_section *spec,
2455218822Sdim			      unsigned int rela)
2456218822Sdim{
2457130563Sobrien  int i;
2458218822Sdim  int len;
2459130563Sobrien
2460218822Sdim  len = strlen (name);
2461218822Sdim
2462218822Sdim  for (i = 0; spec[i].prefix != NULL; i++)
2463130563Sobrien    {
2464130563Sobrien      int suffix_len;
2465218822Sdim      int prefix_len = spec[i].prefix_length;
2466130563Sobrien
2467130563Sobrien      if (len < prefix_len)
2468130563Sobrien	continue;
2469218822Sdim      if (memcmp (name, spec[i].prefix, prefix_len) != 0)
2470130563Sobrien	continue;
2471130563Sobrien
2472218822Sdim      suffix_len = spec[i].suffix_length;
2473130563Sobrien      if (suffix_len <= 0)
2474130563Sobrien	{
2475130563Sobrien	  if (name[prefix_len] != 0)
2476130563Sobrien	    {
2477130563Sobrien	      if (suffix_len == 0)
2478130563Sobrien		continue;
2479130563Sobrien	      if (name[prefix_len] != '.'
2480130563Sobrien		  && (suffix_len == -2
2481218822Sdim		      || (rela && spec[i].type == SHT_REL)))
2482130563Sobrien		continue;
2483130563Sobrien	    }
2484130563Sobrien	}
2485130563Sobrien      else
2486130563Sobrien	{
2487130563Sobrien	  if (len < prefix_len + suffix_len)
2488130563Sobrien	    continue;
2489130563Sobrien	  if (memcmp (name + len - suffix_len,
2490218822Sdim		      spec[i].prefix + prefix_len,
2491130563Sobrien		      suffix_len) != 0)
2492130563Sobrien	    continue;
2493130563Sobrien	}
2494218822Sdim      return &spec[i];
2495130563Sobrien    }
2496130563Sobrien
2497130563Sobrien  return NULL;
2498130563Sobrien}
2499130563Sobrien
2500130563Sobrienconst struct bfd_elf_special_section *
2501218822Sdim_bfd_elf_get_sec_type_attr (bfd *abfd, asection *sec)
2502130563Sobrien{
2503218822Sdim  int i;
2504218822Sdim  const struct bfd_elf_special_section *spec;
2505218822Sdim  const struct elf_backend_data *bed;
2506130563Sobrien
2507130563Sobrien  /* See if this is one of the special sections.  */
2508218822Sdim  if (sec->name == NULL)
2509218822Sdim    return NULL;
2510218822Sdim
2511218822Sdim  bed = get_elf_backend_data (abfd);
2512218822Sdim  spec = bed->special_sections;
2513218822Sdim  if (spec)
2514130563Sobrien    {
2515218822Sdim      spec = _bfd_elf_get_special_section (sec->name,
2516218822Sdim					   bed->special_sections,
2517218822Sdim					   sec->use_rela_p);
2518218822Sdim      if (spec != NULL)
2519218822Sdim	return spec;
2520218822Sdim    }
2521130563Sobrien
2522218822Sdim  if (sec->name[0] != '.')
2523218822Sdim    return NULL;
2524130563Sobrien
2525218822Sdim  i = sec->name[1] - 'b';
2526218822Sdim  if (i < 0 || i > 't' - 'b')
2527218822Sdim    return NULL;
2528130563Sobrien
2529218822Sdim  spec = special_sections[i];
2530218822Sdim
2531218822Sdim  if (spec == NULL)
2532218822Sdim    return NULL;
2533218822Sdim
2534218822Sdim  return _bfd_elf_get_special_section (sec->name, spec, sec->use_rela_p);
2535130563Sobrien}
2536130563Sobrien
2537130563Sobrienbfd_boolean
2538130563Sobrien_bfd_elf_new_section_hook (bfd *abfd, asection *sec)
2539130563Sobrien{
254033965Sjdp  struct bfd_elf_section_data *sdata;
2541218822Sdim  const struct elf_backend_data *bed;
2542130563Sobrien  const struct bfd_elf_special_section *ssect;
254333965Sjdp
2544130563Sobrien  sdata = (struct bfd_elf_section_data *) sec->used_by_bfd;
2545130563Sobrien  if (sdata == NULL)
2546130563Sobrien    {
2547130563Sobrien      sdata = bfd_zalloc (abfd, sizeof (*sdata));
2548130563Sobrien      if (sdata == NULL)
2549130563Sobrien	return FALSE;
2550130563Sobrien      sec->used_by_bfd = sdata;
2551130563Sobrien    }
255260508Sobrien
2553218822Sdim  /* Indicate whether or not this section should use RELA relocations.  */
2554218822Sdim  bed = get_elf_backend_data (abfd);
2555218822Sdim  sec->use_rela_p = bed->default_use_rela_p;
2556218822Sdim
2557218822Sdim  /* When we read a file, we don't need to set ELF section type and
2558218822Sdim     flags.  They will be overridden in _bfd_elf_make_section_from_shdr
2559218822Sdim     anyway.  We will set ELF section type and flags for all linker
2560218822Sdim     created sections.  If user specifies BFD section flags, we will
2561218822Sdim     set ELF section type and flags based on BFD section flags in
2562218822Sdim     elf_fake_sections.  */
2563218822Sdim  if ((!sec->flags && abfd->direction != read_direction)
2564218822Sdim      || (sec->flags & SEC_LINKER_CREATED) != 0)
2565130563Sobrien    {
2566218822Sdim      ssect = (*bed->get_sec_type_attr) (abfd, sec);
2567218822Sdim      if (ssect != NULL)
2568218822Sdim	{
2569218822Sdim	  elf_section_type (sec) = ssect->type;
2570218822Sdim	  elf_section_flags (sec) = ssect->attr;
2571218822Sdim	}
2572130563Sobrien    }
2573130563Sobrien
2574218822Sdim  return _bfd_generic_new_section_hook (abfd, sec);
257533965Sjdp}
257633965Sjdp
257733965Sjdp/* Create a new bfd section from an ELF program header.
257833965Sjdp
257933965Sjdp   Since program segments have no names, we generate a synthetic name
258033965Sjdp   of the form segment<NUM>, where NUM is generally the index in the
258133965Sjdp   program header table.  For segments that are split (see below) we
258233965Sjdp   generate the names segment<NUM>a and segment<NUM>b.
258333965Sjdp
258433965Sjdp   Note that some program segments may have a file size that is different than
258533965Sjdp   (less than) the memory size.  All this means is that at execution the
258633965Sjdp   system must allocate the amount of memory specified by the memory size,
258733965Sjdp   but only initialize it with the first "file size" bytes read from the
258833965Sjdp   file.  This would occur for example, with program segments consisting
258933965Sjdp   of combined data+bss.
259033965Sjdp
259133965Sjdp   To handle the above situation, this routine generates TWO bfd sections
259233965Sjdp   for the single program segment.  The first has the length specified by
259333965Sjdp   the file size of the segment, and the second has the length specified
259433965Sjdp   by the difference between the two sizes.  In effect, the segment is split
259533965Sjdp   into it's initialized and uninitialized parts.
259633965Sjdp
259733965Sjdp */
259833965Sjdp
2599130563Sobrienbfd_boolean
2600130563Sobrien_bfd_elf_make_section_from_phdr (bfd *abfd,
2601130563Sobrien				 Elf_Internal_Phdr *hdr,
2602130563Sobrien				 int index,
2603130563Sobrien				 const char *typename)
260433965Sjdp{
260533965Sjdp  asection *newsect;
260633965Sjdp  char *name;
260733965Sjdp  char namebuf[64];
2608104838Sobrien  size_t len;
260933965Sjdp  int split;
261033965Sjdp
261160508Sobrien  split = ((hdr->p_memsz > 0)
261260508Sobrien	    && (hdr->p_filesz > 0)
261360508Sobrien	    && (hdr->p_memsz > hdr->p_filesz));
261460508Sobrien  sprintf (namebuf, "%s%d%s", typename, index, split ? "a" : "");
2615104838Sobrien  len = strlen (namebuf) + 1;
2616130563Sobrien  name = bfd_alloc (abfd, len);
261733965Sjdp  if (!name)
2618130563Sobrien    return FALSE;
2619104838Sobrien  memcpy (name, namebuf, len);
262033965Sjdp  newsect = bfd_make_section (abfd, name);
262133965Sjdp  if (newsect == NULL)
2622130563Sobrien    return FALSE;
262333965Sjdp  newsect->vma = hdr->p_vaddr;
262433965Sjdp  newsect->lma = hdr->p_paddr;
2625218822Sdim  newsect->size = hdr->p_filesz;
262633965Sjdp  newsect->filepos = hdr->p_offset;
262733965Sjdp  newsect->flags |= SEC_HAS_CONTENTS;
2628130563Sobrien  newsect->alignment_power = bfd_log2 (hdr->p_align);
262933965Sjdp  if (hdr->p_type == PT_LOAD)
263033965Sjdp    {
263133965Sjdp      newsect->flags |= SEC_ALLOC;
263233965Sjdp      newsect->flags |= SEC_LOAD;
263333965Sjdp      if (hdr->p_flags & PF_X)
263433965Sjdp	{
263533965Sjdp	  /* FIXME: all we known is that it has execute PERMISSION,
263677301Sobrien	     may be data.  */
263733965Sjdp	  newsect->flags |= SEC_CODE;
263833965Sjdp	}
263933965Sjdp    }
264033965Sjdp  if (!(hdr->p_flags & PF_W))
264133965Sjdp    {
264233965Sjdp      newsect->flags |= SEC_READONLY;
264333965Sjdp    }
264433965Sjdp
264533965Sjdp  if (split)
264633965Sjdp    {
264760508Sobrien      sprintf (namebuf, "%s%db", typename, index);
2648104838Sobrien      len = strlen (namebuf) + 1;
2649130563Sobrien      name = bfd_alloc (abfd, len);
265033965Sjdp      if (!name)
2651130563Sobrien	return FALSE;
2652104838Sobrien      memcpy (name, namebuf, len);
265333965Sjdp      newsect = bfd_make_section (abfd, name);
265433965Sjdp      if (newsect == NULL)
2655130563Sobrien	return FALSE;
265633965Sjdp      newsect->vma = hdr->p_vaddr + hdr->p_filesz;
265733965Sjdp      newsect->lma = hdr->p_paddr + hdr->p_filesz;
2658218822Sdim      newsect->size = hdr->p_memsz - hdr->p_filesz;
265933965Sjdp      if (hdr->p_type == PT_LOAD)
266033965Sjdp	{
266133965Sjdp	  newsect->flags |= SEC_ALLOC;
266233965Sjdp	  if (hdr->p_flags & PF_X)
266333965Sjdp	    newsect->flags |= SEC_CODE;
266433965Sjdp	}
266533965Sjdp      if (!(hdr->p_flags & PF_W))
266633965Sjdp	newsect->flags |= SEC_READONLY;
266733965Sjdp    }
266833965Sjdp
2669130563Sobrien  return TRUE;
267033965Sjdp}
267133965Sjdp
2672130563Sobrienbfd_boolean
2673130563Sobrienbfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int index)
267460508Sobrien{
2675130563Sobrien  const struct elf_backend_data *bed;
267660508Sobrien
267760508Sobrien  switch (hdr->p_type)
267860508Sobrien    {
267960508Sobrien    case PT_NULL:
268060508Sobrien      return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "null");
268160508Sobrien
268260508Sobrien    case PT_LOAD:
268360508Sobrien      return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "load");
268460508Sobrien
268560508Sobrien    case PT_DYNAMIC:
268660508Sobrien      return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "dynamic");
268760508Sobrien
268860508Sobrien    case PT_INTERP:
268960508Sobrien      return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "interp");
269060508Sobrien
269160508Sobrien    case PT_NOTE:
269260508Sobrien      if (! _bfd_elf_make_section_from_phdr (abfd, hdr, index, "note"))
2693130563Sobrien	return FALSE;
2694130563Sobrien      if (! elfcore_read_notes (abfd, hdr->p_offset, hdr->p_filesz))
2695130563Sobrien	return FALSE;
2696130563Sobrien      return TRUE;
269760508Sobrien
269860508Sobrien    case PT_SHLIB:
269960508Sobrien      return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "shlib");
270060508Sobrien
270160508Sobrien    case PT_PHDR:
270260508Sobrien      return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "phdr");
270360508Sobrien
2704130563Sobrien    case PT_GNU_EH_FRAME:
2705130563Sobrien      return _bfd_elf_make_section_from_phdr (abfd, hdr, index,
2706130563Sobrien					      "eh_frame_hdr");
2707130563Sobrien
2708130563Sobrien    case PT_GNU_STACK:
2709130563Sobrien      return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "stack");
2710130563Sobrien
2711218822Sdim    case PT_GNU_RELRO:
2712218822Sdim      return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "relro");
2713218822Sdim
271460508Sobrien    default:
2715218822Sdim      /* Check for any processor-specific program segment types.  */
271660508Sobrien      bed = get_elf_backend_data (abfd);
2717218822Sdim      return bed->elf_backend_section_from_phdr (abfd, hdr, index, "proc");
271860508Sobrien    }
271960508Sobrien}
272060508Sobrien
272160508Sobrien/* Initialize REL_HDR, the section-header for new section, containing
2722130563Sobrien   relocations against ASECT.  If USE_RELA_P is TRUE, we use RELA
272360508Sobrien   relocations; otherwise, we use REL relocations.  */
272460508Sobrien
2725130563Sobrienbfd_boolean
2726130563Sobrien_bfd_elf_init_reloc_shdr (bfd *abfd,
2727130563Sobrien			  Elf_Internal_Shdr *rel_hdr,
2728130563Sobrien			  asection *asect,
2729130563Sobrien			  bfd_boolean use_rela_p)
273060508Sobrien{
273160508Sobrien  char *name;
2732130563Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
273389860Sobrien  bfd_size_type amt = sizeof ".rela" + strlen (asect->name);
273460508Sobrien
273589860Sobrien  name = bfd_alloc (abfd, amt);
273660508Sobrien  if (name == NULL)
2737130563Sobrien    return FALSE;
273860508Sobrien  sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", asect->name);
273960508Sobrien  rel_hdr->sh_name =
274089860Sobrien    (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), name,
2741130563Sobrien					FALSE);
274260508Sobrien  if (rel_hdr->sh_name == (unsigned int) -1)
2743130563Sobrien    return FALSE;
274460508Sobrien  rel_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL;
274560508Sobrien  rel_hdr->sh_entsize = (use_rela_p
274660508Sobrien			 ? bed->s->sizeof_rela
274760508Sobrien			 : bed->s->sizeof_rel);
2748130563Sobrien  rel_hdr->sh_addralign = 1 << bed->s->log_file_align;
274960508Sobrien  rel_hdr->sh_flags = 0;
275060508Sobrien  rel_hdr->sh_addr = 0;
275160508Sobrien  rel_hdr->sh_size = 0;
275260508Sobrien  rel_hdr->sh_offset = 0;
275360508Sobrien
2754130563Sobrien  return TRUE;
275560508Sobrien}
275660508Sobrien
275733965Sjdp/* Set up an ELF internal section header for a section.  */
275833965Sjdp
275933965Sjdpstatic void
2760130563Sobrienelf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
276133965Sjdp{
2762130563Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
2763130563Sobrien  bfd_boolean *failedptr = failedptrarg;
276433965Sjdp  Elf_Internal_Shdr *this_hdr;
2765218822Sdim  unsigned int sh_type;
276633965Sjdp
276733965Sjdp  if (*failedptr)
276833965Sjdp    {
276933965Sjdp      /* We already failed; just get out of the bfd_map_over_sections
2770218822Sdim	 loop.  */
277133965Sjdp      return;
277233965Sjdp    }
277333965Sjdp
277433965Sjdp  this_hdr = &elf_section_data (asect)->this_hdr;
277533965Sjdp
2776130563Sobrien  this_hdr->sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
2777130563Sobrien							  asect->name, FALSE);
2778130563Sobrien  if (this_hdr->sh_name == (unsigned int) -1)
277933965Sjdp    {
2780130563Sobrien      *failedptr = TRUE;
278133965Sjdp      return;
278233965Sjdp    }
278333965Sjdp
2784218822Sdim  /* Don't clear sh_flags. Assembler may set additional bits.  */
278533965Sjdp
278633965Sjdp  if ((asect->flags & SEC_ALLOC) != 0
278733965Sjdp      || asect->user_set_vma)
278833965Sjdp    this_hdr->sh_addr = asect->vma;
278933965Sjdp  else
279033965Sjdp    this_hdr->sh_addr = 0;
279133965Sjdp
279233965Sjdp  this_hdr->sh_offset = 0;
2793218822Sdim  this_hdr->sh_size = asect->size;
279433965Sjdp  this_hdr->sh_link = 0;
279533965Sjdp  this_hdr->sh_addralign = 1 << asect->alignment_power;
279633965Sjdp  /* The sh_entsize and sh_info fields may have been set already by
279733965Sjdp     copy_private_section_data.  */
279833965Sjdp
279933965Sjdp  this_hdr->bfd_section = asect;
280033965Sjdp  this_hdr->contents = NULL;
280133965Sjdp
2802130563Sobrien  /* If the section type is unspecified, we set it based on
2803130563Sobrien     asect->flags.  */
2804130563Sobrien  if (this_hdr->sh_type == SHT_NULL)
280533965Sjdp    {
2806218822Sdim      if ((asect->flags & SEC_GROUP) != 0)
2807218822Sdim	this_hdr->sh_type = SHT_GROUP;
2808218822Sdim      else if ((asect->flags & SEC_ALLOC) != 0
2809218822Sdim	       && (((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
2810218822Sdim		   || (asect->flags & SEC_NEVER_LOAD) != 0))
2811130563Sobrien	this_hdr->sh_type = SHT_NOBITS;
2812130563Sobrien      else
2813130563Sobrien	this_hdr->sh_type = SHT_PROGBITS;
281433965Sjdp    }
2815130563Sobrien
2816130563Sobrien  switch (this_hdr->sh_type)
281733965Sjdp    {
2818130563Sobrien    default:
2819130563Sobrien      break;
2820130563Sobrien
2821130563Sobrien    case SHT_STRTAB:
2822130563Sobrien    case SHT_INIT_ARRAY:
2823130563Sobrien    case SHT_FINI_ARRAY:
2824130563Sobrien    case SHT_PREINIT_ARRAY:
2825130563Sobrien    case SHT_NOTE:
2826130563Sobrien    case SHT_NOBITS:
2827130563Sobrien    case SHT_PROGBITS:
2828130563Sobrien      break;
2829130563Sobrien
2830130563Sobrien    case SHT_HASH:
2831130563Sobrien      this_hdr->sh_entsize = bed->s->sizeof_hash_entry;
2832130563Sobrien      break;
2833130563Sobrien
2834130563Sobrien    case SHT_DYNSYM:
283533965Sjdp      this_hdr->sh_entsize = bed->s->sizeof_sym;
2836130563Sobrien      break;
2837130563Sobrien
2838130563Sobrien    case SHT_DYNAMIC:
283933965Sjdp      this_hdr->sh_entsize = bed->s->sizeof_dyn;
2840130563Sobrien      break;
2841130563Sobrien
2842130563Sobrien    case SHT_RELA:
2843130563Sobrien      if (get_elf_backend_data (abfd)->may_use_rela_p)
2844130563Sobrien	this_hdr->sh_entsize = bed->s->sizeof_rela;
2845130563Sobrien      break;
2846130563Sobrien
2847130563Sobrien     case SHT_REL:
2848130563Sobrien      if (get_elf_backend_data (abfd)->may_use_rel_p)
2849130563Sobrien	this_hdr->sh_entsize = bed->s->sizeof_rel;
2850130563Sobrien      break;
2851130563Sobrien
2852130563Sobrien     case SHT_GNU_versym:
285333965Sjdp      this_hdr->sh_entsize = sizeof (Elf_External_Versym);
2854130563Sobrien      break;
2855130563Sobrien
2856130563Sobrien     case SHT_GNU_verdef:
285733965Sjdp      this_hdr->sh_entsize = 0;
285833965Sjdp      /* objcopy or strip will copy over sh_info, but may not set
2859218822Sdim	 cverdefs.  The linker will set cverdefs, but sh_info will be
2860218822Sdim	 zero.  */
286133965Sjdp      if (this_hdr->sh_info == 0)
286233965Sjdp	this_hdr->sh_info = elf_tdata (abfd)->cverdefs;
286333965Sjdp      else
286433965Sjdp	BFD_ASSERT (elf_tdata (abfd)->cverdefs == 0
286533965Sjdp		    || this_hdr->sh_info == elf_tdata (abfd)->cverdefs);
2866130563Sobrien      break;
2867130563Sobrien
2868130563Sobrien    case SHT_GNU_verneed:
286933965Sjdp      this_hdr->sh_entsize = 0;
287033965Sjdp      /* objcopy or strip will copy over sh_info, but may not set
2871218822Sdim	 cverrefs.  The linker will set cverrefs, but sh_info will be
2872218822Sdim	 zero.  */
287333965Sjdp      if (this_hdr->sh_info == 0)
287433965Sjdp	this_hdr->sh_info = elf_tdata (abfd)->cverrefs;
287533965Sjdp      else
287633965Sjdp	BFD_ASSERT (elf_tdata (abfd)->cverrefs == 0
287733965Sjdp		    || this_hdr->sh_info == elf_tdata (abfd)->cverrefs);
2878130563Sobrien      break;
2879130563Sobrien
2880130563Sobrien    case SHT_GROUP:
2881218822Sdim      this_hdr->sh_entsize = GRP_ENTRY_SIZE;
2882130563Sobrien      break;
2883218822Sdim
2884218822Sdim    case SHT_GNU_HASH:
2885218822Sdim      this_hdr->sh_entsize = bed->s->arch_size == 64 ? 0 : 4;
2886218822Sdim      break;
288789860Sobrien    }
288833965Sjdp
288933965Sjdp  if ((asect->flags & SEC_ALLOC) != 0)
289033965Sjdp    this_hdr->sh_flags |= SHF_ALLOC;
289133965Sjdp  if ((asect->flags & SEC_READONLY) == 0)
289233965Sjdp    this_hdr->sh_flags |= SHF_WRITE;
289333965Sjdp  if ((asect->flags & SEC_CODE) != 0)
289433965Sjdp    this_hdr->sh_flags |= SHF_EXECINSTR;
289589860Sobrien  if ((asect->flags & SEC_MERGE) != 0)
289689860Sobrien    {
289789860Sobrien      this_hdr->sh_flags |= SHF_MERGE;
289889860Sobrien      this_hdr->sh_entsize = asect->entsize;
289989860Sobrien      if ((asect->flags & SEC_STRINGS) != 0)
290089860Sobrien	this_hdr->sh_flags |= SHF_STRINGS;
290189860Sobrien    }
2902104838Sobrien  if ((asect->flags & SEC_GROUP) == 0 && elf_group_name (asect) != NULL)
290389860Sobrien    this_hdr->sh_flags |= SHF_GROUP;
2904104838Sobrien  if ((asect->flags & SEC_THREAD_LOCAL) != 0)
2905104838Sobrien    {
2906104838Sobrien      this_hdr->sh_flags |= SHF_TLS;
2907218822Sdim      if (asect->size == 0
2908218822Sdim	  && (asect->flags & SEC_HAS_CONTENTS) == 0)
2909104838Sobrien	{
2910218822Sdim	  struct bfd_link_order *o = asect->map_tail.link_order;
2911130563Sobrien
2912104838Sobrien	  this_hdr->sh_size = 0;
2913218822Sdim	  if (o != NULL)
2914218822Sdim	    {
2915104838Sobrien	      this_hdr->sh_size = o->offset + o->size;
2916218822Sdim	      if (this_hdr->sh_size != 0)
2917218822Sdim		this_hdr->sh_type = SHT_NOBITS;
2918218822Sdim	    }
2919104838Sobrien	}
2920104838Sobrien    }
292133965Sjdp
292233965Sjdp  /* Check for processor-specific section types.  */
2923218822Sdim  sh_type = this_hdr->sh_type;
292489860Sobrien  if (bed->elf_backend_fake_sections
292589860Sobrien      && !(*bed->elf_backend_fake_sections) (abfd, this_hdr, asect))
2926130563Sobrien    *failedptr = TRUE;
292733965Sjdp
2928218822Sdim  if (sh_type == SHT_NOBITS && asect->size != 0)
2929218822Sdim    {
2930218822Sdim      /* Don't change the header type from NOBITS if we are being
2931218822Sdim	 called for objcopy --only-keep-debug.  */
2932218822Sdim      this_hdr->sh_type = sh_type;
2933218822Sdim    }
2934218822Sdim
293533965Sjdp  /* If the section has relocs, set up a section header for the
293660508Sobrien     SHT_REL[A] section.  If two relocation sections are required for
293760508Sobrien     this section, it is up to the processor-specific back-end to
293877301Sobrien     create the other.  */
293960508Sobrien  if ((asect->flags & SEC_RELOC) != 0
294077301Sobrien      && !_bfd_elf_init_reloc_shdr (abfd,
294160508Sobrien				    &elf_section_data (asect)->rel_hdr,
294277301Sobrien				    asect,
2943130563Sobrien				    asect->use_rela_p))
2944130563Sobrien    *failedptr = TRUE;
294533965Sjdp}
294633965Sjdp
294789860Sobrien/* Fill in the contents of a SHT_GROUP section.  */
294889860Sobrien
2949104838Sobrienvoid
2950130563Sobrienbfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
295189860Sobrien{
2952130563Sobrien  bfd_boolean *failedptr = failedptrarg;
295389860Sobrien  unsigned long symindx;
2954104838Sobrien  asection *elt, *first;
295589860Sobrien  unsigned char *loc;
2956130563Sobrien  bfd_boolean gas;
295789860Sobrien
2958218822Sdim  /* Ignore linker created group section.  See elfNN_ia64_object_p in
2959218822Sdim     elfxx-ia64.c.  */
2960218822Sdim  if (((sec->flags & (SEC_GROUP | SEC_LINKER_CREATED)) != SEC_GROUP)
296189860Sobrien      || *failedptr)
296289860Sobrien    return;
296389860Sobrien
2964104838Sobrien  symindx = 0;
2965104838Sobrien  if (elf_group_id (sec) != NULL)
2966104838Sobrien    symindx = elf_group_id (sec)->udata.i;
2967104838Sobrien
2968104838Sobrien  if (symindx == 0)
2969104838Sobrien    {
2970104838Sobrien      /* If called from the assembler, swap_out_syms will have set up
2971104838Sobrien	 elf_section_syms;  If called for "ld -r", use target_index.  */
2972104838Sobrien      if (elf_section_syms (abfd) != NULL)
2973104838Sobrien	symindx = elf_section_syms (abfd)[sec->index]->udata.i;
2974104838Sobrien      else
2975104838Sobrien	symindx = sec->target_index;
2976104838Sobrien    }
297789860Sobrien  elf_section_data (sec)->this_hdr.sh_info = symindx;
297889860Sobrien
2979104838Sobrien  /* The contents won't be allocated for "ld -r" or objcopy.  */
2980130563Sobrien  gas = TRUE;
298189860Sobrien  if (sec->contents == NULL)
298289860Sobrien    {
2983130563Sobrien      gas = FALSE;
2984218822Sdim      sec->contents = bfd_alloc (abfd, sec->size);
2985104838Sobrien
2986104838Sobrien      /* Arrange for the section to be written out.  */
2987104838Sobrien      elf_section_data (sec)->this_hdr.contents = sec->contents;
298889860Sobrien      if (sec->contents == NULL)
298989860Sobrien	{
2990130563Sobrien	  *failedptr = TRUE;
299189860Sobrien	  return;
299289860Sobrien	}
299389860Sobrien    }
299489860Sobrien
2995218822Sdim  loc = sec->contents + sec->size;
299689860Sobrien
2997104838Sobrien  /* Get the pointer to the first section in the group that gas
2998104838Sobrien     squirreled away here.  objcopy arranges for this to be set to the
2999104838Sobrien     start of the input section group.  */
3000104838Sobrien  first = elt = elf_next_in_group (sec);
300189860Sobrien
300289860Sobrien  /* First element is a flag word.  Rest of section is elf section
300389860Sobrien     indices for all the sections of the group.  Write them backwards
300489860Sobrien     just to keep the group in the same order as given in .section
300589860Sobrien     directives, not that it matters.  */
300689860Sobrien  while (elt != NULL)
300789860Sobrien    {
3008104838Sobrien      asection *s;
3009104838Sobrien      unsigned int idx;
3010104838Sobrien
301189860Sobrien      loc -= 4;
3012104838Sobrien      s = elt;
3013104838Sobrien      if (!gas)
3014104838Sobrien	s = s->output_section;
3015104838Sobrien      idx = 0;
3016104838Sobrien      if (s != NULL)
3017104838Sobrien	idx = elf_section_data (s)->this_idx;
3018104838Sobrien      H_PUT_32 (abfd, idx, loc);
301989860Sobrien      elt = elf_next_in_group (elt);
3020104838Sobrien      if (elt == first)
3021104838Sobrien	break;
302289860Sobrien    }
302389860Sobrien
3024218822Sdim  if ((loc -= 4) != sec->contents)
3025104838Sobrien    abort ();
3026104838Sobrien
3027104838Sobrien  H_PUT_32 (abfd, sec->flags & SEC_LINK_ONCE ? GRP_COMDAT : 0, loc);
302889860Sobrien}
302989860Sobrien
303033965Sjdp/* Assign all ELF section numbers.  The dummy first section is handled here
303133965Sjdp   too.  The link/info pointers for the standard section types are filled
303233965Sjdp   in here too, while we're at it.  */
303333965Sjdp
3034130563Sobrienstatic bfd_boolean
3035218822Sdimassign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
303633965Sjdp{
303733965Sjdp  struct elf_obj_tdata *t = elf_tdata (abfd);
303833965Sjdp  asection *sec;
303989860Sobrien  unsigned int section_number, secn;
304033965Sjdp  Elf_Internal_Shdr **i_shdrp;
3041218822Sdim  struct bfd_elf_section_data *d;
304233965Sjdp
304333965Sjdp  section_number = 1;
304433965Sjdp
304589860Sobrien  _bfd_elf_strtab_clear_all_refs (elf_shstrtab (abfd));
304689860Sobrien
3047218822Sdim  /* SHT_GROUP sections are in relocatable files only.  */
3048218822Sdim  if (link_info == NULL || link_info->relocatable)
3049218822Sdim    {
3050218822Sdim      /* Put SHT_GROUP sections first.  */
3051218822Sdim      for (sec = abfd->sections; sec != NULL; sec = sec->next)
3052218822Sdim	{
3053218822Sdim	  d = elf_section_data (sec);
3054218822Sdim
3055218822Sdim	  if (d->this_hdr.sh_type == SHT_GROUP)
3056218822Sdim	    {
3057218822Sdim	      if (sec->flags & SEC_LINKER_CREATED)
3058218822Sdim		{
3059218822Sdim		  /* Remove the linker created SHT_GROUP sections.  */
3060218822Sdim		  bfd_section_list_remove (abfd, sec);
3061218822Sdim		  abfd->section_count--;
3062218822Sdim		}
3063218822Sdim	      else
3064218822Sdim		{
3065218822Sdim		  if (section_number == SHN_LORESERVE)
3066218822Sdim		    section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
3067218822Sdim		  d->this_idx = section_number++;
3068218822Sdim		}
3069218822Sdim	    }
3070218822Sdim	}
3071218822Sdim    }
3072218822Sdim
307333965Sjdp  for (sec = abfd->sections; sec; sec = sec->next)
307433965Sjdp    {
3075218822Sdim      d = elf_section_data (sec);
307633965Sjdp
3077218822Sdim      if (d->this_hdr.sh_type != SHT_GROUP)
3078218822Sdim	{
3079218822Sdim	  if (section_number == SHN_LORESERVE)
3080218822Sdim	    section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
3081218822Sdim	  d->this_idx = section_number++;
3082218822Sdim	}
308389860Sobrien      _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name);
308433965Sjdp      if ((sec->flags & SEC_RELOC) == 0)
308533965Sjdp	d->rel_idx = 0;
308633965Sjdp      else
308789860Sobrien	{
308889860Sobrien	  if (section_number == SHN_LORESERVE)
308989860Sobrien	    section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
309089860Sobrien	  d->rel_idx = section_number++;
309189860Sobrien	  _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr.sh_name);
309289860Sobrien	}
309360508Sobrien
309460508Sobrien      if (d->rel_hdr2)
309589860Sobrien	{
309689860Sobrien	  if (section_number == SHN_LORESERVE)
309789860Sobrien	    section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
309889860Sobrien	  d->rel_idx2 = section_number++;
309989860Sobrien	  _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr2->sh_name);
310089860Sobrien	}
310160508Sobrien      else
310260508Sobrien	d->rel_idx2 = 0;
310333965Sjdp    }
310433965Sjdp
310589860Sobrien  if (section_number == SHN_LORESERVE)
310689860Sobrien    section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
310733965Sjdp  t->shstrtab_section = section_number++;
310889860Sobrien  _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name);
310933965Sjdp  elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section;
311033965Sjdp
311160508Sobrien  if (bfd_get_symcount (abfd) > 0)
311233965Sjdp    {
311389860Sobrien      if (section_number == SHN_LORESERVE)
311489860Sobrien	section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
311533965Sjdp      t->symtab_section = section_number++;
311689860Sobrien      _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name);
311789860Sobrien      if (section_number > SHN_LORESERVE - 2)
311889860Sobrien	{
311989860Sobrien	  if (section_number == SHN_LORESERVE)
312089860Sobrien	    section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
312189860Sobrien	  t->symtab_shndx_section = section_number++;
312289860Sobrien	  t->symtab_shndx_hdr.sh_name
312389860Sobrien	    = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
3124130563Sobrien						  ".symtab_shndx", FALSE);
312589860Sobrien	  if (t->symtab_shndx_hdr.sh_name == (unsigned int) -1)
3126130563Sobrien	    return FALSE;
312789860Sobrien	}
312889860Sobrien      if (section_number == SHN_LORESERVE)
312989860Sobrien	section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
313033965Sjdp      t->strtab_section = section_number++;
313189860Sobrien      _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name);
313233965Sjdp    }
313333965Sjdp
313489860Sobrien  _bfd_elf_strtab_finalize (elf_shstrtab (abfd));
313589860Sobrien  t->shstrtab_hdr.sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
313689860Sobrien
313789860Sobrien  elf_numsections (abfd) = section_number;
313833965Sjdp  elf_elfheader (abfd)->e_shnum = section_number;
313989860Sobrien  if (section_number > SHN_LORESERVE)
314089860Sobrien    elf_elfheader (abfd)->e_shnum -= SHN_HIRESERVE + 1 - SHN_LORESERVE;
314133965Sjdp
314233965Sjdp  /* Set up the list of section header pointers, in agreement with the
314333965Sjdp     indices.  */
3144218822Sdim  i_shdrp = bfd_zalloc2 (abfd, section_number, sizeof (Elf_Internal_Shdr *));
314533965Sjdp  if (i_shdrp == NULL)
3146130563Sobrien    return FALSE;
314733965Sjdp
3148218822Sdim  i_shdrp[0] = bfd_zalloc (abfd, sizeof (Elf_Internal_Shdr));
314933965Sjdp  if (i_shdrp[0] == NULL)
315033965Sjdp    {
315133965Sjdp      bfd_release (abfd, i_shdrp);
3152130563Sobrien      return FALSE;
315333965Sjdp    }
315433965Sjdp
315533965Sjdp  elf_elfsections (abfd) = i_shdrp;
315633965Sjdp
315733965Sjdp  i_shdrp[t->shstrtab_section] = &t->shstrtab_hdr;
315860508Sobrien  if (bfd_get_symcount (abfd) > 0)
315933965Sjdp    {
316033965Sjdp      i_shdrp[t->symtab_section] = &t->symtab_hdr;
316189860Sobrien      if (elf_numsections (abfd) > SHN_LORESERVE)
316289860Sobrien	{
316389860Sobrien	  i_shdrp[t->symtab_shndx_section] = &t->symtab_shndx_hdr;
316489860Sobrien	  t->symtab_shndx_hdr.sh_link = t->symtab_section;
316589860Sobrien	}
316633965Sjdp      i_shdrp[t->strtab_section] = &t->strtab_hdr;
316733965Sjdp      t->symtab_hdr.sh_link = t->strtab_section;
316833965Sjdp    }
3169218822Sdim
317033965Sjdp  for (sec = abfd->sections; sec; sec = sec->next)
317133965Sjdp    {
317233965Sjdp      struct bfd_elf_section_data *d = elf_section_data (sec);
317333965Sjdp      asection *s;
317433965Sjdp      const char *name;
317533965Sjdp
317633965Sjdp      i_shdrp[d->this_idx] = &d->this_hdr;
317733965Sjdp      if (d->rel_idx != 0)
317833965Sjdp	i_shdrp[d->rel_idx] = &d->rel_hdr;
317960508Sobrien      if (d->rel_idx2 != 0)
318060508Sobrien	i_shdrp[d->rel_idx2] = d->rel_hdr2;
318133965Sjdp
318233965Sjdp      /* Fill in the sh_link and sh_info fields while we're at it.  */
318333965Sjdp
318433965Sjdp      /* sh_link of a reloc section is the section index of the symbol
318533965Sjdp	 table.  sh_info is the section index of the section to which
318633965Sjdp	 the relocation entries apply.  */
318733965Sjdp      if (d->rel_idx != 0)
318833965Sjdp	{
318933965Sjdp	  d->rel_hdr.sh_link = t->symtab_section;
319033965Sjdp	  d->rel_hdr.sh_info = d->this_idx;
319133965Sjdp	}
319260508Sobrien      if (d->rel_idx2 != 0)
319360508Sobrien	{
319460508Sobrien	  d->rel_hdr2->sh_link = t->symtab_section;
319560508Sobrien	  d->rel_hdr2->sh_info = d->this_idx;
319660508Sobrien	}
319733965Sjdp
3198218822Sdim      /* We need to set up sh_link for SHF_LINK_ORDER.  */
3199218822Sdim      if ((d->this_hdr.sh_flags & SHF_LINK_ORDER) != 0)
3200218822Sdim	{
3201218822Sdim	  s = elf_linked_to_section (sec);
3202218822Sdim	  if (s)
3203218822Sdim	    {
3204218822Sdim	      /* elf_linked_to_section points to the input section.  */
3205218822Sdim	      if (link_info != NULL)
3206218822Sdim		{
3207218822Sdim		  /* Check discarded linkonce section.  */
3208218822Sdim		  if (elf_discarded_section (s))
3209218822Sdim		    {
3210218822Sdim		      asection *kept;
3211218822Sdim		      (*_bfd_error_handler)
3212218822Sdim			(_("%B: sh_link of section `%A' points to discarded section `%A' of `%B'"),
3213218822Sdim			 abfd, d->this_hdr.bfd_section,
3214218822Sdim			 s, s->owner);
3215218822Sdim		      /* Point to the kept section if it has the same
3216218822Sdim			 size as the discarded one.  */
3217218822Sdim		      kept = _bfd_elf_check_kept_section (s, link_info);
3218218822Sdim		      if (kept == NULL)
3219218822Sdim			{
3220218822Sdim			  bfd_set_error (bfd_error_bad_value);
3221218822Sdim			  return FALSE;
3222218822Sdim			}
3223218822Sdim		      s = kept;
3224218822Sdim		    }
3225218822Sdim
3226218822Sdim		  s = s->output_section;
3227218822Sdim		  BFD_ASSERT (s != NULL);
3228218822Sdim		}
3229218822Sdim	      else
3230218822Sdim		{
3231218822Sdim		  /* Handle objcopy. */
3232218822Sdim		  if (s->output_section == NULL)
3233218822Sdim		    {
3234218822Sdim		      (*_bfd_error_handler)
3235218822Sdim			(_("%B: sh_link of section `%A' points to removed section `%A' of `%B'"),
3236218822Sdim			 abfd, d->this_hdr.bfd_section, s, s->owner);
3237218822Sdim		      bfd_set_error (bfd_error_bad_value);
3238218822Sdim		      return FALSE;
3239218822Sdim		    }
3240218822Sdim		  s = s->output_section;
3241218822Sdim		}
3242218822Sdim	      d->this_hdr.sh_link = elf_section_data (s)->this_idx;
3243218822Sdim	    }
3244218822Sdim	  else
3245218822Sdim	    {
3246218822Sdim	      /* PR 290:
3247218822Sdim		 The Intel C compiler generates SHT_IA_64_UNWIND with
3248218822Sdim		 SHF_LINK_ORDER.  But it doesn't set the sh_link or
3249218822Sdim		 sh_info fields.  Hence we could get the situation
3250218822Sdim		 where s is NULL.  */
3251218822Sdim	      const struct elf_backend_data *bed
3252218822Sdim		= get_elf_backend_data (abfd);
3253218822Sdim	      if (bed->link_order_error_handler)
3254218822Sdim		bed->link_order_error_handler
3255218822Sdim		  (_("%B: warning: sh_link not set for section `%A'"),
3256218822Sdim		   abfd, sec);
3257218822Sdim	    }
3258218822Sdim	}
3259218822Sdim
326033965Sjdp      switch (d->this_hdr.sh_type)
326133965Sjdp	{
326233965Sjdp	case SHT_REL:
326333965Sjdp	case SHT_RELA:
326433965Sjdp	  /* A reloc section which we are treating as a normal BFD
326533965Sjdp	     section.  sh_link is the section index of the symbol
326633965Sjdp	     table.  sh_info is the section index of the section to
326733965Sjdp	     which the relocation entries apply.  We assume that an
326833965Sjdp	     allocated reloc section uses the dynamic symbol table.
326933965Sjdp	     FIXME: How can we be sure?  */
327033965Sjdp	  s = bfd_get_section_by_name (abfd, ".dynsym");
327133965Sjdp	  if (s != NULL)
327233965Sjdp	    d->this_hdr.sh_link = elf_section_data (s)->this_idx;
327333965Sjdp
327433965Sjdp	  /* We look up the section the relocs apply to by name.  */
327533965Sjdp	  name = sec->name;
327633965Sjdp	  if (d->this_hdr.sh_type == SHT_REL)
327733965Sjdp	    name += 4;
327833965Sjdp	  else
327933965Sjdp	    name += 5;
328033965Sjdp	  s = bfd_get_section_by_name (abfd, name);
328133965Sjdp	  if (s != NULL)
328233965Sjdp	    d->this_hdr.sh_info = elf_section_data (s)->this_idx;
328333965Sjdp	  break;
328433965Sjdp
328533965Sjdp	case SHT_STRTAB:
328633965Sjdp	  /* We assume that a section named .stab*str is a stabs
328733965Sjdp	     string section.  We look for a section with the same name
328833965Sjdp	     but without the trailing ``str'', and set its sh_link
328933965Sjdp	     field to point to this section.  */
3290218822Sdim	  if (CONST_STRNEQ (sec->name, ".stab")
329133965Sjdp	      && strcmp (sec->name + strlen (sec->name) - 3, "str") == 0)
329233965Sjdp	    {
329333965Sjdp	      size_t len;
329433965Sjdp	      char *alc;
329533965Sjdp
329633965Sjdp	      len = strlen (sec->name);
3297130563Sobrien	      alc = bfd_malloc (len - 2);
329833965Sjdp	      if (alc == NULL)
3299130563Sobrien		return FALSE;
3300104838Sobrien	      memcpy (alc, sec->name, len - 3);
330133965Sjdp	      alc[len - 3] = '\0';
330233965Sjdp	      s = bfd_get_section_by_name (abfd, alc);
330333965Sjdp	      free (alc);
330433965Sjdp	      if (s != NULL)
330533965Sjdp		{
330633965Sjdp		  elf_section_data (s)->this_hdr.sh_link = d->this_idx;
330733965Sjdp
330833965Sjdp		  /* This is a .stab section.  */
3309104838Sobrien		  if (elf_section_data (s)->this_hdr.sh_entsize == 0)
3310104838Sobrien		    elf_section_data (s)->this_hdr.sh_entsize
3311104838Sobrien		      = 4 + 2 * bfd_get_arch_size (abfd) / 8;
331233965Sjdp		}
331333965Sjdp	    }
331433965Sjdp	  break;
331533965Sjdp
331633965Sjdp	case SHT_DYNAMIC:
331733965Sjdp	case SHT_DYNSYM:
331833965Sjdp	case SHT_GNU_verneed:
331933965Sjdp	case SHT_GNU_verdef:
332033965Sjdp	  /* sh_link is the section header index of the string table
332133965Sjdp	     used for the dynamic entries, or the symbol table, or the
332233965Sjdp	     version strings.  */
332333965Sjdp	  s = bfd_get_section_by_name (abfd, ".dynstr");
332433965Sjdp	  if (s != NULL)
332533965Sjdp	    d->this_hdr.sh_link = elf_section_data (s)->this_idx;
332633965Sjdp	  break;
332733965Sjdp
3328218822Sdim	case SHT_GNU_LIBLIST:
3329218822Sdim	  /* sh_link is the section header index of the prelink library
3330218822Sdim	     list used for the dynamic entries, or the symbol table, or
3331218822Sdim	     the version strings.  */
3332218822Sdim	  s = bfd_get_section_by_name (abfd, (sec->flags & SEC_ALLOC)
3333218822Sdim					     ? ".dynstr" : ".gnu.libstr");
3334218822Sdim	  if (s != NULL)
3335218822Sdim	    d->this_hdr.sh_link = elf_section_data (s)->this_idx;
3336218822Sdim	  break;
3337218822Sdim
333833965Sjdp	case SHT_HASH:
3339218822Sdim	case SHT_GNU_HASH:
334033965Sjdp	case SHT_GNU_versym:
334133965Sjdp	  /* sh_link is the section header index of the symbol table
334233965Sjdp	     this hash table or version table is for.  */
334333965Sjdp	  s = bfd_get_section_by_name (abfd, ".dynsym");
334433965Sjdp	  if (s != NULL)
334533965Sjdp	    d->this_hdr.sh_link = elf_section_data (s)->this_idx;
334633965Sjdp	  break;
334789860Sobrien
334889860Sobrien	case SHT_GROUP:
334989860Sobrien	  d->this_hdr.sh_link = t->symtab_section;
335033965Sjdp	}
335133965Sjdp    }
335233965Sjdp
335389860Sobrien  for (secn = 1; secn < section_number; ++secn)
335489860Sobrien    if (i_shdrp[secn] == NULL)
335589860Sobrien      i_shdrp[secn] = i_shdrp[0];
335689860Sobrien    else
335789860Sobrien      i_shdrp[secn]->sh_name = _bfd_elf_strtab_offset (elf_shstrtab (abfd),
335889860Sobrien						       i_shdrp[secn]->sh_name);
3359130563Sobrien  return TRUE;
336033965Sjdp}
336133965Sjdp
336233965Sjdp/* Map symbol from it's internal number to the external number, moving
336333965Sjdp   all local symbols to be at the head of the list.  */
336433965Sjdp
3365218822Sdimstatic bfd_boolean
3366130563Sobriensym_is_global (bfd *abfd, asymbol *sym)
336733965Sjdp{
336833965Sjdp  /* If the backend has a special mapping, use it.  */
3369130563Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
3370130563Sobrien  if (bed->elf_backend_sym_is_global)
3371130563Sobrien    return (*bed->elf_backend_sym_is_global) (abfd, sym);
337233965Sjdp
337333965Sjdp  return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
337433965Sjdp	  || bfd_is_und_section (bfd_get_section (sym))
337533965Sjdp	  || bfd_is_com_section (bfd_get_section (sym)));
337633965Sjdp}
337733965Sjdp
3378218822Sdim/* Don't output section symbols for sections that are not going to be
3379218822Sdim   output.  Also, don't output section symbols for reloc and other
3380218822Sdim   special sections.  */
3381218822Sdim
3382130563Sobrienstatic bfd_boolean
3383218822Sdimignore_section_sym (bfd *abfd, asymbol *sym)
3384218822Sdim{
3385218822Sdim  return ((sym->flags & BSF_SECTION_SYM) != 0
3386218822Sdim	  && (sym->value != 0
3387218822Sdim	      || (sym->section->owner != abfd
3388218822Sdim		  && (sym->section->output_section->owner != abfd
3389218822Sdim		      || sym->section->output_offset != 0))));
3390218822Sdim}
3391218822Sdim
3392218822Sdimstatic bfd_boolean
3393130563Sobrienelf_map_symbols (bfd *abfd)
339433965Sjdp{
339589860Sobrien  unsigned int symcount = bfd_get_symcount (abfd);
339633965Sjdp  asymbol **syms = bfd_get_outsymbols (abfd);
339733965Sjdp  asymbol **sect_syms;
339889860Sobrien  unsigned int num_locals = 0;
339989860Sobrien  unsigned int num_globals = 0;
340089860Sobrien  unsigned int num_locals2 = 0;
340189860Sobrien  unsigned int num_globals2 = 0;
340233965Sjdp  int max_index = 0;
340389860Sobrien  unsigned int idx;
340433965Sjdp  asection *asect;
340533965Sjdp  asymbol **new_syms;
340633965Sjdp
340733965Sjdp#ifdef DEBUG
340833965Sjdp  fprintf (stderr, "elf_map_symbols\n");
340933965Sjdp  fflush (stderr);
341033965Sjdp#endif
341133965Sjdp
341233965Sjdp  for (asect = abfd->sections; asect; asect = asect->next)
341333965Sjdp    {
341433965Sjdp      if (max_index < asect->index)
341533965Sjdp	max_index = asect->index;
341633965Sjdp    }
341733965Sjdp
341833965Sjdp  max_index++;
3419218822Sdim  sect_syms = bfd_zalloc2 (abfd, max_index, sizeof (asymbol *));
342033965Sjdp  if (sect_syms == NULL)
3421130563Sobrien    return FALSE;
342233965Sjdp  elf_section_syms (abfd) = sect_syms;
342389860Sobrien  elf_num_section_syms (abfd) = max_index;
342433965Sjdp
342589860Sobrien  /* Init sect_syms entries for any section symbols we have already
342689860Sobrien     decided to output.  */
342733965Sjdp  for (idx = 0; idx < symcount; idx++)
342833965Sjdp    {
342989860Sobrien      asymbol *sym = syms[idx];
343077301Sobrien
343160508Sobrien      if ((sym->flags & BSF_SECTION_SYM) != 0
3432218822Sdim	  && !ignore_section_sym (abfd, sym))
343333965Sjdp	{
3434218822Sdim	  asection *sec = sym->section;
343533965Sjdp
3436218822Sdim	  if (sec->owner != abfd)
3437218822Sdim	    sec = sec->output_section;
343860508Sobrien
3439218822Sdim	  sect_syms[sec->index] = syms[idx];
344033965Sjdp	}
344133965Sjdp    }
344233965Sjdp
344333965Sjdp  /* Classify all of the symbols.  */
344433965Sjdp  for (idx = 0; idx < symcount; idx++)
344533965Sjdp    {
3446218822Sdim      if (ignore_section_sym (abfd, syms[idx]))
3447218822Sdim	continue;
344833965Sjdp      if (!sym_is_global (abfd, syms[idx]))
344933965Sjdp	num_locals++;
345033965Sjdp      else
345133965Sjdp	num_globals++;
345233965Sjdp    }
345389860Sobrien
3454218822Sdim  /* We will be adding a section symbol for each normal BFD section.  Most
345589860Sobrien     sections will already have a section symbol in outsymbols, but
345689860Sobrien     eg. SHT_GROUP sections will not, and we need the section symbol mapped
345789860Sobrien     at least in that case.  */
345833965Sjdp  for (asect = abfd->sections; asect; asect = asect->next)
345933965Sjdp    {
346089860Sobrien      if (sect_syms[asect->index] == NULL)
346133965Sjdp	{
346289860Sobrien	  if (!sym_is_global (abfd, asect->symbol))
346333965Sjdp	    num_locals++;
346433965Sjdp	  else
346533965Sjdp	    num_globals++;
346633965Sjdp	}
346733965Sjdp    }
346833965Sjdp
346933965Sjdp  /* Now sort the symbols so the local symbols are first.  */
3470218822Sdim  new_syms = bfd_alloc2 (abfd, num_locals + num_globals, sizeof (asymbol *));
347189860Sobrien
347233965Sjdp  if (new_syms == NULL)
3473130563Sobrien    return FALSE;
347433965Sjdp
347533965Sjdp  for (idx = 0; idx < symcount; idx++)
347633965Sjdp    {
347733965Sjdp      asymbol *sym = syms[idx];
347889860Sobrien      unsigned int i;
347933965Sjdp
3480218822Sdim      if (ignore_section_sym (abfd, sym))
3481218822Sdim	continue;
348233965Sjdp      if (!sym_is_global (abfd, sym))
348333965Sjdp	i = num_locals2++;
348433965Sjdp      else
348533965Sjdp	i = num_locals + num_globals2++;
348633965Sjdp      new_syms[i] = sym;
348733965Sjdp      sym->udata.i = i + 1;
348833965Sjdp    }
348933965Sjdp  for (asect = abfd->sections; asect; asect = asect->next)
349033965Sjdp    {
349189860Sobrien      if (sect_syms[asect->index] == NULL)
349233965Sjdp	{
349389860Sobrien	  asymbol *sym = asect->symbol;
349489860Sobrien	  unsigned int i;
349533965Sjdp
349689860Sobrien	  sect_syms[asect->index] = sym;
349733965Sjdp	  if (!sym_is_global (abfd, sym))
349833965Sjdp	    i = num_locals2++;
349933965Sjdp	  else
350033965Sjdp	    i = num_locals + num_globals2++;
350133965Sjdp	  new_syms[i] = sym;
350233965Sjdp	  sym->udata.i = i + 1;
350333965Sjdp	}
350433965Sjdp    }
350533965Sjdp
350633965Sjdp  bfd_set_symtab (abfd, new_syms, num_locals + num_globals);
350733965Sjdp
350833965Sjdp  elf_num_locals (abfd) = num_locals;
350933965Sjdp  elf_num_globals (abfd) = num_globals;
3510130563Sobrien  return TRUE;
351133965Sjdp}
351233965Sjdp
351333965Sjdp/* Align to the maximum file alignment that could be required for any
351433965Sjdp   ELF data structure.  */
351533965Sjdp
3516130563Sobrienstatic inline file_ptr
3517130563Sobrienalign_file_position (file_ptr off, int align)
351833965Sjdp{
351933965Sjdp  return (off + align - 1) & ~(align - 1);
352033965Sjdp}
352133965Sjdp
352233965Sjdp/* Assign a file position to a section, optionally aligning to the
352333965Sjdp   required section alignment.  */
352433965Sjdp
3525130563Sobrienfile_ptr
3526130563Sobrien_bfd_elf_assign_file_position_for_section (Elf_Internal_Shdr *i_shdrp,
3527130563Sobrien					   file_ptr offset,
3528130563Sobrien					   bfd_boolean align)
352933965Sjdp{
353033965Sjdp  if (align)
353133965Sjdp    {
353233965Sjdp      unsigned int al;
353333965Sjdp
353433965Sjdp      al = i_shdrp->sh_addralign;
353533965Sjdp      if (al > 1)
353633965Sjdp	offset = BFD_ALIGN (offset, al);
353733965Sjdp    }
353833965Sjdp  i_shdrp->sh_offset = offset;
353933965Sjdp  if (i_shdrp->bfd_section != NULL)
354033965Sjdp    i_shdrp->bfd_section->filepos = offset;
354133965Sjdp  if (i_shdrp->sh_type != SHT_NOBITS)
354233965Sjdp    offset += i_shdrp->sh_size;
354333965Sjdp  return offset;
354433965Sjdp}
354533965Sjdp
354633965Sjdp/* Compute the file positions we are going to put the sections at, and
354733965Sjdp   otherwise prepare to begin writing out the ELF file.  If LINK_INFO
354833965Sjdp   is not NULL, this is being called by the ELF backend linker.  */
354933965Sjdp
3550130563Sobrienbfd_boolean
3551130563Sobrien_bfd_elf_compute_section_file_positions (bfd *abfd,
3552130563Sobrien					 struct bfd_link_info *link_info)
355333965Sjdp{
3554130563Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
3555130563Sobrien  bfd_boolean failed;
3556218822Sdim  struct bfd_strtab_hash *strtab = NULL;
355733965Sjdp  Elf_Internal_Shdr *shstrtab_hdr;
355833965Sjdp
355933965Sjdp  if (abfd->output_has_begun)
3560130563Sobrien    return TRUE;
356133965Sjdp
356233965Sjdp  /* Do any elf backend specific processing first.  */
356333965Sjdp  if (bed->elf_backend_begin_write_processing)
356433965Sjdp    (*bed->elf_backend_begin_write_processing) (abfd, link_info);
356533965Sjdp
356633965Sjdp  if (! prep_headers (abfd))
3567130563Sobrien    return FALSE;
356833965Sjdp
356960508Sobrien  /* Post process the headers if necessary.  */
357060508Sobrien  if (bed->elf_backend_post_process_headers)
357160508Sobrien    (*bed->elf_backend_post_process_headers) (abfd, link_info);
357260508Sobrien
3573130563Sobrien  failed = FALSE;
357433965Sjdp  bfd_map_over_sections (abfd, elf_fake_sections, &failed);
357533965Sjdp  if (failed)
3576130563Sobrien    return FALSE;
357733965Sjdp
3578218822Sdim  if (!assign_section_numbers (abfd, link_info))
3579130563Sobrien    return FALSE;
358033965Sjdp
358133965Sjdp  /* The backend linker builds symbol table information itself.  */
358260508Sobrien  if (link_info == NULL && bfd_get_symcount (abfd) > 0)
358333965Sjdp    {
358460508Sobrien      /* Non-zero if doing a relocatable link.  */
358560508Sobrien      int relocatable_p = ! (abfd->flags & (EXEC_P | DYNAMIC));
358660508Sobrien
358760508Sobrien      if (! swap_out_syms (abfd, &strtab, relocatable_p))
3588130563Sobrien	return FALSE;
358933965Sjdp    }
359033965Sjdp
3591104838Sobrien  if (link_info == NULL)
359289860Sobrien    {
3593104838Sobrien      bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed);
359489860Sobrien      if (failed)
3595130563Sobrien	return FALSE;
359689860Sobrien    }
359789860Sobrien
359833965Sjdp  shstrtab_hdr = &elf_tdata (abfd)->shstrtab_hdr;
359933965Sjdp  /* sh_name was set in prep_headers.  */
360033965Sjdp  shstrtab_hdr->sh_type = SHT_STRTAB;
360133965Sjdp  shstrtab_hdr->sh_flags = 0;
360233965Sjdp  shstrtab_hdr->sh_addr = 0;
360389860Sobrien  shstrtab_hdr->sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
360433965Sjdp  shstrtab_hdr->sh_entsize = 0;
360533965Sjdp  shstrtab_hdr->sh_link = 0;
360633965Sjdp  shstrtab_hdr->sh_info = 0;
360733965Sjdp  /* sh_offset is set in assign_file_positions_except_relocs.  */
360833965Sjdp  shstrtab_hdr->sh_addralign = 1;
360933965Sjdp
3610130563Sobrien  if (!assign_file_positions_except_relocs (abfd, link_info))
3611130563Sobrien    return FALSE;
361233965Sjdp
361360508Sobrien  if (link_info == NULL && bfd_get_symcount (abfd) > 0)
361433965Sjdp    {
361533965Sjdp      file_ptr off;
361633965Sjdp      Elf_Internal_Shdr *hdr;
361733965Sjdp
361833965Sjdp      off = elf_tdata (abfd)->next_file_pos;
361933965Sjdp
362033965Sjdp      hdr = &elf_tdata (abfd)->symtab_hdr;
3621130563Sobrien      off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
362233965Sjdp
362389860Sobrien      hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
362489860Sobrien      if (hdr->sh_size != 0)
3625130563Sobrien	off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
362689860Sobrien
362733965Sjdp      hdr = &elf_tdata (abfd)->strtab_hdr;
3628130563Sobrien      off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
362933965Sjdp
363033965Sjdp      elf_tdata (abfd)->next_file_pos = off;
363133965Sjdp
363233965Sjdp      /* Now that we know where the .strtab section goes, write it
3633218822Sdim	 out.  */
363433965Sjdp      if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
363533965Sjdp	  || ! _bfd_stringtab_emit (abfd, strtab))
3636130563Sobrien	return FALSE;
363733965Sjdp      _bfd_stringtab_free (strtab);
363833965Sjdp    }
363933965Sjdp
3640130563Sobrien  abfd->output_has_begun = TRUE;
364133965Sjdp
3642130563Sobrien  return TRUE;
364333965Sjdp}
364433965Sjdp
3645218822Sdim/* Make an initial estimate of the size of the program header.  If we
3646218822Sdim   get the number wrong here, we'll redo section placement.  */
3647218822Sdim
3648218822Sdimstatic bfd_size_type
3649218822Sdimget_program_header_size (bfd *abfd, struct bfd_link_info *info)
3650218822Sdim{
3651218822Sdim  size_t segs;
3652218822Sdim  asection *s;
3653218822Sdim  const struct elf_backend_data *bed;
3654218822Sdim
3655218822Sdim  /* Assume we will need exactly two PT_LOAD segments: one for text
3656218822Sdim     and one for data.  */
3657218822Sdim  segs = 2;
3658218822Sdim
3659218822Sdim  s = bfd_get_section_by_name (abfd, ".interp");
3660218822Sdim  if (s != NULL && (s->flags & SEC_LOAD) != 0)
3661218822Sdim    {
3662218822Sdim      /* If we have a loadable interpreter section, we need a
3663218822Sdim	 PT_INTERP segment.  In this case, assume we also need a
3664218822Sdim	 PT_PHDR segment, although that may not be true for all
3665218822Sdim	 targets.  */
3666218822Sdim      segs += 2;
3667218822Sdim    }
3668218822Sdim
3669218822Sdim  if (bfd_get_section_by_name (abfd, ".dynamic") != NULL)
3670218822Sdim    {
3671218822Sdim      /* We need a PT_DYNAMIC segment.  */
3672218822Sdim      ++segs;
3673218822Sdim
3674218822Sdim      if (elf_tdata (abfd)->relro)
3675218822Sdim	{
3676218822Sdim	  /* We need a PT_GNU_RELRO segment only when there is a
3677218822Sdim	     PT_DYNAMIC segment.  */
3678218822Sdim	  ++segs;
3679218822Sdim	}
3680218822Sdim    }
3681218822Sdim
3682218822Sdim  if (elf_tdata (abfd)->eh_frame_hdr)
3683218822Sdim    {
3684218822Sdim      /* We need a PT_GNU_EH_FRAME segment.  */
3685218822Sdim      ++segs;
3686218822Sdim    }
3687218822Sdim
3688218822Sdim  if (elf_tdata (abfd)->stack_flags)
3689218822Sdim    {
3690218822Sdim      /* We need a PT_GNU_STACK segment.  */
3691218822Sdim      ++segs;
3692218822Sdim    }
3693218822Sdim
3694218822Sdim  for (s = abfd->sections; s != NULL; s = s->next)
3695218822Sdim    {
3696218822Sdim      if ((s->flags & SEC_LOAD) != 0
3697218822Sdim	  && CONST_STRNEQ (s->name, ".note"))
3698218822Sdim	{
3699218822Sdim	  /* We need a PT_NOTE segment.  */
3700218822Sdim	  ++segs;
3701218822Sdim	}
3702218822Sdim    }
3703218822Sdim
3704218822Sdim  for (s = abfd->sections; s != NULL; s = s->next)
3705218822Sdim    {
3706218822Sdim      if (s->flags & SEC_THREAD_LOCAL)
3707218822Sdim	{
3708218822Sdim	  /* We need a PT_TLS segment.  */
3709218822Sdim	  ++segs;
3710218822Sdim	  break;
3711218822Sdim	}
3712218822Sdim    }
3713218822Sdim
3714218822Sdim  /* Let the backend count up any program headers it might need.  */
3715218822Sdim  bed = get_elf_backend_data (abfd);
3716218822Sdim  if (bed->elf_backend_additional_program_headers)
3717218822Sdim    {
3718218822Sdim      int a;
3719218822Sdim
3720218822Sdim      a = (*bed->elf_backend_additional_program_headers) (abfd, info);
3721218822Sdim      if (a == -1)
3722218822Sdim	abort ();
3723218822Sdim      segs += a;
3724218822Sdim    }
3725218822Sdim
3726218822Sdim  return segs * bed->s->sizeof_phdr;
3727218822Sdim}
3728218822Sdim
372933965Sjdp/* Create a mapping from a set of sections to a program segment.  */
373033965Sjdp
3731130563Sobrienstatic struct elf_segment_map *
3732130563Sobrienmake_mapping (bfd *abfd,
3733130563Sobrien	      asection **sections,
3734130563Sobrien	      unsigned int from,
3735130563Sobrien	      unsigned int to,
3736130563Sobrien	      bfd_boolean phdr)
373733965Sjdp{
373833965Sjdp  struct elf_segment_map *m;
373933965Sjdp  unsigned int i;
374033965Sjdp  asection **hdrpp;
374189860Sobrien  bfd_size_type amt;
374233965Sjdp
374389860Sobrien  amt = sizeof (struct elf_segment_map);
374489860Sobrien  amt += (to - from - 1) * sizeof (asection *);
3745130563Sobrien  m = bfd_zalloc (abfd, amt);
374633965Sjdp  if (m == NULL)
374733965Sjdp    return NULL;
374833965Sjdp  m->next = NULL;
374933965Sjdp  m->p_type = PT_LOAD;
375033965Sjdp  for (i = from, hdrpp = sections + from; i < to; i++, hdrpp++)
375133965Sjdp    m->sections[i - from] = *hdrpp;
375233965Sjdp  m->count = to - from;
375333965Sjdp
375433965Sjdp  if (from == 0 && phdr)
375533965Sjdp    {
375633965Sjdp      /* Include the headers in the first PT_LOAD segment.  */
375733965Sjdp      m->includes_filehdr = 1;
375833965Sjdp      m->includes_phdrs = 1;
375933965Sjdp    }
376033965Sjdp
376133965Sjdp  return m;
376233965Sjdp}
376333965Sjdp
3764218822Sdim/* Create the PT_DYNAMIC segment, which includes DYNSEC.  Returns NULL
3765218822Sdim   on failure.  */
376633965Sjdp
3767218822Sdimstruct elf_segment_map *
3768218822Sdim_bfd_elf_make_dynamic_segment (bfd *abfd, asection *dynsec)
376933965Sjdp{
377033965Sjdp  struct elf_segment_map *m;
377133965Sjdp
3772218822Sdim  m = bfd_zalloc (abfd, sizeof (struct elf_segment_map));
3773218822Sdim  if (m == NULL)
3774218822Sdim    return NULL;
3775218822Sdim  m->next = NULL;
3776218822Sdim  m->p_type = PT_DYNAMIC;
3777218822Sdim  m->count = 1;
3778218822Sdim  m->sections[0] = dynsec;
377933965Sjdp
3780218822Sdim  return m;
3781218822Sdim}
378233965Sjdp
3783218822Sdim/* Possibly add or remove segments from the segment map.  */
378433965Sjdp
3785218822Sdimstatic bfd_boolean
3786218822Sdimelf_modify_segment_map (bfd *abfd, struct bfd_link_info *info)
3787218822Sdim{
3788218822Sdim  struct elf_segment_map **m;
3789218822Sdim  const struct elf_backend_data *bed;
379033965Sjdp
3791218822Sdim  /* The placement algorithm assumes that non allocated sections are
3792218822Sdim     not in PT_LOAD segments.  We ensure this here by removing such
3793218822Sdim     sections from the segment map.  We also remove excluded
3794218822Sdim     sections.  Finally, any PT_LOAD segment without sections is
3795218822Sdim     removed.  */
3796218822Sdim  m = &elf_tdata (abfd)->segment_map;
3797218822Sdim  while (*m)
379833965Sjdp    {
3799218822Sdim      unsigned int i, new_count;
3800218822Sdim
3801218822Sdim      for (new_count = 0, i = 0; i < (*m)->count; i++)
380233965Sjdp	{
3803218822Sdim	  if (((*m)->sections[i]->flags & SEC_EXCLUDE) == 0
3804218822Sdim	      && (((*m)->sections[i]->flags & SEC_ALLOC) != 0
3805218822Sdim		  || (*m)->p_type != PT_LOAD))
3806218822Sdim	    {
3807218822Sdim	      (*m)->sections[new_count] = (*m)->sections[i];
3808218822Sdim	      new_count++;
3809218822Sdim	    }
381033965Sjdp	}
3811218822Sdim      (*m)->count = new_count;
3812218822Sdim
3813218822Sdim      if ((*m)->p_type == PT_LOAD && (*m)->count == 0)
3814218822Sdim	*m = (*m)->next;
3815218822Sdim      else
3816218822Sdim	m = &(*m)->next;
381733965Sjdp    }
381833965Sjdp
3819218822Sdim  bed = get_elf_backend_data (abfd);
3820218822Sdim  if (bed->elf_backend_modify_segment_map != NULL)
3821218822Sdim    {
3822218822Sdim      if (!(*bed->elf_backend_modify_segment_map) (abfd, info))
3823218822Sdim	return FALSE;
3824218822Sdim    }
382533965Sjdp
3826218822Sdim  return TRUE;
3827218822Sdim}
382833965Sjdp
3829218822Sdim/* Set up a mapping from BFD sections to program segments.  */
383033965Sjdp
3831218822Sdimbfd_boolean
3832218822Sdim_bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
3833218822Sdim{
3834218822Sdim  unsigned int count;
3835218822Sdim  struct elf_segment_map *m;
3836218822Sdim  asection **sections = NULL;
3837218822Sdim  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
3838218822Sdim
3839218822Sdim  if (elf_tdata (abfd)->segment_map == NULL
3840218822Sdim      && bfd_count_sections (abfd) != 0)
384133965Sjdp    {
3842218822Sdim      asection *s;
3843218822Sdim      unsigned int i;
3844218822Sdim      struct elf_segment_map *mfirst;
3845218822Sdim      struct elf_segment_map **pm;
3846218822Sdim      asection *last_hdr;
3847218822Sdim      bfd_vma last_size;
3848218822Sdim      unsigned int phdr_index;
3849218822Sdim      bfd_vma maxpagesize;
3850218822Sdim      asection **hdrpp;
3851218822Sdim      bfd_boolean phdr_in_segment = TRUE;
3852218822Sdim      bfd_boolean writable;
3853218822Sdim      int tls_count = 0;
3854218822Sdim      asection *first_tls = NULL;
3855218822Sdim      asection *dynsec, *eh_frame_hdr;
3856218822Sdim      bfd_size_type amt;
385733965Sjdp
3858218822Sdim      /* Select the allocated sections, and sort them.  */
385933965Sjdp
3860218822Sdim      sections = bfd_malloc2 (bfd_count_sections (abfd), sizeof (asection *));
3861218822Sdim      if (sections == NULL)
386233965Sjdp	goto error_return;
386333965Sjdp
3864218822Sdim      i = 0;
3865218822Sdim      for (s = abfd->sections; s != NULL; s = s->next)
3866218822Sdim	{
3867218822Sdim	  if ((s->flags & SEC_ALLOC) != 0)
3868218822Sdim	    {
3869218822Sdim	      sections[i] = s;
3870218822Sdim	      ++i;
3871218822Sdim	    }
3872218822Sdim	}
3873218822Sdim      BFD_ASSERT (i <= bfd_count_sections (abfd));
3874218822Sdim      count = i;
387533965Sjdp
3876218822Sdim      qsort (sections, (size_t) count, sizeof (asection *), elf_sort_sections);
387733965Sjdp
3878218822Sdim      /* Build the mapping.  */
387933965Sjdp
3880218822Sdim      mfirst = NULL;
3881218822Sdim      pm = &mfirst;
388233965Sjdp
3883218822Sdim      /* If we have a .interp section, then create a PT_PHDR segment for
3884218822Sdim	 the program headers and a PT_INTERP segment for the .interp
3885218822Sdim	 section.  */
3886218822Sdim      s = bfd_get_section_by_name (abfd, ".interp");
3887218822Sdim      if (s != NULL && (s->flags & SEC_LOAD) != 0)
3888218822Sdim	{
3889218822Sdim	  amt = sizeof (struct elf_segment_map);
3890218822Sdim	  m = bfd_zalloc (abfd, amt);
3891218822Sdim	  if (m == NULL)
3892218822Sdim	    goto error_return;
3893218822Sdim	  m->next = NULL;
3894218822Sdim	  m->p_type = PT_PHDR;
3895218822Sdim	  /* FIXME: UnixWare and Solaris set PF_X, Irix 5 does not.  */
3896218822Sdim	  m->p_flags = PF_R | PF_X;
3897218822Sdim	  m->p_flags_valid = 1;
3898218822Sdim	  m->includes_phdrs = 1;
389933965Sjdp
3900218822Sdim	  *pm = m;
3901218822Sdim	  pm = &m->next;
390233965Sjdp
3903218822Sdim	  amt = sizeof (struct elf_segment_map);
3904218822Sdim	  m = bfd_zalloc (abfd, amt);
3905218822Sdim	  if (m == NULL)
3906218822Sdim	    goto error_return;
3907218822Sdim	  m->next = NULL;
3908218822Sdim	  m->p_type = PT_INTERP;
3909218822Sdim	  m->count = 1;
3910218822Sdim	  m->sections[0] = s;
391133965Sjdp
3912218822Sdim	  *pm = m;
3913218822Sdim	  pm = &m->next;
391433965Sjdp	}
3915218822Sdim
3916218822Sdim      /* Look through the sections.  We put sections in the same program
3917218822Sdim	 segment when the start of the second section can be placed within
3918218822Sdim	 a few bytes of the end of the first section.  */
3919218822Sdim      last_hdr = NULL;
3920218822Sdim      last_size = 0;
3921218822Sdim      phdr_index = 0;
3922218822Sdim      maxpagesize = bed->maxpagesize;
3923218822Sdim      writable = FALSE;
3924218822Sdim      dynsec = bfd_get_section_by_name (abfd, ".dynamic");
3925218822Sdim      if (dynsec != NULL
3926218822Sdim	  && (dynsec->flags & SEC_LOAD) == 0)
3927218822Sdim	dynsec = NULL;
3928218822Sdim
3929218822Sdim      /* Deal with -Ttext or something similar such that the first section
3930218822Sdim	 is not adjacent to the program headers.  This is an
3931218822Sdim	 approximation, since at this point we don't know exactly how many
3932218822Sdim	 program headers we will need.  */
3933218822Sdim      if (count > 0)
393433965Sjdp	{
3935218822Sdim	  bfd_size_type phdr_size = elf_tdata (abfd)->program_header_size;
3936218822Sdim
3937218822Sdim	  if (phdr_size == (bfd_size_type) -1)
3938218822Sdim	    phdr_size = get_program_header_size (abfd, info);
3939218822Sdim	  if ((abfd->flags & D_PAGED) == 0
3940218822Sdim	      || sections[0]->lma < phdr_size
3941218822Sdim	      || sections[0]->lma % maxpagesize < phdr_size % maxpagesize)
3942218822Sdim	    phdr_in_segment = FALSE;
394333965Sjdp	}
3944218822Sdim
3945218822Sdim      for (i = 0, hdrpp = sections; i < count; i++, hdrpp++)
394633965Sjdp	{
3947218822Sdim	  asection *hdr;
3948218822Sdim	  bfd_boolean new_segment;
394933965Sjdp
3950218822Sdim	  hdr = *hdrpp;
3951218822Sdim
3952218822Sdim	  /* See if this section and the last one will fit in the same
3953218822Sdim	     segment.  */
3954218822Sdim
3955218822Sdim	  if (last_hdr == NULL)
3956218822Sdim	    {
3957218822Sdim	      /* If we don't have a segment yet, then we don't need a new
3958218822Sdim		 one (we build the last one after this loop).  */
3959218822Sdim	      new_segment = FALSE;
3960218822Sdim	    }
3961218822Sdim	  else if (last_hdr->lma - last_hdr->vma != hdr->lma - hdr->vma)
3962218822Sdim	    {
3963218822Sdim	      /* If this section has a different relation between the
3964218822Sdim		 virtual address and the load address, then we need a new
3965218822Sdim		 segment.  */
3966218822Sdim	      new_segment = TRUE;
3967218822Sdim	    }
3968218822Sdim	  else if (BFD_ALIGN (last_hdr->lma + last_size, maxpagesize)
3969218822Sdim		   < BFD_ALIGN (hdr->lma, maxpagesize))
3970218822Sdim	    {
3971218822Sdim	      /* If putting this section in this segment would force us to
3972218822Sdim		 skip a page in the segment, then we need a new segment.  */
3973218822Sdim	      new_segment = TRUE;
3974218822Sdim	    }
3975218822Sdim	  else if ((last_hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0
3976218822Sdim		   && (hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != 0)
3977218822Sdim	    {
3978218822Sdim	      /* We don't want to put a loadable section after a
3979218822Sdim		 nonloadable section in the same segment.
3980218822Sdim		 Consider .tbss sections as loadable for this purpose.  */
3981218822Sdim	      new_segment = TRUE;
3982218822Sdim	    }
3983218822Sdim	  else if ((abfd->flags & D_PAGED) == 0)
3984218822Sdim	    {
3985218822Sdim	      /* If the file is not demand paged, which means that we
3986218822Sdim		 don't require the sections to be correctly aligned in the
3987218822Sdim		 file, then there is no other reason for a new segment.  */
3988218822Sdim	      new_segment = FALSE;
3989218822Sdim	    }
3990218822Sdim	  else if (! writable
3991218822Sdim		   && (hdr->flags & SEC_READONLY) == 0
3992218822Sdim		   && (((last_hdr->lma + last_size - 1)
3993218822Sdim			& ~(maxpagesize - 1))
3994218822Sdim		       != (hdr->lma & ~(maxpagesize - 1))))
3995218822Sdim	    {
3996218822Sdim	      /* We don't want to put a writable section in a read only
3997218822Sdim		 segment, unless they are on the same page in memory
3998218822Sdim		 anyhow.  We already know that the last section does not
3999218822Sdim		 bring us past the current section on the page, so the
4000218822Sdim		 only case in which the new section is not on the same
4001218822Sdim		 page as the previous section is when the previous section
4002218822Sdim		 ends precisely on a page boundary.  */
4003218822Sdim	      new_segment = TRUE;
4004218822Sdim	    }
4005218822Sdim	  else
4006218822Sdim	    {
4007218822Sdim	      /* Otherwise, we can use the same segment.  */
4008218822Sdim	      new_segment = FALSE;
4009218822Sdim	    }
4010218822Sdim
4011218822Sdim	  /* Allow interested parties a chance to override our decision.  */
4012218822Sdim	  if (last_hdr && info->callbacks->override_segment_assignment)
4013218822Sdim	    new_segment = info->callbacks->override_segment_assignment (info, abfd, hdr, last_hdr, new_segment);
4014218822Sdim
4015218822Sdim	  if (! new_segment)
4016218822Sdim	    {
4017218822Sdim	      if ((hdr->flags & SEC_READONLY) == 0)
4018218822Sdim		writable = TRUE;
4019218822Sdim	      last_hdr = hdr;
4020218822Sdim	      /* .tbss sections effectively have zero size.  */
4021218822Sdim	      if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD))
4022218822Sdim		  != SEC_THREAD_LOCAL)
4023218822Sdim		last_size = hdr->size;
4024218822Sdim	      else
4025218822Sdim		last_size = 0;
4026218822Sdim	      continue;
4027218822Sdim	    }
4028218822Sdim
4029218822Sdim	  /* We need a new program segment.  We must create a new program
4030218822Sdim	     header holding all the sections from phdr_index until hdr.  */
4031218822Sdim
4032218822Sdim	  m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
4033218822Sdim	  if (m == NULL)
4034218822Sdim	    goto error_return;
4035218822Sdim
4036218822Sdim	  *pm = m;
4037218822Sdim	  pm = &m->next;
4038218822Sdim
403933965Sjdp	  if ((hdr->flags & SEC_READONLY) == 0)
4040130563Sobrien	    writable = TRUE;
4041218822Sdim	  else
4042218822Sdim	    writable = FALSE;
4043218822Sdim
404433965Sjdp	  last_hdr = hdr;
4045130563Sobrien	  /* .tbss sections effectively have zero size.  */
4046130563Sobrien	  if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL)
4047218822Sdim	    last_size = hdr->size;
4048130563Sobrien	  else
4049130563Sobrien	    last_size = 0;
4050218822Sdim	  phdr_index = i;
4051218822Sdim	  phdr_in_segment = FALSE;
405233965Sjdp	}
405333965Sjdp
4054218822Sdim      /* Create a final PT_LOAD program segment.  */
4055218822Sdim      if (last_hdr != NULL)
4056218822Sdim	{
4057218822Sdim	  m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
4058218822Sdim	  if (m == NULL)
4059218822Sdim	    goto error_return;
406033965Sjdp
4061218822Sdim	  *pm = m;
4062218822Sdim	  pm = &m->next;
4063218822Sdim	}
406433965Sjdp
4065218822Sdim      /* If there is a .dynamic section, throw in a PT_DYNAMIC segment.  */
4066218822Sdim      if (dynsec != NULL)
4067218822Sdim	{
4068218822Sdim	  m = _bfd_elf_make_dynamic_segment (abfd, dynsec);
4069218822Sdim	  if (m == NULL)
4070218822Sdim	    goto error_return;
4071218822Sdim	  *pm = m;
4072218822Sdim	  pm = &m->next;
4073218822Sdim	}
407433965Sjdp
4075218822Sdim      /* For each loadable .note section, add a PT_NOTE segment.  We don't
4076218822Sdim	 use bfd_get_section_by_name, because if we link together
4077218822Sdim	 nonloadable .note sections and loadable .note sections, we will
4078218822Sdim	 generate two .note sections in the output file.  FIXME: Using
4079218822Sdim	 names for section types is bogus anyhow.  */
4080218822Sdim      for (s = abfd->sections; s != NULL; s = s->next)
4081218822Sdim	{
4082218822Sdim	  if ((s->flags & SEC_LOAD) != 0
4083218822Sdim	      && CONST_STRNEQ (s->name, ".note"))
4084218822Sdim	    {
4085218822Sdim	      amt = sizeof (struct elf_segment_map);
4086218822Sdim	      m = bfd_zalloc (abfd, amt);
4087218822Sdim	      if (m == NULL)
4088218822Sdim		goto error_return;
4089218822Sdim	      m->next = NULL;
4090218822Sdim	      m->p_type = PT_NOTE;
4091218822Sdim	      m->count = 1;
4092218822Sdim	      m->sections[0] = s;
409333965Sjdp
4094218822Sdim	      *pm = m;
4095218822Sdim	      pm = &m->next;
4096218822Sdim	    }
4097218822Sdim	  if (s->flags & SEC_THREAD_LOCAL)
4098218822Sdim	    {
4099218822Sdim	      if (! tls_count)
4100218822Sdim		first_tls = s;
4101218822Sdim	      tls_count++;
4102218822Sdim	    }
4103218822Sdim	}
410433965Sjdp
4105218822Sdim      /* If there are any SHF_TLS output sections, add PT_TLS segment.  */
4106218822Sdim      if (tls_count > 0)
4107218822Sdim	{
4108218822Sdim	  int i;
410933965Sjdp
4110218822Sdim	  amt = sizeof (struct elf_segment_map);
4111218822Sdim	  amt += (tls_count - 1) * sizeof (asection *);
4112218822Sdim	  m = bfd_zalloc (abfd, amt);
4113218822Sdim	  if (m == NULL)
4114218822Sdim	    goto error_return;
4115218822Sdim	  m->next = NULL;
4116218822Sdim	  m->p_type = PT_TLS;
4117218822Sdim	  m->count = tls_count;
4118218822Sdim	  /* Mandated PF_R.  */
4119218822Sdim	  m->p_flags = PF_R;
4120218822Sdim	  m->p_flags_valid = 1;
4121218822Sdim	  for (i = 0; i < tls_count; ++i)
4122218822Sdim	    {
4123218822Sdim	      BFD_ASSERT (first_tls->flags & SEC_THREAD_LOCAL);
4124218822Sdim	      m->sections[i] = first_tls;
4125218822Sdim	      first_tls = first_tls->next;
4126218822Sdim	    }
412733965Sjdp
4128218822Sdim	  *pm = m;
4129218822Sdim	  pm = &m->next;
4130218822Sdim	}
413133965Sjdp
4132218822Sdim      /* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME
4133218822Sdim	 segment.  */
4134218822Sdim      eh_frame_hdr = elf_tdata (abfd)->eh_frame_hdr;
4135218822Sdim      if (eh_frame_hdr != NULL
4136218822Sdim	  && (eh_frame_hdr->output_section->flags & SEC_LOAD) != 0)
413733965Sjdp	{
413889860Sobrien	  amt = sizeof (struct elf_segment_map);
4139130563Sobrien	  m = bfd_zalloc (abfd, amt);
414033965Sjdp	  if (m == NULL)
414133965Sjdp	    goto error_return;
414233965Sjdp	  m->next = NULL;
4143218822Sdim	  m->p_type = PT_GNU_EH_FRAME;
414433965Sjdp	  m->count = 1;
4145218822Sdim	  m->sections[0] = eh_frame_hdr->output_section;
414633965Sjdp
414733965Sjdp	  *pm = m;
414833965Sjdp	  pm = &m->next;
414933965Sjdp	}
4150218822Sdim
4151218822Sdim      if (elf_tdata (abfd)->stack_flags)
4152104838Sobrien	{
4153218822Sdim	  amt = sizeof (struct elf_segment_map);
4154218822Sdim	  m = bfd_zalloc (abfd, amt);
4155218822Sdim	  if (m == NULL)
4156218822Sdim	    goto error_return;
4157218822Sdim	  m->next = NULL;
4158218822Sdim	  m->p_type = PT_GNU_STACK;
4159218822Sdim	  m->p_flags = elf_tdata (abfd)->stack_flags;
4160218822Sdim	  m->p_flags_valid = 1;
4161218822Sdim
4162218822Sdim	  *pm = m;
4163218822Sdim	  pm = &m->next;
4164104838Sobrien	}
416533965Sjdp
4166218822Sdim      if (dynsec != NULL && elf_tdata (abfd)->relro)
4167218822Sdim	{
4168218822Sdim	  /* We make a PT_GNU_RELRO segment only when there is a
4169218822Sdim	     PT_DYNAMIC segment.  */
4170218822Sdim	  amt = sizeof (struct elf_segment_map);
4171218822Sdim	  m = bfd_zalloc (abfd, amt);
4172218822Sdim	  if (m == NULL)
4173218822Sdim	    goto error_return;
4174218822Sdim	  m->next = NULL;
4175218822Sdim	  m->p_type = PT_GNU_RELRO;
4176218822Sdim	  m->p_flags = PF_R;
4177218822Sdim	  m->p_flags_valid = 1;
4178104838Sobrien
4179218822Sdim	  *pm = m;
4180218822Sdim	  pm = &m->next;
4181104838Sobrien	}
4182104838Sobrien
4183218822Sdim      free (sections);
4184218822Sdim      elf_tdata (abfd)->segment_map = mfirst;
4185104838Sobrien    }
4186104838Sobrien
4187218822Sdim  if (!elf_modify_segment_map (abfd, info))
4188218822Sdim    return FALSE;
418989860Sobrien
4190218822Sdim  for (count = 0, m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
4191218822Sdim    ++count;
4192218822Sdim  elf_tdata (abfd)->program_header_size = count * bed->s->sizeof_phdr;
419389860Sobrien
4194130563Sobrien  return TRUE;
419533965Sjdp
419633965Sjdp error_return:
419733965Sjdp  if (sections != NULL)
419833965Sjdp    free (sections);
4199130563Sobrien  return FALSE;
420033965Sjdp}
420133965Sjdp
420260508Sobrien/* Sort sections by address.  */
420333965Sjdp
420433965Sjdpstatic int
4205130563Sobrienelf_sort_sections (const void *arg1, const void *arg2)
420633965Sjdp{
420733965Sjdp  const asection *sec1 = *(const asection **) arg1;
420833965Sjdp  const asection *sec2 = *(const asection **) arg2;
4209130563Sobrien  bfd_size_type size1, size2;
421033965Sjdp
421160508Sobrien  /* Sort by LMA first, since this is the address used to
421260508Sobrien     place the section into a segment.  */
421360508Sobrien  if (sec1->lma < sec2->lma)
421433965Sjdp    return -1;
421560508Sobrien  else if (sec1->lma > sec2->lma)
421633965Sjdp    return 1;
421733965Sjdp
421860508Sobrien  /* Then sort by VMA.  Normally the LMA and the VMA will be
421960508Sobrien     the same, and this will do nothing.  */
422060508Sobrien  if (sec1->vma < sec2->vma)
422133965Sjdp    return -1;
422260508Sobrien  else if (sec1->vma > sec2->vma)
422333965Sjdp    return 1;
422433965Sjdp
422533965Sjdp  /* Put !SEC_LOAD sections after SEC_LOAD ones.  */
422633965Sjdp
4227130563Sobrien#define TOEND(x) (((x)->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0)
422833965Sjdp
422933965Sjdp  if (TOEND (sec1))
423038891Sjdp    {
423138891Sjdp      if (TOEND (sec2))
423289860Sobrien	{
423389860Sobrien	  /* If the indicies are the same, do not return 0
423489860Sobrien	     here, but continue to try the next comparison.  */
423589860Sobrien	  if (sec1->target_index - sec2->target_index != 0)
423689860Sobrien	    return sec1->target_index - sec2->target_index;
423789860Sobrien	}
423860508Sobrien      else
423938891Sjdp	return 1;
424038891Sjdp    }
424189860Sobrien  else if (TOEND (sec2))
424233965Sjdp    return -1;
424333965Sjdp
424433965Sjdp#undef TOEND
424533965Sjdp
424689860Sobrien  /* Sort by size, to put zero sized sections
424789860Sobrien     before others at the same address.  */
424833965Sjdp
4249218822Sdim  size1 = (sec1->flags & SEC_LOAD) ? sec1->size : 0;
4250218822Sdim  size2 = (sec2->flags & SEC_LOAD) ? sec2->size : 0;
4251130563Sobrien
4252130563Sobrien  if (size1 < size2)
425333965Sjdp    return -1;
4254130563Sobrien  if (size1 > size2)
425533965Sjdp    return 1;
425633965Sjdp
425733965Sjdp  return sec1->target_index - sec2->target_index;
425833965Sjdp}
425933965Sjdp
4260130563Sobrien/* Ian Lance Taylor writes:
4261130563Sobrien
4262130563Sobrien   We shouldn't be using % with a negative signed number.  That's just
4263130563Sobrien   not good.  We have to make sure either that the number is not
4264130563Sobrien   negative, or that the number has an unsigned type.  When the types
4265130563Sobrien   are all the same size they wind up as unsigned.  When file_ptr is a
4266130563Sobrien   larger signed type, the arithmetic winds up as signed long long,
4267130563Sobrien   which is wrong.
4268130563Sobrien
4269130563Sobrien   What we're trying to say here is something like ``increase OFF by
4270130563Sobrien   the least amount that will cause it to be equal to the VMA modulo
4271130563Sobrien   the page size.''  */
4272130563Sobrien/* In other words, something like:
4273130563Sobrien
4274130563Sobrien   vma_offset = m->sections[0]->vma % bed->maxpagesize;
4275130563Sobrien   off_offset = off % bed->maxpagesize;
4276130563Sobrien   if (vma_offset < off_offset)
4277130563Sobrien     adjustment = vma_offset + bed->maxpagesize - off_offset;
4278130563Sobrien   else
4279130563Sobrien     adjustment = vma_offset - off_offset;
4280218822Sdim
4281130563Sobrien   which can can be collapsed into the expression below.  */
4282130563Sobrien
4283130563Sobrienstatic file_ptr
4284130563Sobrienvma_page_aligned_bias (bfd_vma vma, ufile_ptr off, bfd_vma maxpagesize)
4285130563Sobrien{
4286130563Sobrien  return ((vma - off) % maxpagesize);
4287130563Sobrien}
4288130563Sobrien
428933965Sjdp/* Assign file positions to the sections based on the mapping from
429033965Sjdp   sections to segments.  This function also sets up some fields in
4291218822Sdim   the file header.  */
429233965Sjdp
4293130563Sobrienstatic bfd_boolean
4294218822Sdimassign_file_positions_for_load_sections (bfd *abfd,
4295218822Sdim					 struct bfd_link_info *link_info)
429633965Sjdp{
429733965Sjdp  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
429833965Sjdp  struct elf_segment_map *m;
429933965Sjdp  Elf_Internal_Phdr *phdrs;
430033965Sjdp  Elf_Internal_Phdr *p;
4301218822Sdim  file_ptr off;
4302218822Sdim  bfd_size_type maxpagesize;
4303218822Sdim  unsigned int alloc;
4304218822Sdim  unsigned int i, j;
430533965Sjdp
4306218822Sdim  if (link_info == NULL
4307218822Sdim      && !elf_modify_segment_map (abfd, link_info))
4308218822Sdim    return FALSE;
430933965Sjdp
4310218822Sdim  alloc = 0;
431133965Sjdp  for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
4312218822Sdim    ++alloc;
431333965Sjdp
431433965Sjdp  elf_elfheader (abfd)->e_phoff = bed->s->sizeof_ehdr;
431533965Sjdp  elf_elfheader (abfd)->e_phentsize = bed->s->sizeof_phdr;
4316218822Sdim  elf_elfheader (abfd)->e_phnum = alloc;
431733965Sjdp
4318218822Sdim  if (elf_tdata (abfd)->program_header_size == (bfd_size_type) -1)
4319218822Sdim    elf_tdata (abfd)->program_header_size = alloc * bed->s->sizeof_phdr;
4320218822Sdim  else
4321218822Sdim    BFD_ASSERT (elf_tdata (abfd)->program_header_size
4322218822Sdim		>= alloc * bed->s->sizeof_phdr);
432333965Sjdp
4324218822Sdim  if (alloc == 0)
432533965Sjdp    {
4326218822Sdim      elf_tdata (abfd)->next_file_pos = bed->s->sizeof_ehdr;
4327218822Sdim      return TRUE;
432833965Sjdp    }
432933965Sjdp
4330218822Sdim  phdrs = bfd_alloc2 (abfd, alloc, sizeof (Elf_Internal_Phdr));
4331218822Sdim  elf_tdata (abfd)->phdr = phdrs;
433233965Sjdp  if (phdrs == NULL)
4333130563Sobrien    return FALSE;
433433965Sjdp
4335218822Sdim  maxpagesize = 1;
4336218822Sdim  if ((abfd->flags & D_PAGED) != 0)
4337218822Sdim    maxpagesize = bed->maxpagesize;
4338218822Sdim
433933965Sjdp  off = bed->s->sizeof_ehdr;
434033965Sjdp  off += alloc * bed->s->sizeof_phdr;
434133965Sjdp
4342218822Sdim  for (m = elf_tdata (abfd)->segment_map, p = phdrs, j = 0;
434333965Sjdp       m != NULL;
4344218822Sdim       m = m->next, p++, j++)
434533965Sjdp    {
434633965Sjdp      asection **secpp;
4347218822Sdim      bfd_vma off_adjust;
4348218822Sdim      bfd_boolean no_contents;
434933965Sjdp
435033965Sjdp      /* If elf_segment_map is not from map_sections_to_segments, the
4351218822Sdim	 sections may not be correctly ordered.  NOTE: sorting should
435289860Sobrien	 not be done to the PT_NOTE section of a corefile, which may
435389860Sobrien	 contain several pseudo-sections artificially created by bfd.
435489860Sobrien	 Sorting these pseudo-sections breaks things badly.  */
4355104838Sobrien      if (m->count > 1
4356104838Sobrien	  && !(elf_elfheader (abfd)->e_type == ET_CORE
435789860Sobrien	       && m->p_type == PT_NOTE))
435833965Sjdp	qsort (m->sections, (size_t) m->count, sizeof (asection *),
435933965Sjdp	       elf_sort_sections);
436033965Sjdp
4361218822Sdim      /* An ELF segment (described by Elf_Internal_Phdr) may contain a
4362218822Sdim	 number of sections with contents contributing to both p_filesz
4363218822Sdim	 and p_memsz, followed by a number of sections with no contents
4364218822Sdim	 that just contribute to p_memsz.  In this loop, OFF tracks next
4365218822Sdim	 available file offset for PT_LOAD and PT_NOTE segments.  */
436633965Sjdp      p->p_type = m->p_type;
436760508Sobrien      p->p_flags = m->p_flags;
436833965Sjdp
436933965Sjdp      if (m->count == 0)
437033965Sjdp	p->p_vaddr = 0;
437133965Sjdp      else
4372218822Sdim	p->p_vaddr = m->sections[0]->vma - m->p_vaddr_offset;
437333965Sjdp
437433965Sjdp      if (m->p_paddr_valid)
437533965Sjdp	p->p_paddr = m->p_paddr;
437633965Sjdp      else if (m->count == 0)
437733965Sjdp	p->p_paddr = 0;
437833965Sjdp      else
4379218822Sdim	p->p_paddr = m->sections[0]->lma - m->p_vaddr_offset;
438033965Sjdp
438133965Sjdp      if (p->p_type == PT_LOAD
438233965Sjdp	  && (abfd->flags & D_PAGED) != 0)
4383218822Sdim	{
4384218822Sdim	  /* p_align in demand paged PT_LOAD segments effectively stores
4385218822Sdim	     the maximum page size.  When copying an executable with
4386218822Sdim	     objcopy, we set m->p_align from the input file.  Use this
4387218822Sdim	     value for maxpagesize rather than bed->maxpagesize, which
4388218822Sdim	     may be different.  Note that we use maxpagesize for PT_TLS
4389218822Sdim	     segment alignment later in this function, so we are relying
4390218822Sdim	     on at least one PT_LOAD segment appearing before a PT_TLS
4391218822Sdim	     segment.  */
4392218822Sdim	  if (m->p_align_valid)
4393218822Sdim	    maxpagesize = m->p_align;
4394218822Sdim
4395218822Sdim	  p->p_align = maxpagesize;
4396218822Sdim	}
439733965Sjdp      else if (m->count == 0)
4398130563Sobrien	p->p_align = 1 << bed->s->log_file_align;
4399218822Sdim      else if (m->p_align_valid)
4400218822Sdim	p->p_align = m->p_align;
440133965Sjdp      else
440233965Sjdp	p->p_align = 0;
440333965Sjdp
4404218822Sdim      no_contents = FALSE;
4405218822Sdim      off_adjust = 0;
4406218822Sdim      if (p->p_type == PT_NOTE)
4407218822Sdim	{
4408218822Sdim	  for (i = 0; i < m->count; i++)
4409218822Sdim	    elf_section_type (m->sections[i]) = SHT_NOTE;
4410218822Sdim	}
4411218822Sdim      else if (p->p_type == PT_LOAD
4412218822Sdim	  && m->count > 0)
4413218822Sdim	{
4414218822Sdim	  bfd_size_type align;
4415218822Sdim	  unsigned int align_power = 0;
4416218822Sdim
4417218822Sdim	  if (m->p_align_valid)
4418218822Sdim	    align = p->p_align;
4419218822Sdim	  else
4420218822Sdim	    {
4421218822Sdim	      for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
4422218822Sdim		{
4423218822Sdim		  unsigned int secalign;
4424218822Sdim
4425218822Sdim		  secalign = bfd_get_section_alignment (abfd, *secpp);
4426218822Sdim		  if (secalign > align_power)
4427218822Sdim		    align_power = secalign;
4428218822Sdim		}
4429218822Sdim	      align = (bfd_size_type) 1 << align_power;
4430218822Sdim	      if (align < maxpagesize)
4431218822Sdim		align = maxpagesize;
4432218822Sdim	    }
4433218822Sdim
4434218822Sdim	  for (i = 0; i < m->count; i++)
4435218822Sdim	    if ((m->sections[i]->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
4436218822Sdim	      /* If we aren't making room for this section, then
4437218822Sdim		 it must be SHT_NOBITS regardless of what we've
4438218822Sdim		 set via struct bfd_elf_special_section.  */
4439218822Sdim	      elf_section_type (m->sections[i]) = SHT_NOBITS;
4440218822Sdim
4441218822Sdim	  /* Find out whether this segment contains any loadable
4442218822Sdim	     sections.  If the first section isn't loadable, the same
4443218822Sdim	     holds for any other sections.  */
4444218822Sdim	  i = 0;
4445218822Sdim	  while (elf_section_type (m->sections[i]) == SHT_NOBITS)
4446218822Sdim	    {
4447218822Sdim	      /* If a segment starts with .tbss, we need to look
4448218822Sdim		 at the next section to decide whether the segment
4449218822Sdim		 has any loadable sections.  */
4450218822Sdim	      if ((elf_section_flags (m->sections[i]) & SHF_TLS) == 0
4451218822Sdim		  || ++i >= m->count)
4452218822Sdim		{
4453218822Sdim		  no_contents = TRUE;
4454218822Sdim		  break;
4455218822Sdim		}
4456218822Sdim	    }
4457218822Sdim
4458218822Sdim	  off_adjust = vma_page_aligned_bias (m->sections[0]->vma, off, align);
4459218822Sdim	  off += off_adjust;
4460218822Sdim	  if (no_contents)
4461218822Sdim	    {
4462218822Sdim	      /* We shouldn't need to align the segment on disk since
4463218822Sdim		 the segment doesn't need file space, but the gABI
4464218822Sdim		 arguably requires the alignment and glibc ld.so
4465218822Sdim		 checks it.  So to comply with the alignment
4466218822Sdim		 requirement but not waste file space, we adjust
4467218822Sdim		 p_offset for just this segment.  (OFF_ADJUST is
4468218822Sdim		 subtracted from OFF later.)  This may put p_offset
4469218822Sdim		 past the end of file, but that shouldn't matter.  */
4470218822Sdim	    }
4471218822Sdim	  else
4472218822Sdim	    off_adjust = 0;
4473218822Sdim	}
4474218822Sdim      /* Make sure the .dynamic section is the first section in the
4475218822Sdim	 PT_DYNAMIC segment.  */
4476218822Sdim      else if (p->p_type == PT_DYNAMIC
4477218822Sdim	       && m->count > 1
4478218822Sdim	       && strcmp (m->sections[0]->name, ".dynamic") != 0)
4479218822Sdim	{
4480218822Sdim	  _bfd_error_handler
4481218822Sdim	    (_("%B: The first section in the PT_DYNAMIC segment is not the .dynamic section"),
4482218822Sdim	     abfd);
4483218822Sdim	  bfd_set_error (bfd_error_bad_value);
4484218822Sdim	  return FALSE;
4485218822Sdim	}
4486218822Sdim
448733965Sjdp      p->p_offset = 0;
448833965Sjdp      p->p_filesz = 0;
448933965Sjdp      p->p_memsz = 0;
449033965Sjdp
449133965Sjdp      if (m->includes_filehdr)
449233965Sjdp	{
4493218822Sdim	  if (!m->p_flags_valid)
449433965Sjdp	    p->p_flags |= PF_R;
449533965Sjdp	  p->p_filesz = bed->s->sizeof_ehdr;
449633965Sjdp	  p->p_memsz = bed->s->sizeof_ehdr;
449733965Sjdp	  if (m->count > 0)
449833965Sjdp	    {
449933965Sjdp	      BFD_ASSERT (p->p_type == PT_LOAD);
450038891Sjdp
450138891Sjdp	      if (p->p_vaddr < (bfd_vma) off)
450238891Sjdp		{
4503104838Sobrien		  (*_bfd_error_handler)
4504218822Sdim		    (_("%B: Not enough room for program headers, try linking with -N"),
4505218822Sdim		     abfd);
450638891Sjdp		  bfd_set_error (bfd_error_bad_value);
4507130563Sobrien		  return FALSE;
450838891Sjdp		}
450960508Sobrien
451033965Sjdp	      p->p_vaddr -= off;
4511218822Sdim	      if (!m->p_paddr_valid)
451233965Sjdp		p->p_paddr -= off;
451333965Sjdp	    }
451433965Sjdp	}
451533965Sjdp
451633965Sjdp      if (m->includes_phdrs)
451733965Sjdp	{
4518218822Sdim	  if (!m->p_flags_valid)
451933965Sjdp	    p->p_flags |= PF_R;
452060508Sobrien
4521218822Sdim	  if (!m->includes_filehdr)
452233965Sjdp	    {
452333965Sjdp	      p->p_offset = bed->s->sizeof_ehdr;
452460508Sobrien
452533965Sjdp	      if (m->count > 0)
452633965Sjdp		{
452733965Sjdp		  BFD_ASSERT (p->p_type == PT_LOAD);
452833965Sjdp		  p->p_vaddr -= off - p->p_offset;
4529218822Sdim		  if (!m->p_paddr_valid)
453033965Sjdp		    p->p_paddr -= off - p->p_offset;
453133965Sjdp		}
453233965Sjdp	    }
453360508Sobrien
453433965Sjdp	  p->p_filesz += alloc * bed->s->sizeof_phdr;
453533965Sjdp	  p->p_memsz += alloc * bed->s->sizeof_phdr;
453633965Sjdp	}
453733965Sjdp
453860508Sobrien      if (p->p_type == PT_LOAD
453960508Sobrien	  || (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core))
454033965Sjdp	{
4541218822Sdim	  if (!m->includes_filehdr && !m->includes_phdrs)
454233965Sjdp	    p->p_offset = off;
454333965Sjdp	  else
454433965Sjdp	    {
454533965Sjdp	      file_ptr adjust;
454633965Sjdp
454733965Sjdp	      adjust = off - (p->p_offset + p->p_filesz);
4548218822Sdim	      if (!no_contents)
4549218822Sdim		p->p_filesz += adjust;
455033965Sjdp	      p->p_memsz += adjust;
455133965Sjdp	    }
455233965Sjdp	}
455333965Sjdp
4554218822Sdim      /* Set up p_filesz, p_memsz, p_align and p_flags from the section
4555218822Sdim	 maps.  Set filepos for sections in PT_LOAD segments, and in
4556218822Sdim	 core files, for sections in PT_NOTE segments.
4557218822Sdim	 assign_file_positions_for_non_load_sections will set filepos
4558218822Sdim	 for other sections and update p_filesz for other segments.  */
455933965Sjdp      for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
456033965Sjdp	{
456133965Sjdp	  asection *sec;
456233965Sjdp	  bfd_size_type align;
4563218822Sdim	  Elf_Internal_Shdr *this_hdr;
456433965Sjdp
456533965Sjdp	  sec = *secpp;
4566218822Sdim	  this_hdr = &elf_section_data (sec)->this_hdr;
4567218822Sdim	  align = (bfd_size_type) 1 << bfd_get_section_alignment (abfd, sec);
456833965Sjdp
4569218822Sdim	  if (p->p_type == PT_LOAD
4570218822Sdim	      || p->p_type == PT_TLS)
457160508Sobrien	    {
4572218822Sdim	      bfd_signed_vma adjust = sec->lma - (p->p_paddr + p->p_memsz);
457360508Sobrien
4574218822Sdim	      if (this_hdr->sh_type != SHT_NOBITS
4575218822Sdim		  || ((this_hdr->sh_flags & SHF_ALLOC) != 0
4576218822Sdim		      && ((this_hdr->sh_flags & SHF_TLS) == 0
4577218822Sdim			  || p->p_type == PT_TLS)))
4578130563Sobrien		{
457960508Sobrien		  if (adjust < 0)
4580218822Sdim		    {
4581218822Sdim		      (*_bfd_error_handler)
4582218822Sdim			(_("%B: section %A lma 0x%lx overlaps previous sections"),
4583218822Sdim			 abfd, sec, (unsigned long) sec->lma);
4584218822Sdim		      adjust = 0;
4585218822Sdim		    }
4586218822Sdim		  p->p_memsz += adjust;
458733965Sjdp
4588218822Sdim		  if (this_hdr->sh_type != SHT_NOBITS)
458960508Sobrien		    {
4590218822Sdim		      off += adjust;
4591218822Sdim		      p->p_filesz += adjust;
459260508Sobrien		    }
459338891Sjdp		}
459433965Sjdp	    }
459533965Sjdp
459660508Sobrien	  if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)
459760508Sobrien	    {
4598218822Sdim	      /* The section at i == 0 is the one that actually contains
4599218822Sdim		 everything.  */
460077301Sobrien	      if (i == 0)
460177301Sobrien		{
4602218822Sdim		  this_hdr->sh_offset = sec->filepos = off;
4603218822Sdim		  off += this_hdr->sh_size;
4604218822Sdim		  p->p_filesz = this_hdr->sh_size;
4605218822Sdim		  p->p_memsz = 0;
4606218822Sdim		  p->p_align = 1;
460760508Sobrien		}
460877301Sobrien	      else
460960508Sobrien		{
4610218822Sdim		  /* The rest are fake sections that shouldn't be written.  */
461160508Sobrien		  sec->filepos = 0;
4612218822Sdim		  sec->size = 0;
4613218822Sdim		  sec->flags = 0;
4614218822Sdim		  continue;
461560508Sobrien		}
461660508Sobrien	    }
461760508Sobrien	  else
461860508Sobrien	    {
4619218822Sdim	      if (p->p_type == PT_LOAD)
4620218822Sdim		{
4621218822Sdim		  this_hdr->sh_offset = sec->filepos = off;
4622218822Sdim		  if (this_hdr->sh_type != SHT_NOBITS)
4623218822Sdim		    off += this_hdr->sh_size;
4624218822Sdim		}
462533965Sjdp
4626218822Sdim	      if (this_hdr->sh_type != SHT_NOBITS)
4627104838Sobrien		{
4628218822Sdim		  p->p_filesz += this_hdr->sh_size;
4629218822Sdim		  /* A load section without SHF_ALLOC is something like
4630218822Sdim		     a note section in a PT_NOTE segment.  These take
4631218822Sdim		     file space but are not loaded into memory.  */
4632218822Sdim		  if ((this_hdr->sh_flags & SHF_ALLOC) != 0)
4633218822Sdim		    p->p_memsz += this_hdr->sh_size;
4634218822Sdim		}
4635218822Sdim	      else if ((this_hdr->sh_flags & SHF_ALLOC) != 0)
4636218822Sdim		{
4637218822Sdim		  if (p->p_type == PT_TLS)
4638218822Sdim		    p->p_memsz += this_hdr->sh_size;
4639104838Sobrien
4640218822Sdim		  /* .tbss is special.  It doesn't contribute to p_memsz of
4641218822Sdim		     normal segments.  */
4642218822Sdim		  else if ((this_hdr->sh_flags & SHF_TLS) == 0)
4643218822Sdim		    p->p_memsz += this_hdr->sh_size;
4644104838Sobrien		}
4645104838Sobrien
4646218822Sdim	      if (p->p_type == PT_GNU_RELRO)
4647218822Sdim		p->p_align = 1;
4648218822Sdim	      else if (align > p->p_align
4649218822Sdim		       && !m->p_align_valid
4650218822Sdim		       && (p->p_type != PT_LOAD
4651218822Sdim			   || (abfd->flags & D_PAGED) == 0))
465260508Sobrien		p->p_align = align;
465360508Sobrien	    }
465433965Sjdp
4655218822Sdim	  if (!m->p_flags_valid)
465633965Sjdp	    {
465733965Sjdp	      p->p_flags |= PF_R;
4658218822Sdim	      if ((this_hdr->sh_flags & SHF_EXECINSTR) != 0)
465933965Sjdp		p->p_flags |= PF_X;
4660218822Sdim	      if ((this_hdr->sh_flags & SHF_WRITE) != 0)
466133965Sjdp		p->p_flags |= PF_W;
466233965Sjdp	    }
466333965Sjdp	}
4664218822Sdim      off -= off_adjust;
466533965Sjdp
4666218822Sdim      /* Check that all sections are in a PT_LOAD segment.
4667218822Sdim	 Don't check funky gdb generated core files.  */
4668218822Sdim      if (p->p_type == PT_LOAD && bfd_get_format (abfd) != bfd_core)
4669218822Sdim	for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
4670218822Sdim	  {
4671218822Sdim	    Elf_Internal_Shdr *this_hdr;
4672218822Sdim	    asection *sec;
467333965Sjdp
4674218822Sdim	    sec = *secpp;
4675218822Sdim	    this_hdr = &(elf_section_data(sec)->this_hdr);
4676218822Sdim	    if (this_hdr->sh_size != 0
4677218822Sdim		&& !ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, p))
4678218822Sdim	      {
4679218822Sdim		(*_bfd_error_handler)
4680218822Sdim		  (_("%B: section `%A' can't be allocated in segment %d"),
4681218822Sdim		   abfd, sec, j);
4682218822Sdim		bfd_set_error (bfd_error_bad_value);
4683218822Sdim		return FALSE;
4684218822Sdim	      }
4685218822Sdim	  }
468633965Sjdp    }
468733965Sjdp
468833965Sjdp  elf_tdata (abfd)->next_file_pos = off;
4689130563Sobrien  return TRUE;
469033965Sjdp}
469133965Sjdp
4692218822Sdim/* Assign file positions for the other sections.  */
469333965Sjdp
4694218822Sdimstatic bfd_boolean
4695218822Sdimassign_file_positions_for_non_load_sections (bfd *abfd,
4696218822Sdim					     struct bfd_link_info *link_info)
469733965Sjdp{
4698130563Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
4699218822Sdim  Elf_Internal_Shdr **i_shdrpp;
4700218822Sdim  Elf_Internal_Shdr **hdrpp;
4701218822Sdim  Elf_Internal_Phdr *phdrs;
4702218822Sdim  Elf_Internal_Phdr *p;
4703218822Sdim  struct elf_segment_map *m;
4704218822Sdim  bfd_vma filehdr_vaddr, filehdr_paddr;
4705218822Sdim  bfd_vma phdrs_vaddr, phdrs_paddr;
4706218822Sdim  file_ptr off;
4707218822Sdim  unsigned int num_sec;
4708218822Sdim  unsigned int i;
4709218822Sdim  unsigned int count;
471033965Sjdp
4711218822Sdim  i_shdrpp = elf_elfsections (abfd);
4712218822Sdim  num_sec = elf_numsections (abfd);
4713218822Sdim  off = elf_tdata (abfd)->next_file_pos;
4714218822Sdim  for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
471533965Sjdp    {
4716218822Sdim      struct elf_obj_tdata *tdata = elf_tdata (abfd);
4717218822Sdim      Elf_Internal_Shdr *hdr;
471833965Sjdp
4719218822Sdim      hdr = *hdrpp;
4720218822Sdim      if (hdr->bfd_section != NULL
4721218822Sdim	  && (hdr->bfd_section->filepos != 0
4722218822Sdim	      || (hdr->sh_type == SHT_NOBITS
4723218822Sdim		  && hdr->contents == NULL)))
4724218822Sdim	BFD_ASSERT (hdr->sh_offset == hdr->bfd_section->filepos);
4725218822Sdim      else if ((hdr->sh_flags & SHF_ALLOC) != 0)
4726218822Sdim	{
4727218822Sdim	  if (hdr->sh_size != 0)
4728218822Sdim	    ((*_bfd_error_handler)
4729218822Sdim	     (_("%B: warning: allocated section `%s' not in segment"),
4730218822Sdim	      abfd,
4731218822Sdim	      (hdr->bfd_section == NULL
4732218822Sdim	       ? "*unknown*"
4733218822Sdim	       : hdr->bfd_section->name)));
4734218822Sdim	  /* We don't need to page align empty sections.  */
4735218822Sdim	  if ((abfd->flags & D_PAGED) != 0 && hdr->sh_size != 0)
4736218822Sdim	    off += vma_page_aligned_bias (hdr->sh_addr, off,
4737218822Sdim					  bed->maxpagesize);
4738218822Sdim	  else
4739218822Sdim	    off += vma_page_aligned_bias (hdr->sh_addr, off,
4740218822Sdim					  hdr->sh_addralign);
4741218822Sdim	  off = _bfd_elf_assign_file_position_for_section (hdr, off,
4742218822Sdim							   FALSE);
4743218822Sdim	}
4744218822Sdim      else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
4745218822Sdim		&& hdr->bfd_section == NULL)
4746218822Sdim	       || hdr == i_shdrpp[tdata->symtab_section]
4747218822Sdim	       || hdr == i_shdrpp[tdata->symtab_shndx_section]
4748218822Sdim	       || hdr == i_shdrpp[tdata->strtab_section])
4749218822Sdim	hdr->sh_offset = -1;
4750218822Sdim      else
4751218822Sdim	off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
475233965Sjdp
4753218822Sdim      if (i == SHN_LORESERVE - 1)
4754218822Sdim	{
4755218822Sdim	  i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
4756218822Sdim	  hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
4757218822Sdim	}
475833965Sjdp    }
475933965Sjdp
4760218822Sdim  /* Now that we have set the section file positions, we can set up
4761218822Sdim     the file positions for the non PT_LOAD segments.  */
4762218822Sdim  count = 0;
4763218822Sdim  filehdr_vaddr = 0;
4764218822Sdim  filehdr_paddr = 0;
4765218822Sdim  phdrs_vaddr = bed->maxpagesize + bed->s->sizeof_ehdr;
4766218822Sdim  phdrs_paddr = 0;
4767218822Sdim  phdrs = elf_tdata (abfd)->phdr;
4768218822Sdim  for (m = elf_tdata (abfd)->segment_map, p = phdrs;
4769218822Sdim       m != NULL;
4770218822Sdim       m = m->next, p++)
477133965Sjdp    {
4772218822Sdim      ++count;
4773218822Sdim      if (p->p_type != PT_LOAD)
4774218822Sdim	continue;
477533965Sjdp
4776218822Sdim      if (m->includes_filehdr)
477733965Sjdp	{
4778218822Sdim	  filehdr_vaddr = p->p_vaddr;
4779218822Sdim	  filehdr_paddr = p->p_paddr;
478033965Sjdp	}
4781218822Sdim      if (m->includes_phdrs)
4782218822Sdim	{
4783218822Sdim	  phdrs_vaddr = p->p_vaddr;
4784218822Sdim	  phdrs_paddr = p->p_paddr;
4785218822Sdim	  if (m->includes_filehdr)
4786218822Sdim	    {
4787218822Sdim	      phdrs_vaddr += bed->s->sizeof_ehdr;
4788218822Sdim	      phdrs_paddr += bed->s->sizeof_ehdr;
4789218822Sdim	    }
4790218822Sdim	}
479133965Sjdp    }
479233965Sjdp
4793218822Sdim  for (m = elf_tdata (abfd)->segment_map, p = phdrs;
4794218822Sdim       m != NULL;
4795218822Sdim       m = m->next, p++)
4796104838Sobrien    {
4797218822Sdim      if (m->count != 0)
4798104838Sobrien	{
4799218822Sdim	  if (p->p_type != PT_LOAD
4800218822Sdim	      && (p->p_type != PT_NOTE || bfd_get_format (abfd) != bfd_core))
4801218822Sdim	    {
4802218822Sdim	      Elf_Internal_Shdr *hdr;
4803218822Sdim	      BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs);
4804218822Sdim
4805218822Sdim	      hdr = &elf_section_data (m->sections[m->count - 1])->this_hdr;
4806218822Sdim	      p->p_filesz = (m->sections[m->count - 1]->filepos
4807218822Sdim			     - m->sections[0]->filepos);
4808218822Sdim	      if (hdr->sh_type != SHT_NOBITS)
4809218822Sdim		p->p_filesz += hdr->sh_size;
4810218822Sdim
4811218822Sdim	      p->p_offset = m->sections[0]->filepos;
4812218822Sdim	    }
4813104838Sobrien	}
4814218822Sdim      else
4815218822Sdim	{
4816218822Sdim	  if (m->includes_filehdr)
4817218822Sdim	    {
4818218822Sdim	      p->p_vaddr = filehdr_vaddr;
4819218822Sdim	      if (! m->p_paddr_valid)
4820218822Sdim		p->p_paddr = filehdr_paddr;
4821218822Sdim	    }
4822218822Sdim	  else if (m->includes_phdrs)
4823218822Sdim	    {
4824218822Sdim	      p->p_vaddr = phdrs_vaddr;
4825218822Sdim	      if (! m->p_paddr_valid)
4826218822Sdim		p->p_paddr = phdrs_paddr;
4827218822Sdim	    }
4828218822Sdim	  else if (p->p_type == PT_GNU_RELRO)
4829218822Sdim	    {
4830218822Sdim	      Elf_Internal_Phdr *lp;
4831104838Sobrien
4832218822Sdim	      for (lp = phdrs; lp < phdrs + count; ++lp)
4833218822Sdim		{
4834218822Sdim		  if (lp->p_type == PT_LOAD
4835218822Sdim		      && lp->p_vaddr <= link_info->relro_end
4836218822Sdim		      && lp->p_vaddr >= link_info->relro_start
4837218822Sdim		      && (lp->p_vaddr + lp->p_filesz
4838218822Sdim			  >= link_info->relro_end))
4839218822Sdim		    break;
4840218822Sdim		}
484133965Sjdp
4842218822Sdim	      if (lp < phdrs + count
4843218822Sdim		  && link_info->relro_end > lp->p_vaddr)
4844218822Sdim		{
4845218822Sdim		  p->p_vaddr = lp->p_vaddr;
4846218822Sdim		  p->p_paddr = lp->p_paddr;
4847218822Sdim		  p->p_offset = lp->p_offset;
4848218822Sdim		  p->p_filesz = link_info->relro_end - lp->p_vaddr;
4849218822Sdim		  p->p_memsz = p->p_filesz;
4850218822Sdim		  p->p_align = 1;
4851218822Sdim		  p->p_flags = (lp->p_flags & ~PF_W);
4852218822Sdim		}
4853218822Sdim	      else
4854218822Sdim		{
4855218822Sdim		  memset (p, 0, sizeof *p);
4856218822Sdim		  p->p_type = PT_NULL;
4857218822Sdim		}
4858218822Sdim	    }
4859218822Sdim	}
486033965Sjdp    }
486133965Sjdp
4862218822Sdim  elf_tdata (abfd)->next_file_pos = off;
4863218822Sdim
4864218822Sdim  return TRUE;
486533965Sjdp}
486633965Sjdp
486733965Sjdp/* Work out the file positions of all the sections.  This is called by
486833965Sjdp   _bfd_elf_compute_section_file_positions.  All the section sizes and
486933965Sjdp   VMAs must be known before this is called.
487033965Sjdp
4871218822Sdim   Reloc sections come in two flavours: Those processed specially as
4872218822Sdim   "side-channel" data attached to a section to which they apply, and
4873218822Sdim   those that bfd doesn't process as relocations.  The latter sort are
4874218822Sdim   stored in a normal bfd section by bfd_section_from_shdr.   We don't
4875218822Sdim   consider the former sort here, unless they form part of the loadable
4876218822Sdim   image.  Reloc sections not assigned here will be handled later by
4877218822Sdim   assign_file_positions_for_relocs.
487833965Sjdp
487933965Sjdp   We also don't set the positions of the .symtab and .strtab here.  */
488033965Sjdp
4881130563Sobrienstatic bfd_boolean
4882130563Sobrienassign_file_positions_except_relocs (bfd *abfd,
4883130563Sobrien				     struct bfd_link_info *link_info)
488433965Sjdp{
4885218822Sdim  struct elf_obj_tdata *tdata = elf_tdata (abfd);
4886218822Sdim  Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
488733965Sjdp  file_ptr off;
4888130563Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
488933965Sjdp
489060508Sobrien  if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
489160508Sobrien      && bfd_get_format (abfd) != bfd_core)
489233965Sjdp    {
4893218822Sdim      Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd);
4894218822Sdim      unsigned int num_sec = elf_numsections (abfd);
489533965Sjdp      Elf_Internal_Shdr **hdrpp;
489633965Sjdp      unsigned int i;
489733965Sjdp
489833965Sjdp      /* Start after the ELF header.  */
489933965Sjdp      off = i_ehdrp->e_ehsize;
490033965Sjdp
490133965Sjdp      /* We are not creating an executable, which means that we are
490233965Sjdp	 not creating a program header, and that the actual order of
490333965Sjdp	 the sections in the file is unimportant.  */
490489860Sobrien      for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
490533965Sjdp	{
490633965Sjdp	  Elf_Internal_Shdr *hdr;
490733965Sjdp
490833965Sjdp	  hdr = *hdrpp;
4909218822Sdim	  if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
4910218822Sdim	       && hdr->bfd_section == NULL)
491189860Sobrien	      || i == tdata->symtab_section
491289860Sobrien	      || i == tdata->symtab_shndx_section
491389860Sobrien	      || i == tdata->strtab_section)
491433965Sjdp	    {
491533965Sjdp	      hdr->sh_offset = -1;
491633965Sjdp	    }
491789860Sobrien	  else
4918130563Sobrien	    off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
491989860Sobrien
492089860Sobrien	  if (i == SHN_LORESERVE - 1)
492133965Sjdp	    {
492289860Sobrien	      i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
492389860Sobrien	      hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
492433965Sjdp	    }
492533965Sjdp	}
492633965Sjdp    }
492733965Sjdp  else
492833965Sjdp    {
4929218822Sdim      unsigned int alloc;
493033965Sjdp
493133965Sjdp      /* Assign file positions for the loaded sections based on the
4932218822Sdim	 assignment of sections to segments.  */
4933218822Sdim      if (!assign_file_positions_for_load_sections (abfd, link_info))
4934130563Sobrien	return FALSE;
493533965Sjdp
4936218822Sdim      /* And for non-load sections.  */
4937218822Sdim      if (!assign_file_positions_for_non_load_sections (abfd, link_info))
4938218822Sdim	return FALSE;
493933965Sjdp
4940218822Sdim      if (bed->elf_backend_modify_program_headers != NULL)
494133965Sjdp	{
4942218822Sdim	  if (!(*bed->elf_backend_modify_program_headers) (abfd, link_info))
4943218822Sdim	    return FALSE;
4944218822Sdim	}
494533965Sjdp
4946218822Sdim      /* Write out the program headers.  */
4947218822Sdim      alloc = tdata->program_header_size / bed->s->sizeof_phdr;
4948218822Sdim      if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0
4949218822Sdim	  || bed->s->write_out_phdrs (abfd, tdata->phdr, alloc) != 0)
4950218822Sdim	return FALSE;
495189860Sobrien
4952218822Sdim      off = tdata->next_file_pos;
495333965Sjdp    }
495433965Sjdp
495533965Sjdp  /* Place the section headers.  */
4956130563Sobrien  off = align_file_position (off, 1 << bed->s->log_file_align);
495733965Sjdp  i_ehdrp->e_shoff = off;
495833965Sjdp  off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize;
495933965Sjdp
4960218822Sdim  tdata->next_file_pos = off;
496133965Sjdp
4962130563Sobrien  return TRUE;
496333965Sjdp}
496433965Sjdp
4965130563Sobrienstatic bfd_boolean
4966130563Sobrienprep_headers (bfd *abfd)
496733965Sjdp{
496833965Sjdp  Elf_Internal_Ehdr *i_ehdrp;	/* Elf file header, internal form */
496960508Sobrien  Elf_Internal_Phdr *i_phdrp = 0; /* Program header table, internal form */
497033965Sjdp  Elf_Internal_Shdr **i_shdrp;	/* Section header table, internal form */
497189860Sobrien  struct elf_strtab_hash *shstrtab;
4972130563Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
497333965Sjdp
497433965Sjdp  i_ehdrp = elf_elfheader (abfd);
497533965Sjdp  i_shdrp = elf_elfsections (abfd);
497633965Sjdp
497789860Sobrien  shstrtab = _bfd_elf_strtab_init ();
497833965Sjdp  if (shstrtab == NULL)
4979130563Sobrien    return FALSE;
498033965Sjdp
498133965Sjdp  elf_shstrtab (abfd) = shstrtab;
498233965Sjdp
498333965Sjdp  i_ehdrp->e_ident[EI_MAG0] = ELFMAG0;
498433965Sjdp  i_ehdrp->e_ident[EI_MAG1] = ELFMAG1;
498533965Sjdp  i_ehdrp->e_ident[EI_MAG2] = ELFMAG2;
498633965Sjdp  i_ehdrp->e_ident[EI_MAG3] = ELFMAG3;
498733965Sjdp
498833965Sjdp  i_ehdrp->e_ident[EI_CLASS] = bed->s->elfclass;
498933965Sjdp  i_ehdrp->e_ident[EI_DATA] =
499033965Sjdp    bfd_big_endian (abfd) ? ELFDATA2MSB : ELFDATA2LSB;
499133965Sjdp  i_ehdrp->e_ident[EI_VERSION] = bed->s->ev_current;
499233965Sjdp
499359342Sobrien  i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
499459342Sobrien
499533965Sjdp  if ((abfd->flags & DYNAMIC) != 0)
499633965Sjdp    i_ehdrp->e_type = ET_DYN;
499733965Sjdp  else if ((abfd->flags & EXEC_P) != 0)
499833965Sjdp    i_ehdrp->e_type = ET_EXEC;
499960508Sobrien  else if (bfd_get_format (abfd) == bfd_core)
500060508Sobrien    i_ehdrp->e_type = ET_CORE;
500133965Sjdp  else
500233965Sjdp    i_ehdrp->e_type = ET_REL;
500333965Sjdp
500433965Sjdp  switch (bfd_get_arch (abfd))
500533965Sjdp    {
500633965Sjdp    case bfd_arch_unknown:
500733965Sjdp      i_ehdrp->e_machine = EM_NONE;
500833965Sjdp      break;
500989860Sobrien
501089860Sobrien      /* There used to be a long list of cases here, each one setting
501189860Sobrien	 e_machine to the same EM_* macro #defined as ELF_MACHINE_CODE
501289860Sobrien	 in the corresponding bfd definition.  To avoid duplication,
501389860Sobrien	 the switch was removed.  Machines that need special handling
501489860Sobrien	 can generally do it in elf_backend_final_write_processing(),
501589860Sobrien	 unless they need the information earlier than the final write.
501689860Sobrien	 Such need can generally be supplied by replacing the tests for
501789860Sobrien	 e_machine with the conditions used to determine it.  */
501889860Sobrien    default:
5019130563Sobrien      i_ehdrp->e_machine = bed->elf_machine_code;
5020130563Sobrien    }
502189860Sobrien
502233965Sjdp  i_ehdrp->e_version = bed->s->ev_current;
502333965Sjdp  i_ehdrp->e_ehsize = bed->s->sizeof_ehdr;
502433965Sjdp
502577301Sobrien  /* No program header, for now.  */
502633965Sjdp  i_ehdrp->e_phoff = 0;
502733965Sjdp  i_ehdrp->e_phentsize = 0;
502833965Sjdp  i_ehdrp->e_phnum = 0;
502933965Sjdp
503077301Sobrien  /* Each bfd section is section header entry.  */
503133965Sjdp  i_ehdrp->e_entry = bfd_get_start_address (abfd);
503233965Sjdp  i_ehdrp->e_shentsize = bed->s->sizeof_shdr;
503333965Sjdp
503477301Sobrien  /* If we're building an executable, we'll need a program header table.  */
503533965Sjdp  if (abfd->flags & EXEC_P)
5036218822Sdim    /* It all happens later.  */
5037218822Sdim    ;
503833965Sjdp  else
503933965Sjdp    {
504033965Sjdp      i_ehdrp->e_phentsize = 0;
504133965Sjdp      i_phdrp = 0;
504233965Sjdp      i_ehdrp->e_phoff = 0;
504333965Sjdp    }
504433965Sjdp
504533965Sjdp  elf_tdata (abfd)->symtab_hdr.sh_name =
5046130563Sobrien    (unsigned int) _bfd_elf_strtab_add (shstrtab, ".symtab", FALSE);
504733965Sjdp  elf_tdata (abfd)->strtab_hdr.sh_name =
5048130563Sobrien    (unsigned int) _bfd_elf_strtab_add (shstrtab, ".strtab", FALSE);
504933965Sjdp  elf_tdata (abfd)->shstrtab_hdr.sh_name =
5050130563Sobrien    (unsigned int) _bfd_elf_strtab_add (shstrtab, ".shstrtab", FALSE);
505133965Sjdp  if (elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1
505233965Sjdp      || elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1
505333965Sjdp      || elf_tdata (abfd)->shstrtab_hdr.sh_name == (unsigned int) -1)
5054130563Sobrien    return FALSE;
505533965Sjdp
5056130563Sobrien  return TRUE;
505733965Sjdp}
505833965Sjdp
505933965Sjdp/* Assign file positions for all the reloc sections which are not part
506033965Sjdp   of the loadable file image.  */
506133965Sjdp
506233965Sjdpvoid
5063130563Sobrien_bfd_elf_assign_file_positions_for_relocs (bfd *abfd)
506433965Sjdp{
506533965Sjdp  file_ptr off;
506689860Sobrien  unsigned int i, num_sec;
506733965Sjdp  Elf_Internal_Shdr **shdrpp;
506833965Sjdp
506933965Sjdp  off = elf_tdata (abfd)->next_file_pos;
507033965Sjdp
507189860Sobrien  num_sec = elf_numsections (abfd);
507289860Sobrien  for (i = 1, shdrpp = elf_elfsections (abfd) + 1; i < num_sec; i++, shdrpp++)
507333965Sjdp    {
507433965Sjdp      Elf_Internal_Shdr *shdrp;
507533965Sjdp
507633965Sjdp      shdrp = *shdrpp;
507733965Sjdp      if ((shdrp->sh_type == SHT_REL || shdrp->sh_type == SHT_RELA)
507833965Sjdp	  && shdrp->sh_offset == -1)
5079130563Sobrien	off = _bfd_elf_assign_file_position_for_section (shdrp, off, TRUE);
508033965Sjdp    }
508133965Sjdp
508233965Sjdp  elf_tdata (abfd)->next_file_pos = off;
508333965Sjdp}
508433965Sjdp
5085130563Sobrienbfd_boolean
5086130563Sobrien_bfd_elf_write_object_contents (bfd *abfd)
508733965Sjdp{
5088130563Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
508933965Sjdp  Elf_Internal_Ehdr *i_ehdrp;
509033965Sjdp  Elf_Internal_Shdr **i_shdrp;
5091130563Sobrien  bfd_boolean failed;
509289860Sobrien  unsigned int count, num_sec;
509333965Sjdp
509433965Sjdp  if (! abfd->output_has_begun
5095130563Sobrien      && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
5096130563Sobrien    return FALSE;
509733965Sjdp
509833965Sjdp  i_shdrp = elf_elfsections (abfd);
509933965Sjdp  i_ehdrp = elf_elfheader (abfd);
510033965Sjdp
5101130563Sobrien  failed = FALSE;
510233965Sjdp  bfd_map_over_sections (abfd, bed->s->write_relocs, &failed);
510333965Sjdp  if (failed)
5104130563Sobrien    return FALSE;
510560508Sobrien
510633965Sjdp  _bfd_elf_assign_file_positions_for_relocs (abfd);
510733965Sjdp
510877301Sobrien  /* After writing the headers, we need to write the sections too...  */
510989860Sobrien  num_sec = elf_numsections (abfd);
511089860Sobrien  for (count = 1; count < num_sec; count++)
511133965Sjdp    {
511233965Sjdp      if (bed->elf_backend_section_processing)
511333965Sjdp	(*bed->elf_backend_section_processing) (abfd, i_shdrp[count]);
511433965Sjdp      if (i_shdrp[count]->contents)
511533965Sjdp	{
511689860Sobrien	  bfd_size_type amt = i_shdrp[count]->sh_size;
511789860Sobrien
511833965Sjdp	  if (bfd_seek (abfd, i_shdrp[count]->sh_offset, SEEK_SET) != 0
511989860Sobrien	      || bfd_bwrite (i_shdrp[count]->contents, amt, abfd) != amt)
5120130563Sobrien	    return FALSE;
512133965Sjdp	}
512289860Sobrien      if (count == SHN_LORESERVE - 1)
512389860Sobrien	count += SHN_HIRESERVE + 1 - SHN_LORESERVE;
512433965Sjdp    }
512533965Sjdp
512633965Sjdp  /* Write out the section header names.  */
5127218822Sdim  if (elf_shstrtab (abfd) != NULL
5128218822Sdim      && (bfd_seek (abfd, elf_tdata (abfd)->shstrtab_hdr.sh_offset, SEEK_SET) != 0
5129218822Sdim	  || !_bfd_elf_strtab_emit (abfd, elf_shstrtab (abfd))))
5130130563Sobrien    return FALSE;
513133965Sjdp
513233965Sjdp  if (bed->elf_backend_final_write_processing)
513333965Sjdp    (*bed->elf_backend_final_write_processing) (abfd,
513433965Sjdp						elf_tdata (abfd)->linker);
513533965Sjdp
513633965Sjdp  return bed->s->write_shdrs_and_ehdr (abfd);
513733965Sjdp}
513833965Sjdp
5139130563Sobrienbfd_boolean
5140130563Sobrien_bfd_elf_write_corefile_contents (bfd *abfd)
514160508Sobrien{
514277301Sobrien  /* Hopefully this can be done just like an object file.  */
514360508Sobrien  return _bfd_elf_write_object_contents (abfd);
514460508Sobrien}
514577301Sobrien
514677301Sobrien/* Given a section, search the header to find them.  */
514777301Sobrien
514833965Sjdpint
5149130563Sobrien_bfd_elf_section_from_bfd_section (bfd *abfd, struct bfd_section *asect)
515033965Sjdp{
5151130563Sobrien  const struct elf_backend_data *bed;
515233965Sjdp  int index;
515333965Sjdp
515489860Sobrien  if (elf_section_data (asect) != NULL
515589860Sobrien      && elf_section_data (asect)->this_idx != 0)
515689860Sobrien    return elf_section_data (asect)->this_idx;
515789860Sobrien
515889860Sobrien  if (bfd_is_abs_section (asect))
515989860Sobrien    index = SHN_ABS;
516089860Sobrien  else if (bfd_is_com_section (asect))
516189860Sobrien    index = SHN_COMMON;
516289860Sobrien  else if (bfd_is_und_section (asect))
516389860Sobrien    index = SHN_UNDEF;
516489860Sobrien  else
5165218822Sdim    index = -1;
516689860Sobrien
516789860Sobrien  bed = get_elf_backend_data (abfd);
516833965Sjdp  if (bed->elf_backend_section_from_bfd_section)
516933965Sjdp    {
517089860Sobrien      int retval = index;
517133965Sjdp
517289860Sobrien      if ((*bed->elf_backend_section_from_bfd_section) (abfd, asect, &retval))
517389860Sobrien	return retval;
517433965Sjdp    }
517533965Sjdp
517689860Sobrien  if (index == -1)
517789860Sobrien    bfd_set_error (bfd_error_nonrepresentable_section);
517833965Sjdp
517989860Sobrien  return index;
518033965Sjdp}
518133965Sjdp
518233965Sjdp/* Given a BFD symbol, return the index in the ELF symbol table, or -1
518333965Sjdp   on error.  */
518433965Sjdp
518533965Sjdpint
5186130563Sobrien_bfd_elf_symbol_from_bfd_symbol (bfd *abfd, asymbol **asym_ptr_ptr)
518733965Sjdp{
518833965Sjdp  asymbol *asym_ptr = *asym_ptr_ptr;
518933965Sjdp  int idx;
519033965Sjdp  flagword flags = asym_ptr->flags;
519133965Sjdp
519233965Sjdp  /* When gas creates relocations against local labels, it creates its
519333965Sjdp     own symbol for the section, but does put the symbol into the
519433965Sjdp     symbol chain, so udata is 0.  When the linker is generating
519533965Sjdp     relocatable output, this section symbol may be for one of the
519633965Sjdp     input sections rather than the output section.  */
519733965Sjdp  if (asym_ptr->udata.i == 0
519833965Sjdp      && (flags & BSF_SECTION_SYM)
519933965Sjdp      && asym_ptr->section)
520033965Sjdp    {
5201218822Sdim      asection *sec;
520233965Sjdp      int indx;
520333965Sjdp
5204218822Sdim      sec = asym_ptr->section;
5205218822Sdim      if (sec->owner != abfd && sec->output_section != NULL)
5206218822Sdim	sec = sec->output_section;
5207218822Sdim      if (sec->owner == abfd
5208218822Sdim	  && (indx = sec->index) < elf_num_section_syms (abfd)
520989860Sobrien	  && elf_section_syms (abfd)[indx] != NULL)
521033965Sjdp	asym_ptr->udata.i = elf_section_syms (abfd)[indx]->udata.i;
521133965Sjdp    }
521233965Sjdp
521333965Sjdp  idx = asym_ptr->udata.i;
521433965Sjdp
521533965Sjdp  if (idx == 0)
521633965Sjdp    {
521733965Sjdp      /* This case can occur when using --strip-symbol on a symbol
5218218822Sdim	 which is used in a relocation entry.  */
521933965Sjdp      (*_bfd_error_handler)
5220218822Sdim	(_("%B: symbol `%s' required but not present"),
5221218822Sdim	 abfd, bfd_asymbol_name (asym_ptr));
522233965Sjdp      bfd_set_error (bfd_error_no_symbols);
522333965Sjdp      return -1;
522433965Sjdp    }
522533965Sjdp
522633965Sjdp#if DEBUG & 4
522733965Sjdp  {
522833965Sjdp    fprintf (stderr,
522991047Sobrien	     "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8lx%s\n",
523033965Sjdp	     (long) asym_ptr, asym_ptr->name, idx, flags,
523133965Sjdp	     elf_symbol_flags (flags));
523233965Sjdp    fflush (stderr);
523333965Sjdp  }
523433965Sjdp#endif
523533965Sjdp
523633965Sjdp  return idx;
523733965Sjdp}
523833965Sjdp
5239218822Sdim/* Rewrite program header information.  */
524033965Sjdp
5241130563Sobrienstatic bfd_boolean
5242218822Sdimrewrite_elf_program_header (bfd *ibfd, bfd *obfd)
524333965Sjdp{
5244130563Sobrien  Elf_Internal_Ehdr *iehdr;
5245130563Sobrien  struct elf_segment_map *map;
5246130563Sobrien  struct elf_segment_map *map_first;
5247130563Sobrien  struct elf_segment_map **pointer_to_map;
5248130563Sobrien  Elf_Internal_Phdr *segment;
5249130563Sobrien  asection *section;
5250130563Sobrien  unsigned int i;
5251130563Sobrien  unsigned int num_segments;
5252130563Sobrien  bfd_boolean phdr_included = FALSE;
5253130563Sobrien  bfd_vma maxpagesize;
5254130563Sobrien  struct elf_segment_map *phdr_adjust_seg = NULL;
5255130563Sobrien  unsigned int phdr_adjust_num = 0;
5256130563Sobrien  const struct elf_backend_data *bed;
525733965Sjdp
5258104838Sobrien  bed = get_elf_backend_data (ibfd);
525933965Sjdp  iehdr = elf_elfheader (ibfd);
526033965Sjdp
526177301Sobrien  map_first = NULL;
526277301Sobrien  pointer_to_map = &map_first;
526333965Sjdp
526460508Sobrien  num_segments = elf_elfheader (ibfd)->e_phnum;
526577301Sobrien  maxpagesize = get_elf_backend_data (obfd)->maxpagesize;
526660508Sobrien
526777301Sobrien  /* Returns the end address of the segment + 1.  */
5268104838Sobrien#define SEGMENT_END(segment, start)					\
5269104838Sobrien  (start + (segment->p_memsz > segment->p_filesz			\
5270104838Sobrien	    ? segment->p_memsz : segment->p_filesz))
527160508Sobrien
5272130563Sobrien#define SECTION_SIZE(section, segment)					\
5273130563Sobrien  (((section->flags & (SEC_HAS_CONTENTS | SEC_THREAD_LOCAL))		\
5274130563Sobrien    != SEC_THREAD_LOCAL || segment->p_type == PT_TLS)			\
5275218822Sdim   ? section->size : 0)
5276130563Sobrien
5277130563Sobrien  /* Returns TRUE if the given section is contained within
527877301Sobrien     the given segment.  VMA addresses are compared.  */
5279104838Sobrien#define IS_CONTAINED_BY_VMA(section, segment)				\
5280104838Sobrien  (section->vma >= segment->p_vaddr					\
5281130563Sobrien   && (section->vma + SECTION_SIZE (section, segment)			\
5282104838Sobrien       <= (SEGMENT_END (segment, segment->p_vaddr))))
528360508Sobrien
5284130563Sobrien  /* Returns TRUE if the given section is contained within
528577301Sobrien     the given segment.  LMA addresses are compared.  */
5286104838Sobrien#define IS_CONTAINED_BY_LMA(section, segment, base)			\
5287104838Sobrien  (section->lma >= base							\
5288130563Sobrien   && (section->lma + SECTION_SIZE (section, segment)			\
5289104838Sobrien       <= SEGMENT_END (segment, base)))
529077301Sobrien
529177301Sobrien  /* Special case: corefile "NOTE" section containing regs, prpsinfo etc.  */
5292104838Sobrien#define IS_COREFILE_NOTE(p, s)						\
5293104838Sobrien  (p->p_type == PT_NOTE							\
5294104838Sobrien   && bfd_get_format (ibfd) == bfd_core					\
5295104838Sobrien   && s->vma == 0 && s->lma == 0					\
5296104838Sobrien   && (bfd_vma) s->filepos >= p->p_offset				\
5297218822Sdim   && ((bfd_vma) s->filepos + s->size					\
5298104838Sobrien       <= p->p_offset + p->p_filesz))
529960508Sobrien
530060508Sobrien  /* The complicated case when p_vaddr is 0 is to handle the Solaris
530160508Sobrien     linker, which generates a PT_INTERP section with p_vaddr and
530260508Sobrien     p_memsz set to 0.  */
5303104838Sobrien#define IS_SOLARIS_PT_INTERP(p, s)					\
5304104838Sobrien  (p->p_vaddr == 0							\
5305104838Sobrien   && p->p_paddr == 0							\
5306104838Sobrien   && p->p_memsz == 0							\
5307104838Sobrien   && p->p_filesz > 0							\
5308104838Sobrien   && (s->flags & SEC_HAS_CONTENTS) != 0				\
5309218822Sdim   && s->size > 0							\
5310104838Sobrien   && (bfd_vma) s->filepos >= p->p_offset				\
5311218822Sdim   && ((bfd_vma) s->filepos + s->size					\
5312104838Sobrien       <= p->p_offset + p->p_filesz))
531360508Sobrien
531477301Sobrien  /* Decide if the given section should be included in the given segment.
531577301Sobrien     A section will be included if:
531689860Sobrien       1. It is within the address space of the segment -- we use the LMA
5317218822Sdim	  if that is set for the segment and the VMA otherwise,
531877301Sobrien       2. It is an allocated segment,
531977301Sobrien       3. There is an output section associated with it,
5320130563Sobrien       4. The section has not already been allocated to a previous segment.
5321130563Sobrien       5. PT_GNU_STACK segments do not include any sections.
5322130563Sobrien       6. PT_TLS segment includes only SHF_TLS sections.
5323218822Sdim       7. SHF_TLS sections are only in PT_TLS or PT_LOAD segments.
5324218822Sdim       8. PT_DYNAMIC should not contain empty sections at the beginning
5325218822Sdim	  (with the possible exception of .dynamic).  */
5326218822Sdim#define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed)		\
5327104838Sobrien  ((((segment->p_paddr							\
5328104838Sobrien      ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr)	\
5329104838Sobrien      : IS_CONTAINED_BY_VMA (section, segment))				\
533089860Sobrien     && (section->flags & SEC_ALLOC) != 0)				\
5331107496Sobrien    || IS_COREFILE_NOTE (segment, section))				\
5332130563Sobrien   && segment->p_type != PT_GNU_STACK					\
5333130563Sobrien   && (segment->p_type != PT_TLS					\
5334130563Sobrien       || (section->flags & SEC_THREAD_LOCAL))				\
5335130563Sobrien   && (segment->p_type == PT_LOAD					\
5336130563Sobrien       || segment->p_type == PT_TLS					\
5337130563Sobrien       || (section->flags & SEC_THREAD_LOCAL) == 0)			\
5338218822Sdim   && (segment->p_type != PT_DYNAMIC					\
5339218822Sdim       || SECTION_SIZE (section, segment) > 0				\
5340218822Sdim       || (segment->p_paddr						\
5341218822Sdim	   ? segment->p_paddr != section->lma				\
5342218822Sdim	   : segment->p_vaddr != section->vma)				\
5343218822Sdim       || (strcmp (bfd_get_section_name (ibfd, section), ".dynamic")	\
5344218822Sdim	   == 0))							\
5345104838Sobrien   && ! section->segment_mark)
534677301Sobrien
5347218822Sdim/* If the output section of a section in the input segment is NULL,
5348218822Sdim   it is removed from the corresponding output segment.   */
5349218822Sdim#define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed)		\
5350218822Sdim  (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed)		\
5351218822Sdim   && section->output_section != NULL)
5352218822Sdim
5353130563Sobrien  /* Returns TRUE iff seg1 starts after the end of seg2.  */
5354130563Sobrien#define SEGMENT_AFTER_SEGMENT(seg1, seg2, field)			\
5355130563Sobrien  (seg1->field >= SEGMENT_END (seg2, seg2->field))
535677301Sobrien
5357130563Sobrien  /* Returns TRUE iff seg1 and seg2 overlap. Segments overlap iff both
5358130563Sobrien     their VMA address ranges and their LMA address ranges overlap.
5359130563Sobrien     It is possible to have overlapping VMA ranges without overlapping LMA
5360130563Sobrien     ranges.  RedBoot images for example can have both .data and .bss mapped
5361130563Sobrien     to the same VMA range, but with the .data section mapped to a different
5362130563Sobrien     LMA.  */
5363104838Sobrien#define SEGMENT_OVERLAPS(seg1, seg2)					\
5364130563Sobrien  (   !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_vaddr)			\
5365218822Sdim	|| SEGMENT_AFTER_SEGMENT (seg2, seg1, p_vaddr))			\
5366130563Sobrien   && !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_paddr)			\
5367218822Sdim	|| SEGMENT_AFTER_SEGMENT (seg2, seg1, p_paddr)))
536877301Sobrien
536977301Sobrien  /* Initialise the segment mark field.  */
537077301Sobrien  for (section = ibfd->sections; section != NULL; section = section->next)
5371130563Sobrien    section->segment_mark = FALSE;
537277301Sobrien
537360508Sobrien  /* Scan through the segments specified in the program header
537477301Sobrien     of the input BFD.  For this first scan we look for overlaps
537589860Sobrien     in the loadable segments.  These can be created by weird
5376104838Sobrien     parameters to objcopy.  Also, fix some solaris weirdness.  */
537777301Sobrien  for (i = 0, segment = elf_tdata (ibfd)->phdr;
537877301Sobrien       i < num_segments;
537977301Sobrien       i++, segment++)
538033965Sjdp    {
538160508Sobrien      unsigned int j;
538277301Sobrien      Elf_Internal_Phdr *segment2;
538333965Sjdp
5384104838Sobrien      if (segment->p_type == PT_INTERP)
5385104838Sobrien	for (section = ibfd->sections; section; section = section->next)
5386104838Sobrien	  if (IS_SOLARIS_PT_INTERP (segment, section))
5387104838Sobrien	    {
5388104838Sobrien	      /* Mininal change so that the normal section to segment
5389130563Sobrien		 assignment code will work.  */
5390104838Sobrien	      segment->p_vaddr = section->vma;
5391104838Sobrien	      break;
5392104838Sobrien	    }
5393104838Sobrien
539477301Sobrien      if (segment->p_type != PT_LOAD)
539577301Sobrien	continue;
539633965Sjdp
539777301Sobrien      /* Determine if this segment overlaps any previous segments.  */
539877301Sobrien      for (j = 0, segment2 = elf_tdata (ibfd)->phdr; j < i; j++, segment2 ++)
539977301Sobrien	{
540077301Sobrien	  bfd_signed_vma extra_length;
540177301Sobrien
540277301Sobrien	  if (segment2->p_type != PT_LOAD
540377301Sobrien	      || ! SEGMENT_OVERLAPS (segment, segment2))
540477301Sobrien	    continue;
540577301Sobrien
540677301Sobrien	  /* Merge the two segments together.  */
540777301Sobrien	  if (segment2->p_vaddr < segment->p_vaddr)
540877301Sobrien	    {
540977301Sobrien	      /* Extend SEGMENT2 to include SEGMENT and then delete
5410218822Sdim		 SEGMENT.  */
541177301Sobrien	      extra_length =
541277301Sobrien		SEGMENT_END (segment, segment->p_vaddr)
541377301Sobrien		- SEGMENT_END (segment2, segment2->p_vaddr);
541477301Sobrien
541577301Sobrien	      if (extra_length > 0)
541677301Sobrien		{
541777301Sobrien		  segment2->p_memsz  += extra_length;
541877301Sobrien		  segment2->p_filesz += extra_length;
541977301Sobrien		}
542077301Sobrien
542177301Sobrien	      segment->p_type = PT_NULL;
542277301Sobrien
542377301Sobrien	      /* Since we have deleted P we must restart the outer loop.  */
542477301Sobrien	      i = 0;
542577301Sobrien	      segment = elf_tdata (ibfd)->phdr;
542677301Sobrien	      break;
542777301Sobrien	    }
542877301Sobrien	  else
542977301Sobrien	    {
543077301Sobrien	      /* Extend SEGMENT to include SEGMENT2 and then delete
5431218822Sdim		 SEGMENT2.  */
543277301Sobrien	      extra_length =
543377301Sobrien		SEGMENT_END (segment2, segment2->p_vaddr)
543477301Sobrien		- SEGMENT_END (segment, segment->p_vaddr);
543577301Sobrien
543677301Sobrien	      if (extra_length > 0)
543777301Sobrien		{
543877301Sobrien		  segment->p_memsz  += extra_length;
543977301Sobrien		  segment->p_filesz += extra_length;
544077301Sobrien		}
544177301Sobrien
544277301Sobrien	      segment2->p_type = PT_NULL;
544377301Sobrien	    }
544477301Sobrien	}
544577301Sobrien    }
544677301Sobrien
544777301Sobrien  /* The second scan attempts to assign sections to segments.  */
544877301Sobrien  for (i = 0, segment = elf_tdata (ibfd)->phdr;
544977301Sobrien       i < num_segments;
545077301Sobrien       i ++, segment ++)
545177301Sobrien    {
545277301Sobrien      unsigned int  section_count;
545377301Sobrien      asection **   sections;
545477301Sobrien      asection *    output_section;
545577301Sobrien      unsigned int  isec;
545677301Sobrien      bfd_vma       matching_lma;
545777301Sobrien      bfd_vma       suggested_lma;
545877301Sobrien      unsigned int  j;
545989860Sobrien      bfd_size_type amt;
5460218822Sdim      asection *    first_section;
546177301Sobrien
546277301Sobrien      if (segment->p_type == PT_NULL)
546377301Sobrien	continue;
546477301Sobrien
5465218822Sdim      first_section = NULL;
546677301Sobrien      /* Compute how many sections might be placed into this segment.  */
5467130563Sobrien      for (section = ibfd->sections, section_count = 0;
5468130563Sobrien	   section != NULL;
5469130563Sobrien	   section = section->next)
5470218822Sdim	{
5471218822Sdim	  /* Find the first section in the input segment, which may be
5472218822Sdim	     removed from the corresponding output segment.   */
5473218822Sdim	  if (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed))
5474218822Sdim	    {
5475218822Sdim	      if (first_section == NULL)
5476218822Sdim		first_section = section;
5477218822Sdim	      if (section->output_section != NULL)
5478218822Sdim		++section_count;
5479218822Sdim	    }
5480218822Sdim	}
548177301Sobrien
5482130563Sobrien      /* Allocate a segment map big enough to contain
5483130563Sobrien	 all of the sections we have selected.  */
548489860Sobrien      amt = sizeof (struct elf_segment_map);
548589860Sobrien      amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
5486218822Sdim      map = bfd_zalloc (obfd, amt);
548777301Sobrien      if (map == NULL)
5488130563Sobrien	return FALSE;
548933965Sjdp
549060508Sobrien      /* Initialise the fields of the segment map.  Default to
549160508Sobrien	 using the physical address of the segment in the input BFD.  */
549277301Sobrien      map->next          = NULL;
549377301Sobrien      map->p_type        = segment->p_type;
549477301Sobrien      map->p_flags       = segment->p_flags;
549577301Sobrien      map->p_flags_valid = 1;
549633965Sjdp
5497218822Sdim      /* If the first section in the input segment is removed, there is
5498218822Sdim	 no need to preserve segment physical address in the corresponding
5499218822Sdim	 output segment.  */
5500218822Sdim      if (!first_section || first_section->output_section != NULL)
5501218822Sdim	{
5502218822Sdim	  map->p_paddr = segment->p_paddr;
5503218822Sdim	  map->p_paddr_valid = 1;
5504218822Sdim	}
5505218822Sdim
550660508Sobrien      /* Determine if this segment contains the ELF file header
550760508Sobrien	 and if it contains the program headers themselves.  */
550877301Sobrien      map->includes_filehdr = (segment->p_offset == 0
550977301Sobrien			       && segment->p_filesz >= iehdr->e_ehsize);
551033965Sjdp
551177301Sobrien      map->includes_phdrs = 0;
551233965Sjdp
551377301Sobrien      if (! phdr_included || segment->p_type != PT_LOAD)
551460508Sobrien	{
551577301Sobrien	  map->includes_phdrs =
551677301Sobrien	    (segment->p_offset <= (bfd_vma) iehdr->e_phoff
551777301Sobrien	     && (segment->p_offset + segment->p_filesz
551860508Sobrien		 >= ((bfd_vma) iehdr->e_phoff
551960508Sobrien		     + iehdr->e_phnum * iehdr->e_phentsize)));
552077301Sobrien
552177301Sobrien	  if (segment->p_type == PT_LOAD && map->includes_phdrs)
5522130563Sobrien	    phdr_included = TRUE;
552360508Sobrien	}
552460508Sobrien
552577301Sobrien      if (section_count == 0)
552660508Sobrien	{
552760508Sobrien	  /* Special segments, such as the PT_PHDR segment, may contain
552860508Sobrien	     no sections, but ordinary, loadable segments should contain
5529104838Sobrien	     something.  They are allowed by the ELF spec however, so only
5530104838Sobrien	     a warning is produced.  */
553177301Sobrien	  if (segment->p_type == PT_LOAD)
5532104838Sobrien	    (*_bfd_error_handler)
5533218822Sdim	      (_("%B: warning: Empty loadable segment detected, is this intentional ?\n"),
5534218822Sdim	       ibfd);
553560508Sobrien
553677301Sobrien	  map->count = 0;
553777301Sobrien	  *pointer_to_map = map;
553877301Sobrien	  pointer_to_map = &map->next;
553960508Sobrien
554060508Sobrien	  continue;
554160508Sobrien	}
554260508Sobrien
554360508Sobrien      /* Now scan the sections in the input BFD again and attempt
554460508Sobrien	 to add their corresponding output sections to the segment map.
554560508Sobrien	 The problem here is how to handle an output section which has
554660508Sobrien	 been moved (ie had its LMA changed).  There are four possibilities:
554760508Sobrien
554860508Sobrien	 1. None of the sections have been moved.
554960508Sobrien	    In this case we can continue to use the segment LMA from the
555060508Sobrien	    input BFD.
555160508Sobrien
555260508Sobrien	 2. All of the sections have been moved by the same amount.
555360508Sobrien	    In this case we can change the segment's LMA to match the LMA
555460508Sobrien	    of the first section.
555560508Sobrien
555660508Sobrien	 3. Some of the sections have been moved, others have not.
555760508Sobrien	    In this case those sections which have not been moved can be
555860508Sobrien	    placed in the current segment which will have to have its size,
555960508Sobrien	    and possibly its LMA changed, and a new segment or segments will
556060508Sobrien	    have to be created to contain the other sections.
556160508Sobrien
5562130563Sobrien	 4. The sections have been moved, but not by the same amount.
556360508Sobrien	    In this case we can change the segment's LMA to match the LMA
556460508Sobrien	    of the first section and we will have to create a new segment
556560508Sobrien	    or segments to contain the other sections.
556660508Sobrien
556760508Sobrien	 In order to save time, we allocate an array to hold the section
556860508Sobrien	 pointers that we are interested in.  As these sections get assigned
556960508Sobrien	 to a segment, they are removed from this array.  */
557060508Sobrien
5571104838Sobrien      /* Gcc 2.96 miscompiles this code on mips. Don't do casting here
5572104838Sobrien	 to work around this long long bug.  */
5573218822Sdim      sections = bfd_malloc2 (section_count, sizeof (asection *));
557460508Sobrien      if (sections == NULL)
5575130563Sobrien	return FALSE;
557660508Sobrien
557760508Sobrien      /* Step One: Scan for segment vs section LMA conflicts.
557860508Sobrien	 Also add the sections to the section array allocated above.
557960508Sobrien	 Also add the sections to the current segment.  In the common
558060508Sobrien	 case, where the sections have not been moved, this means that
558160508Sobrien	 we have completely filled the segment, and there is nothing
558260508Sobrien	 more to do.  */
558333965Sjdp      isec = 0;
558460508Sobrien      matching_lma = 0;
558560508Sobrien      suggested_lma = 0;
558660508Sobrien
558777301Sobrien      for (j = 0, section = ibfd->sections;
558877301Sobrien	   section != NULL;
558977301Sobrien	   section = section->next)
559033965Sjdp	{
5591104838Sobrien	  if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed))
559233965Sjdp	    {
559377301Sobrien	      output_section = section->output_section;
559460508Sobrien
559577301Sobrien	      sections[j ++] = section;
559677301Sobrien
559760508Sobrien	      /* The Solaris native linker always sets p_paddr to 0.
559860508Sobrien		 We try to catch that case here, and set it to the
5599104838Sobrien		 correct value.  Note - some backends require that
5600104838Sobrien		 p_paddr be left as zero.  */
560177301Sobrien	      if (segment->p_paddr == 0
560277301Sobrien		  && segment->p_vaddr != 0
5603104838Sobrien		  && (! bed->want_p_paddr_set_to_zero)
560460508Sobrien		  && isec == 0
560577301Sobrien		  && output_section->lma != 0
560677301Sobrien		  && (output_section->vma == (segment->p_vaddr
560777301Sobrien					      + (map->includes_filehdr
560877301Sobrien						 ? iehdr->e_ehsize
560977301Sobrien						 : 0)
561077301Sobrien					      + (map->includes_phdrs
561189860Sobrien						 ? (iehdr->e_phnum
561289860Sobrien						    * iehdr->e_phentsize)
561377301Sobrien						 : 0))))
561477301Sobrien		map->p_paddr = segment->p_vaddr;
561560508Sobrien
561660508Sobrien	      /* Match up the physical address of the segment with the
561760508Sobrien		 LMA address of the output section.  */
561877301Sobrien	      if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr)
5619104838Sobrien		  || IS_COREFILE_NOTE (segment, section)
5620104838Sobrien		  || (bed->want_p_paddr_set_to_zero &&
5621218822Sdim		      IS_CONTAINED_BY_VMA (output_section, segment)))
562260508Sobrien		{
562360508Sobrien		  if (matching_lma == 0)
562477301Sobrien		    matching_lma = output_section->lma;
562560508Sobrien
562660508Sobrien		  /* We assume that if the section fits within the segment
562777301Sobrien		     then it does not overlap any other section within that
562860508Sobrien		     segment.  */
562977301Sobrien		  map->sections[isec ++] = output_section;
563060508Sobrien		}
563160508Sobrien	      else if (suggested_lma == 0)
563277301Sobrien		suggested_lma = output_section->lma;
563333965Sjdp	    }
563433965Sjdp	}
563533965Sjdp
563677301Sobrien      BFD_ASSERT (j == section_count);
563760508Sobrien
563860508Sobrien      /* Step Two: Adjust the physical address of the current segment,
563960508Sobrien	 if necessary.  */
564077301Sobrien      if (isec == section_count)
564160508Sobrien	{
564260508Sobrien	  /* All of the sections fitted within the segment as currently
564360508Sobrien	     specified.  This is the default case.  Add the segment to
564460508Sobrien	     the list of built segments and carry on to process the next
564560508Sobrien	     program header in the input BFD.  */
564677301Sobrien	  map->count = section_count;
564777301Sobrien	  *pointer_to_map = map;
564877301Sobrien	  pointer_to_map = &map->next;
564960508Sobrien
5650218822Sdim	  if (matching_lma != map->p_paddr
5651218822Sdim	      && !map->includes_filehdr && !map->includes_phdrs)
5652218822Sdim	    /* There is some padding before the first section in the
5653218822Sdim	       segment.  So, we must account for that in the output
5654218822Sdim	       segment's vma.  */
5655218822Sdim	    map->p_vaddr_offset = matching_lma - map->p_paddr;
5656218822Sdim
565760508Sobrien	  free (sections);
565860508Sobrien	  continue;
565960508Sobrien	}
566060508Sobrien      else
566160508Sobrien	{
566260508Sobrien	  if (matching_lma != 0)
566360508Sobrien	    {
566460508Sobrien	      /* At least one section fits inside the current segment.
566560508Sobrien		 Keep it, but modify its physical address to match the
566660508Sobrien		 LMA of the first section that fitted.  */
566777301Sobrien	      map->p_paddr = matching_lma;
566860508Sobrien	    }
566960508Sobrien	  else
567060508Sobrien	    {
567160508Sobrien	      /* None of the sections fitted inside the current segment.
567260508Sobrien		 Change the current segment's physical address to match
567360508Sobrien		 the LMA of the first section.  */
567477301Sobrien	      map->p_paddr = suggested_lma;
567560508Sobrien	    }
567660508Sobrien
567777301Sobrien	  /* Offset the segment physical address from the lma
567877301Sobrien	     to allow for space taken up by elf headers.  */
567977301Sobrien	  if (map->includes_filehdr)
568077301Sobrien	    map->p_paddr -= iehdr->e_ehsize;
568160508Sobrien
568277301Sobrien	  if (map->includes_phdrs)
568377301Sobrien	    {
568477301Sobrien	      map->p_paddr -= iehdr->e_phnum * iehdr->e_phentsize;
568577301Sobrien
568677301Sobrien	      /* iehdr->e_phnum is just an estimate of the number
568777301Sobrien		 of program headers that we will need.  Make a note
568877301Sobrien		 here of the number we used and the segment we chose
568977301Sobrien		 to hold these headers, so that we can adjust the
569077301Sobrien		 offset when we know the correct value.  */
569177301Sobrien	      phdr_adjust_num = iehdr->e_phnum;
569277301Sobrien	      phdr_adjust_seg = map;
569377301Sobrien	    }
569460508Sobrien	}
569560508Sobrien
569660508Sobrien      /* Step Three: Loop over the sections again, this time assigning
5697104838Sobrien	 those that fit to the current segment and removing them from the
569860508Sobrien	 sections array; but making sure not to leave large gaps.  Once all
569960508Sobrien	 possible sections have been assigned to the current segment it is
570060508Sobrien	 added to the list of built segments and if sections still remain
570160508Sobrien	 to be assigned, a new segment is constructed before repeating
570260508Sobrien	 the loop.  */
570360508Sobrien      isec = 0;
570460508Sobrien      do
570560508Sobrien	{
570677301Sobrien	  map->count = 0;
570760508Sobrien	  suggested_lma = 0;
570860508Sobrien
570960508Sobrien	  /* Fill the current segment with sections that fit.  */
571077301Sobrien	  for (j = 0; j < section_count; j++)
571160508Sobrien	    {
571277301Sobrien	      section = sections[j];
571360508Sobrien
571477301Sobrien	      if (section == NULL)
571560508Sobrien		continue;
571660508Sobrien
571777301Sobrien	      output_section = section->output_section;
571860508Sobrien
571977301Sobrien	      BFD_ASSERT (output_section != NULL);
572077301Sobrien
572177301Sobrien	      if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr)
572277301Sobrien		  || IS_COREFILE_NOTE (segment, section))
572360508Sobrien		{
572477301Sobrien		  if (map->count == 0)
572560508Sobrien		    {
572660508Sobrien		      /* If the first section in a segment does not start at
572777301Sobrien			 the beginning of the segment, then something is
572877301Sobrien			 wrong.  */
572977301Sobrien		      if (output_section->lma !=
573077301Sobrien			  (map->p_paddr
573177301Sobrien			   + (map->includes_filehdr ? iehdr->e_ehsize : 0)
573277301Sobrien			   + (map->includes_phdrs
573377301Sobrien			      ? iehdr->e_phnum * iehdr->e_phentsize
573477301Sobrien			      : 0)))
573560508Sobrien			abort ();
573660508Sobrien		    }
573760508Sobrien		  else
573860508Sobrien		    {
573960508Sobrien		      asection * prev_sec;
574060508Sobrien
574177301Sobrien		      prev_sec = map->sections[map->count - 1];
574260508Sobrien
574360508Sobrien		      /* If the gap between the end of the previous section
574477301Sobrien			 and the start of this section is more than
574577301Sobrien			 maxpagesize then we need to start a new segment.  */
5746218822Sdim		      if ((BFD_ALIGN (prev_sec->lma + prev_sec->size,
574789860Sobrien				      maxpagesize)
5748104838Sobrien			   < BFD_ALIGN (output_section->lma, maxpagesize))
5749218822Sdim			  || ((prev_sec->lma + prev_sec->size)
575089860Sobrien			      > output_section->lma))
575160508Sobrien			{
575260508Sobrien			  if (suggested_lma == 0)
575377301Sobrien			    suggested_lma = output_section->lma;
575460508Sobrien
575560508Sobrien			  continue;
575660508Sobrien			}
575760508Sobrien		    }
575860508Sobrien
575977301Sobrien		  map->sections[map->count++] = output_section;
576060508Sobrien		  ++isec;
576160508Sobrien		  sections[j] = NULL;
5762130563Sobrien		  section->segment_mark = TRUE;
576360508Sobrien		}
576460508Sobrien	      else if (suggested_lma == 0)
576577301Sobrien		suggested_lma = output_section->lma;
576660508Sobrien	    }
576760508Sobrien
576877301Sobrien	  BFD_ASSERT (map->count > 0);
576960508Sobrien
577060508Sobrien	  /* Add the current segment to the list of built segments.  */
577177301Sobrien	  *pointer_to_map = map;
577277301Sobrien	  pointer_to_map = &map->next;
577360508Sobrien
577477301Sobrien	  if (isec < section_count)
577560508Sobrien	    {
577660508Sobrien	      /* We still have not allocated all of the sections to
577760508Sobrien		 segments.  Create a new segment here, initialise it
577860508Sobrien		 and carry on looping.  */
577989860Sobrien	      amt = sizeof (struct elf_segment_map);
578089860Sobrien	      amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
5781130563Sobrien	      map = bfd_alloc (obfd, amt);
578277301Sobrien	      if (map == NULL)
5783130563Sobrien		{
5784130563Sobrien		  free (sections);
5785130563Sobrien		  return FALSE;
5786130563Sobrien		}
578760508Sobrien
578860508Sobrien	      /* Initialise the fields of the segment map.  Set the physical
578960508Sobrien		 physical address to the LMA of the first section that has
579060508Sobrien		 not yet been assigned.  */
579177301Sobrien	      map->next             = NULL;
579277301Sobrien	      map->p_type           = segment->p_type;
579377301Sobrien	      map->p_flags          = segment->p_flags;
579477301Sobrien	      map->p_flags_valid    = 1;
579577301Sobrien	      map->p_paddr          = suggested_lma;
579677301Sobrien	      map->p_paddr_valid    = 1;
579777301Sobrien	      map->includes_filehdr = 0;
579877301Sobrien	      map->includes_phdrs   = 0;
579960508Sobrien	    }
580060508Sobrien	}
580177301Sobrien      while (isec < section_count);
580260508Sobrien
580360508Sobrien      free (sections);
580433965Sjdp    }
580533965Sjdp
580638891Sjdp  /* The Solaris linker creates program headers in which all the
580738891Sjdp     p_paddr fields are zero.  When we try to objcopy or strip such a
580838891Sjdp     file, we get confused.  Check for this case, and if we find it
580938891Sjdp     reset the p_paddr_valid fields.  */
581077301Sobrien  for (map = map_first; map != NULL; map = map->next)
581177301Sobrien    if (map->p_paddr != 0)
581238891Sjdp      break;
581377301Sobrien  if (map == NULL)
5814130563Sobrien    for (map = map_first; map != NULL; map = map->next)
5815130563Sobrien      map->p_paddr_valid = 0;
581638891Sjdp
581777301Sobrien  elf_tdata (obfd)->segment_map = map_first;
581833965Sjdp
581977301Sobrien  /* If we had to estimate the number of program headers that were
582089860Sobrien     going to be needed, then check our estimate now and adjust
582177301Sobrien     the offset if necessary.  */
582277301Sobrien  if (phdr_adjust_seg != NULL)
582377301Sobrien    {
582477301Sobrien      unsigned int count;
582577301Sobrien
582677301Sobrien      for (count = 0, map = map_first; map != NULL; map = map->next)
582777301Sobrien	count++;
582877301Sobrien
582977301Sobrien      if (count > phdr_adjust_num)
583077301Sobrien	phdr_adjust_seg->p_paddr
583177301Sobrien	  -= (count - phdr_adjust_num) * iehdr->e_phentsize;
583277301Sobrien    }
583377301Sobrien
583477301Sobrien#undef SEGMENT_END
5835130563Sobrien#undef SECTION_SIZE
583677301Sobrien#undef IS_CONTAINED_BY_VMA
583777301Sobrien#undef IS_CONTAINED_BY_LMA
583877301Sobrien#undef IS_COREFILE_NOTE
583960508Sobrien#undef IS_SOLARIS_PT_INTERP
5840218822Sdim#undef IS_SECTION_IN_INPUT_SEGMENT
584177301Sobrien#undef INCLUDE_SECTION_IN_SEGMENT
584277301Sobrien#undef SEGMENT_AFTER_SEGMENT
584377301Sobrien#undef SEGMENT_OVERLAPS
5844130563Sobrien  return TRUE;
584533965Sjdp}
584633965Sjdp
5847218822Sdim/* Copy ELF program header information.  */
5848218822Sdim
5849218822Sdimstatic bfd_boolean
5850218822Sdimcopy_elf_program_header (bfd *ibfd, bfd *obfd)
5851218822Sdim{
5852218822Sdim  Elf_Internal_Ehdr *iehdr;
5853218822Sdim  struct elf_segment_map *map;
5854218822Sdim  struct elf_segment_map *map_first;
5855218822Sdim  struct elf_segment_map **pointer_to_map;
5856218822Sdim  Elf_Internal_Phdr *segment;
5857218822Sdim  unsigned int i;
5858218822Sdim  unsigned int num_segments;
5859218822Sdim  bfd_boolean phdr_included = FALSE;
5860218822Sdim
5861218822Sdim  iehdr = elf_elfheader (ibfd);
5862218822Sdim
5863218822Sdim  map_first = NULL;
5864218822Sdim  pointer_to_map = &map_first;
5865218822Sdim
5866218822Sdim  num_segments = elf_elfheader (ibfd)->e_phnum;
5867218822Sdim  for (i = 0, segment = elf_tdata (ibfd)->phdr;
5868218822Sdim       i < num_segments;
5869218822Sdim       i++, segment++)
5870218822Sdim    {
5871218822Sdim      asection *section;
5872218822Sdim      unsigned int section_count;
5873218822Sdim      bfd_size_type amt;
5874218822Sdim      Elf_Internal_Shdr *this_hdr;
5875218822Sdim      asection *first_section = NULL;
5876218822Sdim
5877218822Sdim      /* FIXME: Do we need to copy PT_NULL segment?  */
5878218822Sdim      if (segment->p_type == PT_NULL)
5879218822Sdim	continue;
5880218822Sdim
5881218822Sdim      /* Compute how many sections are in this segment.  */
5882218822Sdim      for (section = ibfd->sections, section_count = 0;
5883218822Sdim	   section != NULL;
5884218822Sdim	   section = section->next)
5885218822Sdim	{
5886218822Sdim	  this_hdr = &(elf_section_data(section)->this_hdr);
5887218822Sdim	  if (ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, segment))
5888218822Sdim	    {
5889218822Sdim	      if (!first_section)
5890218822Sdim		first_section = section;
5891218822Sdim	      section_count++;
5892218822Sdim	    }
5893218822Sdim	}
5894218822Sdim
5895218822Sdim      /* Allocate a segment map big enough to contain
5896218822Sdim	 all of the sections we have selected.  */
5897218822Sdim      amt = sizeof (struct elf_segment_map);
5898218822Sdim      if (section_count != 0)
5899218822Sdim	amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
5900218822Sdim      map = bfd_zalloc (obfd, amt);
5901218822Sdim      if (map == NULL)
5902218822Sdim	return FALSE;
5903218822Sdim
5904218822Sdim      /* Initialize the fields of the output segment map with the
5905218822Sdim	 input segment.  */
5906218822Sdim      map->next = NULL;
5907218822Sdim      map->p_type = segment->p_type;
5908218822Sdim      map->p_flags = segment->p_flags;
5909218822Sdim      map->p_flags_valid = 1;
5910218822Sdim      map->p_paddr = segment->p_paddr;
5911218822Sdim      map->p_paddr_valid = 1;
5912218822Sdim      map->p_align = segment->p_align;
5913218822Sdim      map->p_align_valid = 1;
5914218822Sdim      map->p_vaddr_offset = 0;
5915218822Sdim
5916218822Sdim      /* Determine if this segment contains the ELF file header
5917218822Sdim	 and if it contains the program headers themselves.  */
5918218822Sdim      map->includes_filehdr = (segment->p_offset == 0
5919218822Sdim			       && segment->p_filesz >= iehdr->e_ehsize);
5920218822Sdim
5921218822Sdim      map->includes_phdrs = 0;
5922218822Sdim      if (! phdr_included || segment->p_type != PT_LOAD)
5923218822Sdim	{
5924218822Sdim	  map->includes_phdrs =
5925218822Sdim	    (segment->p_offset <= (bfd_vma) iehdr->e_phoff
5926218822Sdim	     && (segment->p_offset + segment->p_filesz
5927218822Sdim		 >= ((bfd_vma) iehdr->e_phoff
5928218822Sdim		     + iehdr->e_phnum * iehdr->e_phentsize)));
5929218822Sdim
5930218822Sdim	  if (segment->p_type == PT_LOAD && map->includes_phdrs)
5931218822Sdim	    phdr_included = TRUE;
5932218822Sdim	}
5933218822Sdim
5934218822Sdim      if (!map->includes_phdrs && !map->includes_filehdr)
5935218822Sdim	/* There is some other padding before the first section.  */
5936218822Sdim	map->p_vaddr_offset = ((first_section ? first_section->lma : 0)
5937218822Sdim			       - segment->p_paddr);
5938218822Sdim
5939218822Sdim      if (section_count != 0)
5940218822Sdim	{
5941218822Sdim	  unsigned int isec = 0;
5942218822Sdim
5943218822Sdim	  for (section = first_section;
5944218822Sdim	       section != NULL;
5945218822Sdim	       section = section->next)
5946218822Sdim	    {
5947218822Sdim	      this_hdr = &(elf_section_data(section)->this_hdr);
5948218822Sdim	      if (ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, segment))
5949218822Sdim		{
5950218822Sdim		  map->sections[isec++] = section->output_section;
5951218822Sdim		  if (isec == section_count)
5952218822Sdim		    break;
5953218822Sdim		}
5954218822Sdim	    }
5955218822Sdim	}
5956218822Sdim
5957218822Sdim      map->count = section_count;
5958218822Sdim      *pointer_to_map = map;
5959218822Sdim      pointer_to_map = &map->next;
5960218822Sdim    }
5961218822Sdim
5962218822Sdim  elf_tdata (obfd)->segment_map = map_first;
5963218822Sdim  return TRUE;
5964218822Sdim}
5965218822Sdim
5966218822Sdim/* Copy private BFD data.  This copies or rewrites ELF program header
5967218822Sdim   information.  */
5968218822Sdim
5969218822Sdimstatic bfd_boolean
5970218822Sdimcopy_private_bfd_data (bfd *ibfd, bfd *obfd)
5971218822Sdim{
5972218822Sdim  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
5973218822Sdim      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
5974218822Sdim    return TRUE;
5975218822Sdim
5976218822Sdim  if (elf_tdata (ibfd)->phdr == NULL)
5977218822Sdim    return TRUE;
5978218822Sdim
5979218822Sdim  if (ibfd->xvec == obfd->xvec)
5980218822Sdim    {
5981218822Sdim      /* Check to see if any sections in the input BFD
5982218822Sdim	 covered by ELF program header have changed.  */
5983218822Sdim      Elf_Internal_Phdr *segment;
5984218822Sdim      asection *section, *osec;
5985218822Sdim      unsigned int i, num_segments;
5986218822Sdim      Elf_Internal_Shdr *this_hdr;
5987218822Sdim
5988218822Sdim      /* Initialize the segment mark field.  */
5989218822Sdim      for (section = obfd->sections; section != NULL;
5990218822Sdim	   section = section->next)
5991218822Sdim	section->segment_mark = FALSE;
5992218822Sdim
5993218822Sdim      num_segments = elf_elfheader (ibfd)->e_phnum;
5994218822Sdim      for (i = 0, segment = elf_tdata (ibfd)->phdr;
5995218822Sdim	   i < num_segments;
5996218822Sdim	   i++, segment++)
5997218822Sdim	{
5998218822Sdim	  /* PR binutils/3535.  The Solaris linker always sets the p_paddr
5999218822Sdim	     and p_memsz fields of special segments (DYNAMIC, INTERP) to 0
6000218822Sdim	     which severly confuses things, so always regenerate the segment
6001218822Sdim	     map in this case.  */
6002218822Sdim	  if (segment->p_paddr == 0
6003218822Sdim	      && segment->p_memsz == 0
6004218822Sdim	      && (segment->p_type == PT_INTERP || segment->p_type == PT_DYNAMIC))
6005218822Sdim	    goto rewrite;
6006218822Sdim
6007218822Sdim	  for (section = ibfd->sections;
6008218822Sdim	       section != NULL; section = section->next)
6009218822Sdim	    {
6010218822Sdim	      /* We mark the output section so that we know it comes
6011218822Sdim		 from the input BFD.  */
6012218822Sdim	      osec = section->output_section;
6013218822Sdim	      if (osec)
6014218822Sdim		osec->segment_mark = TRUE;
6015218822Sdim
6016218822Sdim	      /* Check if this section is covered by the segment.  */
6017218822Sdim	      this_hdr = &(elf_section_data(section)->this_hdr);
6018218822Sdim	      if (ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, segment))
6019218822Sdim		{
6020218822Sdim		  /* FIXME: Check if its output section is changed or
6021218822Sdim		     removed.  What else do we need to check?  */
6022218822Sdim		  if (osec == NULL
6023218822Sdim		      || section->flags != osec->flags
6024218822Sdim		      || section->lma != osec->lma
6025218822Sdim		      || section->vma != osec->vma
6026218822Sdim		      || section->size != osec->size
6027218822Sdim		      || section->rawsize != osec->rawsize
6028218822Sdim		      || section->alignment_power != osec->alignment_power)
6029218822Sdim		    goto rewrite;
6030218822Sdim		}
6031218822Sdim	    }
6032218822Sdim	}
6033218822Sdim
6034218822Sdim      /* Check to see if any output section do not come from the
6035218822Sdim	 input BFD.  */
6036218822Sdim      for (section = obfd->sections; section != NULL;
6037218822Sdim	   section = section->next)
6038218822Sdim	{
6039218822Sdim	  if (section->segment_mark == FALSE)
6040218822Sdim	    goto rewrite;
6041218822Sdim	  else
6042218822Sdim	    section->segment_mark = FALSE;
6043218822Sdim	}
6044218822Sdim
6045218822Sdim      return copy_elf_program_header (ibfd, obfd);
6046218822Sdim    }
6047218822Sdim
6048218822Sdimrewrite:
6049218822Sdim  return rewrite_elf_program_header (ibfd, obfd);
6050218822Sdim}
6051218822Sdim
6052218822Sdim/* Initialize private output section information from input section.  */
6053218822Sdim
6054218822Sdimbfd_boolean
6055218822Sdim_bfd_elf_init_private_section_data (bfd *ibfd,
6056218822Sdim				    asection *isec,
6057218822Sdim				    bfd *obfd,
6058218822Sdim				    asection *osec,
6059218822Sdim				    struct bfd_link_info *link_info)
6060218822Sdim
6061218822Sdim{
6062218822Sdim  Elf_Internal_Shdr *ihdr, *ohdr;
6063218822Sdim  bfd_boolean need_group = link_info == NULL || link_info->relocatable;
6064218822Sdim
6065218822Sdim  if (ibfd->xvec->flavour != bfd_target_elf_flavour
6066218822Sdim      || obfd->xvec->flavour != bfd_target_elf_flavour)
6067218822Sdim    return TRUE;
6068218822Sdim
6069218822Sdim  /* Don't copy the output ELF section type from input if the
6070218822Sdim     output BFD section flags have been set to something different.
6071218822Sdim     elf_fake_sections will set ELF section type based on BFD
6072218822Sdim     section flags.  */
6073218822Sdim  if (elf_section_type (osec) == SHT_NULL
6074218822Sdim      && (osec->flags == isec->flags || !osec->flags))
6075218822Sdim    elf_section_type (osec) = elf_section_type (isec);
6076218822Sdim
6077218822Sdim  /* FIXME: Is this correct for all OS/PROC specific flags?  */
6078218822Sdim  elf_section_flags (osec) |= (elf_section_flags (isec)
6079218822Sdim			       & (SHF_MASKOS | SHF_MASKPROC));
6080218822Sdim
6081218822Sdim  /* Set things up for objcopy and relocatable link.  The output
6082218822Sdim     SHT_GROUP section will have its elf_next_in_group pointing back
6083218822Sdim     to the input group members.  Ignore linker created group section.
6084218822Sdim     See elfNN_ia64_object_p in elfxx-ia64.c.  */
6085218822Sdim  if (need_group)
6086218822Sdim    {
6087218822Sdim      if (elf_sec_group (isec) == NULL
6088218822Sdim	  || (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0)
6089218822Sdim	{
6090218822Sdim	  if (elf_section_flags (isec) & SHF_GROUP)
6091218822Sdim	    elf_section_flags (osec) |= SHF_GROUP;
6092218822Sdim	  elf_next_in_group (osec) = elf_next_in_group (isec);
6093218822Sdim	  elf_group_name (osec) = elf_group_name (isec);
6094218822Sdim	}
6095218822Sdim    }
6096218822Sdim
6097218822Sdim  ihdr = &elf_section_data (isec)->this_hdr;
6098218822Sdim
6099218822Sdim  /* We need to handle elf_linked_to_section for SHF_LINK_ORDER. We
6100218822Sdim     don't use the output section of the linked-to section since it
6101218822Sdim     may be NULL at this point.  */
6102218822Sdim  if ((ihdr->sh_flags & SHF_LINK_ORDER) != 0)
6103218822Sdim    {
6104218822Sdim      ohdr = &elf_section_data (osec)->this_hdr;
6105218822Sdim      ohdr->sh_flags |= SHF_LINK_ORDER;
6106218822Sdim      elf_linked_to_section (osec) = elf_linked_to_section (isec);
6107218822Sdim    }
6108218822Sdim
6109218822Sdim  osec->use_rela_p = isec->use_rela_p;
6110218822Sdim
6111218822Sdim  return TRUE;
6112218822Sdim}
6113218822Sdim
611433965Sjdp/* Copy private section information.  This copies over the entsize
611533965Sjdp   field, and sometimes the info field.  */
611633965Sjdp
6117130563Sobrienbfd_boolean
6118130563Sobrien_bfd_elf_copy_private_section_data (bfd *ibfd,
6119130563Sobrien				    asection *isec,
6120130563Sobrien				    bfd *obfd,
6121130563Sobrien				    asection *osec)
612233965Sjdp{
612333965Sjdp  Elf_Internal_Shdr *ihdr, *ohdr;
612433965Sjdp
612533965Sjdp  if (ibfd->xvec->flavour != bfd_target_elf_flavour
612633965Sjdp      || obfd->xvec->flavour != bfd_target_elf_flavour)
6127130563Sobrien    return TRUE;
612833965Sjdp
612933965Sjdp  ihdr = &elf_section_data (isec)->this_hdr;
613033965Sjdp  ohdr = &elf_section_data (osec)->this_hdr;
613133965Sjdp
613233965Sjdp  ohdr->sh_entsize = ihdr->sh_entsize;
613333965Sjdp
613433965Sjdp  if (ihdr->sh_type == SHT_SYMTAB
613533965Sjdp      || ihdr->sh_type == SHT_DYNSYM
613633965Sjdp      || ihdr->sh_type == SHT_GNU_verneed
613733965Sjdp      || ihdr->sh_type == SHT_GNU_verdef)
613833965Sjdp    ohdr->sh_info = ihdr->sh_info;
613933965Sjdp
6140218822Sdim  return _bfd_elf_init_private_section_data (ibfd, isec, obfd, osec,
6141218822Sdim					     NULL);
6142218822Sdim}
6143104838Sobrien
6144218822Sdim/* Copy private header information.  */
614560508Sobrien
6146218822Sdimbfd_boolean
6147218822Sdim_bfd_elf_copy_private_header_data (bfd *ibfd, bfd *obfd)
6148218822Sdim{
6149218822Sdim  asection *isec;
6150218822Sdim
6151218822Sdim  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
6152218822Sdim      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
6153218822Sdim    return TRUE;
6154218822Sdim
6155218822Sdim  /* Copy over private BFD data if it has not already been copied.
6156218822Sdim     This must be done here, rather than in the copy_private_bfd_data
6157218822Sdim     entry point, because the latter is called after the section
6158218822Sdim     contents have been set, which means that the program headers have
6159218822Sdim     already been worked out.  */
6160218822Sdim  if (elf_tdata (obfd)->segment_map == NULL && elf_tdata (ibfd)->phdr != NULL)
6161218822Sdim    {
6162218822Sdim      if (! copy_private_bfd_data (ibfd, obfd))
6163218822Sdim	return FALSE;
6164218822Sdim    }
6165218822Sdim
6166218822Sdim  /* _bfd_elf_copy_private_section_data copied over the SHF_GROUP flag
6167218822Sdim     but this might be wrong if we deleted the group section.  */
6168218822Sdim  for (isec = ibfd->sections; isec != NULL; isec = isec->next)
6169218822Sdim    if (elf_section_type (isec) == SHT_GROUP
6170218822Sdim	&& isec->output_section == NULL)
6171218822Sdim      {
6172218822Sdim	asection *first = elf_next_in_group (isec);
6173218822Sdim	asection *s = first;
6174218822Sdim	while (s != NULL)
6175218822Sdim	  {
6176218822Sdim	    if (s->output_section != NULL)
6177218822Sdim	      {
6178218822Sdim		elf_section_flags (s->output_section) &= ~SHF_GROUP;
6179218822Sdim		elf_group_name (s->output_section) = NULL;
6180218822Sdim	      }
6181218822Sdim	    s = elf_next_in_group (s);
6182218822Sdim	    if (s == first)
6183218822Sdim	      break;
6184218822Sdim	  }
6185218822Sdim      }
6186218822Sdim
6187130563Sobrien  return TRUE;
618833965Sjdp}
618933965Sjdp
619033965Sjdp/* Copy private symbol information.  If this symbol is in a section
619133965Sjdp   which we did not map into a BFD section, try to map the section
619233965Sjdp   index correctly.  We use special macro definitions for the mapped
619333965Sjdp   section indices; these definitions are interpreted by the
619433965Sjdp   swap_out_syms function.  */
619533965Sjdp
619689860Sobrien#define MAP_ONESYMTAB (SHN_HIOS + 1)
619789860Sobrien#define MAP_DYNSYMTAB (SHN_HIOS + 2)
619889860Sobrien#define MAP_STRTAB    (SHN_HIOS + 3)
619989860Sobrien#define MAP_SHSTRTAB  (SHN_HIOS + 4)
620089860Sobrien#define MAP_SYM_SHNDX (SHN_HIOS + 5)
620133965Sjdp
6202130563Sobrienbfd_boolean
6203130563Sobrien_bfd_elf_copy_private_symbol_data (bfd *ibfd,
6204130563Sobrien				   asymbol *isymarg,
6205130563Sobrien				   bfd *obfd,
6206130563Sobrien				   asymbol *osymarg)
620733965Sjdp{
620833965Sjdp  elf_symbol_type *isym, *osym;
620933965Sjdp
621033965Sjdp  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
621133965Sjdp      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
6212130563Sobrien    return TRUE;
621333965Sjdp
621433965Sjdp  isym = elf_symbol_from (ibfd, isymarg);
621533965Sjdp  osym = elf_symbol_from (obfd, osymarg);
621633965Sjdp
621733965Sjdp  if (isym != NULL
621833965Sjdp      && osym != NULL
621933965Sjdp      && bfd_is_abs_section (isym->symbol.section))
622033965Sjdp    {
622133965Sjdp      unsigned int shndx;
622233965Sjdp
622333965Sjdp      shndx = isym->internal_elf_sym.st_shndx;
622433965Sjdp      if (shndx == elf_onesymtab (ibfd))
622533965Sjdp	shndx = MAP_ONESYMTAB;
622633965Sjdp      else if (shndx == elf_dynsymtab (ibfd))
622733965Sjdp	shndx = MAP_DYNSYMTAB;
622833965Sjdp      else if (shndx == elf_tdata (ibfd)->strtab_section)
622933965Sjdp	shndx = MAP_STRTAB;
623033965Sjdp      else if (shndx == elf_tdata (ibfd)->shstrtab_section)
623133965Sjdp	shndx = MAP_SHSTRTAB;
623289860Sobrien      else if (shndx == elf_tdata (ibfd)->symtab_shndx_section)
623389860Sobrien	shndx = MAP_SYM_SHNDX;
623433965Sjdp      osym->internal_elf_sym.st_shndx = shndx;
623533965Sjdp    }
623633965Sjdp
6237130563Sobrien  return TRUE;
623833965Sjdp}
623933965Sjdp
624033965Sjdp/* Swap out the symbols.  */
624133965Sjdp
6242130563Sobrienstatic bfd_boolean
6243130563Sobrienswap_out_syms (bfd *abfd,
6244130563Sobrien	       struct bfd_strtab_hash **sttp,
6245130563Sobrien	       int relocatable_p)
624633965Sjdp{
6247130563Sobrien  const struct elf_backend_data *bed;
624889860Sobrien  int symcount;
624989860Sobrien  asymbol **syms;
625089860Sobrien  struct bfd_strtab_hash *stt;
625189860Sobrien  Elf_Internal_Shdr *symtab_hdr;
625289860Sobrien  Elf_Internal_Shdr *symtab_shndx_hdr;
625389860Sobrien  Elf_Internal_Shdr *symstrtab_hdr;
6254218822Sdim  bfd_byte *outbound_syms;
6255218822Sdim  bfd_byte *outbound_shndx;
625689860Sobrien  int idx;
625789860Sobrien  bfd_size_type amt;
6258130563Sobrien  bfd_boolean name_local_sections;
625933965Sjdp
626033965Sjdp  if (!elf_map_symbols (abfd))
6261130563Sobrien    return FALSE;
626233965Sjdp
626377301Sobrien  /* Dump out the symtabs.  */
626489860Sobrien  stt = _bfd_elf_stringtab_init ();
626589860Sobrien  if (stt == NULL)
6266130563Sobrien    return FALSE;
626733965Sjdp
626889860Sobrien  bed = get_elf_backend_data (abfd);
626989860Sobrien  symcount = bfd_get_symcount (abfd);
627089860Sobrien  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
627189860Sobrien  symtab_hdr->sh_type = SHT_SYMTAB;
627289860Sobrien  symtab_hdr->sh_entsize = bed->s->sizeof_sym;
627389860Sobrien  symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1);
627489860Sobrien  symtab_hdr->sh_info = elf_num_locals (abfd) + 1;
6275130563Sobrien  symtab_hdr->sh_addralign = 1 << bed->s->log_file_align;
627633965Sjdp
627789860Sobrien  symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
627889860Sobrien  symstrtab_hdr->sh_type = SHT_STRTAB;
627933965Sjdp
6280218822Sdim  outbound_syms = bfd_alloc2 (abfd, 1 + symcount, bed->s->sizeof_sym);
628189860Sobrien  if (outbound_syms == NULL)
6282130563Sobrien    {
6283130563Sobrien      _bfd_stringtab_free (stt);
6284130563Sobrien      return FALSE;
6285130563Sobrien    }
6286130563Sobrien  symtab_hdr->contents = outbound_syms;
628733965Sjdp
628889860Sobrien  outbound_shndx = NULL;
628989860Sobrien  symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
629089860Sobrien  if (symtab_shndx_hdr->sh_name != 0)
629189860Sobrien    {
629289860Sobrien      amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx);
6293218822Sdim      outbound_shndx = bfd_zalloc2 (abfd, 1 + symcount,
6294218822Sdim				    sizeof (Elf_External_Sym_Shndx));
629589860Sobrien      if (outbound_shndx == NULL)
6296130563Sobrien	{
6297130563Sobrien	  _bfd_stringtab_free (stt);
6298130563Sobrien	  return FALSE;
6299130563Sobrien	}
6300130563Sobrien
630189860Sobrien      symtab_shndx_hdr->contents = outbound_shndx;
630289860Sobrien      symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
630389860Sobrien      symtab_shndx_hdr->sh_size = amt;
630489860Sobrien      symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx);
630589860Sobrien      symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx);
630689860Sobrien    }
630733965Sjdp
6308130563Sobrien  /* Now generate the data (for "contents").  */
630989860Sobrien  {
631089860Sobrien    /* Fill in zeroth symbol and swap it out.  */
631189860Sobrien    Elf_Internal_Sym sym;
631289860Sobrien    sym.st_name = 0;
631389860Sobrien    sym.st_value = 0;
631489860Sobrien    sym.st_size = 0;
631589860Sobrien    sym.st_info = 0;
631689860Sobrien    sym.st_other = 0;
631789860Sobrien    sym.st_shndx = SHN_UNDEF;
631889860Sobrien    bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx);
631989860Sobrien    outbound_syms += bed->s->sizeof_sym;
632089860Sobrien    if (outbound_shndx != NULL)
632189860Sobrien      outbound_shndx += sizeof (Elf_External_Sym_Shndx);
632289860Sobrien  }
632389860Sobrien
6324130563Sobrien  name_local_sections
6325130563Sobrien    = (bed->elf_backend_name_local_section_symbols
6326130563Sobrien       && bed->elf_backend_name_local_section_symbols (abfd));
6327130563Sobrien
632889860Sobrien  syms = bfd_get_outsymbols (abfd);
632989860Sobrien  for (idx = 0; idx < symcount; idx++)
633033965Sjdp    {
633133965Sjdp      Elf_Internal_Sym sym;
633289860Sobrien      bfd_vma value = syms[idx]->value;
633389860Sobrien      elf_symbol_type *type_ptr;
633489860Sobrien      flagword flags = syms[idx]->flags;
633589860Sobrien      int type;
633633965Sjdp
6337130563Sobrien      if (!name_local_sections
6338130563Sobrien	  && (flags & (BSF_SECTION_SYM | BSF_GLOBAL)) == BSF_SECTION_SYM)
633989860Sobrien	{
634089860Sobrien	  /* Local section symbols have no name.  */
634189860Sobrien	  sym.st_name = 0;
634289860Sobrien	}
634389860Sobrien      else
634489860Sobrien	{
634589860Sobrien	  sym.st_name = (unsigned long) _bfd_stringtab_add (stt,
634689860Sobrien							    syms[idx]->name,
6347130563Sobrien							    TRUE, FALSE);
634889860Sobrien	  if (sym.st_name == (unsigned long) -1)
6349130563Sobrien	    {
6350130563Sobrien	      _bfd_stringtab_free (stt);
6351130563Sobrien	      return FALSE;
6352130563Sobrien	    }
635389860Sobrien	}
635433965Sjdp
635589860Sobrien      type_ptr = elf_symbol_from (abfd, syms[idx]);
635633965Sjdp
635789860Sobrien      if ((flags & BSF_SECTION_SYM) == 0
635889860Sobrien	  && bfd_is_com_section (syms[idx]->section))
635989860Sobrien	{
636089860Sobrien	  /* ELF common symbols put the alignment into the `value' field,
636189860Sobrien	     and the size into the `size' field.  This is backwards from
636289860Sobrien	     how BFD handles it, so reverse it here.  */
636389860Sobrien	  sym.st_size = value;
636489860Sobrien	  if (type_ptr == NULL
636589860Sobrien	      || type_ptr->internal_elf_sym.st_value == 0)
636689860Sobrien	    sym.st_value = value >= 16 ? 16 : (1 << bfd_log2 (value));
636789860Sobrien	  else
636889860Sobrien	    sym.st_value = type_ptr->internal_elf_sym.st_value;
636989860Sobrien	  sym.st_shndx = _bfd_elf_section_from_bfd_section
637089860Sobrien	    (abfd, syms[idx]->section);
637189860Sobrien	}
637289860Sobrien      else
637389860Sobrien	{
637489860Sobrien	  asection *sec = syms[idx]->section;
637589860Sobrien	  int shndx;
637633965Sjdp
637789860Sobrien	  if (sec->output_section)
637889860Sobrien	    {
637989860Sobrien	      value += sec->output_offset;
638089860Sobrien	      sec = sec->output_section;
638189860Sobrien	    }
6382130563Sobrien
638389860Sobrien	  /* Don't add in the section vma for relocatable output.  */
638489860Sobrien	  if (! relocatable_p)
638589860Sobrien	    value += sec->vma;
638689860Sobrien	  sym.st_value = value;
638789860Sobrien	  sym.st_size = type_ptr ? type_ptr->internal_elf_sym.st_size : 0;
638833965Sjdp
638989860Sobrien	  if (bfd_is_abs_section (sec)
639089860Sobrien	      && type_ptr != NULL
639189860Sobrien	      && type_ptr->internal_elf_sym.st_shndx != 0)
639289860Sobrien	    {
639389860Sobrien	      /* This symbol is in a real ELF section which we did
639489860Sobrien		 not create as a BFD section.  Undo the mapping done
639589860Sobrien		 by copy_private_symbol_data.  */
639689860Sobrien	      shndx = type_ptr->internal_elf_sym.st_shndx;
639789860Sobrien	      switch (shndx)
639889860Sobrien		{
639989860Sobrien		case MAP_ONESYMTAB:
640089860Sobrien		  shndx = elf_onesymtab (abfd);
640189860Sobrien		  break;
640289860Sobrien		case MAP_DYNSYMTAB:
640389860Sobrien		  shndx = elf_dynsymtab (abfd);
640489860Sobrien		  break;
640589860Sobrien		case MAP_STRTAB:
640689860Sobrien		  shndx = elf_tdata (abfd)->strtab_section;
640789860Sobrien		  break;
640889860Sobrien		case MAP_SHSTRTAB:
640989860Sobrien		  shndx = elf_tdata (abfd)->shstrtab_section;
641089860Sobrien		  break;
641189860Sobrien		case MAP_SYM_SHNDX:
641289860Sobrien		  shndx = elf_tdata (abfd)->symtab_shndx_section;
641389860Sobrien		  break;
641489860Sobrien		default:
641589860Sobrien		  break;
641689860Sobrien		}
641789860Sobrien	    }
641889860Sobrien	  else
641989860Sobrien	    {
642089860Sobrien	      shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
642133965Sjdp
642289860Sobrien	      if (shndx == -1)
642389860Sobrien		{
642489860Sobrien		  asection *sec2;
642533965Sjdp
642689860Sobrien		  /* Writing this would be a hell of a lot easier if
642789860Sobrien		     we had some decent documentation on bfd, and
642889860Sobrien		     knew what to expect of the library, and what to
642989860Sobrien		     demand of applications.  For example, it
643089860Sobrien		     appears that `objcopy' might not set the
643189860Sobrien		     section of a symbol to be a section that is
643289860Sobrien		     actually in the output file.  */
643389860Sobrien		  sec2 = bfd_get_section_by_name (abfd, sec->name);
6434130563Sobrien		  if (sec2 == NULL)
6435130563Sobrien		    {
6436130563Sobrien		      _bfd_error_handler (_("\
6437130563SobrienUnable to find equivalent output section for symbol '%s' from section '%s'"),
6438130563Sobrien					  syms[idx]->name ? syms[idx]->name : "<Local sym>",
6439130563Sobrien					  sec->name);
6440130563Sobrien		      bfd_set_error (bfd_error_invalid_operation);
6441130563Sobrien		      _bfd_stringtab_free (stt);
6442130563Sobrien		      return FALSE;
6443130563Sobrien		    }
6444130563Sobrien
644589860Sobrien		  shndx = _bfd_elf_section_from_bfd_section (abfd, sec2);
644689860Sobrien		  BFD_ASSERT (shndx != -1);
644789860Sobrien		}
644889860Sobrien	    }
644933965Sjdp
645089860Sobrien	  sym.st_shndx = shndx;
645189860Sobrien	}
645233965Sjdp
6453104838Sobrien      if ((flags & BSF_THREAD_LOCAL) != 0)
6454104838Sobrien	type = STT_TLS;
6455104838Sobrien      else if ((flags & BSF_FUNCTION) != 0)
645689860Sobrien	type = STT_FUNC;
645789860Sobrien      else if ((flags & BSF_OBJECT) != 0)
645889860Sobrien	type = STT_OBJECT;
6459218822Sdim      else if ((flags & BSF_RELC) != 0)
6460218822Sdim	type = STT_RELC;
6461218822Sdim      else if ((flags & BSF_SRELC) != 0)
6462218822Sdim	type = STT_SRELC;
646389860Sobrien      else
646489860Sobrien	type = STT_NOTYPE;
646533965Sjdp
6466104838Sobrien      if (syms[idx]->section->flags & SEC_THREAD_LOCAL)
6467104838Sobrien	type = STT_TLS;
6468104838Sobrien
6469130563Sobrien      /* Processor-specific types.  */
647089860Sobrien      if (type_ptr != NULL
647189860Sobrien	  && bed->elf_backend_get_symbol_type)
647289860Sobrien	type = ((*bed->elf_backend_get_symbol_type)
647389860Sobrien		(&type_ptr->internal_elf_sym, type));
647460508Sobrien
647589860Sobrien      if (flags & BSF_SECTION_SYM)
647689860Sobrien	{
647789860Sobrien	  if (flags & BSF_GLOBAL)
647889860Sobrien	    sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
647989860Sobrien	  else
648089860Sobrien	    sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
648189860Sobrien	}
648289860Sobrien      else if (bfd_is_com_section (syms[idx]->section))
648389860Sobrien	sym.st_info = ELF_ST_INFO (STB_GLOBAL, type);
648489860Sobrien      else if (bfd_is_und_section (syms[idx]->section))
648589860Sobrien	sym.st_info = ELF_ST_INFO (((flags & BSF_WEAK)
648689860Sobrien				    ? STB_WEAK
648789860Sobrien				    : STB_GLOBAL),
648889860Sobrien				   type);
648989860Sobrien      else if (flags & BSF_FILE)
649089860Sobrien	sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
649189860Sobrien      else
649289860Sobrien	{
649389860Sobrien	  int bind = STB_LOCAL;
649433965Sjdp
649589860Sobrien	  if (flags & BSF_LOCAL)
649689860Sobrien	    bind = STB_LOCAL;
649789860Sobrien	  else if (flags & BSF_WEAK)
649889860Sobrien	    bind = STB_WEAK;
649989860Sobrien	  else if (flags & BSF_GLOBAL)
650089860Sobrien	    bind = STB_GLOBAL;
650133965Sjdp
650289860Sobrien	  sym.st_info = ELF_ST_INFO (bind, type);
650389860Sobrien	}
650433965Sjdp
650589860Sobrien      if (type_ptr != NULL)
650689860Sobrien	sym.st_other = type_ptr->internal_elf_sym.st_other;
650789860Sobrien      else
650889860Sobrien	sym.st_other = 0;
650933965Sjdp
651089860Sobrien      bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx);
651189860Sobrien      outbound_syms += bed->s->sizeof_sym;
651289860Sobrien      if (outbound_shndx != NULL)
651389860Sobrien	outbound_shndx += sizeof (Elf_External_Sym_Shndx);
651489860Sobrien    }
651533965Sjdp
651689860Sobrien  *sttp = stt;
651789860Sobrien  symstrtab_hdr->sh_size = _bfd_stringtab_size (stt);
651889860Sobrien  symstrtab_hdr->sh_type = SHT_STRTAB;
651933965Sjdp
652089860Sobrien  symstrtab_hdr->sh_flags = 0;
652189860Sobrien  symstrtab_hdr->sh_addr = 0;
652289860Sobrien  symstrtab_hdr->sh_entsize = 0;
652389860Sobrien  symstrtab_hdr->sh_link = 0;
652489860Sobrien  symstrtab_hdr->sh_info = 0;
652589860Sobrien  symstrtab_hdr->sh_addralign = 1;
652633965Sjdp
6527130563Sobrien  return TRUE;
652833965Sjdp}
652933965Sjdp
653033965Sjdp/* Return the number of bytes required to hold the symtab vector.
653133965Sjdp
653233965Sjdp   Note that we base it on the count plus 1, since we will null terminate
653333965Sjdp   the vector allocated based on this size.  However, the ELF symbol table
653433965Sjdp   always has a dummy entry as symbol #0, so it ends up even.  */
653533965Sjdp
653633965Sjdplong
6537130563Sobrien_bfd_elf_get_symtab_upper_bound (bfd *abfd)
653833965Sjdp{
653933965Sjdp  long symcount;
654033965Sjdp  long symtab_size;
654133965Sjdp  Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->symtab_hdr;
654233965Sjdp
654333965Sjdp  symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
654494542Sobrien  symtab_size = (symcount + 1) * (sizeof (asymbol *));
654594542Sobrien  if (symcount > 0)
654694542Sobrien    symtab_size -= sizeof (asymbol *);
654733965Sjdp
654833965Sjdp  return symtab_size;
654933965Sjdp}
655033965Sjdp
655133965Sjdplong
6552130563Sobrien_bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd)
655333965Sjdp{
655433965Sjdp  long symcount;
655533965Sjdp  long symtab_size;
655633965Sjdp  Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->dynsymtab_hdr;
655733965Sjdp
655833965Sjdp  if (elf_dynsymtab (abfd) == 0)
655933965Sjdp    {
656033965Sjdp      bfd_set_error (bfd_error_invalid_operation);
656133965Sjdp      return -1;
656233965Sjdp    }
656333965Sjdp
656433965Sjdp  symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
656594542Sobrien  symtab_size = (symcount + 1) * (sizeof (asymbol *));
656694542Sobrien  if (symcount > 0)
656794542Sobrien    symtab_size -= sizeof (asymbol *);
656833965Sjdp
656933965Sjdp  return symtab_size;
657033965Sjdp}
657133965Sjdp
657233965Sjdplong
6573130563Sobrien_bfd_elf_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
6574130563Sobrien				sec_ptr asect)
657533965Sjdp{
657633965Sjdp  return (asect->reloc_count + 1) * sizeof (arelent *);
657733965Sjdp}
657833965Sjdp
657933965Sjdp/* Canonicalize the relocs.  */
658033965Sjdp
658133965Sjdplong
6582130563Sobrien_bfd_elf_canonicalize_reloc (bfd *abfd,
6583130563Sobrien			     sec_ptr section,
6584130563Sobrien			     arelent **relptr,
6585130563Sobrien			     asymbol **symbols)
658633965Sjdp{
658733965Sjdp  arelent *tblptr;
658833965Sjdp  unsigned int i;
6589130563Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
659033965Sjdp
6591130563Sobrien  if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
659233965Sjdp    return -1;
659333965Sjdp
659433965Sjdp  tblptr = section->relocation;
659533965Sjdp  for (i = 0; i < section->reloc_count; i++)
659633965Sjdp    *relptr++ = tblptr++;
659733965Sjdp
659833965Sjdp  *relptr = NULL;
659933965Sjdp
660033965Sjdp  return section->reloc_count;
660133965Sjdp}
660233965Sjdp
660333965Sjdplong
6604130563Sobrien_bfd_elf_canonicalize_symtab (bfd *abfd, asymbol **allocation)
660533965Sjdp{
6606130563Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
6607130563Sobrien  long symcount = bed->s->slurp_symbol_table (abfd, allocation, FALSE);
660833965Sjdp
660933965Sjdp  if (symcount >= 0)
661033965Sjdp    bfd_get_symcount (abfd) = symcount;
661133965Sjdp  return symcount;
661233965Sjdp}
661333965Sjdp
661433965Sjdplong
6615130563Sobrien_bfd_elf_canonicalize_dynamic_symtab (bfd *abfd,
6616130563Sobrien				      asymbol **allocation)
661733965Sjdp{
6618130563Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
6619130563Sobrien  long symcount = bed->s->slurp_symbol_table (abfd, allocation, TRUE);
6620104838Sobrien
6621104838Sobrien  if (symcount >= 0)
6622104838Sobrien    bfd_get_dynamic_symcount (abfd) = symcount;
6623104838Sobrien  return symcount;
662433965Sjdp}
662533965Sjdp
6626218822Sdim/* Return the size required for the dynamic reloc entries.  Any loadable
6627218822Sdim   section that was actually installed in the BFD, and has type SHT_REL
6628218822Sdim   or SHT_RELA, and uses the dynamic symbol table, is considered to be a
6629218822Sdim   dynamic reloc section.  */
663033965Sjdp
663133965Sjdplong
6632130563Sobrien_bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd)
663333965Sjdp{
663433965Sjdp  long ret;
663533965Sjdp  asection *s;
663633965Sjdp
663733965Sjdp  if (elf_dynsymtab (abfd) == 0)
663833965Sjdp    {
663933965Sjdp      bfd_set_error (bfd_error_invalid_operation);
664033965Sjdp      return -1;
664133965Sjdp    }
664233965Sjdp
664333965Sjdp  ret = sizeof (arelent *);
664433965Sjdp  for (s = abfd->sections; s != NULL; s = s->next)
6645218822Sdim    if ((s->flags & SEC_LOAD) != 0
6646218822Sdim	&& elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
664733965Sjdp	&& (elf_section_data (s)->this_hdr.sh_type == SHT_REL
664833965Sjdp	    || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
6649218822Sdim      ret += ((s->size / elf_section_data (s)->this_hdr.sh_entsize)
665033965Sjdp	      * sizeof (arelent *));
665133965Sjdp
665233965Sjdp  return ret;
665333965Sjdp}
665433965Sjdp
6655218822Sdim/* Canonicalize the dynamic relocation entries.  Note that we return the
6656218822Sdim   dynamic relocations as a single block, although they are actually
6657218822Sdim   associated with particular sections; the interface, which was
6658218822Sdim   designed for SunOS style shared libraries, expects that there is only
6659218822Sdim   one set of dynamic relocs.  Any loadable section that was actually
6660218822Sdim   installed in the BFD, and has type SHT_REL or SHT_RELA, and uses the
6661218822Sdim   dynamic symbol table, is considered to be a dynamic reloc section.  */
666233965Sjdp
666333965Sjdplong
6664130563Sobrien_bfd_elf_canonicalize_dynamic_reloc (bfd *abfd,
6665130563Sobrien				     arelent **storage,
6666130563Sobrien				     asymbol **syms)
666733965Sjdp{
6668130563Sobrien  bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
666933965Sjdp  asection *s;
667033965Sjdp  long ret;
667133965Sjdp
667233965Sjdp  if (elf_dynsymtab (abfd) == 0)
667333965Sjdp    {
667433965Sjdp      bfd_set_error (bfd_error_invalid_operation);
667533965Sjdp      return -1;
667633965Sjdp    }
667733965Sjdp
667833965Sjdp  slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
667933965Sjdp  ret = 0;
668033965Sjdp  for (s = abfd->sections; s != NULL; s = s->next)
668133965Sjdp    {
6682218822Sdim      if ((s->flags & SEC_LOAD) != 0
6683218822Sdim	  && elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
668433965Sjdp	  && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
668533965Sjdp	      || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
668633965Sjdp	{
668733965Sjdp	  arelent *p;
668833965Sjdp	  long count, i;
668933965Sjdp
6690130563Sobrien	  if (! (*slurp_relocs) (abfd, s, syms, TRUE))
669133965Sjdp	    return -1;
6692218822Sdim	  count = s->size / elf_section_data (s)->this_hdr.sh_entsize;
669333965Sjdp	  p = s->relocation;
669433965Sjdp	  for (i = 0; i < count; i++)
669533965Sjdp	    *storage++ = p++;
669633965Sjdp	  ret += count;
669733965Sjdp	}
669833965Sjdp    }
669933965Sjdp
670033965Sjdp  *storage = NULL;
670133965Sjdp
670233965Sjdp  return ret;
670333965Sjdp}
670433965Sjdp
670533965Sjdp/* Read in the version information.  */
670633965Sjdp
6707130563Sobrienbfd_boolean
6708218822Sdim_bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
670933965Sjdp{
671033965Sjdp  bfd_byte *contents = NULL;
6711218822Sdim  unsigned int freeidx = 0;
671233965Sjdp
6713218822Sdim  if (elf_dynverref (abfd) != 0)
6714218822Sdim    {
6715218822Sdim      Elf_Internal_Shdr *hdr;
6716218822Sdim      Elf_External_Verneed *everneed;
6717218822Sdim      Elf_Internal_Verneed *iverneed;
6718218822Sdim      unsigned int i;
6719218822Sdim      bfd_byte *contents_end;
6720218822Sdim
6721218822Sdim      hdr = &elf_tdata (abfd)->dynverref_hdr;
6722218822Sdim
6723218822Sdim      elf_tdata (abfd)->verref = bfd_zalloc2 (abfd, hdr->sh_info,
6724218822Sdim					      sizeof (Elf_Internal_Verneed));
6725218822Sdim      if (elf_tdata (abfd)->verref == NULL)
6726218822Sdim	goto error_return;
6727218822Sdim
6728218822Sdim      elf_tdata (abfd)->cverrefs = hdr->sh_info;
6729218822Sdim
6730218822Sdim      contents = bfd_malloc (hdr->sh_size);
6731218822Sdim      if (contents == NULL)
6732218822Sdim	{
6733218822Sdimerror_return_verref:
6734218822Sdim	  elf_tdata (abfd)->verref = NULL;
6735218822Sdim	  elf_tdata (abfd)->cverrefs = 0;
6736218822Sdim	  goto error_return;
6737218822Sdim	}
6738218822Sdim      if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
6739218822Sdim	  || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
6740218822Sdim	goto error_return_verref;
6741218822Sdim
6742218822Sdim      if (hdr->sh_info && hdr->sh_size < sizeof (Elf_External_Verneed))
6743218822Sdim	goto error_return_verref;
6744218822Sdim
6745218822Sdim      BFD_ASSERT (sizeof (Elf_External_Verneed)
6746218822Sdim		  == sizeof (Elf_External_Vernaux));
6747218822Sdim      contents_end = contents + hdr->sh_size - sizeof (Elf_External_Verneed);
6748218822Sdim      everneed = (Elf_External_Verneed *) contents;
6749218822Sdim      iverneed = elf_tdata (abfd)->verref;
6750218822Sdim      for (i = 0; i < hdr->sh_info; i++, iverneed++)
6751218822Sdim	{
6752218822Sdim	  Elf_External_Vernaux *evernaux;
6753218822Sdim	  Elf_Internal_Vernaux *ivernaux;
6754218822Sdim	  unsigned int j;
6755218822Sdim
6756218822Sdim	  _bfd_elf_swap_verneed_in (abfd, everneed, iverneed);
6757218822Sdim
6758218822Sdim	  iverneed->vn_bfd = abfd;
6759218822Sdim
6760218822Sdim	  iverneed->vn_filename =
6761218822Sdim	    bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
6762218822Sdim					     iverneed->vn_file);
6763218822Sdim	  if (iverneed->vn_filename == NULL)
6764218822Sdim	    goto error_return_verref;
6765218822Sdim
6766218822Sdim	  if (iverneed->vn_cnt == 0)
6767218822Sdim	    iverneed->vn_auxptr = NULL;
6768218822Sdim	  else
6769218822Sdim	    {
6770218822Sdim	      iverneed->vn_auxptr = bfd_alloc2 (abfd, iverneed->vn_cnt,
6771218822Sdim						sizeof (Elf_Internal_Vernaux));
6772218822Sdim	      if (iverneed->vn_auxptr == NULL)
6773218822Sdim		goto error_return_verref;
6774218822Sdim	    }
6775218822Sdim
6776218822Sdim	  if (iverneed->vn_aux
6777218822Sdim	      > (size_t) (contents_end - (bfd_byte *) everneed))
6778218822Sdim	    goto error_return_verref;
6779218822Sdim
6780218822Sdim	  evernaux = ((Elf_External_Vernaux *)
6781218822Sdim		      ((bfd_byte *) everneed + iverneed->vn_aux));
6782218822Sdim	  ivernaux = iverneed->vn_auxptr;
6783218822Sdim	  for (j = 0; j < iverneed->vn_cnt; j++, ivernaux++)
6784218822Sdim	    {
6785218822Sdim	      _bfd_elf_swap_vernaux_in (abfd, evernaux, ivernaux);
6786218822Sdim
6787218822Sdim	      ivernaux->vna_nodename =
6788218822Sdim		bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
6789218822Sdim						 ivernaux->vna_name);
6790218822Sdim	      if (ivernaux->vna_nodename == NULL)
6791218822Sdim		goto error_return_verref;
6792218822Sdim
6793218822Sdim	      if (j + 1 < iverneed->vn_cnt)
6794218822Sdim		ivernaux->vna_nextptr = ivernaux + 1;
6795218822Sdim	      else
6796218822Sdim		ivernaux->vna_nextptr = NULL;
6797218822Sdim
6798218822Sdim	      if (ivernaux->vna_next
6799218822Sdim		  > (size_t) (contents_end - (bfd_byte *) evernaux))
6800218822Sdim		goto error_return_verref;
6801218822Sdim
6802218822Sdim	      evernaux = ((Elf_External_Vernaux *)
6803218822Sdim			  ((bfd_byte *) evernaux + ivernaux->vna_next));
6804218822Sdim
6805218822Sdim	      if (ivernaux->vna_other > freeidx)
6806218822Sdim		freeidx = ivernaux->vna_other;
6807218822Sdim	    }
6808218822Sdim
6809218822Sdim	  if (i + 1 < hdr->sh_info)
6810218822Sdim	    iverneed->vn_nextref = iverneed + 1;
6811218822Sdim	  else
6812218822Sdim	    iverneed->vn_nextref = NULL;
6813218822Sdim
6814218822Sdim	  if (iverneed->vn_next
6815218822Sdim	      > (size_t) (contents_end - (bfd_byte *) everneed))
6816218822Sdim	    goto error_return_verref;
6817218822Sdim
6818218822Sdim	  everneed = ((Elf_External_Verneed *)
6819218822Sdim		      ((bfd_byte *) everneed + iverneed->vn_next));
6820218822Sdim	}
6821218822Sdim
6822218822Sdim      free (contents);
6823218822Sdim      contents = NULL;
6824218822Sdim    }
6825218822Sdim
682633965Sjdp  if (elf_dynverdef (abfd) != 0)
682733965Sjdp    {
682833965Sjdp      Elf_Internal_Shdr *hdr;
682933965Sjdp      Elf_External_Verdef *everdef;
683033965Sjdp      Elf_Internal_Verdef *iverdef;
683168767Sobrien      Elf_Internal_Verdef *iverdefarr;
683268767Sobrien      Elf_Internal_Verdef iverdefmem;
683333965Sjdp      unsigned int i;
683468767Sobrien      unsigned int maxidx;
6835218822Sdim      bfd_byte *contents_end_def, *contents_end_aux;
683633965Sjdp
683733965Sjdp      hdr = &elf_tdata (abfd)->dynverdef_hdr;
683833965Sjdp
6839130563Sobrien      contents = bfd_malloc (hdr->sh_size);
684033965Sjdp      if (contents == NULL)
684133965Sjdp	goto error_return;
684233965Sjdp      if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
6843130563Sobrien	  || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
684433965Sjdp	goto error_return;
684533965Sjdp
6846218822Sdim      if (hdr->sh_info && hdr->sh_size < sizeof (Elf_External_Verdef))
6847218822Sdim	goto error_return;
6848218822Sdim
6849218822Sdim      BFD_ASSERT (sizeof (Elf_External_Verdef)
6850218822Sdim		  >= sizeof (Elf_External_Verdaux));
6851218822Sdim      contents_end_def = contents + hdr->sh_size
6852218822Sdim			 - sizeof (Elf_External_Verdef);
6853218822Sdim      contents_end_aux = contents + hdr->sh_size
6854218822Sdim			 - sizeof (Elf_External_Verdaux);
6855218822Sdim
685668767Sobrien      /* We know the number of entries in the section but not the maximum
685768767Sobrien	 index.  Therefore we have to run through all entries and find
685868767Sobrien	 the maximum.  */
685933965Sjdp      everdef = (Elf_External_Verdef *) contents;
686068767Sobrien      maxidx = 0;
686168767Sobrien      for (i = 0; i < hdr->sh_info; ++i)
686233965Sjdp	{
686368767Sobrien	  _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);
686468767Sobrien
686578831Sobrien	  if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) > maxidx)
686678831Sobrien	    maxidx = iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION);
686768767Sobrien
6868218822Sdim	  if (iverdefmem.vd_next
6869218822Sdim	      > (size_t) (contents_end_def - (bfd_byte *) everdef))
6870218822Sdim	    goto error_return;
6871218822Sdim
687268767Sobrien	  everdef = ((Elf_External_Verdef *)
687368767Sobrien		     ((bfd_byte *) everdef + iverdefmem.vd_next));
687468767Sobrien	}
687568767Sobrien
6876218822Sdim      if (default_imported_symver)
6877218822Sdim	{
6878218822Sdim	  if (freeidx > maxidx)
6879218822Sdim	    maxidx = ++freeidx;
6880218822Sdim	  else
6881218822Sdim	    freeidx = ++maxidx;
6882218822Sdim	}
6883218822Sdim      elf_tdata (abfd)->verdef = bfd_zalloc2 (abfd, maxidx,
6884218822Sdim					      sizeof (Elf_Internal_Verdef));
688568767Sobrien      if (elf_tdata (abfd)->verdef == NULL)
688668767Sobrien	goto error_return;
688768767Sobrien
688868767Sobrien      elf_tdata (abfd)->cverdefs = maxidx;
688968767Sobrien
689068767Sobrien      everdef = (Elf_External_Verdef *) contents;
689168767Sobrien      iverdefarr = elf_tdata (abfd)->verdef;
689268767Sobrien      for (i = 0; i < hdr->sh_info; i++)
689368767Sobrien	{
689433965Sjdp	  Elf_External_Verdaux *everdaux;
689533965Sjdp	  Elf_Internal_Verdaux *iverdaux;
689633965Sjdp	  unsigned int j;
689733965Sjdp
689868767Sobrien	  _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);
689933965Sjdp
6900218822Sdim	  if ((iverdefmem.vd_ndx & VERSYM_VERSION) == 0)
6901218822Sdim	    {
6902218822Sdimerror_return_verdef:
6903218822Sdim	      elf_tdata (abfd)->verdef = NULL;
6904218822Sdim	      elf_tdata (abfd)->cverdefs = 0;
6905218822Sdim	      goto error_return;
6906218822Sdim	    }
6907218822Sdim
690868767Sobrien	  iverdef = &iverdefarr[(iverdefmem.vd_ndx & VERSYM_VERSION) - 1];
690968767Sobrien	  memcpy (iverdef, &iverdefmem, sizeof (Elf_Internal_Verdef));
691068767Sobrien
691133965Sjdp	  iverdef->vd_bfd = abfd;
691233965Sjdp
6913218822Sdim	  if (iverdef->vd_cnt == 0)
6914218822Sdim	    iverdef->vd_auxptr = NULL;
6915218822Sdim	  else
6916218822Sdim	    {
6917218822Sdim	      iverdef->vd_auxptr = bfd_alloc2 (abfd, iverdef->vd_cnt,
6918218822Sdim					       sizeof (Elf_Internal_Verdaux));
6919218822Sdim	      if (iverdef->vd_auxptr == NULL)
6920218822Sdim		goto error_return_verdef;
6921218822Sdim	    }
692233965Sjdp
6923218822Sdim	  if (iverdef->vd_aux
6924218822Sdim	      > (size_t) (contents_end_aux - (bfd_byte *) everdef))
6925218822Sdim	    goto error_return_verdef;
6926218822Sdim
692733965Sjdp	  everdaux = ((Elf_External_Verdaux *)
692833965Sjdp		      ((bfd_byte *) everdef + iverdef->vd_aux));
692933965Sjdp	  iverdaux = iverdef->vd_auxptr;
693033965Sjdp	  for (j = 0; j < iverdef->vd_cnt; j++, iverdaux++)
693133965Sjdp	    {
693233965Sjdp	      _bfd_elf_swap_verdaux_in (abfd, everdaux, iverdaux);
693333965Sjdp
693433965Sjdp	      iverdaux->vda_nodename =
693533965Sjdp		bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
693633965Sjdp						 iverdaux->vda_name);
693733965Sjdp	      if (iverdaux->vda_nodename == NULL)
6938218822Sdim		goto error_return_verdef;
693933965Sjdp
694033965Sjdp	      if (j + 1 < iverdef->vd_cnt)
694133965Sjdp		iverdaux->vda_nextptr = iverdaux + 1;
694233965Sjdp	      else
694333965Sjdp		iverdaux->vda_nextptr = NULL;
694433965Sjdp
6945218822Sdim	      if (iverdaux->vda_next
6946218822Sdim		  > (size_t) (contents_end_aux - (bfd_byte *) everdaux))
6947218822Sdim		goto error_return_verdef;
6948218822Sdim
694933965Sjdp	      everdaux = ((Elf_External_Verdaux *)
695033965Sjdp			  ((bfd_byte *) everdaux + iverdaux->vda_next));
695133965Sjdp	    }
695233965Sjdp
6953218822Sdim	  if (iverdef->vd_cnt)
6954218822Sdim	    iverdef->vd_nodename = iverdef->vd_auxptr->vda_nodename;
695533965Sjdp
6956218822Sdim	  if ((size_t) (iverdef - iverdefarr) + 1 < maxidx)
695733965Sjdp	    iverdef->vd_nextdef = iverdef + 1;
695833965Sjdp	  else
695933965Sjdp	    iverdef->vd_nextdef = NULL;
696033965Sjdp
696133965Sjdp	  everdef = ((Elf_External_Verdef *)
696233965Sjdp		     ((bfd_byte *) everdef + iverdef->vd_next));
696333965Sjdp	}
696433965Sjdp
696533965Sjdp      free (contents);
696633965Sjdp      contents = NULL;
696733965Sjdp    }
6968218822Sdim  else if (default_imported_symver)
696933965Sjdp    {
6970218822Sdim      if (freeidx < 3)
6971218822Sdim	freeidx = 3;
6972218822Sdim      else
6973218822Sdim	freeidx++;
697433965Sjdp
6975218822Sdim      elf_tdata (abfd)->verdef = bfd_zalloc2 (abfd, freeidx,
6976218822Sdim					      sizeof (Elf_Internal_Verdef));
6977218822Sdim      if (elf_tdata (abfd)->verdef == NULL)
697833965Sjdp	goto error_return;
697933965Sjdp
6980218822Sdim      elf_tdata (abfd)->cverdefs = freeidx;
6981218822Sdim    }
698233965Sjdp
6983218822Sdim  /* Create a default version based on the soname.  */
6984218822Sdim  if (default_imported_symver)
6985218822Sdim    {
6986218822Sdim      Elf_Internal_Verdef *iverdef;
6987218822Sdim      Elf_Internal_Verdaux *iverdaux;
698833965Sjdp
6989218822Sdim      iverdef = &elf_tdata (abfd)->verdef[freeidx - 1];;
699033965Sjdp
6991218822Sdim      iverdef->vd_version = VER_DEF_CURRENT;
6992218822Sdim      iverdef->vd_flags = 0;
6993218822Sdim      iverdef->vd_ndx = freeidx;
6994218822Sdim      iverdef->vd_cnt = 1;
699533965Sjdp
6996218822Sdim      iverdef->vd_bfd = abfd;
699733965Sjdp
6998218822Sdim      iverdef->vd_nodename = bfd_elf_get_dt_soname (abfd);
6999218822Sdim      if (iverdef->vd_nodename == NULL)
7000218822Sdim	goto error_return_verdef;
7001218822Sdim      iverdef->vd_nextdef = NULL;
7002218822Sdim      iverdef->vd_auxptr = bfd_alloc (abfd, sizeof (Elf_Internal_Verdaux));
7003218822Sdim      if (iverdef->vd_auxptr == NULL)
7004218822Sdim	goto error_return_verdef;
700533965Sjdp
7006218822Sdim      iverdaux = iverdef->vd_auxptr;
7007218822Sdim      iverdaux->vda_nodename = iverdef->vd_nodename;
7008218822Sdim      iverdaux->vda_nextptr = NULL;
700933965Sjdp    }
701033965Sjdp
7011130563Sobrien  return TRUE;
701233965Sjdp
701333965Sjdp error_return:
7014130563Sobrien  if (contents != NULL)
701533965Sjdp    free (contents);
7016130563Sobrien  return FALSE;
701733965Sjdp}
701833965Sjdp
701933965Sjdpasymbol *
7020130563Sobrien_bfd_elf_make_empty_symbol (bfd *abfd)
702133965Sjdp{
702233965Sjdp  elf_symbol_type *newsym;
702389860Sobrien  bfd_size_type amt = sizeof (elf_symbol_type);
702433965Sjdp
7025130563Sobrien  newsym = bfd_zalloc (abfd, amt);
702633965Sjdp  if (!newsym)
702733965Sjdp    return NULL;
702833965Sjdp  else
702933965Sjdp    {
703033965Sjdp      newsym->symbol.the_bfd = abfd;
703133965Sjdp      return &newsym->symbol;
703233965Sjdp    }
703333965Sjdp}
703433965Sjdp
703533965Sjdpvoid
7036130563Sobrien_bfd_elf_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
7037130563Sobrien			  asymbol *symbol,
7038130563Sobrien			  symbol_info *ret)
703933965Sjdp{
704033965Sjdp  bfd_symbol_info (symbol, ret);
704133965Sjdp}
704233965Sjdp
704333965Sjdp/* Return whether a symbol name implies a local symbol.  Most targets
704433965Sjdp   use this function for the is_local_label_name entry point, but some
704533965Sjdp   override it.  */
704633965Sjdp
7047130563Sobrienbfd_boolean
7048130563Sobrien_bfd_elf_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
7049130563Sobrien			      const char *name)
705033965Sjdp{
705133965Sjdp  /* Normal local symbols start with ``.L''.  */
705233965Sjdp  if (name[0] == '.' && name[1] == 'L')
7053130563Sobrien    return TRUE;
705433965Sjdp
705533965Sjdp  /* At least some SVR4 compilers (e.g., UnixWare 2.1 cc) generate
705633965Sjdp     DWARF debugging symbols starting with ``..''.  */
705733965Sjdp  if (name[0] == '.' && name[1] == '.')
7058130563Sobrien    return TRUE;
705933965Sjdp
706033965Sjdp  /* gcc will sometimes generate symbols beginning with ``_.L_'' when
706133965Sjdp     emitting DWARF debugging output.  I suspect this is actually a
706233965Sjdp     small bug in gcc (it calls ASM_OUTPUT_LABEL when it should call
706333965Sjdp     ASM_GENERATE_INTERNAL_LABEL, and this causes the leading
706433965Sjdp     underscore to be emitted on some ELF targets).  For ease of use,
706533965Sjdp     we treat such symbols as local.  */
706633965Sjdp  if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_')
7067130563Sobrien    return TRUE;
706833965Sjdp
7069130563Sobrien  return FALSE;
707033965Sjdp}
707133965Sjdp
707233965Sjdpalent *
7073130563Sobrien_bfd_elf_get_lineno (bfd *abfd ATTRIBUTE_UNUSED,
7074130563Sobrien		     asymbol *symbol ATTRIBUTE_UNUSED)
707533965Sjdp{
707633965Sjdp  abort ();
707733965Sjdp  return NULL;
707833965Sjdp}
707933965Sjdp
7080130563Sobrienbfd_boolean
7081130563Sobrien_bfd_elf_set_arch_mach (bfd *abfd,
7082130563Sobrien			enum bfd_architecture arch,
7083130563Sobrien			unsigned long machine)
708433965Sjdp{
708533965Sjdp  /* If this isn't the right architecture for this backend, and this
708633965Sjdp     isn't the generic backend, fail.  */
708733965Sjdp  if (arch != get_elf_backend_data (abfd)->arch
708833965Sjdp      && arch != bfd_arch_unknown
708933965Sjdp      && get_elf_backend_data (abfd)->arch != bfd_arch_unknown)
7090130563Sobrien    return FALSE;
709133965Sjdp
709233965Sjdp  return bfd_default_set_arch_mach (abfd, arch, machine);
709333965Sjdp}
709433965Sjdp
709578831Sobrien/* Find the function to a particular section and offset,
709678831Sobrien   for error reporting.  */
709733965Sjdp
7098130563Sobrienstatic bfd_boolean
7099130563Sobrienelf_find_function (bfd *abfd ATTRIBUTE_UNUSED,
7100130563Sobrien		   asection *section,
7101130563Sobrien		   asymbol **symbols,
7102130563Sobrien		   bfd_vma offset,
7103130563Sobrien		   const char **filename_ptr,
7104130563Sobrien		   const char **functionname_ptr)
710533965Sjdp{
710633965Sjdp  const char *filename;
7107218822Sdim  asymbol *func, *file;
710833965Sjdp  bfd_vma low_func;
710933965Sjdp  asymbol **p;
7110218822Sdim  /* ??? Given multiple file symbols, it is impossible to reliably
7111218822Sdim     choose the right file name for global symbols.  File symbols are
7112218822Sdim     local symbols, and thus all file symbols must sort before any
7113218822Sdim     global symbols.  The ELF spec may be interpreted to say that a
7114218822Sdim     file symbol must sort before other local symbols, but currently
7115218822Sdim     ld -r doesn't do this.  So, for ld -r output, it is possible to
7116218822Sdim     make a better choice of file name for local symbols by ignoring
7117218822Sdim     file symbols appearing after a given local symbol.  */
7118218822Sdim  enum { nothing_seen, symbol_seen, file_after_symbol_seen } state;
711933965Sjdp
712033965Sjdp  filename = NULL;
712133965Sjdp  func = NULL;
7122218822Sdim  file = NULL;
712333965Sjdp  low_func = 0;
7124218822Sdim  state = nothing_seen;
712533965Sjdp
712633965Sjdp  for (p = symbols; *p != NULL; p++)
712733965Sjdp    {
712833965Sjdp      elf_symbol_type *q;
712933965Sjdp
713033965Sjdp      q = (elf_symbol_type *) *p;
713133965Sjdp
713233965Sjdp      switch (ELF_ST_TYPE (q->internal_elf_sym.st_info))
713333965Sjdp	{
713433965Sjdp	default:
713533965Sjdp	  break;
713633965Sjdp	case STT_FILE:
7137218822Sdim	  file = &q->symbol;
7138218822Sdim	  if (state == symbol_seen)
7139218822Sdim	    state = file_after_symbol_seen;
7140218822Sdim	  continue;
714160508Sobrien	case STT_NOTYPE:
714233965Sjdp	case STT_FUNC:
7143218822Sdim	  if (bfd_get_section (&q->symbol) == section
714433965Sjdp	      && q->symbol.value >= low_func
714533965Sjdp	      && q->symbol.value <= offset)
714633965Sjdp	    {
714733965Sjdp	      func = (asymbol *) q;
714833965Sjdp	      low_func = q->symbol.value;
7149218822Sdim	      filename = NULL;
7150218822Sdim	      if (file != NULL
7151218822Sdim		  && (ELF_ST_BIND (q->internal_elf_sym.st_info) == STB_LOCAL
7152218822Sdim		      || state != file_after_symbol_seen))
7153218822Sdim		filename = bfd_asymbol_name (file);
715433965Sjdp	    }
715533965Sjdp	  break;
715633965Sjdp	}
7157218822Sdim      if (state == nothing_seen)
7158218822Sdim	state = symbol_seen;
715933965Sjdp    }
716033965Sjdp
716133965Sjdp  if (func == NULL)
7162130563Sobrien    return FALSE;
716333965Sjdp
716478831Sobrien  if (filename_ptr)
716578831Sobrien    *filename_ptr = filename;
716678831Sobrien  if (functionname_ptr)
716778831Sobrien    *functionname_ptr = bfd_asymbol_name (func);
716878831Sobrien
7169130563Sobrien  return TRUE;
717078831Sobrien}
717178831Sobrien
717278831Sobrien/* Find the nearest line to a particular section and offset,
717378831Sobrien   for error reporting.  */
717478831Sobrien
7175130563Sobrienbfd_boolean
7176130563Sobrien_bfd_elf_find_nearest_line (bfd *abfd,
7177130563Sobrien			    asection *section,
7178130563Sobrien			    asymbol **symbols,
7179130563Sobrien			    bfd_vma offset,
7180130563Sobrien			    const char **filename_ptr,
7181130563Sobrien			    const char **functionname_ptr,
7182130563Sobrien			    unsigned int *line_ptr)
718378831Sobrien{
7184130563Sobrien  bfd_boolean found;
718578831Sobrien
718678831Sobrien  if (_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset,
718778831Sobrien				     filename_ptr, functionname_ptr,
718878831Sobrien				     line_ptr))
718978831Sobrien    {
719078831Sobrien      if (!*functionname_ptr)
719178831Sobrien	elf_find_function (abfd, section, symbols, offset,
719278831Sobrien			   *filename_ptr ? NULL : filename_ptr,
719378831Sobrien			   functionname_ptr);
719478831Sobrien
7195130563Sobrien      return TRUE;
719678831Sobrien    }
719778831Sobrien
719878831Sobrien  if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
719978831Sobrien				     filename_ptr, functionname_ptr,
720078831Sobrien				     line_ptr, 0,
720178831Sobrien				     &elf_tdata (abfd)->dwarf2_find_line_info))
720278831Sobrien    {
720378831Sobrien      if (!*functionname_ptr)
720478831Sobrien	elf_find_function (abfd, section, symbols, offset,
720578831Sobrien			   *filename_ptr ? NULL : filename_ptr,
720678831Sobrien			   functionname_ptr);
720778831Sobrien
7208130563Sobrien      return TRUE;
720978831Sobrien    }
721078831Sobrien
721178831Sobrien  if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
721278831Sobrien					     &found, filename_ptr,
721378831Sobrien					     functionname_ptr, line_ptr,
721478831Sobrien					     &elf_tdata (abfd)->line_info))
7215130563Sobrien    return FALSE;
7216104838Sobrien  if (found && (*functionname_ptr || *line_ptr))
7217130563Sobrien    return TRUE;
721878831Sobrien
721978831Sobrien  if (symbols == NULL)
7220130563Sobrien    return FALSE;
722178831Sobrien
722278831Sobrien  if (! elf_find_function (abfd, section, symbols, offset,
722378831Sobrien			   filename_ptr, functionname_ptr))
7224130563Sobrien    return FALSE;
722578831Sobrien
722633965Sjdp  *line_ptr = 0;
7227130563Sobrien  return TRUE;
722833965Sjdp}
722933965Sjdp
7230218822Sdim/* Find the line for a symbol.  */
7231218822Sdim
7232218822Sdimbfd_boolean
7233218822Sdim_bfd_elf_find_line (bfd *abfd, asymbol **symbols, asymbol *symbol,
7234218822Sdim		    const char **filename_ptr, unsigned int *line_ptr)
7235218822Sdim{
7236218822Sdim  return _bfd_dwarf2_find_line (abfd, symbols, symbol,
7237218822Sdim				filename_ptr, line_ptr, 0,
7238218822Sdim				&elf_tdata (abfd)->dwarf2_find_line_info);
7239218822Sdim}
7240218822Sdim
7241218822Sdim/* After a call to bfd_find_nearest_line, successive calls to
7242218822Sdim   bfd_find_inliner_info can be used to get source information about
7243218822Sdim   each level of function inlining that terminated at the address
7244218822Sdim   passed to bfd_find_nearest_line.  Currently this is only supported
7245218822Sdim   for DWARF2 with appropriate DWARF3 extensions. */
7246218822Sdim
7247218822Sdimbfd_boolean
7248218822Sdim_bfd_elf_find_inliner_info (bfd *abfd,
7249218822Sdim			    const char **filename_ptr,
7250218822Sdim			    const char **functionname_ptr,
7251218822Sdim			    unsigned int *line_ptr)
7252218822Sdim{
7253218822Sdim  bfd_boolean found;
7254218822Sdim  found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr,
7255218822Sdim					 functionname_ptr, line_ptr,
7256218822Sdim					 & elf_tdata (abfd)->dwarf2_find_line_info);
7257218822Sdim  return found;
7258218822Sdim}
7259218822Sdim
726033965Sjdpint
7261218822Sdim_bfd_elf_sizeof_headers (bfd *abfd, struct bfd_link_info *info)
726233965Sjdp{
7263218822Sdim  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
7264218822Sdim  int ret = bed->s->sizeof_ehdr;
726533965Sjdp
7266218822Sdim  if (!info->relocatable)
7267218822Sdim    {
7268218822Sdim      bfd_size_type phdr_size = elf_tdata (abfd)->program_header_size;
7269218822Sdim
7270218822Sdim      if (phdr_size == (bfd_size_type) -1)
7271218822Sdim	{
7272218822Sdim	  struct elf_segment_map *m;
7273218822Sdim
7274218822Sdim	  phdr_size = 0;
7275218822Sdim	  for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
7276218822Sdim	    phdr_size += bed->s->sizeof_phdr;
7277218822Sdim
7278218822Sdim	  if (phdr_size == 0)
7279218822Sdim	    phdr_size = get_program_header_size (abfd, info);
7280218822Sdim	}
7281218822Sdim
7282218822Sdim      elf_tdata (abfd)->program_header_size = phdr_size;
7283218822Sdim      ret += phdr_size;
7284218822Sdim    }
7285218822Sdim
728633965Sjdp  return ret;
728733965Sjdp}
728833965Sjdp
7289130563Sobrienbfd_boolean
7290130563Sobrien_bfd_elf_set_section_contents (bfd *abfd,
7291130563Sobrien			       sec_ptr section,
7292130563Sobrien			       const void *location,
7293130563Sobrien			       file_ptr offset,
7294130563Sobrien			       bfd_size_type count)
729533965Sjdp{
729633965Sjdp  Elf_Internal_Shdr *hdr;
729789860Sobrien  bfd_signed_vma pos;
729833965Sjdp
729933965Sjdp  if (! abfd->output_has_begun
7300130563Sobrien      && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
7301130563Sobrien    return FALSE;
730233965Sjdp
730333965Sjdp  hdr = &elf_section_data (section)->this_hdr;
730489860Sobrien  pos = hdr->sh_offset + offset;
730589860Sobrien  if (bfd_seek (abfd, pos, SEEK_SET) != 0
730689860Sobrien      || bfd_bwrite (location, count, abfd) != count)
7307130563Sobrien    return FALSE;
730833965Sjdp
7309130563Sobrien  return TRUE;
731033965Sjdp}
731133965Sjdp
731233965Sjdpvoid
7313130563Sobrien_bfd_elf_no_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
7314130563Sobrien			   arelent *cache_ptr ATTRIBUTE_UNUSED,
7315130563Sobrien			   Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
731633965Sjdp{
731733965Sjdp  abort ();
731833965Sjdp}
731933965Sjdp
732033965Sjdp/* Try to convert a non-ELF reloc into an ELF one.  */
732133965Sjdp
7322130563Sobrienbfd_boolean
7323130563Sobrien_bfd_elf_validate_reloc (bfd *abfd, arelent *areloc)
732433965Sjdp{
732577301Sobrien  /* Check whether we really have an ELF howto.  */
732633965Sjdp
732760508Sobrien  if ((*areloc->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec)
732833965Sjdp    {
732933965Sjdp      bfd_reloc_code_real_type code;
733033965Sjdp      reloc_howto_type *howto;
733160508Sobrien
733233965Sjdp      /* Alien reloc: Try to determine its type to replace it with an
733377301Sobrien	 equivalent ELF reloc.  */
733433965Sjdp
733533965Sjdp      if (areloc->howto->pc_relative)
733633965Sjdp	{
733733965Sjdp	  switch (areloc->howto->bitsize)
733833965Sjdp	    {
733933965Sjdp	    case 8:
734060508Sobrien	      code = BFD_RELOC_8_PCREL;
734133965Sjdp	      break;
734233965Sjdp	    case 12:
734360508Sobrien	      code = BFD_RELOC_12_PCREL;
734433965Sjdp	      break;
734533965Sjdp	    case 16:
734660508Sobrien	      code = BFD_RELOC_16_PCREL;
734733965Sjdp	      break;
734833965Sjdp	    case 24:
734960508Sobrien	      code = BFD_RELOC_24_PCREL;
735033965Sjdp	      break;
735133965Sjdp	    case 32:
735260508Sobrien	      code = BFD_RELOC_32_PCREL;
735333965Sjdp	      break;
735433965Sjdp	    case 64:
735560508Sobrien	      code = BFD_RELOC_64_PCREL;
735633965Sjdp	      break;
735733965Sjdp	    default:
735833965Sjdp	      goto fail;
735933965Sjdp	    }
736033965Sjdp
736133965Sjdp	  howto = bfd_reloc_type_lookup (abfd, code);
736233965Sjdp
736333965Sjdp	  if (areloc->howto->pcrel_offset != howto->pcrel_offset)
736433965Sjdp	    {
736533965Sjdp	      if (howto->pcrel_offset)
736633965Sjdp		areloc->addend += areloc->address;
736733965Sjdp	      else
736833965Sjdp		areloc->addend -= areloc->address; /* addend is unsigned!! */
736933965Sjdp	    }
737033965Sjdp	}
737133965Sjdp      else
737233965Sjdp	{
737333965Sjdp	  switch (areloc->howto->bitsize)
737433965Sjdp	    {
737533965Sjdp	    case 8:
737660508Sobrien	      code = BFD_RELOC_8;
737733965Sjdp	      break;
737833965Sjdp	    case 14:
737960508Sobrien	      code = BFD_RELOC_14;
738033965Sjdp	      break;
738133965Sjdp	    case 16:
738260508Sobrien	      code = BFD_RELOC_16;
738333965Sjdp	      break;
738433965Sjdp	    case 26:
738560508Sobrien	      code = BFD_RELOC_26;
738633965Sjdp	      break;
738733965Sjdp	    case 32:
738860508Sobrien	      code = BFD_RELOC_32;
738933965Sjdp	      break;
739033965Sjdp	    case 64:
739160508Sobrien	      code = BFD_RELOC_64;
739233965Sjdp	      break;
739333965Sjdp	    default:
739433965Sjdp	      goto fail;
739533965Sjdp	    }
739633965Sjdp
739733965Sjdp	  howto = bfd_reloc_type_lookup (abfd, code);
739833965Sjdp	}
739933965Sjdp
740033965Sjdp      if (howto)
740133965Sjdp	areloc->howto = howto;
740233965Sjdp      else
740333965Sjdp	goto fail;
740433965Sjdp    }
740533965Sjdp
7406130563Sobrien  return TRUE;
740733965Sjdp
740833965Sjdp fail:
740933965Sjdp  (*_bfd_error_handler)
7410218822Sdim    (_("%B: unsupported relocation type %s"),
7411218822Sdim     abfd, areloc->howto->name);
741233965Sjdp  bfd_set_error (bfd_error_bad_value);
7413130563Sobrien  return FALSE;
741433965Sjdp}
741538891Sjdp
7416130563Sobrienbfd_boolean
7417130563Sobrien_bfd_elf_close_and_cleanup (bfd *abfd)
741838891Sjdp{
741938891Sjdp  if (bfd_get_format (abfd) == bfd_object)
742038891Sjdp    {
7421218822Sdim      if (elf_tdata (abfd) != NULL && elf_shstrtab (abfd) != NULL)
742289860Sobrien	_bfd_elf_strtab_free (elf_shstrtab (abfd));
7423218822Sdim      _bfd_dwarf2_cleanup_debug_info (abfd);
742438891Sjdp    }
742538891Sjdp
742638891Sjdp  return _bfd_generic_close_and_cleanup (abfd);
742738891Sjdp}
742860508Sobrien
742960508Sobrien/* For Rel targets, we encode meaningful data for BFD_RELOC_VTABLE_ENTRY
743060508Sobrien   in the relocation's offset.  Thus we cannot allow any sort of sanity
743160508Sobrien   range-checking to interfere.  There is nothing else to do in processing
743260508Sobrien   this reloc.  */
743360508Sobrien
743460508Sobrienbfd_reloc_status_type
7435130563Sobrien_bfd_elf_rel_vtable_reloc_fn
7436130563Sobrien  (bfd *abfd ATTRIBUTE_UNUSED, arelent *re ATTRIBUTE_UNUSED,
7437130563Sobrien   struct bfd_symbol *symbol ATTRIBUTE_UNUSED,
7438130563Sobrien   void *data ATTRIBUTE_UNUSED, asection *is ATTRIBUTE_UNUSED,
7439130563Sobrien   bfd *obfd ATTRIBUTE_UNUSED, char **errmsg ATTRIBUTE_UNUSED)
744060508Sobrien{
744160508Sobrien  return bfd_reloc_ok;
744260508Sobrien}
744360508Sobrien
744460508Sobrien/* Elf core file support.  Much of this only works on native
744560508Sobrien   toolchains, since we rely on knowing the
744660508Sobrien   machine-dependent procfs structure in order to pick
744777301Sobrien   out details about the corefile.  */
744860508Sobrien
744960508Sobrien#ifdef HAVE_SYS_PROCFS_H
745060508Sobrien# include <sys/procfs.h>
7451215679Sattilio
7452215679Sattilio/* Define HAVE_THRMISC_T for consistency with other similar GNU-type stubs. */
7453215679Sattilio#undef	HAVE_THRMISC_T
7454215679Sattilio#if defined (THRMISC_VERSION)
7455215679Sattilio#define	HAVE_THRMISC_T	1
745660508Sobrien#endif
7457215679Sattilio#endif
745860508Sobrien
745977301Sobrien/* FIXME: this is kinda wrong, but it's what gdb wants.  */
746060508Sobrien
746160508Sobrienstatic int
7462130563Sobrienelfcore_make_pid (bfd *abfd)
746360508Sobrien{
746460508Sobrien  return ((elf_tdata (abfd)->core_lwpid << 16)
746560508Sobrien	  + (elf_tdata (abfd)->core_pid));
746660508Sobrien}
746760508Sobrien
746860508Sobrien/* If there isn't a section called NAME, make one, using
746960508Sobrien   data from SECT.  Note, this function will generate a
747060508Sobrien   reference to NAME, so you shouldn't deallocate or
747177301Sobrien   overwrite it.  */
747260508Sobrien
7473130563Sobrienstatic bfd_boolean
7474130563Sobrienelfcore_maybe_make_sect (bfd *abfd, char *name, asection *sect)
747560508Sobrien{
747677301Sobrien  asection *sect2;
747760508Sobrien
747860508Sobrien  if (bfd_get_section_by_name (abfd, name) != NULL)
7479130563Sobrien    return TRUE;
748060508Sobrien
7481218822Sdim  sect2 = bfd_make_section_with_flags (abfd, name, sect->flags);
748260508Sobrien  if (sect2 == NULL)
7483130563Sobrien    return FALSE;
748460508Sobrien
7485218822Sdim  sect2->size = sect->size;
748660508Sobrien  sect2->filepos = sect->filepos;
748760508Sobrien  sect2->alignment_power = sect->alignment_power;
7488130563Sobrien  return TRUE;
748960508Sobrien}
749060508Sobrien
749189860Sobrien/* Create a pseudosection containing SIZE bytes at FILEPOS.  This
749289860Sobrien   actually creates up to two pseudosections:
749389860Sobrien   - For the single-threaded case, a section named NAME, unless
749489860Sobrien     such a section already exists.
749589860Sobrien   - For the multi-threaded case, a section named "NAME/PID", where
749689860Sobrien     PID is elfcore_make_pid (abfd).
749789860Sobrien   Both pseudosections have identical contents. */
7498130563Sobrienbfd_boolean
7499130563Sobrien_bfd_elfcore_make_pseudosection (bfd *abfd,
7500130563Sobrien				 char *name,
7501130563Sobrien				 size_t size,
7502130563Sobrien				 ufile_ptr filepos)
750389860Sobrien{
750489860Sobrien  char buf[100];
750589860Sobrien  char *threaded_name;
7506104838Sobrien  size_t len;
750789860Sobrien  asection *sect;
750889860Sobrien
750989860Sobrien  /* Build the section name.  */
751089860Sobrien
751189860Sobrien  sprintf (buf, "%s/%d", name, elfcore_make_pid (abfd));
7512104838Sobrien  len = strlen (buf) + 1;
7513130563Sobrien  threaded_name = bfd_alloc (abfd, len);
751489860Sobrien  if (threaded_name == NULL)
7515130563Sobrien    return FALSE;
7516104838Sobrien  memcpy (threaded_name, buf, len);
751789860Sobrien
7518218822Sdim  sect = bfd_make_section_anyway_with_flags (abfd, threaded_name,
7519218822Sdim					     SEC_HAS_CONTENTS);
752089860Sobrien  if (sect == NULL)
7521130563Sobrien    return FALSE;
7522218822Sdim  sect->size = size;
752389860Sobrien  sect->filepos = filepos;
752489860Sobrien  sect->alignment_power = 2;
752589860Sobrien
752689860Sobrien  return elfcore_maybe_make_sect (abfd, name, sect);
752789860Sobrien}
752889860Sobrien
752960508Sobrien/* prstatus_t exists on:
753077301Sobrien     solaris 2.5+
753160508Sobrien     linux 2.[01] + glibc
753260508Sobrien     unixware 4.2
753360508Sobrien*/
753460508Sobrien
753560508Sobrien#if defined (HAVE_PRSTATUS_T)
753689860Sobrien
7537130563Sobrienstatic bfd_boolean
7538130563Sobrienelfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
753960508Sobrien{
7540218822Sdim  size_t size;
754177301Sobrien  int offset;
754260508Sobrien
754377301Sobrien  if (note->descsz == sizeof (prstatus_t))
754477301Sobrien    {
754577301Sobrien      prstatus_t prstat;
754660508Sobrien
7547218822Sdim      size = sizeof (prstat.pr_reg);
754877301Sobrien      offset   = offsetof (prstatus_t, pr_reg);
754977301Sobrien      memcpy (&prstat, note->descdata, sizeof (prstat));
755060508Sobrien
755189860Sobrien      /* Do not overwrite the core signal if it
755289860Sobrien	 has already been set by another thread.  */
755389860Sobrien      if (elf_tdata (abfd)->core_signal == 0)
755489860Sobrien	elf_tdata (abfd)->core_signal = prstat.pr_cursig;
755577301Sobrien      elf_tdata (abfd)->core_pid = prstat.pr_pid;
755660508Sobrien
755777301Sobrien      /* pr_who exists on:
755877301Sobrien	 solaris 2.5+
755977301Sobrien	 unixware 4.2
756077301Sobrien	 pr_who doesn't exist on:
756177301Sobrien	 linux 2.[01]
756277301Sobrien	 */
756360508Sobrien#if defined (HAVE_PRSTATUS_T_PR_WHO)
756477301Sobrien      elf_tdata (abfd)->core_lwpid = prstat.pr_who;
756560508Sobrien#endif
756677301Sobrien    }
756777301Sobrien#if defined (HAVE_PRSTATUS32_T)
756877301Sobrien  else if (note->descsz == sizeof (prstatus32_t))
756977301Sobrien    {
757077301Sobrien      /* 64-bit host, 32-bit corefile */
757177301Sobrien      prstatus32_t prstat;
757260508Sobrien
7573218822Sdim      size = sizeof (prstat.pr_reg);
757477301Sobrien      offset   = offsetof (prstatus32_t, pr_reg);
757577301Sobrien      memcpy (&prstat, note->descdata, sizeof (prstat));
757660508Sobrien
757789860Sobrien      /* Do not overwrite the core signal if it
757889860Sobrien	 has already been set by another thread.  */
757989860Sobrien      if (elf_tdata (abfd)->core_signal == 0)
758089860Sobrien	elf_tdata (abfd)->core_signal = prstat.pr_cursig;
758177301Sobrien      elf_tdata (abfd)->core_pid = prstat.pr_pid;
758277301Sobrien
758377301Sobrien      /* pr_who exists on:
758477301Sobrien	 solaris 2.5+
758577301Sobrien	 unixware 4.2
758677301Sobrien	 pr_who doesn't exist on:
758777301Sobrien	 linux 2.[01]
758877301Sobrien	 */
758977301Sobrien#if defined (HAVE_PRSTATUS32_T_PR_WHO)
759077301Sobrien      elf_tdata (abfd)->core_lwpid = prstat.pr_who;
759177301Sobrien#endif
759277301Sobrien    }
759377301Sobrien#endif /* HAVE_PRSTATUS32_T */
759477301Sobrien  else
759577301Sobrien    {
759677301Sobrien      /* Fail - we don't know how to handle any other
759777301Sobrien	 note size (ie. data object type).  */
7598130563Sobrien      return TRUE;
759977301Sobrien    }
760077301Sobrien
760189860Sobrien  /* Make a ".reg/999" section and a ".reg" section.  */
760289860Sobrien  return _bfd_elfcore_make_pseudosection (abfd, ".reg",
7603218822Sdim					  size, note->descpos + offset);
760460508Sobrien}
760560508Sobrien#endif /* defined (HAVE_PRSTATUS_T) */
760660508Sobrien
760789860Sobrien/* Create a pseudosection containing the exact contents of NOTE.  */
7608130563Sobrienstatic bfd_boolean
7609130563Sobrienelfcore_make_note_pseudosection (bfd *abfd,
7610130563Sobrien				 char *name,
7611130563Sobrien				 Elf_Internal_Note *note)
761260508Sobrien{
761389860Sobrien  return _bfd_elfcore_make_pseudosection (abfd, name,
761489860Sobrien					  note->descsz, note->descpos);
761560508Sobrien}
761660508Sobrien
761760508Sobrien/* There isn't a consistent prfpregset_t across platforms,
761860508Sobrien   but it doesn't matter, because we don't have to pick this
761977301Sobrien   data structure apart.  */
762077301Sobrien
7621130563Sobrienstatic bfd_boolean
7622130563Sobrienelfcore_grok_prfpreg (bfd *abfd, Elf_Internal_Note *note)
762360508Sobrien{
762460508Sobrien  return elfcore_make_note_pseudosection (abfd, ".reg2", note);
762560508Sobrien}
762660508Sobrien
762760508Sobrien/* Linux dumps the Intel SSE regs in a note named "LINUX" with a note
762860508Sobrien   type of 5 (NT_PRXFPREG).  Just include the whole note's contents
762960508Sobrien   literally.  */
763077301Sobrien
7631130563Sobrienstatic bfd_boolean
7632130563Sobrienelfcore_grok_prxfpreg (bfd *abfd, Elf_Internal_Note *note)
763360508Sobrien{
763460508Sobrien  return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note);
763560508Sobrien}
763660508Sobrien
7637215679Sattilio#if defined (HAVE_THRMISC_T)
7638215679Sattilio
7639215679Sattiliostatic bfd_boolean
7640215679Sattilioelfcore_grok_thrmisc (bfd *abfd, Elf_Internal_Note *note)
7641215679Sattilio{
7642215679Sattilio  return elfcore_make_note_pseudosection (abfd, ".tname", note);
7643215679Sattilio}
7644215679Sattilio
7645215679Sattilio#endif /* defined (HAVE_THRMISC_T) */
7646215679Sattilio
764760508Sobrien#if defined (HAVE_PRPSINFO_T)
764877301Sobrientypedef prpsinfo_t   elfcore_psinfo_t;
764977301Sobrien#if defined (HAVE_PRPSINFO32_T)		/* Sparc64 cross Sparc32 */
765077301Sobrientypedef prpsinfo32_t elfcore_psinfo32_t;
765160508Sobrien#endif
765277301Sobrien#endif
765360508Sobrien
765460508Sobrien#if defined (HAVE_PSINFO_T)
765577301Sobrientypedef psinfo_t   elfcore_psinfo_t;
765677301Sobrien#if defined (HAVE_PSINFO32_T)		/* Sparc64 cross Sparc32 */
765777301Sobrientypedef psinfo32_t elfcore_psinfo32_t;
765860508Sobrien#endif
765977301Sobrien#endif
766060508Sobrien
766160508Sobrien/* return a malloc'ed copy of a string at START which is at
766260508Sobrien   most MAX bytes long, possibly without a terminating '\0'.
766377301Sobrien   the copy will always have a terminating '\0'.  */
766460508Sobrien
766589860Sobrienchar *
7666130563Sobrien_bfd_elfcore_strndup (bfd *abfd, char *start, size_t max)
766760508Sobrien{
766889860Sobrien  char *dups;
766977301Sobrien  char *end = memchr (start, '\0', max);
767089860Sobrien  size_t len;
767160508Sobrien
767260508Sobrien  if (end == NULL)
767360508Sobrien    len = max;
767460508Sobrien  else
767560508Sobrien    len = end - start;
767660508Sobrien
7677130563Sobrien  dups = bfd_alloc (abfd, len + 1);
767889860Sobrien  if (dups == NULL)
767960508Sobrien    return NULL;
768060508Sobrien
768189860Sobrien  memcpy (dups, start, len);
768289860Sobrien  dups[len] = '\0';
768360508Sobrien
768489860Sobrien  return dups;
768560508Sobrien}
768660508Sobrien
768789860Sobrien#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
7688130563Sobrienstatic bfd_boolean
7689130563Sobrienelfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
769060508Sobrien{
769177301Sobrien  if (note->descsz == sizeof (elfcore_psinfo_t))
769277301Sobrien    {
769377301Sobrien      elfcore_psinfo_t psinfo;
769460508Sobrien
769577301Sobrien      memcpy (&psinfo, note->descdata, sizeof (psinfo));
769660508Sobrien
769777301Sobrien      elf_tdata (abfd)->core_program
769889860Sobrien	= _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
769989860Sobrien				sizeof (psinfo.pr_fname));
770060508Sobrien
770177301Sobrien      elf_tdata (abfd)->core_command
770289860Sobrien	= _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
770389860Sobrien				sizeof (psinfo.pr_psargs));
770477301Sobrien    }
770577301Sobrien#if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
770677301Sobrien  else if (note->descsz == sizeof (elfcore_psinfo32_t))
770777301Sobrien    {
770877301Sobrien      /* 64-bit host, 32-bit corefile */
770977301Sobrien      elfcore_psinfo32_t psinfo;
771060508Sobrien
771177301Sobrien      memcpy (&psinfo, note->descdata, sizeof (psinfo));
771260508Sobrien
771377301Sobrien      elf_tdata (abfd)->core_program
771489860Sobrien	= _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
771589860Sobrien				sizeof (psinfo.pr_fname));
771677301Sobrien
771777301Sobrien      elf_tdata (abfd)->core_command
771889860Sobrien	= _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
771989860Sobrien				sizeof (psinfo.pr_psargs));
772077301Sobrien    }
772177301Sobrien#endif
772277301Sobrien
772377301Sobrien  else
772477301Sobrien    {
772577301Sobrien      /* Fail - we don't know how to handle any other
772677301Sobrien	 note size (ie. data object type).  */
7727130563Sobrien      return TRUE;
772877301Sobrien    }
772977301Sobrien
773060508Sobrien  /* Note that for some reason, a spurious space is tacked
773160508Sobrien     onto the end of the args in some (at least one anyway)
773277301Sobrien     implementations, so strip it off if it exists.  */
773360508Sobrien
773460508Sobrien  {
773577301Sobrien    char *command = elf_tdata (abfd)->core_command;
773660508Sobrien    int n = strlen (command);
773760508Sobrien
773860508Sobrien    if (0 < n && command[n - 1] == ' ')
773960508Sobrien      command[n - 1] = '\0';
774060508Sobrien  }
774160508Sobrien
7742130563Sobrien  return TRUE;
774360508Sobrien}
774460508Sobrien#endif /* defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) */
774560508Sobrien
774660508Sobrien#if defined (HAVE_PSTATUS_T)
7747130563Sobrienstatic bfd_boolean
7748130563Sobrienelfcore_grok_pstatus (bfd *abfd, Elf_Internal_Note *note)
774960508Sobrien{
775077301Sobrien  if (note->descsz == sizeof (pstatus_t)
775177301Sobrien#if defined (HAVE_PXSTATUS_T)
775277301Sobrien      || note->descsz == sizeof (pxstatus_t)
775377301Sobrien#endif
775477301Sobrien      )
775577301Sobrien    {
775677301Sobrien      pstatus_t pstat;
775760508Sobrien
775877301Sobrien      memcpy (&pstat, note->descdata, sizeof (pstat));
775960508Sobrien
776077301Sobrien      elf_tdata (abfd)->core_pid = pstat.pr_pid;
776177301Sobrien    }
776277301Sobrien#if defined (HAVE_PSTATUS32_T)
776377301Sobrien  else if (note->descsz == sizeof (pstatus32_t))
776477301Sobrien    {
776577301Sobrien      /* 64-bit host, 32-bit corefile */
776677301Sobrien      pstatus32_t pstat;
776760508Sobrien
776877301Sobrien      memcpy (&pstat, note->descdata, sizeof (pstat));
776960508Sobrien
777077301Sobrien      elf_tdata (abfd)->core_pid = pstat.pr_pid;
777177301Sobrien    }
777277301Sobrien#endif
777360508Sobrien  /* Could grab some more details from the "representative"
777460508Sobrien     lwpstatus_t in pstat.pr_lwp, but we'll catch it all in an
777577301Sobrien     NT_LWPSTATUS note, presumably.  */
777660508Sobrien
7777130563Sobrien  return TRUE;
777860508Sobrien}
777960508Sobrien#endif /* defined (HAVE_PSTATUS_T) */
778060508Sobrien
778160508Sobrien#if defined (HAVE_LWPSTATUS_T)
7782130563Sobrienstatic bfd_boolean
7783130563Sobrienelfcore_grok_lwpstatus (bfd *abfd, Elf_Internal_Note *note)
778460508Sobrien{
778560508Sobrien  lwpstatus_t lwpstat;
778660508Sobrien  char buf[100];
778777301Sobrien  char *name;
7788104838Sobrien  size_t len;
778977301Sobrien  asection *sect;
779060508Sobrien
779177301Sobrien  if (note->descsz != sizeof (lwpstat)
779277301Sobrien#if defined (HAVE_LWPXSTATUS_T)
779377301Sobrien      && note->descsz != sizeof (lwpxstatus_t)
779477301Sobrien#endif
779577301Sobrien      )
7796130563Sobrien    return TRUE;
779760508Sobrien
779860508Sobrien  memcpy (&lwpstat, note->descdata, sizeof (lwpstat));
779960508Sobrien
780060508Sobrien  elf_tdata (abfd)->core_lwpid = lwpstat.pr_lwpid;
780160508Sobrien  elf_tdata (abfd)->core_signal = lwpstat.pr_cursig;
780260508Sobrien
780377301Sobrien  /* Make a ".reg/999" section.  */
780460508Sobrien
780560508Sobrien  sprintf (buf, ".reg/%d", elfcore_make_pid (abfd));
7806104838Sobrien  len = strlen (buf) + 1;
7807130563Sobrien  name = bfd_alloc (abfd, len);
780860508Sobrien  if (name == NULL)
7809130563Sobrien    return FALSE;
7810104838Sobrien  memcpy (name, buf, len);
781160508Sobrien
7812218822Sdim  sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
781360508Sobrien  if (sect == NULL)
7814130563Sobrien    return FALSE;
781560508Sobrien
781660508Sobrien#if defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
7817218822Sdim  sect->size = sizeof (lwpstat.pr_context.uc_mcontext.gregs);
781860508Sobrien  sect->filepos = note->descpos
781960508Sobrien    + offsetof (lwpstatus_t, pr_context.uc_mcontext.gregs);
782060508Sobrien#endif
782160508Sobrien
782260508Sobrien#if defined (HAVE_LWPSTATUS_T_PR_REG)
7823218822Sdim  sect->size = sizeof (lwpstat.pr_reg);
782460508Sobrien  sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_reg);
782560508Sobrien#endif
782660508Sobrien
782760508Sobrien  sect->alignment_power = 2;
782860508Sobrien
782960508Sobrien  if (!elfcore_maybe_make_sect (abfd, ".reg", sect))
7830130563Sobrien    return FALSE;
783160508Sobrien
783260508Sobrien  /* Make a ".reg2/999" section */
783360508Sobrien
783460508Sobrien  sprintf (buf, ".reg2/%d", elfcore_make_pid (abfd));
7835104838Sobrien  len = strlen (buf) + 1;
7836130563Sobrien  name = bfd_alloc (abfd, len);
783760508Sobrien  if (name == NULL)
7838130563Sobrien    return FALSE;
7839104838Sobrien  memcpy (name, buf, len);
784060508Sobrien
7841218822Sdim  sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
784260508Sobrien  if (sect == NULL)
7843130563Sobrien    return FALSE;
784460508Sobrien
784560508Sobrien#if defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
7846218822Sdim  sect->size = sizeof (lwpstat.pr_context.uc_mcontext.fpregs);
784760508Sobrien  sect->filepos = note->descpos
784860508Sobrien    + offsetof (lwpstatus_t, pr_context.uc_mcontext.fpregs);
784960508Sobrien#endif
785060508Sobrien
785160508Sobrien#if defined (HAVE_LWPSTATUS_T_PR_FPREG)
7852218822Sdim  sect->size = sizeof (lwpstat.pr_fpreg);
785360508Sobrien  sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_fpreg);
785460508Sobrien#endif
785560508Sobrien
785660508Sobrien  sect->alignment_power = 2;
785760508Sobrien
785889860Sobrien  return elfcore_maybe_make_sect (abfd, ".reg2", sect);
785960508Sobrien}
786060508Sobrien#endif /* defined (HAVE_LWPSTATUS_T) */
786160508Sobrien
786260508Sobrien#if defined (HAVE_WIN32_PSTATUS_T)
7863130563Sobrienstatic bfd_boolean
7864130563Sobrienelfcore_grok_win32pstatus (bfd *abfd, Elf_Internal_Note *note)
786560508Sobrien{
786660508Sobrien  char buf[30];
786777301Sobrien  char *name;
7868104838Sobrien  size_t len;
786977301Sobrien  asection *sect;
787060508Sobrien  win32_pstatus_t pstatus;
787160508Sobrien
787260508Sobrien  if (note->descsz < sizeof (pstatus))
7873130563Sobrien    return TRUE;
787460508Sobrien
787589860Sobrien  memcpy (&pstatus, note->descdata, sizeof (pstatus));
787677301Sobrien
787777301Sobrien  switch (pstatus.data_type)
787860508Sobrien    {
787960508Sobrien    case NOTE_INFO_PROCESS:
788060508Sobrien      /* FIXME: need to add ->core_command.  */
788160508Sobrien      elf_tdata (abfd)->core_signal = pstatus.data.process_info.signal;
788260508Sobrien      elf_tdata (abfd)->core_pid = pstatus.data.process_info.pid;
788377301Sobrien      break;
788460508Sobrien
788560508Sobrien    case NOTE_INFO_THREAD:
788660508Sobrien      /* Make a ".reg/999" section.  */
7887218822Sdim      sprintf (buf, ".reg/%ld", (long) pstatus.data.thread_info.tid);
788877301Sobrien
7889104838Sobrien      len = strlen (buf) + 1;
7890130563Sobrien      name = bfd_alloc (abfd, len);
789160508Sobrien      if (name == NULL)
7892130563Sobrien	return FALSE;
789377301Sobrien
7894104838Sobrien      memcpy (name, buf, len);
789560508Sobrien
7896218822Sdim      sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
789760508Sobrien      if (sect == NULL)
7898130563Sobrien	return FALSE;
789977301Sobrien
7900218822Sdim      sect->size = sizeof (pstatus.data.thread_info.thread_context);
790189860Sobrien      sect->filepos = (note->descpos
790289860Sobrien		       + offsetof (struct win32_pstatus,
790389860Sobrien				   data.thread_info.thread_context));
790460508Sobrien      sect->alignment_power = 2;
790560508Sobrien
790660508Sobrien      if (pstatus.data.thread_info.is_active_thread)
790760508Sobrien	if (! elfcore_maybe_make_sect (abfd, ".reg", sect))
7908130563Sobrien	  return FALSE;
790960508Sobrien      break;
791060508Sobrien
791160508Sobrien    case NOTE_INFO_MODULE:
791260508Sobrien      /* Make a ".module/xxxxxxxx" section.  */
7913218822Sdim      sprintf (buf, ".module/%08lx",
7914218822Sdim	       (long) pstatus.data.module_info.base_address);
791577301Sobrien
7916104838Sobrien      len = strlen (buf) + 1;
7917130563Sobrien      name = bfd_alloc (abfd, len);
791860508Sobrien      if (name == NULL)
7919130563Sobrien	return FALSE;
792077301Sobrien
7921104838Sobrien      memcpy (name, buf, len);
792260508Sobrien
7923218822Sdim      sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
792477301Sobrien
792560508Sobrien      if (sect == NULL)
7926130563Sobrien	return FALSE;
792777301Sobrien
7928218822Sdim      sect->size = note->descsz;
792960508Sobrien      sect->filepos = note->descpos;
793060508Sobrien      sect->alignment_power = 2;
793160508Sobrien      break;
793260508Sobrien
793360508Sobrien    default:
7934130563Sobrien      return TRUE;
793560508Sobrien    }
793660508Sobrien
7937130563Sobrien  return TRUE;
793860508Sobrien}
793960508Sobrien#endif /* HAVE_WIN32_PSTATUS_T */
794060508Sobrien
7941130563Sobrienstatic bfd_boolean
7942130563Sobrienelfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
794360508Sobrien{
7944130563Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
794589860Sobrien
794660508Sobrien  switch (note->type)
794760508Sobrien    {
794860508Sobrien    default:
7949130563Sobrien      return TRUE;
795060508Sobrien
795189860Sobrien    case NT_PRSTATUS:
795289860Sobrien      if (bed->elf_backend_grok_prstatus)
795389860Sobrien	if ((*bed->elf_backend_grok_prstatus) (abfd, note))
7954130563Sobrien	  return TRUE;
795560508Sobrien#if defined (HAVE_PRSTATUS_T)
795660508Sobrien      return elfcore_grok_prstatus (abfd, note);
795789860Sobrien#else
7958130563Sobrien      return TRUE;
795960508Sobrien#endif
796060508Sobrien
796160508Sobrien#if defined (HAVE_PSTATUS_T)
796260508Sobrien    case NT_PSTATUS:
796360508Sobrien      return elfcore_grok_pstatus (abfd, note);
796460508Sobrien#endif
796560508Sobrien
796660508Sobrien#if defined (HAVE_LWPSTATUS_T)
796760508Sobrien    case NT_LWPSTATUS:
796860508Sobrien      return elfcore_grok_lwpstatus (abfd, note);
796960508Sobrien#endif
797060508Sobrien
797160508Sobrien    case NT_FPREGSET:		/* FIXME: rename to NT_PRFPREG */
797260508Sobrien      return elfcore_grok_prfpreg (abfd, note);
797360508Sobrien
797460508Sobrien#if defined (HAVE_WIN32_PSTATUS_T)
797577301Sobrien    case NT_WIN32PSTATUS:
797660508Sobrien      return elfcore_grok_win32pstatus (abfd, note);
797760508Sobrien#endif
797860508Sobrien
797977301Sobrien    case NT_PRXFPREG:		/* Linux SSE extension */
7980130563Sobrien      if (note->namesz == 6
7981130563Sobrien	  && strcmp (note->namedata, "LINUX") == 0)
798260508Sobrien	return elfcore_grok_prxfpreg (abfd, note);
798360508Sobrien      else
7984130563Sobrien	return TRUE;
798560508Sobrien
798660508Sobrien    case NT_PRPSINFO:
798760508Sobrien    case NT_PSINFO:
798889860Sobrien      if (bed->elf_backend_grok_psinfo)
798989860Sobrien	if ((*bed->elf_backend_grok_psinfo) (abfd, note))
7990130563Sobrien	  return TRUE;
799189860Sobrien#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
799260508Sobrien      return elfcore_grok_psinfo (abfd, note);
799389860Sobrien#else
7994130563Sobrien      return TRUE;
799560508Sobrien#endif
7996130563Sobrien
7997130563Sobrien    case NT_AUXV:
7998130563Sobrien      {
7999218822Sdim	asection *sect = bfd_make_section_anyway_with_flags (abfd, ".auxv",
8000218822Sdim							     SEC_HAS_CONTENTS);
8001130563Sobrien
8002130563Sobrien	if (sect == NULL)
8003130563Sobrien	  return FALSE;
8004218822Sdim	sect->size = note->descsz;
8005130563Sobrien	sect->filepos = note->descpos;
8006130563Sobrien	sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32;
8007130563Sobrien
8008130563Sobrien	return TRUE;
8009130563Sobrien      }
8010215679Sattilio
8011215679Sattilio#if defined (HAVE_THRMISC_T)
8012215679Sattilio    case NT_THRMISC:
8013215679Sattilio      return elfcore_grok_thrmisc (abfd, note);
8014215679Sattilio#endif
8015215679Sattilio
801660508Sobrien    }
801760508Sobrien}
801860508Sobrien
8019130563Sobrienstatic bfd_boolean
8020130563Sobrienelfcore_netbsd_get_lwpid (Elf_Internal_Note *note, int *lwpidp)
802189860Sobrien{
802289860Sobrien  char *cp;
802389860Sobrien
802489860Sobrien  cp = strchr (note->namedata, '@');
802589860Sobrien  if (cp != NULL)
802689860Sobrien    {
802794542Sobrien      *lwpidp = atoi(cp + 1);
8028130563Sobrien      return TRUE;
802989860Sobrien    }
8030130563Sobrien  return FALSE;
803189860Sobrien}
803289860Sobrien
8033130563Sobrienstatic bfd_boolean
8034130563Sobrienelfcore_grok_netbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
803589860Sobrien{
803689860Sobrien  /* Signal number at offset 0x08. */
803789860Sobrien  elf_tdata (abfd)->core_signal
803889860Sobrien    = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);
803989860Sobrien
804089860Sobrien  /* Process ID at offset 0x50. */
804189860Sobrien  elf_tdata (abfd)->core_pid
804289860Sobrien    = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x50);
804389860Sobrien
804489860Sobrien  /* Command name at 0x7c (max 32 bytes, including nul). */
804589860Sobrien  elf_tdata (abfd)->core_command
804689860Sobrien    = _bfd_elfcore_strndup (abfd, note->descdata + 0x7c, 31);
804789860Sobrien
8048130563Sobrien  return elfcore_make_note_pseudosection (abfd, ".note.netbsdcore.procinfo",
8049130563Sobrien					  note);
805089860Sobrien}
805189860Sobrien
8052130563Sobrienstatic bfd_boolean
8053130563Sobrienelfcore_grok_netbsd_note (bfd *abfd, Elf_Internal_Note *note)
805489860Sobrien{
805589860Sobrien  int lwp;
805689860Sobrien
805789860Sobrien  if (elfcore_netbsd_get_lwpid (note, &lwp))
805889860Sobrien    elf_tdata (abfd)->core_lwpid = lwp;
805989860Sobrien
806089860Sobrien  if (note->type == NT_NETBSDCORE_PROCINFO)
806189860Sobrien    {
806289860Sobrien      /* NetBSD-specific core "procinfo".  Note that we expect to
8063218822Sdim	 find this note before any of the others, which is fine,
8064218822Sdim	 since the kernel writes this note out first when it
8065218822Sdim	 creates a core file.  */
8066104838Sobrien
806789860Sobrien      return elfcore_grok_netbsd_procinfo (abfd, note);
806889860Sobrien    }
806989860Sobrien
807089860Sobrien  /* As of Jan 2002 there are no other machine-independent notes
807189860Sobrien     defined for NetBSD core files.  If the note type is less
807289860Sobrien     than the start of the machine-dependent note types, we don't
807389860Sobrien     understand it.  */
8074104838Sobrien
807589860Sobrien  if (note->type < NT_NETBSDCORE_FIRSTMACH)
8076130563Sobrien    return TRUE;
807789860Sobrien
807889860Sobrien
807989860Sobrien  switch (bfd_get_arch (abfd))
808089860Sobrien    {
8081218822Sdim      /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0 and
8082218822Sdim	 PT_GETFPREGS == mach+2.  */
808389860Sobrien
808489860Sobrien    case bfd_arch_alpha:
808589860Sobrien    case bfd_arch_sparc:
808689860Sobrien      switch (note->type)
8087218822Sdim	{
8088218822Sdim	case NT_NETBSDCORE_FIRSTMACH+0:
8089218822Sdim	  return elfcore_make_note_pseudosection (abfd, ".reg", note);
809089860Sobrien
8091218822Sdim	case NT_NETBSDCORE_FIRSTMACH+2:
8092218822Sdim	  return elfcore_make_note_pseudosection (abfd, ".reg2", note);
809389860Sobrien
8094218822Sdim	default:
8095218822Sdim	  return TRUE;
8096218822Sdim	}
809789860Sobrien
8098218822Sdim      /* On all other arch's, PT_GETREGS == mach+1 and
8099218822Sdim	 PT_GETFPREGS == mach+3.  */
810089860Sobrien
810189860Sobrien    default:
810289860Sobrien      switch (note->type)
8103218822Sdim	{
8104218822Sdim	case NT_NETBSDCORE_FIRSTMACH+1:
8105218822Sdim	  return elfcore_make_note_pseudosection (abfd, ".reg", note);
810689860Sobrien
8107218822Sdim	case NT_NETBSDCORE_FIRSTMACH+3:
8108218822Sdim	  return elfcore_make_note_pseudosection (abfd, ".reg2", note);
810989860Sobrien
8110218822Sdim	default:
8111218822Sdim	  return TRUE;
8112218822Sdim	}
811389860Sobrien    }
811489860Sobrien    /* NOTREACHED */
811589860Sobrien}
811689860Sobrien
8117130563Sobrienstatic bfd_boolean
8118218822Sdimelfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, long *tid)
8119130563Sobrien{
8120130563Sobrien  void *ddata = note->descdata;
8121130563Sobrien  char buf[100];
8122130563Sobrien  char *name;
8123130563Sobrien  asection *sect;
8124130563Sobrien  short sig;
8125130563Sobrien  unsigned flags;
8126130563Sobrien
8127130563Sobrien  /* nto_procfs_status 'pid' field is at offset 0.  */
8128130563Sobrien  elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, (bfd_byte *) ddata);
8129130563Sobrien
8130130563Sobrien  /* nto_procfs_status 'tid' field is at offset 4.  Pass it back.  */
8131130563Sobrien  *tid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4);
8132130563Sobrien
8133130563Sobrien  /* nto_procfs_status 'flags' field is at offset 8.  */
8134130563Sobrien  flags = bfd_get_32 (abfd, (bfd_byte *) ddata + 8);
8135130563Sobrien
8136130563Sobrien  /* nto_procfs_status 'what' field is at offset 14.  */
8137130563Sobrien  if ((sig = bfd_get_16 (abfd, (bfd_byte *) ddata + 14)) > 0)
8138130563Sobrien    {
8139130563Sobrien      elf_tdata (abfd)->core_signal = sig;
8140130563Sobrien      elf_tdata (abfd)->core_lwpid = *tid;
8141130563Sobrien    }
8142130563Sobrien
8143130563Sobrien  /* _DEBUG_FLAG_CURTID (current thread) is 0x80.  Some cores
8144130563Sobrien     do not come from signals so we make sure we set the current
8145130563Sobrien     thread just in case.  */
8146130563Sobrien  if (flags & 0x00000080)
8147130563Sobrien    elf_tdata (abfd)->core_lwpid = *tid;
8148130563Sobrien
8149130563Sobrien  /* Make a ".qnx_core_status/%d" section.  */
8150218822Sdim  sprintf (buf, ".qnx_core_status/%ld", *tid);
8151130563Sobrien
8152130563Sobrien  name = bfd_alloc (abfd, strlen (buf) + 1);
8153130563Sobrien  if (name == NULL)
8154130563Sobrien    return FALSE;
8155130563Sobrien  strcpy (name, buf);
8156130563Sobrien
8157218822Sdim  sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
8158130563Sobrien  if (sect == NULL)
8159130563Sobrien    return FALSE;
8160130563Sobrien
8161218822Sdim  sect->size            = note->descsz;
8162130563Sobrien  sect->filepos         = note->descpos;
8163130563Sobrien  sect->alignment_power = 2;
8164130563Sobrien
8165130563Sobrien  return (elfcore_maybe_make_sect (abfd, ".qnx_core_status", sect));
8166130563Sobrien}
8167130563Sobrien
8168130563Sobrienstatic bfd_boolean
8169218822Sdimelfcore_grok_nto_regs (bfd *abfd,
8170218822Sdim		       Elf_Internal_Note *note,
8171218822Sdim		       long tid,
8172218822Sdim		       char *base)
8173130563Sobrien{
8174130563Sobrien  char buf[100];
8175130563Sobrien  char *name;
8176130563Sobrien  asection *sect;
8177130563Sobrien
8178218822Sdim  /* Make a "(base)/%d" section.  */
8179218822Sdim  sprintf (buf, "%s/%ld", base, tid);
8180130563Sobrien
8181130563Sobrien  name = bfd_alloc (abfd, strlen (buf) + 1);
8182130563Sobrien  if (name == NULL)
8183130563Sobrien    return FALSE;
8184130563Sobrien  strcpy (name, buf);
8185130563Sobrien
8186218822Sdim  sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
8187130563Sobrien  if (sect == NULL)
8188130563Sobrien    return FALSE;
8189130563Sobrien
8190218822Sdim  sect->size            = note->descsz;
8191130563Sobrien  sect->filepos         = note->descpos;
8192130563Sobrien  sect->alignment_power = 2;
8193130563Sobrien
8194130563Sobrien  /* This is the current thread.  */
8195130563Sobrien  if (elf_tdata (abfd)->core_lwpid == tid)
8196218822Sdim    return elfcore_maybe_make_sect (abfd, base, sect);
8197130563Sobrien
8198130563Sobrien  return TRUE;
8199130563Sobrien}
8200130563Sobrien
8201130563Sobrien#define BFD_QNT_CORE_INFO	7
8202130563Sobrien#define BFD_QNT_CORE_STATUS	8
8203130563Sobrien#define BFD_QNT_CORE_GREG	9
8204130563Sobrien#define BFD_QNT_CORE_FPREG	10
8205130563Sobrien
8206130563Sobrienstatic bfd_boolean
8207130563Sobrienelfcore_grok_nto_note (bfd *abfd, Elf_Internal_Note *note)
8208130563Sobrien{
8209130563Sobrien  /* Every GREG section has a STATUS section before it.  Store the
8210130563Sobrien     tid from the previous call to pass down to the next gregs
8211130563Sobrien     function.  */
8212218822Sdim  static long tid = 1;
8213130563Sobrien
8214130563Sobrien  switch (note->type)
8215130563Sobrien    {
8216218822Sdim    case BFD_QNT_CORE_INFO:
8217218822Sdim      return elfcore_make_note_pseudosection (abfd, ".qnx_core_info", note);
8218218822Sdim    case BFD_QNT_CORE_STATUS:
8219218822Sdim      return elfcore_grok_nto_status (abfd, note, &tid);
8220218822Sdim    case BFD_QNT_CORE_GREG:
8221218822Sdim      return elfcore_grok_nto_regs (abfd, note, tid, ".reg");
8222218822Sdim    case BFD_QNT_CORE_FPREG:
8223218822Sdim      return elfcore_grok_nto_regs (abfd, note, tid, ".reg2");
8224218822Sdim    default:
8225218822Sdim      return TRUE;
8226130563Sobrien    }
8227130563Sobrien}
8228130563Sobrien
822989860Sobrien/* Function: elfcore_write_note
823089860Sobrien
8231104838Sobrien   Inputs:
8232218822Sdim     buffer to hold note, and current size of buffer
823389860Sobrien     name of note
823489860Sobrien     type of note
823589860Sobrien     data for note
823689860Sobrien     size of data for note
823789860Sobrien
8238218822Sdim   Writes note to end of buffer.  ELF64 notes are written exactly as
8239218822Sdim   for ELF32, despite the current (as of 2006) ELF gabi specifying
8240218822Sdim   that they ought to have 8-byte namesz and descsz field, and have
8241218822Sdim   8-byte alignment.  Other writers, eg. Linux kernel, do the same.
8242218822Sdim
824389860Sobrien   Return:
8244218822Sdim   Pointer to realloc'd buffer, *BUFSIZ updated.  */
824589860Sobrien
824689860Sobrienchar *
8247218822Sdimelfcore_write_note (bfd *abfd,
8248130563Sobrien		    char *buf,
8249218822Sdim		    int *bufsiz,
8250130563Sobrien		    const char *name,
8251218822Sdim		    int type,
8252130563Sobrien		    const void *input,
8253218822Sdim		    int size)
825489860Sobrien{
825589860Sobrien  Elf_External_Note *xnp;
8256104838Sobrien  size_t namesz;
8257104838Sobrien  size_t newspace;
8258218822Sdim  char *dest;
825989860Sobrien
8260104838Sobrien  namesz = 0;
8261104838Sobrien  if (name != NULL)
8262218822Sdim    namesz = strlen (name) + 1;
8263104838Sobrien
8264218822Sdim  newspace = 12 + ((namesz + 3) & -4) + ((size + 3) & -4);
8265104838Sobrien
8266218822Sdim  buf = realloc (buf, *bufsiz + newspace);
8267218822Sdim  dest = buf + *bufsiz;
826889860Sobrien  *bufsiz += newspace;
826989860Sobrien  xnp = (Elf_External_Note *) dest;
827089860Sobrien  H_PUT_32 (abfd, namesz, xnp->namesz);
827189860Sobrien  H_PUT_32 (abfd, size, xnp->descsz);
827289860Sobrien  H_PUT_32 (abfd, type, xnp->type);
8273104838Sobrien  dest = xnp->name;
8274104838Sobrien  if (name != NULL)
8275104838Sobrien    {
8276104838Sobrien      memcpy (dest, name, namesz);
8277104838Sobrien      dest += namesz;
8278218822Sdim      while (namesz & 3)
8279104838Sobrien	{
8280104838Sobrien	  *dest++ = '\0';
8281218822Sdim	  ++namesz;
8282104838Sobrien	}
8283104838Sobrien    }
8284104838Sobrien  memcpy (dest, input, size);
8285218822Sdim  dest += size;
8286218822Sdim  while (size & 3)
8287218822Sdim    {
8288218822Sdim      *dest++ = '\0';
8289218822Sdim      ++size;
8290218822Sdim    }
8291218822Sdim  return buf;
829289860Sobrien}
829389860Sobrien
829489860Sobrien#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
829589860Sobrienchar *
8296130563Sobrienelfcore_write_prpsinfo (bfd  *abfd,
8297130563Sobrien			char *buf,
8298130563Sobrien			int  *bufsiz,
8299130563Sobrien			const char *fname,
8300130563Sobrien			const char *psargs)
830189860Sobrien{
8302218822Sdim  const char *note_name = "CORE";
8303218822Sdim  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
830489860Sobrien
8305218822Sdim  if (bed->elf_backend_write_core_note != NULL)
8306218822Sdim    {
8307218822Sdim      char *ret;
8308218822Sdim      ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
8309218822Sdim						 NT_PRPSINFO, fname, psargs);
8310218822Sdim      if (ret != NULL)
8311218822Sdim	return ret;
8312218822Sdim    }
8313218822Sdim
8314218822Sdim#if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
8315218822Sdim  if (bed->s->elfclass == ELFCLASS32)
8316218822Sdim    {
8317218822Sdim#if defined (HAVE_PSINFO32_T)
8318218822Sdim      psinfo32_t data;
8319218822Sdim      int note_type = NT_PSINFO;
8320218822Sdim#else
8321218822Sdim      prpsinfo32_t data;
8322218822Sdim      int note_type = NT_PRPSINFO;
8323218822Sdim#endif
8324218822Sdim
8325218822Sdim      memset (&data, 0, sizeof (data));
8326218822Sdim      strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
8327218822Sdim      strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
8328218822Sdim      return elfcore_write_note (abfd, buf, bufsiz,
8329218822Sdim				 note_name, note_type, &data, sizeof (data));
8330218822Sdim    }
8331218822Sdim  else
8332218822Sdim#endif
8333218822Sdim    {
833489860Sobrien#if defined (HAVE_PSINFO_T)
8335218822Sdim      psinfo_t data;
8336218822Sdim      int note_type = NT_PSINFO;
833789860Sobrien#else
8338218822Sdim      prpsinfo_t data;
8339218822Sdim      int note_type = NT_PRPSINFO;
834089860Sobrien#endif
834189860Sobrien
8342218822Sdim      memset (&data, 0, sizeof (data));
8343218822Sdim      strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
8344218822Sdim      strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
8345218822Sdim      return elfcore_write_note (abfd, buf, bufsiz,
8346218822Sdim				 note_name, note_type, &data, sizeof (data));
8347218822Sdim    }
834889860Sobrien}
834989860Sobrien#endif	/* PSINFO_T or PRPSINFO_T */
835089860Sobrien
835189860Sobrien#if defined (HAVE_PRSTATUS_T)
835289860Sobrienchar *
8353130563Sobrienelfcore_write_prstatus (bfd *abfd,
8354130563Sobrien			char *buf,
8355130563Sobrien			int *bufsiz,
8356130563Sobrien			long pid,
8357130563Sobrien			int cursig,
8358130563Sobrien			const void *gregs)
835989860Sobrien{
8360218822Sdim  const char *note_name = "CORE";
8361218822Sdim  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
836289860Sobrien
8363218822Sdim  if (bed->elf_backend_write_core_note != NULL)
8364218822Sdim    {
8365218822Sdim      char *ret;
8366218822Sdim      ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
8367218822Sdim						 NT_PRSTATUS,
8368218822Sdim						 pid, cursig, gregs);
8369218822Sdim      if (ret != NULL)
8370218822Sdim	return ret;
8371218822Sdim    }
8372218822Sdim
8373218822Sdim#if defined (HAVE_PRSTATUS32_T)
8374218822Sdim  if (bed->s->elfclass == ELFCLASS32)
8375218822Sdim    {
8376218822Sdim      prstatus32_t prstat;
8377218822Sdim
8378218822Sdim      memset (&prstat, 0, sizeof (prstat));
8379218822Sdim      prstat.pr_pid = pid;
8380218822Sdim      prstat.pr_cursig = cursig;
8381218822Sdim      memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
8382218822Sdim      return elfcore_write_note (abfd, buf, bufsiz, note_name,
8383218822Sdim				 NT_PRSTATUS, &prstat, sizeof (prstat));
8384218822Sdim    }
8385218822Sdim  else
8386218822Sdim#endif
8387218822Sdim    {
8388218822Sdim      prstatus_t prstat;
8389218822Sdim
8390218822Sdim      memset (&prstat, 0, sizeof (prstat));
8391218822Sdim      prstat.pr_pid = pid;
8392218822Sdim      prstat.pr_cursig = cursig;
8393218822Sdim      memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
8394218822Sdim      return elfcore_write_note (abfd, buf, bufsiz, note_name,
8395218822Sdim				 NT_PRSTATUS, &prstat, sizeof (prstat));
8396218822Sdim    }
839789860Sobrien}
839889860Sobrien#endif /* HAVE_PRSTATUS_T */
839989860Sobrien
840094542Sobrien#if defined (HAVE_LWPSTATUS_T)
840194542Sobrienchar *
8402130563Sobrienelfcore_write_lwpstatus (bfd *abfd,
8403130563Sobrien			 char *buf,
8404130563Sobrien			 int *bufsiz,
8405130563Sobrien			 long pid,
8406130563Sobrien			 int cursig,
8407130563Sobrien			 const void *gregs)
840894542Sobrien{
840994542Sobrien  lwpstatus_t lwpstat;
8410218822Sdim  const char *note_name = "CORE";
841194542Sobrien
841294542Sobrien  memset (&lwpstat, 0, sizeof (lwpstat));
841394542Sobrien  lwpstat.pr_lwpid  = pid >> 16;
841494542Sobrien  lwpstat.pr_cursig = cursig;
841594542Sobrien#if defined (HAVE_LWPSTATUS_T_PR_REG)
841694542Sobrien  memcpy (lwpstat.pr_reg, gregs, sizeof (lwpstat.pr_reg));
841794542Sobrien#elif defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
841894542Sobrien#if !defined(gregs)
841994542Sobrien  memcpy (lwpstat.pr_context.uc_mcontext.gregs,
842094542Sobrien	  gregs, sizeof (lwpstat.pr_context.uc_mcontext.gregs));
842194542Sobrien#else
842294542Sobrien  memcpy (lwpstat.pr_context.uc_mcontext.__gregs,
842394542Sobrien	  gregs, sizeof (lwpstat.pr_context.uc_mcontext.__gregs));
842494542Sobrien#endif
842594542Sobrien#endif
8426104838Sobrien  return elfcore_write_note (abfd, buf, bufsiz, note_name,
842794542Sobrien			     NT_LWPSTATUS, &lwpstat, sizeof (lwpstat));
842894542Sobrien}
842994542Sobrien#endif /* HAVE_LWPSTATUS_T */
843094542Sobrien
843189860Sobrien#if defined (HAVE_PSTATUS_T)
843289860Sobrienchar *
8433130563Sobrienelfcore_write_pstatus (bfd *abfd,
8434130563Sobrien		       char *buf,
8435130563Sobrien		       int *bufsiz,
8436130563Sobrien		       long pid,
8437218822Sdim		       int cursig ATTRIBUTE_UNUSED,
8438218822Sdim		       const void *gregs ATTRIBUTE_UNUSED)
843989860Sobrien{
8440218822Sdim  const char *note_name = "CORE";
8441218822Sdim#if defined (HAVE_PSTATUS32_T)
8442218822Sdim  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
844389860Sobrien
8444218822Sdim  if (bed->s->elfclass == ELFCLASS32)
8445218822Sdim    {
8446218822Sdim      pstatus32_t pstat;
8447218822Sdim
8448218822Sdim      memset (&pstat, 0, sizeof (pstat));
8449218822Sdim      pstat.pr_pid = pid & 0xffff;
8450218822Sdim      buf = elfcore_write_note (abfd, buf, bufsiz, note_name,
8451218822Sdim				NT_PSTATUS, &pstat, sizeof (pstat));
8452218822Sdim      return buf;
8453218822Sdim    }
8454218822Sdim  else
8455218822Sdim#endif
8456218822Sdim    {
8457218822Sdim      pstatus_t pstat;
8458218822Sdim
8459218822Sdim      memset (&pstat, 0, sizeof (pstat));
8460218822Sdim      pstat.pr_pid = pid & 0xffff;
8461218822Sdim      buf = elfcore_write_note (abfd, buf, bufsiz, note_name,
8462218822Sdim				NT_PSTATUS, &pstat, sizeof (pstat));
8463218822Sdim      return buf;
8464218822Sdim    }
846589860Sobrien}
846689860Sobrien#endif /* HAVE_PSTATUS_T */
846789860Sobrien
846889860Sobrienchar *
8469130563Sobrienelfcore_write_prfpreg (bfd *abfd,
8470130563Sobrien		       char *buf,
8471130563Sobrien		       int *bufsiz,
8472130563Sobrien		       const void *fpregs,
8473130563Sobrien		       int size)
847489860Sobrien{
8475218822Sdim  const char *note_name = "CORE";
8476104838Sobrien  return elfcore_write_note (abfd, buf, bufsiz,
847789860Sobrien			     note_name, NT_FPREGSET, fpregs, size);
847889860Sobrien}
847989860Sobrien
848089860Sobrienchar *
8481215679Sattilioelfcore_write_thrmisc (bfd *abfd,
8482215679Sattilio		       char *buf,
8483215679Sattilio		       int *bufsiz,
8484215679Sattilio		       const char *tname,
8485215679Sattilio		       int size)
8486215679Sattilio{
8487215679Sattilio#if defined (HAVE_THRMISC_T)
8488215679Sattilio  char *note_name = "CORE";
8489215679Sattilio  return elfcore_write_note (abfd, buf, bufsiz,
8490215679Sattilio			     note_name, NT_THRMISC, tname, size);
8491215679Sattilio#else
8492215679Sattilio  return buf;
8493215679Sattilio#endif
8494215679Sattilio}
8495215679Sattilio
8496215679Sattiliochar *
8497130563Sobrienelfcore_write_prxfpreg (bfd *abfd,
8498130563Sobrien			char *buf,
8499130563Sobrien			int *bufsiz,
8500130563Sobrien			const void *xfpregs,
8501130563Sobrien			int size)
850289860Sobrien{
850389860Sobrien  char *note_name = "LINUX";
8504104838Sobrien  return elfcore_write_note (abfd, buf, bufsiz,
850589860Sobrien			     note_name, NT_PRXFPREG, xfpregs, size);
850689860Sobrien}
850789860Sobrien
8508130563Sobrienstatic bfd_boolean
8509130563Sobrienelfcore_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size)
851060508Sobrien{
851177301Sobrien  char *buf;
851277301Sobrien  char *p;
851360508Sobrien
851460508Sobrien  if (size <= 0)
8515130563Sobrien    return TRUE;
851660508Sobrien
851789860Sobrien  if (bfd_seek (abfd, offset, SEEK_SET) != 0)
8518130563Sobrien    return FALSE;
851960508Sobrien
852089860Sobrien  buf = bfd_malloc (size);
852160508Sobrien  if (buf == NULL)
8522130563Sobrien    return FALSE;
852360508Sobrien
852489860Sobrien  if (bfd_bread (buf, size, abfd) != size)
852560508Sobrien    {
852660508Sobrien    error:
852760508Sobrien      free (buf);
8528130563Sobrien      return FALSE;
852960508Sobrien    }
853060508Sobrien
853160508Sobrien  p = buf;
853260508Sobrien  while (p < buf + size)
853360508Sobrien    {
853477301Sobrien      /* FIXME: bad alignment assumption.  */
853577301Sobrien      Elf_External_Note *xnp = (Elf_External_Note *) p;
853660508Sobrien      Elf_Internal_Note in;
853760508Sobrien
853889860Sobrien      in.type = H_GET_32 (abfd, xnp->type);
853960508Sobrien
854089860Sobrien      in.namesz = H_GET_32 (abfd, xnp->namesz);
854160508Sobrien      in.namedata = xnp->name;
854260508Sobrien
854389860Sobrien      in.descsz = H_GET_32 (abfd, xnp->descsz);
854460508Sobrien      in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4);
854560508Sobrien      in.descpos = offset + (in.descdata - buf);
854660508Sobrien
8547218822Sdim      if (CONST_STRNEQ (in.namedata, "NetBSD-CORE"))
8548130563Sobrien	{
8549218822Sdim	  if (! elfcore_grok_netbsd_note (abfd, &in))
8550218822Sdim	    goto error;
8551218822Sdim	}
8552218822Sdim      else if (CONST_STRNEQ (in.namedata, "QNX"))
8553218822Sdim	{
8554130563Sobrien	  if (! elfcore_grok_nto_note (abfd, &in))
8555130563Sobrien	    goto error;
8556130563Sobrien	}
855789860Sobrien      else
8558218822Sdim	{
8559218822Sdim	  if (! elfcore_grok_note (abfd, &in))
8560218822Sdim	    goto error;
8561218822Sdim	}
856260508Sobrien
856360508Sobrien      p = in.descdata + BFD_ALIGN (in.descsz, 4);
856460508Sobrien    }
856560508Sobrien
856660508Sobrien  free (buf);
8567130563Sobrien  return TRUE;
856860508Sobrien}
856960508Sobrien
857060508Sobrien/* Providing external access to the ELF program header table.  */
857160508Sobrien
857260508Sobrien/* Return an upper bound on the number of bytes required to store a
857360508Sobrien   copy of ABFD's program header table entries.  Return -1 if an error
857460508Sobrien   occurs; bfd_get_error will return an appropriate code.  */
857577301Sobrien
857660508Sobrienlong
8577130563Sobrienbfd_get_elf_phdr_upper_bound (bfd *abfd)
857860508Sobrien{
857960508Sobrien  if (abfd->xvec->flavour != bfd_target_elf_flavour)
858060508Sobrien    {
858160508Sobrien      bfd_set_error (bfd_error_wrong_format);
858260508Sobrien      return -1;
858360508Sobrien    }
858460508Sobrien
858589860Sobrien  return elf_elfheader (abfd)->e_phnum * sizeof (Elf_Internal_Phdr);
858660508Sobrien}
858760508Sobrien
858860508Sobrien/* Copy ABFD's program header table entries to *PHDRS.  The entries
858960508Sobrien   will be stored as an array of Elf_Internal_Phdr structures, as
859060508Sobrien   defined in include/elf/internal.h.  To find out how large the
859160508Sobrien   buffer needs to be, call bfd_get_elf_phdr_upper_bound.
859260508Sobrien
859360508Sobrien   Return the number of program header table entries read, or -1 if an
859460508Sobrien   error occurs; bfd_get_error will return an appropriate code.  */
859577301Sobrien
859660508Sobrienint
8597130563Sobrienbfd_get_elf_phdrs (bfd *abfd, void *phdrs)
859860508Sobrien{
859960508Sobrien  int num_phdrs;
860060508Sobrien
860160508Sobrien  if (abfd->xvec->flavour != bfd_target_elf_flavour)
860260508Sobrien    {
860360508Sobrien      bfd_set_error (bfd_error_wrong_format);
860460508Sobrien      return -1;
860560508Sobrien    }
860660508Sobrien
860760508Sobrien  num_phdrs = elf_elfheader (abfd)->e_phnum;
860877301Sobrien  memcpy (phdrs, elf_tdata (abfd)->phdr,
860960508Sobrien	  num_phdrs * sizeof (Elf_Internal_Phdr));
861060508Sobrien
861160508Sobrien  return num_phdrs;
861260508Sobrien}
861389860Sobrien
861489860Sobrienvoid
8615130563Sobrien_bfd_elf_sprintf_vma (bfd *abfd ATTRIBUTE_UNUSED, char *buf, bfd_vma value)
861689860Sobrien{
861789860Sobrien#ifdef BFD64
861889860Sobrien  Elf_Internal_Ehdr *i_ehdrp;	/* Elf file header, internal form */
861989860Sobrien
862089860Sobrien  i_ehdrp = elf_elfheader (abfd);
862189860Sobrien  if (i_ehdrp == NULL)
862289860Sobrien    sprintf_vma (buf, value);
862389860Sobrien  else
862489860Sobrien    {
862589860Sobrien      if (i_ehdrp->e_ident[EI_CLASS] == ELFCLASS64)
862689860Sobrien	{
862789860Sobrien#if BFD_HOST_64BIT_LONG
862889860Sobrien	  sprintf (buf, "%016lx", value);
862989860Sobrien#else
863089860Sobrien	  sprintf (buf, "%08lx%08lx", _bfd_int64_high (value),
863189860Sobrien		   _bfd_int64_low (value));
863289860Sobrien#endif
863389860Sobrien	}
863489860Sobrien      else
863589860Sobrien	sprintf (buf, "%08lx", (unsigned long) (value & 0xffffffff));
863689860Sobrien    }
863789860Sobrien#else
863889860Sobrien  sprintf_vma (buf, value);
863989860Sobrien#endif
864089860Sobrien}
864189860Sobrien
864289860Sobrienvoid
8643130563Sobrien_bfd_elf_fprintf_vma (bfd *abfd ATTRIBUTE_UNUSED, void *stream, bfd_vma value)
864489860Sobrien{
864589860Sobrien#ifdef BFD64
864689860Sobrien  Elf_Internal_Ehdr *i_ehdrp;	/* Elf file header, internal form */
864789860Sobrien
864889860Sobrien  i_ehdrp = elf_elfheader (abfd);
864989860Sobrien  if (i_ehdrp == NULL)
865089860Sobrien    fprintf_vma ((FILE *) stream, value);
865189860Sobrien  else
865289860Sobrien    {
865389860Sobrien      if (i_ehdrp->e_ident[EI_CLASS] == ELFCLASS64)
865489860Sobrien	{
865589860Sobrien#if BFD_HOST_64BIT_LONG
865689860Sobrien	  fprintf ((FILE *) stream, "%016lx", value);
865789860Sobrien#else
865889860Sobrien	  fprintf ((FILE *) stream, "%08lx%08lx",
865989860Sobrien		   _bfd_int64_high (value), _bfd_int64_low (value));
866089860Sobrien#endif
866189860Sobrien	}
866289860Sobrien      else
866389860Sobrien	fprintf ((FILE *) stream, "%08lx",
866489860Sobrien		 (unsigned long) (value & 0xffffffff));
866589860Sobrien    }
866689860Sobrien#else
866789860Sobrien  fprintf_vma ((FILE *) stream, value);
866889860Sobrien#endif
866989860Sobrien}
867089860Sobrien
867189860Sobrienenum elf_reloc_type_class
8672130563Sobrien_bfd_elf_reloc_type_class (const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED)
867389860Sobrien{
867489860Sobrien  return reloc_class_normal;
867589860Sobrien}
867689860Sobrien
8677104838Sobrien/* For RELA architectures, return the relocation value for a
867889860Sobrien   relocation against a local symbol.  */
867989860Sobrien
868089860Sobrienbfd_vma
8681130563Sobrien_bfd_elf_rela_local_sym (bfd *abfd,
8682130563Sobrien			 Elf_Internal_Sym *sym,
8683130563Sobrien			 asection **psec,
8684130563Sobrien			 Elf_Internal_Rela *rel)
868589860Sobrien{
8686130563Sobrien  asection *sec = *psec;
868789860Sobrien  bfd_vma relocation;
868889860Sobrien
868989860Sobrien  relocation = (sec->output_section->vma
869089860Sobrien		+ sec->output_offset
869189860Sobrien		+ sym->st_value);
869289860Sobrien  if ((sec->flags & SEC_MERGE)
869389860Sobrien      && ELF_ST_TYPE (sym->st_info) == STT_SECTION
8694130563Sobrien      && sec->sec_info_type == ELF_INFO_TYPE_MERGE)
869589860Sobrien    {
869689860Sobrien      rel->r_addend =
8697130563Sobrien	_bfd_merged_section_offset (abfd, psec,
869889860Sobrien				    elf_section_data (sec)->sec_info,
8699218822Sdim				    sym->st_value + rel->r_addend);
8700218822Sdim      if (sec != *psec)
8701218822Sdim	{
8702218822Sdim	  /* If we have changed the section, and our original section is
8703218822Sdim	     marked with SEC_EXCLUDE, it means that the original
8704218822Sdim	     SEC_MERGE section has been completely subsumed in some
8705218822Sdim	     other SEC_MERGE section.  In this case, we need to leave
8706218822Sdim	     some info around for --emit-relocs.  */
8707218822Sdim	  if ((sec->flags & SEC_EXCLUDE) != 0)
8708218822Sdim	    sec->kept_section = *psec;
8709218822Sdim	  sec = *psec;
8710218822Sdim	}
8711130563Sobrien      rel->r_addend -= relocation;
8712130563Sobrien      rel->r_addend += sec->output_section->vma + sec->output_offset;
871389860Sobrien    }
871489860Sobrien  return relocation;
871589860Sobrien}
871689860Sobrien
871789860Sobrienbfd_vma
8718130563Sobrien_bfd_elf_rel_local_sym (bfd *abfd,
8719130563Sobrien			Elf_Internal_Sym *sym,
8720130563Sobrien			asection **psec,
8721130563Sobrien			bfd_vma addend)
8722104838Sobrien{
872389860Sobrien  asection *sec = *psec;
872489860Sobrien
8725130563Sobrien  if (sec->sec_info_type != ELF_INFO_TYPE_MERGE)
872689860Sobrien    return sym->st_value + addend;
872789860Sobrien
872889860Sobrien  return _bfd_merged_section_offset (abfd, psec,
872989860Sobrien				     elf_section_data (sec)->sec_info,
8730218822Sdim				     sym->st_value + addend);
873189860Sobrien}
873289860Sobrien
873389860Sobrienbfd_vma
8734130563Sobrien_bfd_elf_section_offset (bfd *abfd,
8735130563Sobrien			 struct bfd_link_info *info,
8736130563Sobrien			 asection *sec,
8737130563Sobrien			 bfd_vma offset)
873889860Sobrien{
8739130563Sobrien  switch (sec->sec_info_type)
874089860Sobrien    {
874189860Sobrien    case ELF_INFO_TYPE_STABS:
8742218822Sdim      return _bfd_stab_section_offset (sec, elf_section_data (sec)->sec_info,
8743218822Sdim				       offset);
874489860Sobrien    case ELF_INFO_TYPE_EH_FRAME:
8745218822Sdim      return _bfd_elf_eh_frame_section_offset (abfd, info, sec, offset);
874689860Sobrien    default:
874789860Sobrien      return offset;
874889860Sobrien    }
874989860Sobrien}
8750130563Sobrien
8751130563Sobrien/* Create a new BFD as if by bfd_openr.  Rather than opening a file,
8752130563Sobrien   reconstruct an ELF file by reading the segments out of remote memory
8753130563Sobrien   based on the ELF file header at EHDR_VMA and the ELF program headers it
8754130563Sobrien   points to.  If not null, *LOADBASEP is filled in with the difference
8755130563Sobrien   between the VMAs from which the segments were read, and the VMAs the
8756130563Sobrien   file headers (and hence BFD's idea of each section's VMA) put them at.
8757130563Sobrien
8758130563Sobrien   The function TARGET_READ_MEMORY is called to copy LEN bytes from the
8759130563Sobrien   remote memory at target address VMA into the local buffer at MYADDR; it
8760130563Sobrien   should return zero on success or an `errno' code on failure.  TEMPL must
8761130563Sobrien   be a BFD for an ELF target with the word size and byte order found in
8762130563Sobrien   the remote memory.  */
8763130563Sobrien
8764130563Sobrienbfd *
8765130563Sobrienbfd_elf_bfd_from_remote_memory
8766130563Sobrien  (bfd *templ,
8767130563Sobrien   bfd_vma ehdr_vma,
8768130563Sobrien   bfd_vma *loadbasep,
8769218822Sdim   int (*target_read_memory) (bfd_vma, bfd_byte *, int))
8770130563Sobrien{
8771130563Sobrien  return (*get_elf_backend_data (templ)->elf_backend_bfd_from_remote_memory)
8772130563Sobrien    (templ, ehdr_vma, loadbasep, target_read_memory);
8773130563Sobrien}
8774218822Sdim
8775218822Sdimlong
8776218822Sdim_bfd_elf_get_synthetic_symtab (bfd *abfd,
8777218822Sdim			       long symcount ATTRIBUTE_UNUSED,
8778218822Sdim			       asymbol **syms ATTRIBUTE_UNUSED,
8779218822Sdim			       long dynsymcount,
8780218822Sdim			       asymbol **dynsyms,
8781218822Sdim			       asymbol **ret)
8782218822Sdim{
8783218822Sdim  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
8784218822Sdim  asection *relplt;
8785218822Sdim  asymbol *s;
8786218822Sdim  const char *relplt_name;
8787218822Sdim  bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
8788218822Sdim  arelent *p;
8789218822Sdim  long count, i, n;
8790218822Sdim  size_t size;
8791218822Sdim  Elf_Internal_Shdr *hdr;
8792218822Sdim  char *names;
8793218822Sdim  asection *plt;
8794218822Sdim
8795218822Sdim  *ret = NULL;
8796218822Sdim
8797218822Sdim  if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0)
8798218822Sdim    return 0;
8799218822Sdim
8800218822Sdim  if (dynsymcount <= 0)
8801218822Sdim    return 0;
8802218822Sdim
8803218822Sdim  if (!bed->plt_sym_val)
8804218822Sdim    return 0;
8805218822Sdim
8806218822Sdim  relplt_name = bed->relplt_name;
8807218822Sdim  if (relplt_name == NULL)
8808218822Sdim    relplt_name = bed->default_use_rela_p ? ".rela.plt" : ".rel.plt";
8809218822Sdim  relplt = bfd_get_section_by_name (abfd, relplt_name);
8810218822Sdim  if (relplt == NULL)
8811218822Sdim    return 0;
8812218822Sdim
8813218822Sdim  hdr = &elf_section_data (relplt)->this_hdr;
8814218822Sdim  if (hdr->sh_link != elf_dynsymtab (abfd)
8815218822Sdim      || (hdr->sh_type != SHT_REL && hdr->sh_type != SHT_RELA))
8816218822Sdim    return 0;
8817218822Sdim
8818218822Sdim  plt = bfd_get_section_by_name (abfd, ".plt");
8819218822Sdim  if (plt == NULL)
8820218822Sdim    return 0;
8821218822Sdim
8822218822Sdim  slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
8823218822Sdim  if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE))
8824218822Sdim    return -1;
8825218822Sdim
8826218822Sdim  count = relplt->size / hdr->sh_entsize;
8827218822Sdim  size = count * sizeof (asymbol);
8828218822Sdim  p = relplt->relocation;
8829218822Sdim  for (i = 0; i < count; i++, s++, p++)
8830218822Sdim    size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
8831218822Sdim
8832218822Sdim  s = *ret = bfd_malloc (size);
8833218822Sdim  if (s == NULL)
8834218822Sdim    return -1;
8835218822Sdim
8836218822Sdim  names = (char *) (s + count);
8837218822Sdim  p = relplt->relocation;
8838218822Sdim  n = 0;
8839218822Sdim  for (i = 0; i < count; i++, s++, p++)
8840218822Sdim    {
8841218822Sdim      size_t len;
8842218822Sdim      bfd_vma addr;
8843218822Sdim
8844218822Sdim      addr = bed->plt_sym_val (i, plt, p);
8845218822Sdim      if (addr == (bfd_vma) -1)
8846218822Sdim	continue;
8847218822Sdim
8848218822Sdim      *s = **p->sym_ptr_ptr;
8849218822Sdim      /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set.  Since
8850218822Sdim	 we are defining a symbol, ensure one of them is set.  */
8851218822Sdim      if ((s->flags & BSF_LOCAL) == 0)
8852218822Sdim	s->flags |= BSF_GLOBAL;
8853218822Sdim      s->section = plt;
8854218822Sdim      s->value = addr - plt->vma;
8855218822Sdim      s->name = names;
8856218822Sdim      len = strlen ((*p->sym_ptr_ptr)->name);
8857218822Sdim      memcpy (names, (*p->sym_ptr_ptr)->name, len);
8858218822Sdim      names += len;
8859218822Sdim      memcpy (names, "@plt", sizeof ("@plt"));
8860218822Sdim      names += sizeof ("@plt");
8861218822Sdim      ++n;
8862218822Sdim    }
8863218822Sdim
8864218822Sdim  return n;
8865218822Sdim}
8866218822Sdim
8867218822Sdimstruct elf_symbuf_symbol
8868218822Sdim{
8869218822Sdim  unsigned long st_name;	/* Symbol name, index in string tbl */
8870218822Sdim  unsigned char st_info;	/* Type and binding attributes */
8871218822Sdim  unsigned char st_other;	/* Visibilty, and target specific */
8872218822Sdim};
8873218822Sdim
8874218822Sdimstruct elf_symbuf_head
8875218822Sdim{
8876218822Sdim  struct elf_symbuf_symbol *ssym;
8877218822Sdim  bfd_size_type count;
8878218822Sdim  unsigned int st_shndx;
8879218822Sdim};
8880218822Sdim
8881218822Sdimstruct elf_symbol
8882218822Sdim{
8883218822Sdim  union
8884218822Sdim    {
8885218822Sdim      Elf_Internal_Sym *isym;
8886218822Sdim      struct elf_symbuf_symbol *ssym;
8887218822Sdim    } u;
8888218822Sdim  const char *name;
8889218822Sdim};
8890218822Sdim
8891218822Sdim/* Sort references to symbols by ascending section number.  */
8892218822Sdim
8893218822Sdimstatic int
8894218822Sdimelf_sort_elf_symbol (const void *arg1, const void *arg2)
8895218822Sdim{
8896218822Sdim  const Elf_Internal_Sym *s1 = *(const Elf_Internal_Sym **) arg1;
8897218822Sdim  const Elf_Internal_Sym *s2 = *(const Elf_Internal_Sym **) arg2;
8898218822Sdim
8899218822Sdim  return s1->st_shndx - s2->st_shndx;
8900218822Sdim}
8901218822Sdim
8902218822Sdimstatic int
8903218822Sdimelf_sym_name_compare (const void *arg1, const void *arg2)
8904218822Sdim{
8905218822Sdim  const struct elf_symbol *s1 = (const struct elf_symbol *) arg1;
8906218822Sdim  const struct elf_symbol *s2 = (const struct elf_symbol *) arg2;
8907218822Sdim  return strcmp (s1->name, s2->name);
8908218822Sdim}
8909218822Sdim
8910218822Sdimstatic struct elf_symbuf_head *
8911218822Sdimelf_create_symbuf (bfd_size_type symcount, Elf_Internal_Sym *isymbuf)
8912218822Sdim{
8913218822Sdim  Elf_Internal_Sym **ind, **indbufend, **indbuf
8914218822Sdim    = bfd_malloc2 (symcount, sizeof (*indbuf));
8915218822Sdim  struct elf_symbuf_symbol *ssym;
8916218822Sdim  struct elf_symbuf_head *ssymbuf, *ssymhead;
8917218822Sdim  bfd_size_type i, shndx_count;
8918218822Sdim
8919218822Sdim  if (indbuf == NULL)
8920218822Sdim    return NULL;
8921218822Sdim
8922218822Sdim  for (ind = indbuf, i = 0; i < symcount; i++)
8923218822Sdim    if (isymbuf[i].st_shndx != SHN_UNDEF)
8924218822Sdim      *ind++ = &isymbuf[i];
8925218822Sdim  indbufend = ind;
8926218822Sdim
8927218822Sdim  qsort (indbuf, indbufend - indbuf, sizeof (Elf_Internal_Sym *),
8928218822Sdim	 elf_sort_elf_symbol);
8929218822Sdim
8930218822Sdim  shndx_count = 0;
8931218822Sdim  if (indbufend > indbuf)
8932218822Sdim    for (ind = indbuf, shndx_count++; ind < indbufend - 1; ind++)
8933218822Sdim      if (ind[0]->st_shndx != ind[1]->st_shndx)
8934218822Sdim	shndx_count++;
8935218822Sdim
8936218822Sdim  ssymbuf = bfd_malloc ((shndx_count + 1) * sizeof (*ssymbuf)
8937296437Sdim			+ (indbufend - indbuf) * sizeof (*ssym));
8938218822Sdim  if (ssymbuf == NULL)
8939218822Sdim    {
8940218822Sdim      free (indbuf);
8941218822Sdim      return NULL;
8942218822Sdim    }
8943218822Sdim
8944296437Sdim  ssym = (struct elf_symbuf_symbol *) (ssymbuf + shndx_count + 1);
8945218822Sdim  ssymbuf->ssym = NULL;
8946218822Sdim  ssymbuf->count = shndx_count;
8947218822Sdim  ssymbuf->st_shndx = 0;
8948218822Sdim  for (ssymhead = ssymbuf, ind = indbuf; ind < indbufend; ssym++, ind++)
8949218822Sdim    {
8950218822Sdim      if (ind == indbuf || ssymhead->st_shndx != (*ind)->st_shndx)
8951218822Sdim	{
8952218822Sdim	  ssymhead++;
8953218822Sdim	  ssymhead->ssym = ssym;
8954218822Sdim	  ssymhead->count = 0;
8955218822Sdim	  ssymhead->st_shndx = (*ind)->st_shndx;
8956218822Sdim	}
8957218822Sdim      ssym->st_name = (*ind)->st_name;
8958218822Sdim      ssym->st_info = (*ind)->st_info;
8959218822Sdim      ssym->st_other = (*ind)->st_other;
8960218822Sdim      ssymhead->count++;
8961218822Sdim    }
8962218822Sdim  BFD_ASSERT ((bfd_size_type) (ssymhead - ssymbuf) == shndx_count);
8963218822Sdim
8964218822Sdim  free (indbuf);
8965218822Sdim  return ssymbuf;
8966218822Sdim}
8967218822Sdim
8968218822Sdim/* Check if 2 sections define the same set of local and global
8969218822Sdim   symbols.  */
8970218822Sdim
8971218822Sdimbfd_boolean
8972218822Sdimbfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2,
8973218822Sdim				   struct bfd_link_info *info)
8974218822Sdim{
8975218822Sdim  bfd *bfd1, *bfd2;
8976218822Sdim  const struct elf_backend_data *bed1, *bed2;
8977218822Sdim  Elf_Internal_Shdr *hdr1, *hdr2;
8978218822Sdim  bfd_size_type symcount1, symcount2;
8979218822Sdim  Elf_Internal_Sym *isymbuf1, *isymbuf2;
8980218822Sdim  struct elf_symbuf_head *ssymbuf1, *ssymbuf2;
8981218822Sdim  Elf_Internal_Sym *isym, *isymend;
8982218822Sdim  struct elf_symbol *symtable1 = NULL, *symtable2 = NULL;
8983218822Sdim  bfd_size_type count1, count2, i;
8984218822Sdim  int shndx1, shndx2;
8985218822Sdim  bfd_boolean result;
8986218822Sdim
8987218822Sdim  bfd1 = sec1->owner;
8988218822Sdim  bfd2 = sec2->owner;
8989218822Sdim
8990218822Sdim  /* If both are .gnu.linkonce sections, they have to have the same
8991218822Sdim     section name.  */
8992218822Sdim  if (CONST_STRNEQ (sec1->name, ".gnu.linkonce")
8993218822Sdim      && CONST_STRNEQ (sec2->name, ".gnu.linkonce"))
8994218822Sdim    return strcmp (sec1->name + sizeof ".gnu.linkonce",
8995218822Sdim		   sec2->name + sizeof ".gnu.linkonce") == 0;
8996218822Sdim
8997218822Sdim  /* Both sections have to be in ELF.  */
8998218822Sdim  if (bfd_get_flavour (bfd1) != bfd_target_elf_flavour
8999218822Sdim      || bfd_get_flavour (bfd2) != bfd_target_elf_flavour)
9000218822Sdim    return FALSE;
9001218822Sdim
9002218822Sdim  if (elf_section_type (sec1) != elf_section_type (sec2))
9003218822Sdim    return FALSE;
9004218822Sdim
9005218822Sdim  if ((elf_section_flags (sec1) & SHF_GROUP) != 0
9006218822Sdim      && (elf_section_flags (sec2) & SHF_GROUP) != 0)
9007218822Sdim    {
9008218822Sdim      /* If both are members of section groups, they have to have the
9009218822Sdim	 same group name.  */
9010218822Sdim      if (strcmp (elf_group_name (sec1), elf_group_name (sec2)) != 0)
9011218822Sdim	return FALSE;
9012218822Sdim    }
9013218822Sdim
9014218822Sdim  shndx1 = _bfd_elf_section_from_bfd_section (bfd1, sec1);
9015218822Sdim  shndx2 = _bfd_elf_section_from_bfd_section (bfd2, sec2);
9016218822Sdim  if (shndx1 == -1 || shndx2 == -1)
9017218822Sdim    return FALSE;
9018218822Sdim
9019218822Sdim  bed1 = get_elf_backend_data (bfd1);
9020218822Sdim  bed2 = get_elf_backend_data (bfd2);
9021218822Sdim  hdr1 = &elf_tdata (bfd1)->symtab_hdr;
9022218822Sdim  symcount1 = hdr1->sh_size / bed1->s->sizeof_sym;
9023218822Sdim  hdr2 = &elf_tdata (bfd2)->symtab_hdr;
9024218822Sdim  symcount2 = hdr2->sh_size / bed2->s->sizeof_sym;
9025218822Sdim
9026218822Sdim  if (symcount1 == 0 || symcount2 == 0)
9027218822Sdim    return FALSE;
9028218822Sdim
9029218822Sdim  result = FALSE;
9030218822Sdim  isymbuf1 = NULL;
9031218822Sdim  isymbuf2 = NULL;
9032218822Sdim  ssymbuf1 = elf_tdata (bfd1)->symbuf;
9033218822Sdim  ssymbuf2 = elf_tdata (bfd2)->symbuf;
9034218822Sdim
9035218822Sdim  if (ssymbuf1 == NULL)
9036218822Sdim    {
9037218822Sdim      isymbuf1 = bfd_elf_get_elf_syms (bfd1, hdr1, symcount1, 0,
9038218822Sdim				       NULL, NULL, NULL);
9039218822Sdim      if (isymbuf1 == NULL)
9040218822Sdim	goto done;
9041218822Sdim
9042218822Sdim      if (!info->reduce_memory_overheads)
9043218822Sdim	elf_tdata (bfd1)->symbuf = ssymbuf1
9044218822Sdim	  = elf_create_symbuf (symcount1, isymbuf1);
9045218822Sdim    }
9046218822Sdim
9047218822Sdim  if (ssymbuf1 == NULL || ssymbuf2 == NULL)
9048218822Sdim    {
9049218822Sdim      isymbuf2 = bfd_elf_get_elf_syms (bfd2, hdr2, symcount2, 0,
9050218822Sdim				       NULL, NULL, NULL);
9051218822Sdim      if (isymbuf2 == NULL)
9052218822Sdim	goto done;
9053218822Sdim
9054218822Sdim      if (ssymbuf1 != NULL && !info->reduce_memory_overheads)
9055218822Sdim	elf_tdata (bfd2)->symbuf = ssymbuf2
9056218822Sdim	  = elf_create_symbuf (symcount2, isymbuf2);
9057218822Sdim    }
9058218822Sdim
9059218822Sdim  if (ssymbuf1 != NULL && ssymbuf2 != NULL)
9060218822Sdim    {
9061218822Sdim      /* Optimized faster version.  */
9062218822Sdim      bfd_size_type lo, hi, mid;
9063218822Sdim      struct elf_symbol *symp;
9064218822Sdim      struct elf_symbuf_symbol *ssym, *ssymend;
9065218822Sdim
9066218822Sdim      lo = 0;
9067218822Sdim      hi = ssymbuf1->count;
9068218822Sdim      ssymbuf1++;
9069218822Sdim      count1 = 0;
9070218822Sdim      while (lo < hi)
9071218822Sdim	{
9072218822Sdim	  mid = (lo + hi) / 2;
9073218822Sdim	  if ((unsigned int) shndx1 < ssymbuf1[mid].st_shndx)
9074218822Sdim	    hi = mid;
9075218822Sdim	  else if ((unsigned int) shndx1 > ssymbuf1[mid].st_shndx)
9076218822Sdim	    lo = mid + 1;
9077218822Sdim	  else
9078218822Sdim	    {
9079218822Sdim	      count1 = ssymbuf1[mid].count;
9080218822Sdim	      ssymbuf1 += mid;
9081218822Sdim	      break;
9082218822Sdim	    }
9083218822Sdim	}
9084218822Sdim
9085218822Sdim      lo = 0;
9086218822Sdim      hi = ssymbuf2->count;
9087218822Sdim      ssymbuf2++;
9088218822Sdim      count2 = 0;
9089218822Sdim      while (lo < hi)
9090218822Sdim	{
9091218822Sdim	  mid = (lo + hi) / 2;
9092218822Sdim	  if ((unsigned int) shndx2 < ssymbuf2[mid].st_shndx)
9093218822Sdim	    hi = mid;
9094218822Sdim	  else if ((unsigned int) shndx2 > ssymbuf2[mid].st_shndx)
9095218822Sdim	    lo = mid + 1;
9096218822Sdim	  else
9097218822Sdim	    {
9098218822Sdim	      count2 = ssymbuf2[mid].count;
9099218822Sdim	      ssymbuf2 += mid;
9100218822Sdim	      break;
9101218822Sdim	    }
9102218822Sdim	}
9103218822Sdim
9104218822Sdim      if (count1 == 0 || count2 == 0 || count1 != count2)
9105218822Sdim	goto done;
9106218822Sdim
9107218822Sdim      symtable1 = bfd_malloc (count1 * sizeof (struct elf_symbol));
9108218822Sdim      symtable2 = bfd_malloc (count2 * sizeof (struct elf_symbol));
9109218822Sdim      if (symtable1 == NULL || symtable2 == NULL)
9110218822Sdim	goto done;
9111218822Sdim
9112218822Sdim      symp = symtable1;
9113218822Sdim      for (ssym = ssymbuf1->ssym, ssymend = ssym + count1;
9114218822Sdim	   ssym < ssymend; ssym++, symp++)
9115218822Sdim	{
9116218822Sdim	  symp->u.ssym = ssym;
9117218822Sdim	  symp->name = bfd_elf_string_from_elf_section (bfd1,
9118218822Sdim							hdr1->sh_link,
9119218822Sdim							ssym->st_name);
9120218822Sdim	}
9121218822Sdim
9122218822Sdim      symp = symtable2;
9123218822Sdim      for (ssym = ssymbuf2->ssym, ssymend = ssym + count2;
9124218822Sdim	   ssym < ssymend; ssym++, symp++)
9125218822Sdim	{
9126218822Sdim	  symp->u.ssym = ssym;
9127218822Sdim	  symp->name = bfd_elf_string_from_elf_section (bfd2,
9128218822Sdim							hdr2->sh_link,
9129218822Sdim							ssym->st_name);
9130218822Sdim	}
9131218822Sdim
9132218822Sdim      /* Sort symbol by name.  */
9133218822Sdim      qsort (symtable1, count1, sizeof (struct elf_symbol),
9134218822Sdim	     elf_sym_name_compare);
9135218822Sdim      qsort (symtable2, count1, sizeof (struct elf_symbol),
9136218822Sdim	     elf_sym_name_compare);
9137218822Sdim
9138218822Sdim      for (i = 0; i < count1; i++)
9139218822Sdim	/* Two symbols must have the same binding, type and name.  */
9140218822Sdim	if (symtable1 [i].u.ssym->st_info != symtable2 [i].u.ssym->st_info
9141218822Sdim	    || symtable1 [i].u.ssym->st_other != symtable2 [i].u.ssym->st_other
9142218822Sdim	    || strcmp (symtable1 [i].name, symtable2 [i].name) != 0)
9143218822Sdim	  goto done;
9144218822Sdim
9145218822Sdim      result = TRUE;
9146218822Sdim      goto done;
9147218822Sdim    }
9148218822Sdim
9149218822Sdim  symtable1 = bfd_malloc (symcount1 * sizeof (struct elf_symbol));
9150218822Sdim  symtable2 = bfd_malloc (symcount2 * sizeof (struct elf_symbol));
9151218822Sdim  if (symtable1 == NULL || symtable2 == NULL)
9152218822Sdim    goto done;
9153218822Sdim
9154218822Sdim  /* Count definitions in the section.  */
9155218822Sdim  count1 = 0;
9156218822Sdim  for (isym = isymbuf1, isymend = isym + symcount1; isym < isymend; isym++)
9157218822Sdim    if (isym->st_shndx == (unsigned int) shndx1)
9158218822Sdim      symtable1[count1++].u.isym = isym;
9159218822Sdim
9160218822Sdim  count2 = 0;
9161218822Sdim  for (isym = isymbuf2, isymend = isym + symcount2; isym < isymend; isym++)
9162218822Sdim    if (isym->st_shndx == (unsigned int) shndx2)
9163218822Sdim      symtable2[count2++].u.isym = isym;
9164218822Sdim
9165218822Sdim  if (count1 == 0 || count2 == 0 || count1 != count2)
9166218822Sdim    goto done;
9167218822Sdim
9168218822Sdim  for (i = 0; i < count1; i++)
9169218822Sdim    symtable1[i].name
9170218822Sdim      = bfd_elf_string_from_elf_section (bfd1, hdr1->sh_link,
9171218822Sdim					 symtable1[i].u.isym->st_name);
9172218822Sdim
9173218822Sdim  for (i = 0; i < count2; i++)
9174218822Sdim    symtable2[i].name
9175218822Sdim      = bfd_elf_string_from_elf_section (bfd2, hdr2->sh_link,
9176218822Sdim					 symtable2[i].u.isym->st_name);
9177218822Sdim
9178218822Sdim  /* Sort symbol by name.  */
9179218822Sdim  qsort (symtable1, count1, sizeof (struct elf_symbol),
9180218822Sdim	 elf_sym_name_compare);
9181218822Sdim  qsort (symtable2, count1, sizeof (struct elf_symbol),
9182218822Sdim	 elf_sym_name_compare);
9183218822Sdim
9184218822Sdim  for (i = 0; i < count1; i++)
9185218822Sdim    /* Two symbols must have the same binding, type and name.  */
9186218822Sdim    if (symtable1 [i].u.isym->st_info != symtable2 [i].u.isym->st_info
9187218822Sdim	|| symtable1 [i].u.isym->st_other != symtable2 [i].u.isym->st_other
9188218822Sdim	|| strcmp (symtable1 [i].name, symtable2 [i].name) != 0)
9189218822Sdim      goto done;
9190218822Sdim
9191218822Sdim  result = TRUE;
9192218822Sdim
9193218822Sdimdone:
9194218822Sdim  if (symtable1)
9195218822Sdim    free (symtable1);
9196218822Sdim  if (symtable2)
9197218822Sdim    free (symtable2);
9198218822Sdim  if (isymbuf1)
9199218822Sdim    free (isymbuf1);
9200218822Sdim  if (isymbuf2)
9201218822Sdim    free (isymbuf2);
9202218822Sdim
9203218822Sdim  return result;
9204218822Sdim}
9205218822Sdim
9206218822Sdim/* It is only used by x86-64 so far.  */
9207218822Sdimasection _bfd_elf_large_com_section
9208218822Sdim  = BFD_FAKE_SECTION (_bfd_elf_large_com_section,
9209218822Sdim		      SEC_IS_COMMON, NULL, "LARGE_COMMON", 0);
9210218822Sdim
9211218822Sdim/* Return TRUE if 2 section types are compatible.  */
9212218822Sdim
9213218822Sdimbfd_boolean
9214218822Sdim_bfd_elf_match_sections_by_type (bfd *abfd, const asection *asec,
9215218822Sdim				 bfd *bbfd, const asection *bsec)
9216218822Sdim{
9217218822Sdim  if (asec == NULL
9218218822Sdim      || bsec == NULL
9219218822Sdim      || abfd->xvec->flavour != bfd_target_elf_flavour
9220218822Sdim      || bbfd->xvec->flavour != bfd_target_elf_flavour)
9221218822Sdim    return TRUE;
9222218822Sdim
9223218822Sdim  return elf_section_type (asec) == elf_section_type (bsec);
9224218822Sdim}
9225218822Sdim
9226218822Sdimvoid
9227218822Sdim_bfd_elf_set_osabi (bfd * abfd,
9228218822Sdim		    struct bfd_link_info * link_info ATTRIBUTE_UNUSED)
9229218822Sdim{
9230218822Sdim  Elf_Internal_Ehdr * i_ehdrp;	/* ELF file header, internal form.  */
9231218822Sdim
9232218822Sdim  i_ehdrp = elf_elfheader (abfd);
9233218822Sdim
9234218822Sdim  i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
9235218822Sdim}
9236218822Sdim
9237218822Sdim
9238218822Sdim/* Return TRUE for ELF symbol types that represent functions.
9239218822Sdim   This is the default version of this function, which is sufficient for
9240218822Sdim   most targets.  It returns true if TYPE is STT_FUNC.  */
9241218822Sdim
9242218822Sdimbfd_boolean
9243218822Sdim_bfd_elf_is_function_type (unsigned int type)
9244218822Sdim{
9245218822Sdim  return (type == STT_FUNC);
9246218822Sdim}
9247