OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [bfd/] [elf.c] - Diff between revs 157 and 225

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 157 Rev 225
Line 1... Line 1...
/* ELF executable support for BFD.
/* ELF executable support for BFD.
 
 
   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
   2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
   2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
 
   Free Software Foundation, Inc.
 
 
   This file is part of BFD, the Binary File Descriptor library.
   This file is part of BFD, the Binary File Descriptor library.
 
 
   This program is free software; you can redistribute it and/or modify
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   it under the terms of the GNU General Public License as published by
Line 256... Line 257...
{
{
  /* I think this can be done just like an object file.  */
  /* I think this can be done just like an object file.  */
  return bfd_elf_make_generic_object (abfd);
  return bfd_elf_make_generic_object (abfd);
}
}
 
 
char *
static char *
bfd_elf_get_str_section (bfd *abfd, unsigned int shindex)
bfd_elf_get_str_section (bfd *abfd, unsigned int shindex)
{
{
  Elf_Internal_Shdr **i_shdrp;
  Elf_Internal_Shdr **i_shdrp;
  bfd_byte *shstrtab = NULL;
  bfd_byte *shstrtab = NULL;
  file_ptr offset;
  file_ptr offset;
Line 279... Line 280...
      offset = i_shdrp[shindex]->sh_offset;
      offset = i_shdrp[shindex]->sh_offset;
      shstrtabsize = i_shdrp[shindex]->sh_size;
      shstrtabsize = i_shdrp[shindex]->sh_size;
 
 
      /* Allocate and clear an extra byte at the end, to prevent crashes
      /* Allocate and clear an extra byte at the end, to prevent crashes
         in case the string table is not terminated.  */
         in case the string table is not terminated.  */
      if (shstrtabsize + 1 == 0
      if (shstrtabsize + 1 <= 1
          || (shstrtab = bfd_alloc (abfd, shstrtabsize + 1)) == NULL
          || (shstrtab = (bfd_byte *) bfd_alloc (abfd, shstrtabsize + 1)) == NULL
          || bfd_seek (abfd, offset, SEEK_SET) != 0)
          || bfd_seek (abfd, offset, SEEK_SET) != 0)
        shstrtab = NULL;
        shstrtab = NULL;
      else if (bfd_bread (shstrtab, shstrtabsize, abfd) != shstrtabsize)
      else if (bfd_bread (shstrtab, shstrtabsize, abfd) != shstrtabsize)
        {
        {
          if (bfd_get_error () != bfd_error_system_call)
          if (bfd_get_error () != bfd_error_system_call)
            bfd_set_error (bfd_error_file_truncated);
            bfd_set_error (bfd_error_file_truncated);
          shstrtab = NULL;
          shstrtab = NULL;
 
          /* Once we've failed to read it, make sure we don't keep
 
             trying.  Otherwise, we'll keep allocating space for
 
             the string table over and over.  */
 
          i_shdrp[shindex]->sh_size = 0;
        }
        }
      else
      else
        shstrtab[shstrtabsize] = '\0';
        shstrtab[shstrtabsize] = '\0';
      i_shdrp[shindex]->contents = shstrtab;
      i_shdrp[shindex]->contents = shstrtab;
    }
    }
Line 324... Line 329...
        (_("%B: invalid string offset %u >= %lu for section `%s'"),
        (_("%B: invalid string offset %u >= %lu for section `%s'"),
         abfd, strindex, (unsigned long) hdr->sh_size,
         abfd, strindex, (unsigned long) hdr->sh_size,
         (shindex == shstrndx && strindex == hdr->sh_name
         (shindex == shstrndx && strindex == hdr->sh_name
          ? ".shstrtab"
          ? ".shstrtab"
          : bfd_elf_string_from_elf_section (abfd, shstrndx, hdr->sh_name)));
          : bfd_elf_string_from_elf_section (abfd, shstrndx, hdr->sh_name)));
      return "";
      return NULL;
    }
    }
 
 
  return ((char *) hdr->contents) + strindex;
  return ((char *) hdr->contents) + strindex;
}
}
 
 
Line 352... Line 357...
  Elf_Internal_Shdr *shndx_hdr;
  Elf_Internal_Shdr *shndx_hdr;
  void *alloc_ext;
  void *alloc_ext;
  const bfd_byte *esym;
  const bfd_byte *esym;
  Elf_External_Sym_Shndx *alloc_extshndx;
  Elf_External_Sym_Shndx *alloc_extshndx;
  Elf_External_Sym_Shndx *shndx;
  Elf_External_Sym_Shndx *shndx;
 
  Elf_Internal_Sym *alloc_intsym;
  Elf_Internal_Sym *isym;
  Elf_Internal_Sym *isym;
  Elf_Internal_Sym *isymend;
  Elf_Internal_Sym *isymend;
  const struct elf_backend_data *bed;
  const struct elf_backend_data *bed;
  size_t extsym_size;
  size_t extsym_size;
  bfd_size_type amt;
  bfd_size_type amt;
Line 373... Line 379...
    shndx_hdr = &elf_tdata (ibfd)->symtab_shndx_hdr;
    shndx_hdr = &elf_tdata (ibfd)->symtab_shndx_hdr;
 
 
  /* Read the symbols.  */
  /* Read the symbols.  */
  alloc_ext = NULL;
  alloc_ext = NULL;
  alloc_extshndx = NULL;
  alloc_extshndx = NULL;
 
  alloc_intsym = NULL;
  bed = get_elf_backend_data (ibfd);
  bed = get_elf_backend_data (ibfd);
  extsym_size = bed->s->sizeof_sym;
  extsym_size = bed->s->sizeof_sym;
  amt = symcount * extsym_size;
  amt = symcount * extsym_size;
  pos = symtab_hdr->sh_offset + symoffset * extsym_size;
  pos = symtab_hdr->sh_offset + symoffset * extsym_size;
  if (extsym_buf == NULL)
  if (extsym_buf == NULL)
Line 398... Line 405...
    {
    {
      amt = symcount * sizeof (Elf_External_Sym_Shndx);
      amt = symcount * sizeof (Elf_External_Sym_Shndx);
      pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx);
      pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx);
      if (extshndx_buf == NULL)
      if (extshndx_buf == NULL)
        {
        {
          alloc_extshndx = bfd_malloc2 (symcount,
          alloc_extshndx = (Elf_External_Sym_Shndx *)
                                        sizeof (Elf_External_Sym_Shndx));
              bfd_malloc2 (symcount, sizeof (Elf_External_Sym_Shndx));
          extshndx_buf = alloc_extshndx;
          extshndx_buf = alloc_extshndx;
        }
        }
      if (extshndx_buf == NULL
      if (extshndx_buf == NULL
          || bfd_seek (ibfd, pos, SEEK_SET) != 0
          || bfd_seek (ibfd, pos, SEEK_SET) != 0
          || bfd_bread (extshndx_buf, amt, ibfd) != amt)
          || bfd_bread (extshndx_buf, amt, ibfd) != amt)
Line 413... Line 420...
        }
        }
    }
    }
 
 
  if (intsym_buf == NULL)
  if (intsym_buf == NULL)
    {
    {
      intsym_buf = bfd_malloc2 (symcount, sizeof (Elf_Internal_Sym));
      alloc_intsym = (Elf_Internal_Sym *)
 
          bfd_malloc2 (symcount, sizeof (Elf_Internal_Sym));
 
      intsym_buf = alloc_intsym;
      if (intsym_buf == NULL)
      if (intsym_buf == NULL)
        goto out;
        goto out;
    }
    }
 
 
  /* Convert the symbols to internal form.  */
  /* Convert the symbols to internal form.  */
  isymend = intsym_buf + symcount;
  isymend = intsym_buf + symcount;
  for (esym = extsym_buf, isym = intsym_buf, shndx = extshndx_buf;
  for (esym = (const bfd_byte *) extsym_buf, isym = intsym_buf,
 
           shndx = extshndx_buf;
       isym < isymend;
       isym < isymend;
       esym += extsym_size, isym++, shndx = shndx != NULL ? shndx + 1 : NULL)
       esym += extsym_size, isym++, shndx = shndx != NULL ? shndx + 1 : NULL)
    if (!(*bed->s->swap_symbol_in) (ibfd, esym, shndx, isym))
    if (!(*bed->s->swap_symbol_in) (ibfd, esym, shndx, isym))
      {
      {
        symoffset += (esym - (bfd_byte *) extsym_buf) / extsym_size;
        symoffset += (esym - (bfd_byte *) extsym_buf) / extsym_size;
        (*_bfd_error_handler) (_("%B symbol number %lu references "
        (*_bfd_error_handler) (_("%B symbol number %lu references "
                                 "nonexistent SHT_SYMTAB_SHNDX section"),
                                 "nonexistent SHT_SYMTAB_SHNDX section"),
                               ibfd, (unsigned long) symoffset);
                               ibfd, (unsigned long) symoffset);
 
        if (alloc_intsym != NULL)
 
          free (alloc_intsym);
        intsym_buf = NULL;
        intsym_buf = NULL;
        goto out;
        goto out;
      }
      }
 
 
 out:
 out:
Line 455... Line 467...
  unsigned int iname = isym->st_name;
  unsigned int iname = isym->st_name;
  unsigned int shindex = symtab_hdr->sh_link;
  unsigned int shindex = symtab_hdr->sh_link;
 
 
  if (iname == 0 && ELF_ST_TYPE (isym->st_info) == STT_SECTION
  if (iname == 0 && ELF_ST_TYPE (isym->st_info) == STT_SECTION
      /* Check for a bogus st_shndx to avoid crashing.  */
      /* Check for a bogus st_shndx to avoid crashing.  */
      && isym->st_shndx < elf_numsections (abfd)
      && isym->st_shndx < elf_numsections (abfd))
      && !(isym->st_shndx >= SHN_LORESERVE && isym->st_shndx <= SHN_HIRESERVE))
 
    {
    {
      iname = elf_elfsections (abfd)[isym->st_shndx]->sh_name;
      iname = elf_elfsections (abfd)[isym->st_shndx]->sh_name;
      shindex = elf_elfheader (abfd)->e_shstrndx;
      shindex = elf_elfheader (abfd)->e_shstrndx;
    }
    }
 
 
Line 493... Line 504...
  Elf_External_Sym_Shndx eshndx;
  Elf_External_Sym_Shndx eshndx;
  Elf_Internal_Sym isym;
  Elf_Internal_Sym isym;
 
 
  /* First we need to ensure the symbol table is available.  Make sure
  /* First we need to ensure the symbol table is available.  Make sure
     that it is a symbol table section.  */
     that it is a symbol table section.  */
 
  if (ghdr->sh_link >= elf_numsections (abfd))
 
    return NULL;
  hdr = elf_elfsections (abfd) [ghdr->sh_link];
  hdr = elf_elfsections (abfd) [ghdr->sh_link];
  if (hdr->sh_type != SHT_SYMTAB
  if (hdr->sh_type != SHT_SYMTAB
      || ! bfd_section_from_shdr (abfd, ghdr->sh_link))
      || ! bfd_section_from_shdr (abfd, ghdr->sh_link))
    return NULL;
    return NULL;
 
 
Line 551... Line 564...
          /* We keep a list of elf section headers for group sections,
          /* We keep a list of elf section headers for group sections,
             so we can find them quickly.  */
             so we can find them quickly.  */
          bfd_size_type amt;
          bfd_size_type amt;
 
 
          elf_tdata (abfd)->num_group = num_group;
          elf_tdata (abfd)->num_group = num_group;
          elf_tdata (abfd)->group_sect_ptr
          elf_tdata (abfd)->group_sect_ptr = (Elf_Internal_Shdr **)
            = bfd_alloc2 (abfd, num_group, sizeof (Elf_Internal_Shdr *));
              bfd_alloc2 (abfd, num_group, sizeof (Elf_Internal_Shdr *));
          if (elf_tdata (abfd)->group_sect_ptr == NULL)
          if (elf_tdata (abfd)->group_sect_ptr == NULL)
            return FALSE;
            return FALSE;
 
 
          num_group = 0;
          num_group = 0;
          for (i = 0; i < shnum; i++)
          for (i = 0; i < shnum; i++)
Line 573... Line 586...
                  num_group += 1;
                  num_group += 1;
 
 
                  /* Read the raw contents.  */
                  /* Read the raw contents.  */
                  BFD_ASSERT (sizeof (*dest) >= 4);
                  BFD_ASSERT (sizeof (*dest) >= 4);
                  amt = shdr->sh_size * sizeof (*dest) / 4;
                  amt = shdr->sh_size * sizeof (*dest) / 4;
                  shdr->contents = bfd_alloc2 (abfd, shdr->sh_size,
                  shdr->contents = (unsigned char *)
                                               sizeof (*dest) / 4);
                      bfd_alloc2 (abfd, shdr->sh_size, sizeof (*dest) / 4);
                  /* PR binutils/4110: Handle corrupt group headers.  */
                  /* PR binutils/4110: Handle corrupt group headers.  */
                  if (shdr->contents == NULL)
                  if (shdr->contents == NULL)
                    {
                    {
                      _bfd_error_handler
                      _bfd_error_handler
                        (_("%B: Corrupt size field in group section header: 0x%lx"), abfd, shdr->sh_size);
                        (_("%B: Corrupt size field in group section header: 0x%lx"), abfd, shdr->sh_size);
Line 711... Line 724...
          /* FIXME: The old Intel compiler and old strip/objcopy may
          /* FIXME: The old Intel compiler and old strip/objcopy may
             not set the sh_link or sh_info fields.  Hence we could
             not set the sh_link or sh_info fields.  Hence we could
             get the situation where elfsec is 0.  */
             get the situation where elfsec is 0.  */
          if (elfsec == 0)
          if (elfsec == 0)
            {
            {
              const struct elf_backend_data *bed
              const struct elf_backend_data *bed = get_elf_backend_data (abfd);
                = get_elf_backend_data (abfd);
 
              if (bed->link_order_error_handler)
              if (bed->link_order_error_handler)
                bed->link_order_error_handler
                bed->link_order_error_handler
                  (_("%B: warning: sh_link not set for section `%A'"),
                  (_("%B: warning: sh_link not set for section `%A'"),
                   abfd, s);
                   abfd, s);
            }
            }
          else
          else
            {
            {
              asection *link;
              asection *link = NULL;
 
 
 
              if (elfsec < elf_numsections (abfd))
 
                {
              this_hdr = elf_elfsections (abfd)[elfsec];
              this_hdr = elf_elfsections (abfd)[elfsec];
 
                  link = this_hdr->bfd_section;
 
                }
 
 
              /* PR 1991, 2008:
              /* PR 1991, 2008:
                 Some strip/objcopy may leave an incorrect value in
                 Some strip/objcopy may leave an incorrect value in
                 sh_link.  We don't want to proceed.  */
                 sh_link.  We don't want to proceed.  */
              link = this_hdr->bfd_section;
 
              if (link == NULL)
              if (link == NULL)
                {
                {
                  (*_bfd_error_handler)
                  (*_bfd_error_handler)
                    (_("%B: sh_link [%d] in section `%A' is incorrect"),
                    (_("%B: sh_link [%d] in section `%A' is incorrect"),
                     s->owner, s, elfsec);
                     s->owner, s, elfsec);
Line 823... Line 838...
  newsect->filepos = hdr->sh_offset;
  newsect->filepos = hdr->sh_offset;
 
 
  if (! bfd_set_section_vma (abfd, newsect, hdr->sh_addr)
  if (! bfd_set_section_vma (abfd, newsect, hdr->sh_addr)
      || ! bfd_set_section_size (abfd, newsect, hdr->sh_size)
      || ! bfd_set_section_size (abfd, newsect, hdr->sh_size)
      || ! bfd_set_section_alignment (abfd, newsect,
      || ! bfd_set_section_alignment (abfd, newsect,
                                      bfd_log2 ((bfd_vma) hdr->sh_addralign)))
                                      bfd_log2 (hdr->sh_addralign)))
    return FALSE;
    return FALSE;
 
 
  flags = SEC_NO_FLAGS;
  flags = SEC_NO_FLAGS;
  if (hdr->sh_type != SHT_NOBITS)
  if (hdr->sh_type != SHT_NOBITS)
    flags |= SEC_HAS_CONTENTS;
    flags |= SEC_HAS_CONTENTS;
Line 881... Line 896...
          { NULL,                0  },   /* 'n' */
          { NULL,                0  },   /* 'n' */
          { NULL,                0  },   /* 'o' */
          { NULL,                0  },   /* 'o' */
          { NULL,                0  },   /* 'p' */
          { NULL,                0  },   /* 'p' */
          { NULL,                0  },   /* 'q' */
          { NULL,                0  },   /* 'q' */
          { NULL,                0  },   /* 'r' */
          { NULL,                0  },   /* 'r' */
          { STRING_COMMA_LEN ("stab") } /* 's' */
          { STRING_COMMA_LEN ("stab") },        /* 's' */
 
          { NULL,                0  },   /* 't' */
 
          { NULL,                0  },   /* 'u' */
 
          { NULL,                0  },   /* 'v' */
 
          { NULL,                0  },   /* 'w' */
 
          { NULL,                0  },   /* 'x' */
 
          { NULL,                0  },   /* 'y' */
 
          { STRING_COMMA_LEN ("zdebug") }       /* 'z' */
        };
        };
 
 
      if (name [0] == '.')
      if (name [0] == '.')
        {
        {
          int i = name [1] - 'd';
          int i = name [1] - 'd';
Line 919... Line 941...
  /* We do not parse the PT_NOTE segments as we are interested even in the
  /* We do not parse the PT_NOTE segments as we are interested even in the
     separate debug info files which may have the segments offsets corrupted.
     separate debug info files which may have the segments offsets corrupted.
     PT_NOTEs from the core files are currently not parsed using BFD.  */
     PT_NOTEs from the core files are currently not parsed using BFD.  */
  if (hdr->sh_type == SHT_NOTE)
  if (hdr->sh_type == SHT_NOTE)
    {
    {
      char *contents;
      bfd_byte *contents;
 
 
      contents = bfd_malloc (hdr->sh_size);
      if (!bfd_malloc_and_get_section (abfd, newsect, &contents))
      if (!contents)
 
        return FALSE;
        return FALSE;
 
 
      if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0,
      elf_parse_notes (abfd, (char *) contents, hdr->sh_size, -1);
                                     hdr->sh_size)
 
          || !elf_parse_notes (abfd, contents, hdr->sh_size, -1))
 
        {
 
          free (contents);
 
          return FALSE;
 
        }
 
 
 
      free (contents);
      free (contents);
    }
    }
 
 
  if ((flags & SEC_ALLOC) != 0)
  if ((flags & SEC_ALLOC) != 0)
    {
    {
      Elf_Internal_Phdr *phdr;
      Elf_Internal_Phdr *phdr;
      unsigned int i;
      unsigned int i, nload;
 
 
      /* Look through the phdrs to see if we need to adjust the lma.
      /* Some ELF linkers produce binaries with all the program header
         If all the p_paddr fields are zero, we ignore them, since
         p_paddr fields zero.  If we have such a binary with more than
         some ELF linkers produce such output.  */
         one PT_LOAD header, then leave the section lma equal to vma
 
         so that we don't create sections with overlapping lma.  */
      phdr = elf_tdata (abfd)->phdr;
      phdr = elf_tdata (abfd)->phdr;
      for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
      for (nload = 0, i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
        {
 
          if (phdr->p_paddr != 0)
          if (phdr->p_paddr != 0)
            break;
            break;
        }
        else if (phdr->p_type == PT_LOAD && phdr->p_memsz != 0)
      if (i < elf_elfheader (abfd)->e_phnum)
          ++nload;
        {
      if (i >= elf_elfheader (abfd)->e_phnum && nload > 1)
 
        return TRUE;
 
 
          phdr = elf_tdata (abfd)->phdr;
          phdr = elf_tdata (abfd)->phdr;
          for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
          for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
            {
            {
              /* This section is part of this segment if its file
 
                 offset plus size lies within the segment's memory
 
                 span and, if the section is loaded, the extent of the
 
                 loaded data lies within the extent of the segment.
 
 
 
                 Note - we used to check the p_paddr field as well, and
 
                 refuse to set the LMA if it was 0.  This is wrong
 
                 though, as a perfectly valid initialised segment can
 
                 have a p_paddr of zero.  Some architectures, eg ARM,
 
                 place special significance on the address 0 and
 
                 executables need to be able to have a segment which
 
                 covers this address.  */
 
              if (phdr->p_type == PT_LOAD
              if (phdr->p_type == PT_LOAD
                  && (bfd_vma) hdr->sh_offset >= phdr->p_offset
              && ELF_IS_SECTION_IN_SEGMENT (hdr, phdr))
                  && (hdr->sh_offset + hdr->sh_size
 
                      <= phdr->p_offset + phdr->p_memsz)
 
                  && ((flags & SEC_LOAD) == 0
 
                      || (hdr->sh_offset + hdr->sh_size
 
                          <= phdr->p_offset + phdr->p_filesz)))
 
                {
                {
                  if ((flags & SEC_LOAD) == 0)
                  if ((flags & SEC_LOAD) == 0)
                    newsect->lma = (phdr->p_paddr
                    newsect->lma = (phdr->p_paddr
                                    + hdr->sh_addr - phdr->p_vaddr);
                                    + hdr->sh_addr - phdr->p_vaddr);
                  else
                  else
Line 1000... Line 999...
                          <= phdr->p_vaddr + phdr->p_memsz))
                          <= phdr->p_vaddr + phdr->p_memsz))
                    break;
                    break;
                }
                }
            }
            }
        }
        }
    }
 
 
 
  return TRUE;
  return TRUE;
}
}
 
 
/*
 
INTERNAL_FUNCTION
 
        bfd_elf_find_section
 
 
 
SYNOPSIS
 
        struct elf_internal_shdr *bfd_elf_find_section (bfd *abfd, char *name);
 
 
 
DESCRIPTION
 
        Helper functions for GDB to locate the string tables.
 
        Since BFD hides string tables from callers, GDB needs to use an
 
        internal hook to find them.  Sun's .stabstr, in particular,
 
        isn't even pointed to by the .stab section, so ordinary
 
        mechanisms wouldn't work to find it, even if we had some.
 
*/
 
 
 
struct elf_internal_shdr *
 
bfd_elf_find_section (bfd *abfd, char *name)
 
{
 
  Elf_Internal_Shdr **i_shdrp;
 
  char *shstrtab;
 
  unsigned int max;
 
  unsigned int i;
 
 
 
  i_shdrp = elf_elfsections (abfd);
 
  if (i_shdrp != NULL)
 
    {
 
      shstrtab = bfd_elf_get_str_section (abfd,
 
                                          elf_elfheader (abfd)->e_shstrndx);
 
      if (shstrtab != NULL)
 
        {
 
          max = elf_numsections (abfd);
 
          for (i = 1; i < max; i++)
 
            if (!strcmp (&shstrtab[i_shdrp[i]->sh_name], name))
 
              return i_shdrp[i];
 
        }
 
    }
 
  return 0;
 
}
 
 
 
const char *const bfd_elf_section_type_names[] = {
const char *const bfd_elf_section_type_names[] = {
  "SHT_NULL", "SHT_PROGBITS", "SHT_SYMTAB", "SHT_STRTAB",
  "SHT_NULL", "SHT_PROGBITS", "SHT_SYMTAB", "SHT_STRTAB",
  "SHT_RELA", "SHT_HASH", "SHT_DYNAMIC", "SHT_NOTE",
  "SHT_RELA", "SHT_HASH", "SHT_DYNAMIC", "SHT_NOTE",
  "SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM",
  "SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM",
};
};
Line 1132... Line 1091...
/* Print out the program headers.  */
/* Print out the program headers.  */
 
 
bfd_boolean
bfd_boolean
_bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
_bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
{
{
  FILE *f = farg;
  FILE *f = (FILE *) farg;
  Elf_Internal_Phdr *p;
  Elf_Internal_Phdr *p;
  asection *s;
  asection *s;
  bfd_byte *dynbuf = NULL;
  bfd_byte *dynbuf = NULL;
 
 
  p = elf_tdata (abfd)->phdr;
  p = elf_tdata (abfd)->phdr;
Line 1178... Line 1137...
    }
    }
 
 
  s = bfd_get_section_by_name (abfd, ".dynamic");
  s = bfd_get_section_by_name (abfd, ".dynamic");
  if (s != NULL)
  if (s != NULL)
    {
    {
      int elfsec;
      unsigned int elfsec;
      unsigned long shlink;
      unsigned long shlink;
      bfd_byte *extdyn, *extdynend;
      bfd_byte *extdyn, *extdynend;
      size_t extdynsize;
      size_t extdynsize;
      void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
      void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
 
 
Line 1190... Line 1149...
 
 
      if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
      if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
        goto error_return;
        goto error_return;
 
 
      elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
      elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
      if (elfsec == -1)
      if (elfsec == SHN_BAD)
        goto error_return;
        goto error_return;
      shlink = elf_elfsections (abfd)[elfsec]->sh_link;
      shlink = elf_elfsections (abfd)[elfsec]->sh_link;
 
 
      extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
      extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
      swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
      swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
Line 1202... Line 1161...
      extdyn = dynbuf;
      extdyn = dynbuf;
      extdynend = extdyn + s->size;
      extdynend = extdyn + s->size;
      for (; extdyn < extdynend; extdyn += extdynsize)
      for (; extdyn < extdynend; extdyn += extdynsize)
        {
        {
          Elf_Internal_Dyn dyn;
          Elf_Internal_Dyn dyn;
          const char *name;
          const char *name = "";
          char ab[20];
          char ab[20];
          bfd_boolean stringp;
          bfd_boolean stringp;
 
          const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
 
          (*swap_dyn_in) (abfd, extdyn, &dyn);
          (*swap_dyn_in) (abfd, extdyn, &dyn);
 
 
          if (dyn.d_tag == DT_NULL)
          if (dyn.d_tag == DT_NULL)
            break;
            break;
 
 
          stringp = FALSE;
          stringp = FALSE;
          switch (dyn.d_tag)
          switch (dyn.d_tag)
            {
            {
            default:
            default:
 
              if (bed->elf_backend_get_target_dtag)
 
                name = (*bed->elf_backend_get_target_dtag) (dyn.d_tag);
 
 
 
              if (!strcmp (name, ""))
 
                {
              sprintf (ab, "0x%lx", (unsigned long) dyn.d_tag);
              sprintf (ab, "0x%lx", (unsigned long) dyn.d_tag);
              name = ab;
              name = ab;
 
                }
              break;
              break;
 
 
            case DT_NEEDED: name = "NEEDED"; stringp = TRUE; break;
            case DT_NEEDED: name = "NEEDED"; stringp = TRUE; break;
            case DT_PLTRELSZ: name = "PLTRELSZ"; break;
            case DT_PLTRELSZ: name = "PLTRELSZ"; break;
            case DT_PLTGOT: name = "PLTGOT"; break;
            case DT_PLTGOT: name = "PLTGOT"; break;
Line 1279... Line 1245...
            case DT_USED: name = "USED"; break;
            case DT_USED: name = "USED"; break;
            case DT_FILTER: name = "FILTER"; stringp = TRUE; break;
            case DT_FILTER: name = "FILTER"; stringp = TRUE; break;
            case DT_GNU_HASH: name = "GNU_HASH"; break;
            case DT_GNU_HASH: name = "GNU_HASH"; break;
            }
            }
 
 
          fprintf (f, "  %-11s ", name);
          fprintf (f, "  %-20s ", name);
          if (! stringp)
          if (! stringp)
            fprintf (f, "0x%lx", (unsigned long) dyn.d_un.d_val);
            {
 
              fprintf (f, "0x");
 
              bfd_fprintf_vma (abfd, f, dyn.d_un.d_val);
 
            }
          else
          else
            {
            {
              const char *string;
              const char *string;
              unsigned int tagv = dyn.d_un.d_val;
              unsigned int tagv = dyn.d_un.d_val;
 
 
Line 1365... Line 1334...
bfd_elf_print_symbol (bfd *abfd,
bfd_elf_print_symbol (bfd *abfd,
                      void *filep,
                      void *filep,
                      asymbol *symbol,
                      asymbol *symbol,
                      bfd_print_symbol_type how)
                      bfd_print_symbol_type how)
{
{
  FILE *file = filep;
  FILE *file = (FILE *) filep;
  switch (how)
  switch (how)
    {
    {
    case bfd_print_symbol_name:
    case bfd_print_symbol_name:
      fprintf (file, "%s", symbol->name);
      fprintf (file, "%s", symbol->name);
      break;
      break;
    case bfd_print_symbol_more:
    case bfd_print_symbol_more:
      fprintf (file, "elf ");
      fprintf (file, "elf ");
      bfd_fprintf_vma (abfd, file, symbol->value);
      bfd_fprintf_vma (abfd, file, symbol->value);
      fprintf (file, " %lx", (long) symbol->flags);
      fprintf (file, " %lx", (unsigned long) symbol->flags);
      break;
      break;
    case bfd_print_symbol_all:
    case bfd_print_symbol_all:
      {
      {
        const char *section_name;
        const char *section_name;
        const char *name = NULL;
        const char *name = NULL;
Line 1509... Line 1478...
/* Create a new bfd section from an ELF section header.  */
/* Create a new bfd section from an ELF section header.  */
 
 
bfd_boolean
bfd_boolean
bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
{
{
  Elf_Internal_Shdr *hdr = elf_elfsections (abfd)[shindex];
  Elf_Internal_Shdr *hdr;
  Elf_Internal_Ehdr *ehdr = elf_elfheader (abfd);
  Elf_Internal_Ehdr *ehdr;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  const struct elf_backend_data *bed;
  const char *name;
  const char *name;
 
 
  name = bfd_elf_string_from_elf_section (abfd,
  if (shindex >= elf_numsections (abfd))
                                          elf_elfheader (abfd)->e_shstrndx,
    return FALSE;
 
 
 
  hdr = elf_elfsections (abfd)[shindex];
 
  ehdr = elf_elfheader (abfd);
 
  name = bfd_elf_string_from_elf_section (abfd, ehdr->e_shstrndx,
                                          hdr->sh_name);
                                          hdr->sh_name);
  if (name == NULL)
  if (name == NULL)
    return FALSE;
    return FALSE;
 
 
 
  bed = get_elf_backend_data (abfd);
  switch (hdr->sh_type)
  switch (hdr->sh_type)
    {
    {
    case SHT_NULL:
    case SHT_NULL:
      /* Inactive section. Throw it away.  */
      /* Inactive section. Throw it away.  */
      return TRUE;
      return TRUE;
Line 1540... Line 1514...
      return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
      return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
 
 
    case SHT_DYNAMIC:   /* Dynamic linking information.  */
    case SHT_DYNAMIC:   /* Dynamic linking information.  */
      if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
      if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
        return FALSE;
        return FALSE;
      if (hdr->sh_link > elf_numsections (abfd)
      if (hdr->sh_link > elf_numsections (abfd))
          || elf_elfsections (abfd)[hdr->sh_link] == NULL)
        {
 
          /* PR 10478: Accept sparc binaries with a sh_link
 
             field set to SHN_BEFORE or SHN_AFTER.  */
 
          switch (bfd_get_arch (abfd))
 
            {
 
            case bfd_arch_sparc:
 
              if (hdr->sh_link == (SHN_LORESERVE & 0xffff) /* SHN_BEFORE */
 
                  || hdr->sh_link == ((SHN_LORESERVE + 1) & 0xffff) /* SHN_AFTER */)
 
                break;
 
              /* Otherwise fall through.  */
 
            default:
 
              return FALSE;
 
            }
 
        }
 
      else if (elf_elfsections (abfd)[hdr->sh_link] == NULL)
        return FALSE;
        return FALSE;
      if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB)
      else if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB)
        {
        {
          Elf_Internal_Shdr *dynsymhdr;
          Elf_Internal_Shdr *dynsymhdr;
 
 
          /* The shared libraries distributed with hpux11 have a bogus
          /* The shared libraries distributed with hpux11 have a bogus
             sh_link field for the ".dynamic" section.  Find the
             sh_link field for the ".dynamic" section.  Find the
Line 1579... Line 1567...
      if (elf_onesymtab (abfd) == shindex)
      if (elf_onesymtab (abfd) == shindex)
        return TRUE;
        return TRUE;
 
 
      if (hdr->sh_entsize != bed->s->sizeof_sym)
      if (hdr->sh_entsize != bed->s->sizeof_sym)
        return FALSE;
        return FALSE;
 
      if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size)
 
        return FALSE;
      BFD_ASSERT (elf_onesymtab (abfd) == 0);
      BFD_ASSERT (elf_onesymtab (abfd) == 0);
      elf_onesymtab (abfd) = shindex;
      elf_onesymtab (abfd) = shindex;
      elf_tdata (abfd)->symtab_hdr = *hdr;
      elf_tdata (abfd)->symtab_hdr = *hdr;
      elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->symtab_hdr;
      elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->symtab_hdr;
      abfd->flags |= HAS_SYMS;
      abfd->flags |= HAS_SYMS;
Line 1720... Line 1710...
            != (bfd_size_type) (hdr->sh_type == SHT_REL
            != (bfd_size_type) (hdr->sh_type == SHT_REL
                                ? bed->s->sizeof_rel : bed->s->sizeof_rela))
                                ? bed->s->sizeof_rel : bed->s->sizeof_rela))
          return FALSE;
          return FALSE;
 
 
        /* Check for a bogus link to avoid crashing.  */
        /* Check for a bogus link to avoid crashing.  */
        if ((hdr->sh_link >= SHN_LORESERVE && hdr->sh_link <= SHN_HIRESERVE)
        if (hdr->sh_link >= num_sec)
            || hdr->sh_link >= num_sec)
 
          {
          {
            ((*_bfd_error_handler)
            ((*_bfd_error_handler)
             (_("%B: invalid link %lu for reloc section %s (index %u)"),
             (_("%B: invalid link %lu for reloc section %s (index %u)"),
              abfd, hdr->sh_link, name, shindex));
              abfd, hdr->sh_link, name, shindex));
            return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
            return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
Line 1736... Line 1725...
           libraries for Solaris in which some of the objects have
           libraries for Solaris in which some of the objects have
           bogus sh_link fields.  It would be nice if we could just
           bogus sh_link fields.  It would be nice if we could just
           reject them, but, unfortunately, some people need to use
           reject them, but, unfortunately, some people need to use
           them.  We scan through the section headers; if we find only
           them.  We scan through the section headers; if we find only
           one suitable symbol table, we clobber the sh_link to point
           one suitable symbol table, we clobber the sh_link to point
           to it.  I hope this doesn't break anything.  */
           to it.  I hope this doesn't break anything.
        if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_SYMTAB
 
 
           Don't do it on executable nor shared library.  */
 
        if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0
 
            && elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_SYMTAB
            && elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_DYNSYM)
            && elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_DYNSYM)
          {
          {
            unsigned int scan;
            unsigned int scan;
            int found;
            int found;
 
 
Line 1772... Line 1764...
        /* If this reloc section does not use the main symbol table we
        /* If this reloc section does not use the main symbol table we
           don't treat it as a reloc section.  BFD can't adequately
           don't treat it as a reloc section.  BFD can't adequately
           represent such a section, so at least for now, we don't
           represent such a section, so at least for now, we don't
           try.  We just present it as a normal section.  We also
           try.  We just present it as a normal section.  We also
           can't use it as a reloc section if it points to the null
           can't use it as a reloc section if it points to the null
           section, an invalid section, or another reloc section.  */
           section, an invalid section, another reloc section, or its
 
           sh_link points to the null section.  */
        if (hdr->sh_link != elf_onesymtab (abfd)
        if (hdr->sh_link != elf_onesymtab (abfd)
 
            || hdr->sh_link == SHN_UNDEF
            || hdr->sh_info == SHN_UNDEF
            || hdr->sh_info == SHN_UNDEF
            || (hdr->sh_info >= SHN_LORESERVE && hdr->sh_info <= SHN_HIRESERVE)
 
            || hdr->sh_info >= num_sec
            || hdr->sh_info >= num_sec
            || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL
            || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL
            || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA)
            || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA)
          return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
          return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
                                                  shindex);
                                                  shindex);
Line 1796... Line 1789...
        else
        else
          {
          {
            bfd_size_type amt;
            bfd_size_type amt;
            BFD_ASSERT (elf_section_data (target_sect)->rel_hdr2 == NULL);
            BFD_ASSERT (elf_section_data (target_sect)->rel_hdr2 == NULL);
            amt = sizeof (*hdr2);
            amt = sizeof (*hdr2);
            hdr2 = bfd_alloc (abfd, amt);
            hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
            if (hdr2 == NULL)
            if (hdr2 == NULL)
              return FALSE;
              return FALSE;
            elf_section_data (target_sect)->rel_hdr2 = hdr2;
            elf_section_data (target_sect)->rel_hdr2 = hdr2;
          }
          }
        *hdr2 = *hdr;
        *hdr2 = *hdr;
Line 1836... Line 1829...
 
 
    case SHT_SHLIB:
    case SHT_SHLIB:
      return TRUE;
      return TRUE;
 
 
    case SHT_GROUP:
    case SHT_GROUP:
      /* We need a BFD section for objcopy and relocatable linking,
 
         and it's handy to have the signature available as the section
 
         name.  */
 
      if (! IS_VALID_GROUP_SECTION_HEADER (hdr))
      if (! IS_VALID_GROUP_SECTION_HEADER (hdr))
        return FALSE;
        return FALSE;
      name = group_signature (abfd, hdr);
 
      if (name == NULL)
 
        return FALSE;
 
      if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
      if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
        return FALSE;
        return FALSE;
      if (hdr->contents != NULL)
      if (hdr->contents != NULL)
        {
        {
          Elf_Internal_Group *idx = (Elf_Internal_Group *) hdr->contents;
          Elf_Internal_Group *idx = (Elf_Internal_Group *) hdr->contents;
Line 1936... Line 1923...
    }
    }
 
 
  return TRUE;
  return TRUE;
}
}
 
 
/* Return the section for the local symbol specified by ABFD, R_SYMNDX.
/* Return the local symbol specified by ABFD, R_SYMNDX.  */
   Return SEC for sections that have no elf section, and NULL on error.  */
 
 
 
asection *
Elf_Internal_Sym *
bfd_section_from_r_symndx (bfd *abfd,
bfd_sym_from_r_symndx (struct sym_cache *cache,
                           struct sym_sec_cache *cache,
                       bfd *abfd,
                           asection *sec,
 
                           unsigned long r_symndx)
                           unsigned long r_symndx)
{
{
  unsigned int ent = r_symndx % LOCAL_SYM_CACHE_SIZE;
  unsigned int ent = r_symndx % LOCAL_SYM_CACHE_SIZE;
  asection *s;
 
 
 
  if (cache->abfd != abfd || cache->indx[ent] != r_symndx)
  if (cache->abfd != abfd || cache->indx[ent] != r_symndx)
    {
    {
      Elf_Internal_Shdr *symtab_hdr;
      Elf_Internal_Shdr *symtab_hdr;
      unsigned char esym[sizeof (Elf64_External_Sym)];
      unsigned char esym[sizeof (Elf64_External_Sym)];
      Elf_External_Sym_Shndx eshndx;
      Elf_External_Sym_Shndx eshndx;
      Elf_Internal_Sym isym;
 
 
 
      symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
      symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
      if (bfd_elf_get_elf_syms (abfd, symtab_hdr, 1, r_symndx,
      if (bfd_elf_get_elf_syms (abfd, symtab_hdr, 1, r_symndx,
                                &isym, esym, &eshndx) == NULL)
                                &cache->sym[ent], esym, &eshndx) == NULL)
        return NULL;
        return NULL;
 
 
      if (cache->abfd != abfd)
      if (cache->abfd != abfd)
        {
        {
          memset (cache->indx, -1, sizeof (cache->indx));
          memset (cache->indx, -1, sizeof (cache->indx));
          cache->abfd = abfd;
          cache->abfd = abfd;
        }
        }
      cache->indx[ent] = r_symndx;
      cache->indx[ent] = r_symndx;
      cache->shndx[ent] = isym.st_shndx;
 
    }
    }
 
 
  s = bfd_section_from_elf_index (abfd, cache->shndx[ent]);
  return &cache->sym[ent];
  if (s != NULL)
 
    return s;
 
 
 
  return sec;
 
}
}
 
 
/* Given an ELF section number, retrieve the corresponding BFD
/* Given an ELF section number, retrieve the corresponding BFD
   section.  */
   section.  */
 
 
Line 2096... Line 2074...
  { STRING_COMMA_LEN (".tbss"),  -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_TLS },
  { STRING_COMMA_LEN (".tbss"),  -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_TLS },
  { STRING_COMMA_LEN (".tdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS },
  { STRING_COMMA_LEN (".tdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS },
  { NULL,                     0,  0, 0,            0 }
  { NULL,                     0,  0, 0,            0 }
};
};
 
 
 
static const struct bfd_elf_special_section special_sections_z[] =
 
{
 
  { STRING_COMMA_LEN (".zdebug_line"),    0, SHT_PROGBITS, 0 },
 
  { STRING_COMMA_LEN (".zdebug_info"),    0, SHT_PROGBITS, 0 },
 
  { STRING_COMMA_LEN (".zdebug_abbrev"),  0, SHT_PROGBITS, 0 },
 
  { STRING_COMMA_LEN (".zdebug_aranges"), 0, SHT_PROGBITS, 0 },
 
  { NULL,                     0,  0, 0,            0 }
 
};
 
 
static const struct bfd_elf_special_section *special_sections[] =
static const struct bfd_elf_special_section *special_sections[] =
{
{
  special_sections_b,           /* 'b' */
  special_sections_b,           /* 'b' */
  special_sections_c,           /* 'c' */
  special_sections_c,           /* 'c' */
  special_sections_d,           /* 'd' */
  special_sections_d,           /* 'd' */
Line 2117... Line 2104...
  special_sections_p,           /* 'p' */
  special_sections_p,           /* 'p' */
  NULL,                         /* 'q' */
  NULL,                         /* 'q' */
  special_sections_r,           /* 'r' */
  special_sections_r,           /* 'r' */
  special_sections_s,           /* 's' */
  special_sections_s,           /* 's' */
  special_sections_t,           /* 't' */
  special_sections_t,           /* 't' */
 
  NULL,                         /* 'u' */
 
  NULL,                         /* 'v' */
 
  NULL,                         /* 'w' */
 
  NULL,                         /* 'x' */
 
  NULL,                         /* 'y' */
 
  special_sections_z            /* 'z' */
};
};
 
 
const struct bfd_elf_special_section *
const struct bfd_elf_special_section *
_bfd_elf_get_special_section (const char *name,
_bfd_elf_get_special_section (const char *name,
                              const struct bfd_elf_special_section *spec,
                              const struct bfd_elf_special_section *spec,
Line 2193... Line 2186...
 
 
  if (sec->name[0] != '.')
  if (sec->name[0] != '.')
    return NULL;
    return NULL;
 
 
  i = sec->name[1] - 'b';
  i = sec->name[1] - 'b';
  if (i < 0 || i > 't' - 'b')
  if (i < 0 || i > 'z' - 'b')
    return NULL;
    return NULL;
 
 
  spec = special_sections[i];
  spec = special_sections[i];
 
 
  if (spec == NULL)
  if (spec == NULL)
Line 2214... Line 2207...
  const struct bfd_elf_special_section *ssect;
  const struct bfd_elf_special_section *ssect;
 
 
  sdata = (struct bfd_elf_section_data *) sec->used_by_bfd;
  sdata = (struct bfd_elf_section_data *) sec->used_by_bfd;
  if (sdata == NULL)
  if (sdata == NULL)
    {
    {
      sdata = bfd_zalloc (abfd, sizeof (*sdata));
      sdata = (struct bfd_elf_section_data *) bfd_zalloc (abfd,
 
                                                          sizeof (*sdata));
      if (sdata == NULL)
      if (sdata == NULL)
        return FALSE;
        return FALSE;
      sec->used_by_bfd = sdata;
      sec->used_by_bfd = sdata;
    }
    }
 
 
Line 2270... Line 2264...
 
 
bfd_boolean
bfd_boolean
_bfd_elf_make_section_from_phdr (bfd *abfd,
_bfd_elf_make_section_from_phdr (bfd *abfd,
                                 Elf_Internal_Phdr *hdr,
                                 Elf_Internal_Phdr *hdr,
                                 int index,
                                 int index,
                                 const char *typename)
                                 const char *type_name)
{
{
  asection *newsect;
  asection *newsect;
  char *name;
  char *name;
  char namebuf[64];
  char namebuf[64];
  size_t len;
  size_t len;
Line 2284... Line 2278...
            && (hdr->p_filesz > 0)
            && (hdr->p_filesz > 0)
            && (hdr->p_memsz > hdr->p_filesz));
            && (hdr->p_memsz > hdr->p_filesz));
 
 
  if (hdr->p_filesz > 0)
  if (hdr->p_filesz > 0)
    {
    {
      sprintf (namebuf, "%s%d%s", typename, index, split ? "a" : "");
      sprintf (namebuf, "%s%d%s", type_name, index, split ? "a" : "");
      len = strlen (namebuf) + 1;
      len = strlen (namebuf) + 1;
      name = bfd_alloc (abfd, len);
      name = (char *) bfd_alloc (abfd, len);
      if (!name)
      if (!name)
        return FALSE;
        return FALSE;
      memcpy (name, namebuf, len);
      memcpy (name, namebuf, len);
      newsect = bfd_make_section (abfd, name);
      newsect = bfd_make_section (abfd, name);
      if (newsect == NULL)
      if (newsect == NULL)
Line 2320... Line 2314...
 
 
  if (hdr->p_memsz > hdr->p_filesz)
  if (hdr->p_memsz > hdr->p_filesz)
    {
    {
      bfd_vma align;
      bfd_vma align;
 
 
      sprintf (namebuf, "%s%d%s", typename, index, split ? "b" : "");
      sprintf (namebuf, "%s%d%s", type_name, index, split ? "b" : "");
      len = strlen (namebuf) + 1;
      len = strlen (namebuf) + 1;
      name = bfd_alloc (abfd, len);
      name = (char *) bfd_alloc (abfd, len);
      if (!name)
      if (!name)
        return FALSE;
        return FALSE;
      memcpy (name, namebuf, len);
      memcpy (name, namebuf, len);
      newsect = bfd_make_section (abfd, name);
      newsect = bfd_make_section (abfd, name);
      if (newsect == NULL)
      if (newsect == NULL)
Line 2421... Line 2415...
{
{
  char *name;
  char *name;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  bfd_size_type amt = sizeof ".rela" + strlen (asect->name);
  bfd_size_type amt = sizeof ".rela" + strlen (asect->name);
 
 
  name = bfd_alloc (abfd, amt);
  name = (char *) bfd_alloc (abfd, amt);
  if (name == NULL)
  if (name == NULL)
    return FALSE;
    return FALSE;
  sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", asect->name);
  sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", asect->name);
  rel_hdr->sh_name =
  rel_hdr->sh_name =
    (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), name,
    (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), name,
Line 2434... Line 2428...
    return FALSE;
    return FALSE;
  rel_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL;
  rel_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL;
  rel_hdr->sh_entsize = (use_rela_p
  rel_hdr->sh_entsize = (use_rela_p
                         ? bed->s->sizeof_rela
                         ? bed->s->sizeof_rela
                         : bed->s->sizeof_rel);
                         : bed->s->sizeof_rel);
  rel_hdr->sh_addralign = 1 << bed->s->log_file_align;
  rel_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align;
  rel_hdr->sh_flags = 0;
  rel_hdr->sh_flags = 0;
  rel_hdr->sh_addr = 0;
  rel_hdr->sh_addr = 0;
  rel_hdr->sh_size = 0;
  rel_hdr->sh_size = 0;
  rel_hdr->sh_offset = 0;
  rel_hdr->sh_offset = 0;
 
 
  return TRUE;
  return TRUE;
}
}
 
 
 
/* Return the default section type based on the passed in section flags.  */
 
 
 
int
 
bfd_elf_get_default_section_type (flagword flags)
 
{
 
  if ((flags & SEC_ALLOC) != 0
 
      && ((flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0
 
          || (flags & SEC_NEVER_LOAD) != 0))
 
    return SHT_NOBITS;
 
  return SHT_PROGBITS;
 
}
 
 
/* Set up an ELF internal section header for a section.  */
/* Set up an ELF internal section header for a section.  */
 
 
static void
static void
elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
{
{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  bfd_boolean *failedptr = failedptrarg;
  bfd_boolean *failedptr = (bfd_boolean *) failedptrarg;
  Elf_Internal_Shdr *this_hdr;
  Elf_Internal_Shdr *this_hdr;
  unsigned int sh_type;
  unsigned int sh_type;
 
 
  if (*failedptr)
  if (*failedptr)
    {
    {
Line 2481... Line 2487...
    this_hdr->sh_addr = 0;
    this_hdr->sh_addr = 0;
 
 
  this_hdr->sh_offset = 0;
  this_hdr->sh_offset = 0;
  this_hdr->sh_size = asect->size;
  this_hdr->sh_size = asect->size;
  this_hdr->sh_link = 0;
  this_hdr->sh_link = 0;
  this_hdr->sh_addralign = 1 << asect->alignment_power;
  this_hdr->sh_addralign = (bfd_vma) 1 << asect->alignment_power;
  /* The sh_entsize and sh_info fields may have been set already by
  /* The sh_entsize and sh_info fields may have been set already by
     copy_private_section_data.  */
     copy_private_section_data.  */
 
 
  this_hdr->bfd_section = asect;
  this_hdr->bfd_section = asect;
  this_hdr->contents = NULL;
  this_hdr->contents = NULL;
 
 
  /* If the section type is unspecified, we set it based on
  /* If the section type is unspecified, we set it based on
     asect->flags.  */
     asect->flags.  */
  if ((asect->flags & SEC_GROUP) != 0)
  if ((asect->flags & SEC_GROUP) != 0)
    sh_type = SHT_GROUP;
    sh_type = SHT_GROUP;
  else if ((asect->flags & SEC_ALLOC) != 0
 
           && (((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
 
               || (asect->flags & SEC_NEVER_LOAD) != 0))
 
    sh_type = SHT_NOBITS;
 
  else
  else
    sh_type = SHT_PROGBITS;
    sh_type = bfd_elf_get_default_section_type (asect->flags);
 
 
  if (this_hdr->sh_type == SHT_NULL)
  if (this_hdr->sh_type == SHT_NULL)
    this_hdr->sh_type = sh_type;
    this_hdr->sh_type = sh_type;
  else if (this_hdr->sh_type == SHT_NOBITS
  else if (this_hdr->sh_type == SHT_NOBITS
           && sh_type == SHT_PROGBITS
           && sh_type == SHT_PROGBITS
Line 2645... Line 2647...
                                    asect,
                                    asect,
                                    asect->use_rela_p))
                                    asect->use_rela_p))
    *failedptr = TRUE;
    *failedptr = TRUE;
}
}
 
 
/* Fill in the contents of a SHT_GROUP section.  */
/* Fill in the contents of a SHT_GROUP section.  Called from
 
   _bfd_elf_compute_section_file_positions for gas, objcopy, and
 
   when ELF targets use the generic linker, ld.  Called for ld -r
 
   from bfd_elf_final_link.  */
 
 
void
void
bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
{
{
  bfd_boolean *failedptr = failedptrarg;
  bfd_boolean *failedptr = (bfd_boolean *) failedptrarg;
  unsigned long symindx;
 
  asection *elt, *first;
  asection *elt, *first;
  unsigned char *loc;
  unsigned char *loc;
  bfd_boolean gas;
  bfd_boolean gas;
 
 
  /* Ignore linker created group section.  See elfNN_ia64_object_p in
  /* Ignore linker created group section.  See elfNN_ia64_object_p in
     elfxx-ia64.c.  */
     elfxx-ia64.c.  */
  if (((sec->flags & (SEC_GROUP | SEC_LINKER_CREATED)) != SEC_GROUP)
  if (((sec->flags & (SEC_GROUP | SEC_LINKER_CREATED)) != SEC_GROUP)
      || *failedptr)
      || *failedptr)
    return;
    return;
 
 
  symindx = 0;
  if (elf_section_data (sec)->this_hdr.sh_info == 0)
 
    {
 
      unsigned long symindx = 0;
 
 
 
      /* elf_group_id will have been set up by objcopy and the
 
         generic linker.  */
  if (elf_group_id (sec) != NULL)
  if (elf_group_id (sec) != NULL)
    symindx = elf_group_id (sec)->udata.i;
    symindx = elf_group_id (sec)->udata.i;
 
 
  if (symindx == 0)
  if (symindx == 0)
    {
    {
      /* If called from the assembler, swap_out_syms will have set up
      /* If called from the assembler, swap_out_syms will have set up
         elf_section_syms;  If called for "ld -r", use target_index.  */
             elf_section_syms.  */
      if (elf_section_syms (abfd) != NULL)
          BFD_ASSERT (elf_section_syms (abfd) != NULL);
        symindx = elf_section_syms (abfd)[sec->index]->udata.i;
        symindx = elf_section_syms (abfd)[sec->index]->udata.i;
      else
 
        symindx = sec->target_index;
 
    }
    }
  elf_section_data (sec)->this_hdr.sh_info = symindx;
  elf_section_data (sec)->this_hdr.sh_info = symindx;
 
    }
 
  else if (elf_section_data (sec)->this_hdr.sh_info == (unsigned int) -2)
 
    {
 
      /* The ELF backend linker sets sh_info to -2 when the group
 
         signature symbol is global, and thus the index can't be
 
         set until all local symbols are output.  */
 
      asection *igroup = elf_sec_group (elf_next_in_group (sec));
 
      struct bfd_elf_section_data *sec_data = elf_section_data (igroup);
 
      unsigned long symndx = sec_data->this_hdr.sh_info;
 
      unsigned long extsymoff = 0;
 
      struct elf_link_hash_entry *h;
 
 
 
      if (!elf_bad_symtab (igroup->owner))
 
        {
 
          Elf_Internal_Shdr *symtab_hdr;
 
 
 
          symtab_hdr = &elf_tdata (igroup->owner)->symtab_hdr;
 
          extsymoff = symtab_hdr->sh_info;
 
        }
 
      h = elf_sym_hashes (igroup->owner)[symndx - extsymoff];
 
      while (h->root.type == bfd_link_hash_indirect
 
             || h->root.type == bfd_link_hash_warning)
 
        h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
 
 
      elf_section_data (sec)->this_hdr.sh_info = h->indx;
 
    }
 
 
  /* The contents won't be allocated for "ld -r" or objcopy.  */
  /* The contents won't be allocated for "ld -r" or objcopy.  */
  gas = TRUE;
  gas = TRUE;
  if (sec->contents == NULL)
  if (sec->contents == NULL)
    {
    {
      gas = FALSE;
      gas = FALSE;
      sec->contents = bfd_alloc (abfd, sec->size);
      sec->contents = (unsigned char *) bfd_alloc (abfd, sec->size);
 
 
      /* Arrange for the section to be written out.  */
      /* Arrange for the section to be written out.  */
      elf_section_data (sec)->this_hdr.contents = sec->contents;
      elf_section_data (sec)->this_hdr.contents = sec->contents;
      if (sec->contents == NULL)
      if (sec->contents == NULL)
        {
        {
Line 2709... Line 2742...
  while (elt != NULL)
  while (elt != NULL)
    {
    {
      asection *s;
      asection *s;
      unsigned int idx;
      unsigned int idx;
 
 
      loc -= 4;
 
      s = elt;
      s = elt;
 
      if (! elf_discarded_section (s))
 
        {
 
          loc -= 4;
      if (!gas)
      if (!gas)
        s = s->output_section;
        s = s->output_section;
      idx = 0;
      idx = 0;
      if (s != NULL)
      if (s != NULL)
        idx = elf_section_data (s)->this_idx;
        idx = elf_section_data (s)->this_idx;
      H_PUT_32 (abfd, idx, loc);
      H_PUT_32 (abfd, idx, loc);
 
        }
      elt = elf_next_in_group (elt);
      elt = elf_next_in_group (elt);
      if (elt == first)
      if (elt == first)
        break;
        break;
    }
    }
 
 
Line 2740... Line 2776...
  struct elf_obj_tdata *t = elf_tdata (abfd);
  struct elf_obj_tdata *t = elf_tdata (abfd);
  asection *sec;
  asection *sec;
  unsigned int section_number, secn;
  unsigned int section_number, secn;
  Elf_Internal_Shdr **i_shdrp;
  Elf_Internal_Shdr **i_shdrp;
  struct bfd_elf_section_data *d;
  struct bfd_elf_section_data *d;
 
  bfd_boolean need_symtab;
 
 
  section_number = 1;
  section_number = 1;
 
 
  _bfd_elf_strtab_clear_all_refs (elf_shstrtab (abfd));
  _bfd_elf_strtab_clear_all_refs (elf_shstrtab (abfd));
 
 
Line 2762... Line 2799...
                  /* Remove the linker created SHT_GROUP sections.  */
                  /* Remove the linker created SHT_GROUP sections.  */
                  bfd_section_list_remove (abfd, sec);
                  bfd_section_list_remove (abfd, sec);
                  abfd->section_count--;
                  abfd->section_count--;
                }
                }
              else
              else
                {
 
                  if (section_number == SHN_LORESERVE)
 
                    section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
 
                  d->this_idx = section_number++;
                  d->this_idx = section_number++;
                }
                }
            }
            }
        }
        }
    }
 
 
 
  for (sec = abfd->sections; sec; sec = sec->next)
  for (sec = abfd->sections; sec; sec = sec->next)
    {
    {
      d = elf_section_data (sec);
      d = elf_section_data (sec);
 
 
      if (d->this_hdr.sh_type != SHT_GROUP)
      if (d->this_hdr.sh_type != SHT_GROUP)
        {
 
          if (section_number == SHN_LORESERVE)
 
            section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
 
          d->this_idx = section_number++;
          d->this_idx = section_number++;
        }
 
      _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name);
      _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name);
      if ((sec->flags & SEC_RELOC) == 0)
      if ((sec->flags & SEC_RELOC) == 0)
        d->rel_idx = 0;
        d->rel_idx = 0;
      else
      else
        {
        {
          if (section_number == SHN_LORESERVE)
 
            section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
 
          d->rel_idx = section_number++;
          d->rel_idx = section_number++;
          _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr.sh_name);
          _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr.sh_name);
        }
        }
 
 
      if (d->rel_hdr2)
      if (d->rel_hdr2)
        {
        {
          if (section_number == SHN_LORESERVE)
 
            section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
 
          d->rel_idx2 = section_number++;
          d->rel_idx2 = section_number++;
          _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr2->sh_name);
          _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr2->sh_name);
        }
        }
      else
      else
        d->rel_idx2 = 0;
        d->rel_idx2 = 0;
    }
    }
 
 
  if (section_number == SHN_LORESERVE)
 
    section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
 
  t->shstrtab_section = section_number++;
  t->shstrtab_section = section_number++;
  _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name);
  _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name);
  elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section;
  elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section;
 
 
  if (bfd_get_symcount (abfd) > 0)
  need_symtab = (bfd_get_symcount (abfd) > 0
 
                || (link_info == NULL
 
                    && ((abfd->flags & (EXEC_P | DYNAMIC | HAS_RELOC))
 
                        == HAS_RELOC)));
 
  if (need_symtab)
    {
    {
      if (section_number == SHN_LORESERVE)
 
        section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
 
      t->symtab_section = section_number++;
      t->symtab_section = section_number++;
      _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name);
      _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name);
      if (section_number > SHN_LORESERVE - 2)
      if (section_number > ((SHN_LORESERVE - 2) & 0xFFFF))
        {
        {
          if (section_number == SHN_LORESERVE)
 
            section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
 
          t->symtab_shndx_section = section_number++;
          t->symtab_shndx_section = section_number++;
          t->symtab_shndx_hdr.sh_name
          t->symtab_shndx_hdr.sh_name
            = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
            = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
                                                  ".symtab_shndx", FALSE);
                                                  ".symtab_shndx", FALSE);
          if (t->symtab_shndx_hdr.sh_name == (unsigned int) -1)
          if (t->symtab_shndx_hdr.sh_name == (unsigned int) -1)
            return FALSE;
            return FALSE;
        }
        }
      if (section_number == SHN_LORESERVE)
 
        section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
 
      t->strtab_section = section_number++;
      t->strtab_section = section_number++;
      _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name);
      _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name);
    }
    }
 
 
  _bfd_elf_strtab_finalize (elf_shstrtab (abfd));
  _bfd_elf_strtab_finalize (elf_shstrtab (abfd));
  t->shstrtab_hdr.sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
  t->shstrtab_hdr.sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
 
 
  elf_numsections (abfd) = section_number;
  elf_numsections (abfd) = section_number;
  elf_elfheader (abfd)->e_shnum = section_number;
  elf_elfheader (abfd)->e_shnum = section_number;
  if (section_number > SHN_LORESERVE)
 
    elf_elfheader (abfd)->e_shnum -= SHN_HIRESERVE + 1 - SHN_LORESERVE;
 
 
 
  /* Set up the list of section header pointers, in agreement with the
  /* Set up the list of section header pointers, in agreement with the
     indices.  */
     indices.  */
  i_shdrp = bfd_zalloc2 (abfd, section_number, sizeof (Elf_Internal_Shdr *));
  i_shdrp = (Elf_Internal_Shdr **) bfd_zalloc2 (abfd, section_number,
 
                                                sizeof (Elf_Internal_Shdr *));
  if (i_shdrp == NULL)
  if (i_shdrp == NULL)
    return FALSE;
    return FALSE;
 
 
  i_shdrp[0] = bfd_zalloc (abfd, sizeof (Elf_Internal_Shdr));
  i_shdrp[0] = (Elf_Internal_Shdr *) bfd_zalloc (abfd,
 
                                                 sizeof (Elf_Internal_Shdr));
  if (i_shdrp[0] == NULL)
  if (i_shdrp[0] == NULL)
    {
    {
      bfd_release (abfd, i_shdrp);
      bfd_release (abfd, i_shdrp);
      return FALSE;
      return FALSE;
    }
    }
 
 
  elf_elfsections (abfd) = i_shdrp;
  elf_elfsections (abfd) = i_shdrp;
 
 
  i_shdrp[t->shstrtab_section] = &t->shstrtab_hdr;
  i_shdrp[t->shstrtab_section] = &t->shstrtab_hdr;
  if (bfd_get_symcount (abfd) > 0)
  if (need_symtab)
    {
    {
      i_shdrp[t->symtab_section] = &t->symtab_hdr;
      i_shdrp[t->symtab_section] = &t->symtab_hdr;
      if (elf_numsections (abfd) > SHN_LORESERVE)
      if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF))
        {
        {
          i_shdrp[t->symtab_shndx_section] = &t->symtab_shndx_hdr;
          i_shdrp[t->symtab_shndx_section] = &t->symtab_shndx_hdr;
          t->symtab_shndx_hdr.sh_link = t->symtab_section;
          t->symtab_shndx_hdr.sh_link = t->symtab_section;
        }
        }
      i_shdrp[t->strtab_section] = &t->strtab_hdr;
      i_shdrp[t->strtab_section] = &t->strtab_hdr;
Line 2995... Line 3016...
            {
            {
              size_t len;
              size_t len;
              char *alc;
              char *alc;
 
 
              len = strlen (sec->name);
              len = strlen (sec->name);
              alc = bfd_malloc (len - 2);
              alc = (char *) bfd_malloc (len - 2);
              if (alc == NULL)
              if (alc == NULL)
                return FALSE;
                return FALSE;
              memcpy (alc, sec->name, len - 3);
              memcpy (alc, sec->name, len - 3);
              alc[len - 3] = '\0';
              alc[len - 3] = '\0';
              s = bfd_get_section_by_name (abfd, alc);
              s = bfd_get_section_by_name (abfd, alc);
Line 3071... Line 3092...
  /* If the backend has a special mapping, use it.  */
  /* If the backend has a special mapping, use it.  */
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  if (bed->elf_backend_sym_is_global)
  if (bed->elf_backend_sym_is_global)
    return (*bed->elf_backend_sym_is_global) (abfd, sym);
    return (*bed->elf_backend_sym_is_global) (abfd, sym);
 
 
  return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
  return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0
          || bfd_is_und_section (bfd_get_section (sym))
          || bfd_is_und_section (bfd_get_section (sym))
          || bfd_is_com_section (bfd_get_section (sym)));
          || bfd_is_com_section (bfd_get_section (sym)));
}
}
 
 
/* Don't output section symbols for sections that are not going to be
/* Don't output section symbols for sections that are not going to be
   output.  Also, don't output section symbols for reloc and other
   output.  */
   special sections.  */
 
 
 
static bfd_boolean
static bfd_boolean
ignore_section_sym (bfd *abfd, asymbol *sym)
ignore_section_sym (bfd *abfd, asymbol *sym)
{
{
  return ((sym->flags & BSF_SECTION_SYM) != 0
  return ((sym->flags & BSF_SECTION_SYM) != 0
          && (sym->value != 0
          && !(sym->section->owner == abfd
              || (sym->section->owner != abfd
               || (sym->section->output_section->owner == abfd
                  && (sym->section->output_section->owner != abfd
                   && sym->section->output_offset == 0)));
                      || sym->section->output_offset != 0))));
 
}
}
 
 
static bfd_boolean
static bfd_boolean
elf_map_symbols (bfd *abfd)
elf_map_symbols (bfd *abfd)
{
{
Line 3117... Line 3136...
      if (max_index < asect->index)
      if (max_index < asect->index)
        max_index = asect->index;
        max_index = asect->index;
    }
    }
 
 
  max_index++;
  max_index++;
  sect_syms = bfd_zalloc2 (abfd, max_index, sizeof (asymbol *));
  sect_syms = (asymbol **) bfd_zalloc2 (abfd, max_index, sizeof (asymbol *));
  if (sect_syms == NULL)
  if (sect_syms == NULL)
    return FALSE;
    return FALSE;
  elf_section_syms (abfd) = sect_syms;
  elf_section_syms (abfd) = sect_syms;
  elf_num_section_syms (abfd) = max_index;
  elf_num_section_syms (abfd) = max_index;
 
 
Line 3130... Line 3149...
  for (idx = 0; idx < symcount; idx++)
  for (idx = 0; idx < symcount; idx++)
    {
    {
      asymbol *sym = syms[idx];
      asymbol *sym = syms[idx];
 
 
      if ((sym->flags & BSF_SECTION_SYM) != 0
      if ((sym->flags & BSF_SECTION_SYM) != 0
 
          && sym->value == 0
          && !ignore_section_sym (abfd, sym))
          && !ignore_section_sym (abfd, sym))
        {
        {
          asection *sec = sym->section;
          asection *sec = sym->section;
 
 
          if (sec->owner != abfd)
          if (sec->owner != abfd)
Line 3168... Line 3188...
            num_globals++;
            num_globals++;
        }
        }
    }
    }
 
 
  /* Now sort the symbols so the local symbols are first.  */
  /* Now sort the symbols so the local symbols are first.  */
  new_syms = bfd_alloc2 (abfd, num_locals + num_globals, sizeof (asymbol *));
  new_syms = (asymbol **) bfd_alloc2 (abfd, num_locals + num_globals,
 
                                      sizeof (asymbol *));
 
 
  if (new_syms == NULL)
  if (new_syms == NULL)
    return FALSE;
    return FALSE;
 
 
  for (idx = 0; idx < symcount; idx++)
  for (idx = 0; idx < symcount; idx++)
Line 3228... Line 3249...
file_ptr
file_ptr
_bfd_elf_assign_file_position_for_section (Elf_Internal_Shdr *i_shdrp,
_bfd_elf_assign_file_position_for_section (Elf_Internal_Shdr *i_shdrp,
                                           file_ptr offset,
                                           file_ptr offset,
                                           bfd_boolean align)
                                           bfd_boolean align)
{
{
  if (align)
  if (align && i_shdrp->sh_addralign > 1)
    {
    offset = BFD_ALIGN (offset, i_shdrp->sh_addralign);
      unsigned int al;
 
 
 
      al = i_shdrp->sh_addralign;
 
      if (al > 1)
 
        offset = BFD_ALIGN (offset, al);
 
    }
 
  i_shdrp->sh_offset = offset;
  i_shdrp->sh_offset = offset;
  if (i_shdrp->bfd_section != NULL)
  if (i_shdrp->bfd_section != NULL)
    i_shdrp->bfd_section->filepos = offset;
    i_shdrp->bfd_section->filepos = offset;
  if (i_shdrp->sh_type != SHT_NOBITS)
  if (i_shdrp->sh_type != SHT_NOBITS)
    offset += i_shdrp->sh_size;
    offset += i_shdrp->sh_size;
Line 3256... Line 3271...
{
{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  bfd_boolean failed;
  bfd_boolean failed;
  struct bfd_strtab_hash *strtab = NULL;
  struct bfd_strtab_hash *strtab = NULL;
  Elf_Internal_Shdr *shstrtab_hdr;
  Elf_Internal_Shdr *shstrtab_hdr;
 
  bfd_boolean need_symtab;
 
 
  if (abfd->output_has_begun)
  if (abfd->output_has_begun)
    return TRUE;
    return TRUE;
 
 
  /* Do any elf backend specific processing first.  */
  /* Do any elf backend specific processing first.  */
Line 3280... Line 3296...
 
 
  if (!assign_section_numbers (abfd, link_info))
  if (!assign_section_numbers (abfd, link_info))
    return FALSE;
    return FALSE;
 
 
  /* The backend linker builds symbol table information itself.  */
  /* The backend linker builds symbol table information itself.  */
  if (link_info == NULL && bfd_get_symcount (abfd) > 0)
  need_symtab = (link_info == NULL
 
                 && (bfd_get_symcount (abfd) > 0
 
                     || ((abfd->flags & (EXEC_P | DYNAMIC | HAS_RELOC))
 
                         == HAS_RELOC)));
 
  if (need_symtab)
    {
    {
      /* Non-zero if doing a relocatable link.  */
      /* Non-zero if doing a relocatable link.  */
      int relocatable_p = ! (abfd->flags & (EXEC_P | DYNAMIC));
      int relocatable_p = ! (abfd->flags & (EXEC_P | DYNAMIC));
 
 
      if (! swap_out_syms (abfd, &strtab, relocatable_p))
      if (! swap_out_syms (abfd, &strtab, relocatable_p))
Line 3311... Line 3331...
  shstrtab_hdr->sh_addralign = 1;
  shstrtab_hdr->sh_addralign = 1;
 
 
  if (!assign_file_positions_except_relocs (abfd, link_info))
  if (!assign_file_positions_except_relocs (abfd, link_info))
    return FALSE;
    return FALSE;
 
 
  if (link_info == NULL && bfd_get_symcount (abfd) > 0)
  if (need_symtab)
    {
    {
      file_ptr off;
      file_ptr off;
      Elf_Internal_Shdr *hdr;
      Elf_Internal_Shdr *hdr;
 
 
      off = elf_tdata (abfd)->next_file_pos;
      off = elf_tdata (abfd)->next_file_pos;
Line 3373... Line 3393...
    {
    {
      /* We need a PT_DYNAMIC segment.  */
      /* We need a PT_DYNAMIC segment.  */
      ++segs;
      ++segs;
    }
    }
 
 
  if (info->relro)
  if (info != NULL && info->relro)
    {
    {
      /* We need a PT_GNU_RELRO segment.  */
      /* We need a PT_GNU_RELRO segment.  */
      ++segs;
      ++segs;
    }
    }
 
 
Line 3478... Line 3498...
  asection **hdrpp;
  asection **hdrpp;
  bfd_size_type amt;
  bfd_size_type amt;
 
 
  amt = sizeof (struct elf_segment_map);
  amt = sizeof (struct elf_segment_map);
  amt += (to - from - 1) * sizeof (asection *);
  amt += (to - from - 1) * sizeof (asection *);
  m = bfd_zalloc (abfd, amt);
  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
  if (m == NULL)
  if (m == NULL)
    return NULL;
    return NULL;
  m->next = NULL;
  m->next = NULL;
  m->p_type = PT_LOAD;
  m->p_type = PT_LOAD;
  for (i = from, hdrpp = sections + from; i < to; i++, hdrpp++)
  for (i = from, hdrpp = sections + from; i < to; i++, hdrpp++)
Line 3505... Line 3525...
struct elf_segment_map *
struct elf_segment_map *
_bfd_elf_make_dynamic_segment (bfd *abfd, asection *dynsec)
_bfd_elf_make_dynamic_segment (bfd *abfd, asection *dynsec)
{
{
  struct elf_segment_map *m;
  struct elf_segment_map *m;
 
 
  m = bfd_zalloc (abfd, sizeof (struct elf_segment_map));
  m = (struct elf_segment_map *) bfd_zalloc (abfd,
 
                                             sizeof (struct elf_segment_map));
  if (m == NULL)
  if (m == NULL)
    return NULL;
    return NULL;
  m->next = NULL;
  m->next = NULL;
  m->p_type = PT_DYNAMIC;
  m->p_type = PT_DYNAMIC;
  m->count = 1;
  m->count = 1;
Line 3596... Line 3617...
      asection *dynsec, *eh_frame_hdr;
      asection *dynsec, *eh_frame_hdr;
      bfd_size_type amt;
      bfd_size_type amt;
 
 
      /* Select the allocated sections, and sort them.  */
      /* Select the allocated sections, and sort them.  */
 
 
      sections = bfd_malloc2 (bfd_count_sections (abfd), sizeof (asection *));
      sections = (asection **) bfd_malloc2 (bfd_count_sections (abfd),
 
                                            sizeof (asection *));
      if (sections == NULL)
      if (sections == NULL)
        goto error_return;
        goto error_return;
 
 
      i = 0;
      i = 0;
      for (s = abfd->sections; s != NULL; s = s->next)
      for (s = abfd->sections; s != NULL; s = s->next)
Line 3626... Line 3648...
         section.  */
         section.  */
      s = bfd_get_section_by_name (abfd, ".interp");
      s = bfd_get_section_by_name (abfd, ".interp");
      if (s != NULL && (s->flags & SEC_LOAD) != 0)
      if (s != NULL && (s->flags & SEC_LOAD) != 0)
        {
        {
          amt = sizeof (struct elf_segment_map);
          amt = sizeof (struct elf_segment_map);
          m = bfd_zalloc (abfd, amt);
          m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
          if (m == NULL)
          if (m == NULL)
            goto error_return;
            goto error_return;
          m->next = NULL;
          m->next = NULL;
          m->p_type = PT_PHDR;
          m->p_type = PT_PHDR;
          /* FIXME: UnixWare and Solaris set PF_X, Irix 5 does not.  */
          /* FIXME: UnixWare and Solaris set PF_X, Irix 5 does not.  */
Line 3640... Line 3662...
 
 
          *pm = m;
          *pm = m;
          pm = &m->next;
          pm = &m->next;
 
 
          amt = sizeof (struct elf_segment_map);
          amt = sizeof (struct elf_segment_map);
          m = bfd_zalloc (abfd, amt);
          m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
          if (m == NULL)
          if (m == NULL)
            goto error_return;
            goto error_return;
          m->next = NULL;
          m->next = NULL;
          m->p_type = PT_INTERP;
          m->p_type = PT_INTERP;
          m->count = 1;
          m->count = 1;
Line 3704... Line 3726...
              /* If this section has a different relation between the
              /* If this section has a different relation between the
                 virtual address and the load address, then we need a new
                 virtual address and the load address, then we need a new
                 segment.  */
                 segment.  */
              new_segment = TRUE;
              new_segment = TRUE;
            }
            }
          else if (BFD_ALIGN (last_hdr->lma + last_size, maxpagesize)
          /* In the next test we have to be careful when last_hdr->lma is close
                   < BFD_ALIGN (hdr->lma, maxpagesize))
             to the end of the address space.  If the aligned address wraps
 
             around to the start of the address space, then there are no more
 
             pages left in memory and it is OK to assume that the current
 
             section can be included in the current segment.  */
 
          else if ((BFD_ALIGN (last_hdr->lma + last_size, maxpagesize) + maxpagesize
 
                    > last_hdr->lma)
 
                   && (BFD_ALIGN (last_hdr->lma + last_size, maxpagesize) + maxpagesize
 
                       <= hdr->lma))
            {
            {
              /* If putting this section in this segment would force us to
              /* If putting this section in this segment would force us to
                 skip a page in the segment, then we need a new segment.  */
                 skip a page in the segment, then we need a new segment.  */
              new_segment = TRUE;
              new_segment = TRUE;
            }
            }
Line 3748... Line 3777...
              /* Otherwise, we can use the same segment.  */
              /* Otherwise, we can use the same segment.  */
              new_segment = FALSE;
              new_segment = FALSE;
            }
            }
 
 
          /* Allow interested parties a chance to override our decision.  */
          /* Allow interested parties a chance to override our decision.  */
          if (last_hdr && info->callbacks->override_segment_assignment)
          if (last_hdr != NULL
            new_segment = info->callbacks->override_segment_assignment (info, abfd, hdr, last_hdr, new_segment);
              && info != NULL
 
              && info->callbacks->override_segment_assignment != NULL)
 
            new_segment
 
              = info->callbacks->override_segment_assignment (info, abfd, hdr,
 
                                                              last_hdr,
 
                                                              new_segment);
 
 
          if (! new_segment)
          if (! new_segment)
            {
            {
              if ((hdr->flags & SEC_READONLY) == 0)
              if ((hdr->flags & SEC_READONLY) == 0)
                writable = TRUE;
                writable = TRUE;
Line 3838... Line 3872...
                      count++;
                      count++;
                    else
                    else
                      break;
                      break;
                  }
                  }
              amt += (count - 1) * sizeof (asection *);
              amt += (count - 1) * sizeof (asection *);
              m = bfd_zalloc (abfd, amt);
              m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
              if (m == NULL)
              if (m == NULL)
                goto error_return;
                goto error_return;
              m->next = NULL;
              m->next = NULL;
              m->p_type = PT_NOTE;
              m->p_type = PT_NOTE;
              m->count = count;
              m->count = count;
Line 3870... Line 3904...
        {
        {
          int i;
          int i;
 
 
          amt = sizeof (struct elf_segment_map);
          amt = sizeof (struct elf_segment_map);
          amt += (tls_count - 1) * sizeof (asection *);
          amt += (tls_count - 1) * sizeof (asection *);
          m = bfd_zalloc (abfd, amt);
          m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
          if (m == NULL)
          if (m == NULL)
            goto error_return;
            goto error_return;
          m->next = NULL;
          m->next = NULL;
          m->p_type = PT_TLS;
          m->p_type = PT_TLS;
          m->count = tls_count;
          m->count = tls_count;
Line 3897... Line 3931...
      eh_frame_hdr = elf_tdata (abfd)->eh_frame_hdr;
      eh_frame_hdr = elf_tdata (abfd)->eh_frame_hdr;
      if (eh_frame_hdr != NULL
      if (eh_frame_hdr != NULL
          && (eh_frame_hdr->output_section->flags & SEC_LOAD) != 0)
          && (eh_frame_hdr->output_section->flags & SEC_LOAD) != 0)
        {
        {
          amt = sizeof (struct elf_segment_map);
          amt = sizeof (struct elf_segment_map);
          m = bfd_zalloc (abfd, amt);
          m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
          if (m == NULL)
          if (m == NULL)
            goto error_return;
            goto error_return;
          m->next = NULL;
          m->next = NULL;
          m->p_type = PT_GNU_EH_FRAME;
          m->p_type = PT_GNU_EH_FRAME;
          m->count = 1;
          m->count = 1;
Line 3912... Line 3946...
        }
        }
 
 
      if (elf_tdata (abfd)->stack_flags)
      if (elf_tdata (abfd)->stack_flags)
        {
        {
          amt = sizeof (struct elf_segment_map);
          amt = sizeof (struct elf_segment_map);
          m = bfd_zalloc (abfd, amt);
          m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
          if (m == NULL)
          if (m == NULL)
            goto error_return;
            goto error_return;
          m->next = NULL;
          m->next = NULL;
          m->p_type = PT_GNU_STACK;
          m->p_type = PT_GNU_STACK;
          m->p_flags = elf_tdata (abfd)->stack_flags;
          m->p_flags = elf_tdata (abfd)->stack_flags;
Line 3924... Line 3958...
 
 
          *pm = m;
          *pm = m;
          pm = &m->next;
          pm = &m->next;
        }
        }
 
 
      if (info->relro)
      if (info != NULL && info->relro)
        {
        {
          for (m = mfirst; m != NULL; m = m->next)
          for (m = mfirst; m != NULL; m = m->next)
            {
            {
              if (m->p_type == PT_LOAD)
              if (m->p_type == PT_LOAD)
                {
                {
Line 3945... Line 3979...
 
 
          /* Make a PT_GNU_RELRO segment only when it isn't empty.  */
          /* Make a PT_GNU_RELRO segment only when it isn't empty.  */
          if (m != NULL)
          if (m != NULL)
            {
            {
              amt = sizeof (struct elf_segment_map);
              amt = sizeof (struct elf_segment_map);
              m = bfd_zalloc (abfd, amt);
              m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
              if (m == NULL)
              if (m == NULL)
                goto error_return;
                goto error_return;
              m->next = NULL;
              m->next = NULL;
              m->p_type = PT_GNU_RELRO;
              m->p_type = PT_GNU_RELRO;
              m->p_flags = PF_R;
              m->p_flags = PF_R;
Line 4106... Line 4140...
  Elf_Internal_Phdr *p;
  Elf_Internal_Phdr *p;
  file_ptr off;
  file_ptr off;
  bfd_size_type maxpagesize;
  bfd_size_type maxpagesize;
  unsigned int alloc;
  unsigned int alloc;
  unsigned int i, j;
  unsigned int i, j;
 
  bfd_vma header_pad = 0;
 
 
  if (link_info == NULL
  if (link_info == NULL
      && !elf_modify_segment_map (abfd, link_info, FALSE))
      && !_bfd_elf_map_sections_to_segments (abfd, link_info))
    return FALSE;
    return FALSE;
 
 
  alloc = 0;
  alloc = 0;
  for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
  for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
 
    {
    ++alloc;
    ++alloc;
 
      if (m->header_size)
 
        header_pad = m->header_size;
 
    }
 
 
  elf_elfheader (abfd)->e_phoff = bed->s->sizeof_ehdr;
  elf_elfheader (abfd)->e_phoff = bed->s->sizeof_ehdr;
  elf_elfheader (abfd)->e_phentsize = bed->s->sizeof_phdr;
  elf_elfheader (abfd)->e_phentsize = bed->s->sizeof_phdr;
  elf_elfheader (abfd)->e_phnum = alloc;
  elf_elfheader (abfd)->e_phnum = alloc;
 
 
Line 4131... Line 4170...
    {
    {
      elf_tdata (abfd)->next_file_pos = bed->s->sizeof_ehdr;
      elf_tdata (abfd)->next_file_pos = bed->s->sizeof_ehdr;
      return TRUE;
      return TRUE;
    }
    }
 
 
  phdrs = bfd_alloc2 (abfd, alloc, sizeof (Elf_Internal_Phdr));
  /* We're writing the size in elf_tdata (abfd)->program_header_size,
 
     see assign_file_positions_except_relocs, so make sure we have
 
     that amount allocated, with trailing space cleared.
 
     The variable alloc contains the computed need, while elf_tdata
 
     (abfd)->program_header_size contains the size used for the
 
     layout.
 
     See ld/emultempl/elf-generic.em:gld${EMULATION_NAME}_map_segments
 
     where the layout is forced to according to a larger size in the
 
     last iterations for the testcase ld-elf/header.  */
 
  BFD_ASSERT (elf_tdata (abfd)->program_header_size % bed->s->sizeof_phdr
 
              == 0);
 
  phdrs = (Elf_Internal_Phdr *)
 
     bfd_zalloc2 (abfd,
 
                  (elf_tdata (abfd)->program_header_size / bed->s->sizeof_phdr),
 
                  sizeof (Elf_Internal_Phdr));
  elf_tdata (abfd)->phdr = phdrs;
  elf_tdata (abfd)->phdr = phdrs;
  if (phdrs == NULL)
  if (phdrs == NULL)
    return FALSE;
    return FALSE;
 
 
  maxpagesize = 1;
  maxpagesize = 1;
  if ((abfd->flags & D_PAGED) != 0)
  if ((abfd->flags & D_PAGED) != 0)
    maxpagesize = bed->maxpagesize;
    maxpagesize = bed->maxpagesize;
 
 
  off = bed->s->sizeof_ehdr;
  off = bed->s->sizeof_ehdr;
  off += alloc * bed->s->sizeof_phdr;
  off += alloc * bed->s->sizeof_phdr;
 
  if (header_pad < (bfd_vma) off)
 
    header_pad = 0;
 
  else
 
    header_pad -= off;
 
  off += header_pad;
 
 
  for (m = elf_tdata (abfd)->segment_map, p = phdrs, j = 0;
  for (m = elf_tdata (abfd)->segment_map, p = phdrs, j = 0;
       m != NULL;
       m != NULL;
       m = m->next, p++, j++)
       m = m->next, p++, j++)
    {
    {
Line 4238... Line 4296...
                 it must be SHT_NOBITS regardless of what we've
                 it must be SHT_NOBITS regardless of what we've
                 set via struct bfd_elf_special_section.  */
                 set via struct bfd_elf_special_section.  */
              elf_section_type (m->sections[i]) = SHT_NOBITS;
              elf_section_type (m->sections[i]) = SHT_NOBITS;
 
 
          /* Find out whether this segment contains any loadable
          /* Find out whether this segment contains any loadable
             sections.  If the first section isn't loadable, the same
             sections.  */
             holds for any other sections.  */
 
          i = 0;
 
          while (elf_section_type (m->sections[i]) == SHT_NOBITS)
 
            {
 
              /* If a segment starts with .tbss, we need to look
 
                 at the next section to decide whether the segment
 
                 has any loadable sections.  */
 
              if ((elf_section_flags (m->sections[i]) & SHF_TLS) == 0
 
                  || ++i >= m->count)
 
                {
 
                  no_contents = TRUE;
                  no_contents = TRUE;
 
          for (i = 0; i < m->count; i++)
 
            if (elf_section_type (m->sections[i]) != SHT_NOBITS)
 
              {
 
                no_contents = FALSE;
                  break;
                  break;
                }
                }
            }
 
 
 
          off_adjust = vma_page_aligned_bias (m->sections[0]->vma, off, align);
          off_adjust = vma_page_aligned_bias (m->sections[0]->vma, off, align);
          off += off_adjust;
          off += off_adjust;
          if (no_contents)
          if (no_contents)
            {
            {
Line 4336... Line 4387...
                }
                }
            }
            }
 
 
          p->p_filesz += alloc * bed->s->sizeof_phdr;
          p->p_filesz += alloc * bed->s->sizeof_phdr;
          p->p_memsz += alloc * bed->s->sizeof_phdr;
          p->p_memsz += alloc * bed->s->sizeof_phdr;
 
          if (m->count)
 
            {
 
              p->p_filesz += header_pad;
 
              p->p_memsz += header_pad;
 
            }
        }
        }
 
 
      if (p->p_type == PT_LOAD
      if (p->p_type == PT_LOAD
          || (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core))
          || (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core))
        {
        {
Line 4369... Line 4425...
 
 
          sec = *secpp;
          sec = *secpp;
          this_hdr = &elf_section_data (sec)->this_hdr;
          this_hdr = &elf_section_data (sec)->this_hdr;
          align = (bfd_size_type) 1 << bfd_get_section_alignment (abfd, sec);
          align = (bfd_size_type) 1 << bfd_get_section_alignment (abfd, sec);
 
 
          if (p->p_type == PT_LOAD
          if ((p->p_type == PT_LOAD
              || p->p_type == PT_TLS)
              || p->p_type == PT_TLS)
            {
              && (this_hdr->sh_type != SHT_NOBITS
              bfd_signed_vma adjust = sec->lma - (p->p_paddr + p->p_memsz);
 
 
 
              if (this_hdr->sh_type != SHT_NOBITS
 
                  || ((this_hdr->sh_flags & SHF_ALLOC) != 0
                  || ((this_hdr->sh_flags & SHF_ALLOC) != 0
                      && ((this_hdr->sh_flags & SHF_TLS) == 0
                      && ((this_hdr->sh_flags & SHF_TLS) == 0
                          || p->p_type == PT_TLS)))
                          || p->p_type == PT_TLS))))
                {
                {
 
              bfd_signed_vma adjust = sec->vma - (p->p_vaddr + p->p_memsz);
 
 
                  if (adjust < 0)
                  if (adjust < 0)
                    {
                    {
                      (*_bfd_error_handler)
                      (*_bfd_error_handler)
                        (_("%B: section %A lma 0x%lx overlaps previous sections"),
                    (_("%B: section %A vma 0x%lx overlaps previous sections"),
                         abfd, sec, (unsigned long) sec->lma);
                     abfd, sec, (unsigned long) sec->vma);
                      adjust = 0;
                      adjust = 0;
                    }
                    }
                  p->p_memsz += adjust;
                  p->p_memsz += adjust;
 
 
                  if (this_hdr->sh_type != SHT_NOBITS)
                  if (this_hdr->sh_type != SHT_NOBITS)
                    {
                    {
                      off += adjust;
                      off += adjust;
                      p->p_filesz += adjust;
                      p->p_filesz += adjust;
                    }
                    }
                }
                }
            }
 
 
 
          if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)
          if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)
            {
            {
              /* The section at i == 0 is the one that actually contains
              /* The section at i == 0 is the one that actually contains
                 everything.  */
                 everything.  */
Line 4551... Line 4605...
               || hdr == i_shdrpp[tdata->symtab_shndx_section]
               || hdr == i_shdrpp[tdata->symtab_shndx_section]
               || hdr == i_shdrpp[tdata->strtab_section])
               || hdr == i_shdrpp[tdata->strtab_section])
        hdr->sh_offset = -1;
        hdr->sh_offset = -1;
      else
      else
        off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
        off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
 
 
      if (i == SHN_LORESERVE - 1)
 
        {
 
          i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
 
          hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
 
        }
 
    }
    }
 
 
  /* Now that we have set the section file positions, we can set up
  /* Now that we have set the section file positions, we can set up
     the file positions for the non PT_LOAD segments.  */
     the file positions for the non PT_LOAD segments.  */
  count = 0;
  count = 0;
Line 4596... Line 4644...
 
 
  for (m = elf_tdata (abfd)->segment_map, p = phdrs;
  for (m = elf_tdata (abfd)->segment_map, p = phdrs;
       m != NULL;
       m != NULL;
       m = m->next, p++)
       m = m->next, p++)
    {
    {
      if (m->count != 0)
      if (p->p_type == PT_GNU_RELRO)
        {
 
          if (p->p_type != PT_LOAD
 
              && (p->p_type != PT_NOTE
 
                  || bfd_get_format (abfd) != bfd_core))
 
            {
            {
              Elf_Internal_Shdr *hdr;
          const Elf_Internal_Phdr *lp;
              asection *sect;
 
 
 
              BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs);
              BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs);
 
 
              sect = m->sections[m->count - 1];
          if (link_info != NULL)
              hdr = &elf_section_data (sect)->this_hdr;
 
              p->p_filesz = sect->filepos - m->sections[0]->filepos;
 
              if (hdr->sh_type != SHT_NOBITS)
 
                p->p_filesz += hdr->sh_size;
 
 
 
              if (p->p_type == PT_GNU_RELRO)
 
                {
                {
                  /* When we get here, we are copying executable
              /* During linking the range of the RELRO segment is passed
                     or shared library. But we need to use the same
                 in link_info.  */
                     linker logic.  */
              for (lp = phdrs; lp < phdrs + count; ++lp)
                  Elf_Internal_Phdr *lp;
                {
 
                  if (lp->p_type == PT_LOAD
 
                      && lp->p_vaddr >= link_info->relro_start
 
                      && lp->p_vaddr < link_info->relro_end
 
                      && lp->p_vaddr + lp->p_filesz >= link_info->relro_end)
 
                    break;
 
                }
 
            }
 
          else
 
            {
 
              /* Otherwise we are copying an executable or shared
 
                 library, but we need to use the same linker logic.  */
                  for (lp = phdrs; lp < phdrs + count; ++lp)
                  for (lp = phdrs; lp < phdrs + count; ++lp)
                    {
                    {
                      if (lp->p_type == PT_LOAD
                      if (lp->p_type == PT_LOAD
                          && lp->p_paddr == p->p_paddr)
                          && lp->p_paddr == p->p_paddr)
                        break;
                        break;
                    }
                    }
 
            }
 
 
                  if (lp < phdrs + count)
                  if (lp < phdrs + count)
                    {
                    {
                      /* We should use p_size if it is valid since it
              p->p_vaddr = lp->p_vaddr;
                         may contain the first few bytes of the next
              p->p_paddr = lp->p_paddr;
                         SEC_ALLOC section.  */
              p->p_offset = lp->p_offset;
                      if (m->p_size_valid)
              if (link_info != NULL)
 
                p->p_filesz = link_info->relro_end - lp->p_vaddr;
 
              else if (m->p_size_valid)
                        p->p_filesz = m->p_size;
                        p->p_filesz = m->p_size;
                      else
                      else
                        abort ();
                        abort ();
                      p->p_vaddr = lp->p_vaddr;
 
                      p->p_offset = lp->p_offset;
 
                      p->p_memsz = p->p_filesz;
                      p->p_memsz = p->p_filesz;
                      p->p_align = 1;
                      p->p_align = 1;
 
              p->p_flags = (lp->p_flags & ~PF_W);
                    }
                    }
                  else
                  else
                    abort ();
            {
 
              memset (p, 0, sizeof *p);
 
              p->p_type = PT_NULL;
                }
                }
              else
        }
 
      else if (m->count != 0)
 
        {
 
          if (p->p_type != PT_LOAD
 
              && (p->p_type != PT_NOTE
 
                  || bfd_get_format (abfd) != bfd_core))
 
            {
 
              Elf_Internal_Shdr *hdr;
 
              asection *sect;
 
 
 
              BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs);
 
 
 
              sect = m->sections[m->count - 1];
 
              hdr = &elf_section_data (sect)->this_hdr;
 
              p->p_filesz = sect->filepos - m->sections[0]->filepos;
 
              if (hdr->sh_type != SHT_NOBITS)
 
                p->p_filesz += hdr->sh_size;
                p->p_offset = m->sections[0]->filepos;
                p->p_offset = m->sections[0]->filepos;
            }
            }
        }
        }
      else
      else if (m->includes_filehdr)
        {
 
          if (m->includes_filehdr)
 
            {
            {
              p->p_vaddr = filehdr_vaddr;
              p->p_vaddr = filehdr_vaddr;
              if (! m->p_paddr_valid)
              if (! m->p_paddr_valid)
                p->p_paddr = filehdr_paddr;
                p->p_paddr = filehdr_paddr;
            }
            }
Line 4662... Line 4727...
            {
            {
              p->p_vaddr = phdrs_vaddr;
              p->p_vaddr = phdrs_vaddr;
              if (! m->p_paddr_valid)
              if (! m->p_paddr_valid)
                p->p_paddr = phdrs_paddr;
                p->p_paddr = phdrs_paddr;
            }
            }
          else if (p->p_type == PT_GNU_RELRO)
 
            {
 
              Elf_Internal_Phdr *lp;
 
 
 
              for (lp = phdrs; lp < phdrs + count; ++lp)
 
                {
 
                  if (lp->p_type == PT_LOAD
 
                      && lp->p_vaddr <= link_info->relro_end
 
                      && lp->p_vaddr >= link_info->relro_start
 
                      && (lp->p_vaddr + lp->p_filesz
 
                          >= link_info->relro_end))
 
                    break;
 
                }
 
 
 
              if (lp < phdrs + count
 
                  && link_info->relro_end > lp->p_vaddr)
 
                {
 
                  p->p_vaddr = lp->p_vaddr;
 
                  p->p_paddr = lp->p_paddr;
 
                  p->p_offset = lp->p_offset;
 
                  p->p_filesz = link_info->relro_end - lp->p_vaddr;
 
                  p->p_memsz = p->p_filesz;
 
                  p->p_align = 1;
 
                  p->p_flags = (lp->p_flags & ~PF_W);
 
                }
 
              else
 
                {
 
                  memset (p, 0, sizeof *p);
 
                  p->p_type = PT_NULL;
 
                }
 
            }
 
        }
 
    }
    }
 
 
  elf_tdata (abfd)->next_file_pos = off;
  elf_tdata (abfd)->next_file_pos = off;
 
 
  return TRUE;
  return TRUE;
Line 4753... Line 4786...
            {
            {
              hdr->sh_offset = -1;
              hdr->sh_offset = -1;
            }
            }
          else
          else
            off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
            off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
 
 
          if (i == SHN_LORESERVE - 1)
 
            {
 
              i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
 
              hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
 
            }
 
        }
        }
    }
    }
  else
  else
    {
    {
      unsigned int alloc;
      unsigned int alloc;
Line 4804... Line 4831...
static bfd_boolean
static bfd_boolean
prep_headers (bfd *abfd)
prep_headers (bfd *abfd)
{
{
  Elf_Internal_Ehdr *i_ehdrp;   /* Elf file header, internal form */
  Elf_Internal_Ehdr *i_ehdrp;   /* Elf file header, internal form */
  Elf_Internal_Phdr *i_phdrp = 0; /* Program header table, internal form */
  Elf_Internal_Phdr *i_phdrp = 0; /* Program header table, internal form */
  Elf_Internal_Shdr **i_shdrp;  /* Section header table, internal form */
 
  struct elf_strtab_hash *shstrtab;
  struct elf_strtab_hash *shstrtab;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
 
  i_ehdrp = elf_elfheader (abfd);
  i_ehdrp = elf_elfheader (abfd);
  i_shdrp = elf_elfsections (abfd);
 
 
 
  shstrtab = _bfd_elf_strtab_init ();
  shstrtab = _bfd_elf_strtab_init ();
  if (shstrtab == NULL)
  if (shstrtab == NULL)
    return FALSE;
    return FALSE;
 
 
Line 4954... Line 4979...
 
 
          if (bfd_seek (abfd, i_shdrp[count]->sh_offset, SEEK_SET) != 0
          if (bfd_seek (abfd, i_shdrp[count]->sh_offset, SEEK_SET) != 0
              || bfd_bwrite (i_shdrp[count]->contents, amt, abfd) != amt)
              || bfd_bwrite (i_shdrp[count]->contents, amt, abfd) != amt)
            return FALSE;
            return FALSE;
        }
        }
      if (count == SHN_LORESERVE - 1)
 
        count += SHN_HIRESERVE + 1 - SHN_LORESERVE;
 
    }
    }
 
 
  /* Write out the section header names.  */
  /* Write out the section header names.  */
  if (elf_shstrtab (abfd) != NULL
  if (elf_shstrtab (abfd) != NULL
      && (bfd_seek (abfd, elf_tdata (abfd)->shstrtab_hdr.sh_offset, SEEK_SET) != 0
      && (bfd_seek (abfd, elf_tdata (abfd)->shstrtab_hdr.sh_offset, SEEK_SET) != 0
Line 4987... Line 5010...
  return _bfd_elf_write_object_contents (abfd);
  return _bfd_elf_write_object_contents (abfd);
}
}
 
 
/* Given a section, search the header to find them.  */
/* Given a section, search the header to find them.  */
 
 
int
unsigned int
_bfd_elf_section_from_bfd_section (bfd *abfd, struct bfd_section *asect)
_bfd_elf_section_from_bfd_section (bfd *abfd, struct bfd_section *asect)
{
{
  const struct elf_backend_data *bed;
  const struct elf_backend_data *bed;
  int index;
  unsigned int index;
 
 
  if (elf_section_data (asect) != NULL
  if (elf_section_data (asect) != NULL
      && elf_section_data (asect)->this_idx != 0)
      && elf_section_data (asect)->this_idx != 0)
    return elf_section_data (asect)->this_idx;
    return elf_section_data (asect)->this_idx;
 
 
Line 5004... Line 5027...
  else if (bfd_is_com_section (asect))
  else if (bfd_is_com_section (asect))
    index = SHN_COMMON;
    index = SHN_COMMON;
  else if (bfd_is_und_section (asect))
  else if (bfd_is_und_section (asect))
    index = SHN_UNDEF;
    index = SHN_UNDEF;
  else
  else
    index = -1;
    index = SHN_BAD;
 
 
  bed = get_elf_backend_data (abfd);
  bed = get_elf_backend_data (abfd);
  if (bed->elf_backend_section_from_bfd_section)
  if (bed->elf_backend_section_from_bfd_section)
    {
    {
      int retval = index;
      int retval = index;
 
 
      if ((*bed->elf_backend_section_from_bfd_section) (abfd, asect, &retval))
      if ((*bed->elf_backend_section_from_bfd_section) (abfd, asect, &retval))
        return retval;
        return retval;
    }
    }
 
 
  if (index == -1)
  if (index == SHN_BAD)
    bfd_set_error (bfd_error_nonrepresentable_section);
    bfd_set_error (bfd_error_nonrepresentable_section);
 
 
  return index;
  return index;
}
}
 
 
Line 5092... Line 5115...
  Elf_Internal_Phdr *segment;
  Elf_Internal_Phdr *segment;
  asection *section;
  asection *section;
  unsigned int i;
  unsigned int i;
  unsigned int num_segments;
  unsigned int num_segments;
  bfd_boolean phdr_included = FALSE;
  bfd_boolean phdr_included = FALSE;
 
  bfd_boolean p_paddr_valid;
  bfd_vma maxpagesize;
  bfd_vma maxpagesize;
  struct elf_segment_map *phdr_adjust_seg = NULL;
  struct elf_segment_map *phdr_adjust_seg = NULL;
  unsigned int phdr_adjust_num = 0;
  unsigned int phdr_adjust_num = 0;
  const struct elf_backend_data *bed;
  const struct elf_backend_data *bed;
 
 
Line 5220... Line 5244...
 
 
  /* Initialise the segment mark field.  */
  /* Initialise the segment mark field.  */
  for (section = ibfd->sections; section != NULL; section = section->next)
  for (section = ibfd->sections; section != NULL; section = section->next)
    section->segment_mark = FALSE;
    section->segment_mark = FALSE;
 
 
 
  /* The Solaris linker creates program headers in which all the
 
     p_paddr fields are zero.  When we try to objcopy or strip such a
 
     file, we get confused.  Check for this case, and if we find it
 
     don't set the p_paddr_valid fields.  */
 
  p_paddr_valid = FALSE;
 
  for (i = 0, segment = elf_tdata (ibfd)->phdr;
 
       i < num_segments;
 
       i++, segment++)
 
    if (segment->p_paddr != 0)
 
      {
 
        p_paddr_valid = TRUE;
 
        break;
 
      }
 
 
  /* Scan through the segments specified in the program header
  /* Scan through the segments specified in the program header
     of the input BFD.  For this first scan we look for overlaps
     of the input BFD.  For this first scan we look for overlaps
     in the loadable segments.  These can be created by weird
     in the loadable segments.  These can be created by weird
     parameters to objcopy.  Also, fix some solaris weirdness.  */
     parameters to objcopy.  Also, fix some solaris weirdness.  */
  for (i = 0, segment = elf_tdata (ibfd)->phdr;
  for (i = 0, segment = elf_tdata (ibfd)->phdr;
Line 5338... Line 5376...
 
 
      /* Allocate a segment map big enough to contain
      /* Allocate a segment map big enough to contain
         all of the sections we have selected.  */
         all of the sections we have selected.  */
      amt = sizeof (struct elf_segment_map);
      amt = sizeof (struct elf_segment_map);
      amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
      amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
      map = bfd_zalloc (obfd, amt);
      map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
      if (map == NULL)
      if (map == NULL)
        return FALSE;
        return FALSE;
 
 
      /* Initialise the fields of the segment map.  Default to
      /* Initialise the fields of the segment map.  Default to
         using the physical address of the segment in the input BFD.  */
         using the physical address of the segment in the input BFD.  */
Line 5355... Line 5393...
         no need to preserve segment physical address in the corresponding
         no need to preserve segment physical address in the corresponding
         output segment.  */
         output segment.  */
      if (!first_section || first_section->output_section != NULL)
      if (!first_section || first_section->output_section != NULL)
        {
        {
          map->p_paddr = segment->p_paddr;
          map->p_paddr = segment->p_paddr;
          map->p_paddr_valid = 1;
          map->p_paddr_valid = p_paddr_valid;
        }
        }
 
 
      /* Determine if this segment contains the ELF file header
      /* Determine if this segment contains the ELF file header
         and if it contains the program headers themselves.  */
         and if it contains the program headers themselves.  */
      map->includes_filehdr = (segment->p_offset == 0
      map->includes_filehdr = (segment->p_offset == 0
Line 5422... Line 5460...
 
 
         In order to save time, we allocate an array to hold the section
         In order to save time, we allocate an array to hold the section
         pointers that we are interested in.  As these sections get assigned
         pointers that we are interested in.  As these sections get assigned
         to a segment, they are removed from this array.  */
         to a segment, they are removed from this array.  */
 
 
      /* Gcc 2.96 miscompiles this code on mips. Don't do casting here
      sections = (asection **) bfd_malloc2 (section_count, sizeof (asection *));
         to work around this long long bug.  */
 
      sections = bfd_malloc2 (section_count, sizeof (asection *));
 
      if (sections == NULL)
      if (sections == NULL)
        return FALSE;
        return FALSE;
 
 
      /* Step One: Scan for segment vs section LMA conflicts.
      /* Step One: Scan for segment vs section LMA conflicts.
         Also add the sections to the section array allocated above.
         Also add the sections to the section array allocated above.
Line 5458... Line 5494...
 
 
              /* The Solaris native linker always sets p_paddr to 0.
              /* The Solaris native linker always sets p_paddr to 0.
                 We try to catch that case here, and set it to the
                 We try to catch that case here, and set it to the
                 correct value.  Note - some backends require that
                 correct value.  Note - some backends require that
                 p_paddr be left as zero.  */
                 p_paddr be left as zero.  */
              if (segment->p_paddr == 0
              if (!p_paddr_valid
                  && segment->p_vaddr != 0
                  && segment->p_vaddr != 0
                  && !bed->want_p_paddr_set_to_zero
                  && !bed->want_p_paddr_set_to_zero
                  && isec == 0
                  && isec == 0
                  && output_section->lma != 0
                  && output_section->lma != 0
                  && output_section->vma == (segment->p_vaddr
                  && output_section->vma == (segment->p_vaddr
Line 5516... Line 5552...
             program header in the input BFD.  */
             program header in the input BFD.  */
          map->count = section_count;
          map->count = section_count;
          *pointer_to_map = map;
          *pointer_to_map = map;
          pointer_to_map = &map->next;
          pointer_to_map = &map->next;
 
 
          if (!bed->want_p_paddr_set_to_zero
          if (p_paddr_valid
 
              && !bed->want_p_paddr_set_to_zero
              && matching_lma != map->p_paddr
              && matching_lma != map->p_paddr
              && !map->includes_filehdr && !map->includes_phdrs)
              && !map->includes_filehdr
 
              && !map->includes_phdrs)
            /* There is some padding before the first section in the
            /* There is some padding before the first section in the
               segment.  So, we must account for that in the output
               segment.  So, we must account for that in the output
               segment's vma.  */
               segment's vma.  */
            map->p_vaddr_offset = matching_lma - map->p_paddr;
            map->p_vaddr_offset = matching_lma - map->p_paddr;
 
 
Line 5547... Line 5585...
            }
            }
 
 
          /* Offset the segment physical address from the lma
          /* Offset the segment physical address from the lma
             to allow for space taken up by elf headers.  */
             to allow for space taken up by elf headers.  */
          if (map->includes_filehdr)
          if (map->includes_filehdr)
 
            {
 
              if (map->p_paddr >= iehdr->e_ehsize)
            map->p_paddr -= iehdr->e_ehsize;
            map->p_paddr -= iehdr->e_ehsize;
 
              else
 
                {
 
                  map->includes_filehdr = FALSE;
 
                  map->includes_phdrs = FALSE;
 
                }
 
            }
 
 
          if (map->includes_phdrs)
          if (map->includes_phdrs)
            {
            {
 
              if (map->p_paddr >= iehdr->e_phnum * iehdr->e_phentsize)
 
                {
              map->p_paddr -= iehdr->e_phnum * iehdr->e_phentsize;
              map->p_paddr -= iehdr->e_phnum * iehdr->e_phentsize;
 
 
              /* iehdr->e_phnum is just an estimate of the number
              /* iehdr->e_phnum is just an estimate of the number
                 of program headers that we will need.  Make a note
                 of program headers that we will need.  Make a note
                 here of the number we used and the segment we chose
                 here of the number we used and the segment we chose
                 to hold these headers, so that we can adjust the
                 to hold these headers, so that we can adjust the
                 offset when we know the correct value.  */
                 offset when we know the correct value.  */
              phdr_adjust_num = iehdr->e_phnum;
              phdr_adjust_num = iehdr->e_phnum;
              phdr_adjust_seg = map;
              phdr_adjust_seg = map;
            }
            }
 
              else
 
                map->includes_phdrs = FALSE;
 
            }
        }
        }
 
 
      /* Step Three: Loop over the sections again, this time assigning
      /* Step Three: Loop over the sections again, this time assigning
         those that fit to the current segment and removing them from the
         those that fit to the current segment and removing them from the
         sections array; but making sure not to leave large gaps.  Once all
         sections array; but making sure not to leave large gaps.  Once all
Line 5655... Line 5706...
              /* We still have not allocated all of the sections to
              /* We still have not allocated all of the sections to
                 segments.  Create a new segment here, initialise it
                 segments.  Create a new segment here, initialise it
                 and carry on looping.  */
                 and carry on looping.  */
              amt = sizeof (struct elf_segment_map);
              amt = sizeof (struct elf_segment_map);
              amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
              amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
              map = bfd_alloc (obfd, amt);
              map = (struct elf_segment_map *) bfd_alloc (obfd, amt);
              if (map == NULL)
              if (map == NULL)
                {
                {
                  free (sections);
                  free (sections);
                  return FALSE;
                  return FALSE;
                }
                }
Line 5670... Line 5721...
              map->next = NULL;
              map->next = NULL;
              map->p_type = segment->p_type;
              map->p_type = segment->p_type;
              map->p_flags = segment->p_flags;
              map->p_flags = segment->p_flags;
              map->p_flags_valid = 1;
              map->p_flags_valid = 1;
              map->p_paddr = suggested_lma;
              map->p_paddr = suggested_lma;
              map->p_paddr_valid = 1;
              map->p_paddr_valid = p_paddr_valid;
              map->includes_filehdr = 0;
              map->includes_filehdr = 0;
              map->includes_phdrs = 0;
              map->includes_phdrs = 0;
            }
            }
        }
        }
      while (isec < section_count);
      while (isec < section_count);
 
 
      free (sections);
      free (sections);
    }
    }
 
 
  /* The Solaris linker creates program headers in which all the
 
     p_paddr fields are zero.  When we try to objcopy or strip such a
 
     file, we get confused.  Check for this case, and if we find it
 
     reset the p_paddr_valid fields.  */
 
  for (map = map_first; map != NULL; map = map->next)
 
    if (map->p_paddr != 0)
 
      break;
 
  if (map == NULL)
 
    for (map = map_first; map != NULL; map = map->next)
 
      map->p_paddr_valid = 0;
 
 
 
  elf_tdata (obfd)->segment_map = map_first;
  elf_tdata (obfd)->segment_map = map_first;
 
 
  /* If we had to estimate the number of program headers that were
  /* If we had to estimate the number of program headers that were
     going to be needed, then check our estimate now and adjust
     going to be needed, then check our estimate now and adjust
     the offset if necessary.  */
     the offset if necessary.  */
Line 5735... Line 5775...
  struct elf_segment_map **pointer_to_map;
  struct elf_segment_map **pointer_to_map;
  Elf_Internal_Phdr *segment;
  Elf_Internal_Phdr *segment;
  unsigned int i;
  unsigned int i;
  unsigned int num_segments;
  unsigned int num_segments;
  bfd_boolean phdr_included = FALSE;
  bfd_boolean phdr_included = FALSE;
 
  bfd_boolean p_paddr_valid;
 
 
  iehdr = elf_elfheader (ibfd);
  iehdr = elf_elfheader (ibfd);
 
 
  map_first = NULL;
  map_first = NULL;
  pointer_to_map = &map_first;
  pointer_to_map = &map_first;
 
 
 
  /* If all the segment p_paddr fields are zero, don't set
 
     map->p_paddr_valid.  */
 
  p_paddr_valid = FALSE;
  num_segments = elf_elfheader (ibfd)->e_phnum;
  num_segments = elf_elfheader (ibfd)->e_phnum;
  for (i = 0, segment = elf_tdata (ibfd)->phdr;
  for (i = 0, segment = elf_tdata (ibfd)->phdr;
       i < num_segments;
       i < num_segments;
       i++, segment++)
       i++, segment++)
 
    if (segment->p_paddr != 0)
 
      {
 
        p_paddr_valid = TRUE;
 
        break;
 
      }
 
 
 
  for (i = 0, segment = elf_tdata (ibfd)->phdr;
 
       i < num_segments;
 
       i++, segment++)
    {
    {
      asection *section;
      asection *section;
      unsigned int section_count;
      unsigned int section_count;
      bfd_size_type amt;
      bfd_size_type amt;
      Elf_Internal_Shdr *this_hdr;
      Elf_Internal_Shdr *this_hdr;
Line 5774... Line 5827...
      /* Allocate a segment map big enough to contain
      /* Allocate a segment map big enough to contain
         all of the sections we have selected.  */
         all of the sections we have selected.  */
      amt = sizeof (struct elf_segment_map);
      amt = sizeof (struct elf_segment_map);
      if (section_count != 0)
      if (section_count != 0)
        amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
        amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
      map = bfd_zalloc (obfd, amt);
      map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
      if (map == NULL)
      if (map == NULL)
        return FALSE;
        return FALSE;
 
 
      /* Initialize the fields of the output segment map with the
      /* Initialize the fields of the output segment map with the
         input segment.  */
         input segment.  */
      map->next = NULL;
      map->next = NULL;
      map->p_type = segment->p_type;
      map->p_type = segment->p_type;
      map->p_flags = segment->p_flags;
      map->p_flags = segment->p_flags;
      map->p_flags_valid = 1;
      map->p_flags_valid = 1;
      map->p_paddr = segment->p_paddr;
      map->p_paddr = segment->p_paddr;
      map->p_paddr_valid = 1;
      map->p_paddr_valid = p_paddr_valid;
      map->p_align = segment->p_align;
      map->p_align = segment->p_align;
      map->p_align_valid = 1;
      map->p_align_valid = 1;
      map->p_vaddr_offset = 0;
      map->p_vaddr_offset = 0;
 
 
      if (map->p_type == PT_GNU_RELRO
      if (map->p_type == PT_GNU_RELRO)
          && segment->p_filesz == segment->p_memsz)
 
        {
        {
          /* The PT_GNU_RELRO segment may contain the first a few
          /* The PT_GNU_RELRO segment may contain the first a few
             bytes in the .got.plt section even if the whole .got.plt
             bytes in the .got.plt section even if the whole .got.plt
             section isn't in the PT_GNU_RELRO segment.  We won't
             section isn't in the PT_GNU_RELRO segment.  We won't
             change the size of the PT_GNU_RELRO segment.  */
             change the size of the PT_GNU_RELRO segment.  */
          map->p_size = segment->p_filesz;
          map->p_size = segment->p_memsz;
          map->p_size_valid = 1;
          map->p_size_valid = 1;
        }
        }
 
 
      /* Determine if this segment contains the ELF file header
      /* Determine if this segment contains the ELF file header
         and if it contains the program headers themselves.  */
         and if it contains the program headers themselves.  */
Line 5819... Line 5871...
 
 
          if (segment->p_type == PT_LOAD && map->includes_phdrs)
          if (segment->p_type == PT_LOAD && map->includes_phdrs)
            phdr_included = TRUE;
            phdr_included = TRUE;
        }
        }
 
 
      if (!map->includes_phdrs && !map->includes_filehdr)
      if (map->includes_filehdr && first_section)
 
        /* We need to keep the space used by the headers fixed.  */
 
        map->header_size = first_section->vma - segment->p_vaddr;
 
 
 
      if (!map->includes_phdrs
 
          && !map->includes_filehdr
 
          && map->p_paddr_valid)
        /* There is some other padding before the first section.  */
        /* There is some other padding before the first section.  */
        map->p_vaddr_offset = ((lowest_section ? lowest_section->lma : 0)
        map->p_vaddr_offset = ((lowest_section ? lowest_section->lma : 0)
                               - segment->p_paddr);
                               - segment->p_paddr);
 
 
      if (section_count != 0)
      if (section_count != 0)
Line 5985... Line 6043...
          || (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0)
          || (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0)
        {
        {
          if (elf_section_flags (isec) & SHF_GROUP)
          if (elf_section_flags (isec) & SHF_GROUP)
            elf_section_flags (osec) |= SHF_GROUP;
            elf_section_flags (osec) |= SHF_GROUP;
          elf_next_in_group (osec) = elf_next_in_group (isec);
          elf_next_in_group (osec) = elf_next_in_group (isec);
          elf_group_name (osec) = elf_group_name (isec);
          elf_section_data (osec)->group = elf_section_data (isec)->group;
        }
        }
    }
    }
 
 
  ihdr = &elf_section_data (isec)->this_hdr;
  ihdr = &elf_section_data (isec)->this_hdr;
 
 
Line 6168... Line 6226...
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  symtab_hdr->sh_type = SHT_SYMTAB;
  symtab_hdr->sh_type = SHT_SYMTAB;
  symtab_hdr->sh_entsize = bed->s->sizeof_sym;
  symtab_hdr->sh_entsize = bed->s->sizeof_sym;
  symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1);
  symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1);
  symtab_hdr->sh_info = elf_num_locals (abfd) + 1;
  symtab_hdr->sh_info = elf_num_locals (abfd) + 1;
  symtab_hdr->sh_addralign = 1 << bed->s->log_file_align;
  symtab_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align;
 
 
  symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
  symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
  symstrtab_hdr->sh_type = SHT_STRTAB;
  symstrtab_hdr->sh_type = SHT_STRTAB;
 
 
  outbound_syms = bfd_alloc2 (abfd, 1 + symcount, bed->s->sizeof_sym);
  outbound_syms = (bfd_byte *) bfd_alloc2 (abfd, 1 + symcount,
 
                                           bed->s->sizeof_sym);
  if (outbound_syms == NULL)
  if (outbound_syms == NULL)
    {
    {
      _bfd_stringtab_free (stt);
      _bfd_stringtab_free (stt);
      return FALSE;
      return FALSE;
    }
    }
Line 6186... Line 6245...
  outbound_shndx = NULL;
  outbound_shndx = NULL;
  symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
  symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
  if (symtab_shndx_hdr->sh_name != 0)
  if (symtab_shndx_hdr->sh_name != 0)
    {
    {
      amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx);
      amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx);
      outbound_shndx = bfd_zalloc2 (abfd, 1 + symcount,
      outbound_shndx =  (bfd_byte *)
                                    sizeof (Elf_External_Sym_Shndx));
          bfd_zalloc2 (abfd, 1 + symcount, sizeof (Elf_External_Sym_Shndx));
      if (outbound_shndx == NULL)
      if (outbound_shndx == NULL)
        {
        {
          _bfd_stringtab_free (stt);
          _bfd_stringtab_free (stt);
          return FALSE;
          return FALSE;
        }
        }
Line 6268... Line 6327...
            (abfd, syms[idx]->section);
            (abfd, syms[idx]->section);
        }
        }
      else
      else
        {
        {
          asection *sec = syms[idx]->section;
          asection *sec = syms[idx]->section;
          int shndx;
          unsigned int shndx;
 
 
          if (sec->output_section)
          if (sec->output_section)
            {
            {
              value += sec->output_offset;
              value += sec->output_offset;
              sec = sec->output_section;
              sec = sec->output_section;
Line 6315... Line 6374...
            }
            }
          else
          else
            {
            {
              shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
              shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
 
 
              if (shndx == -1)
              if (shndx == SHN_BAD)
                {
                {
                  asection *sec2;
                  asection *sec2;
 
 
                  /* Writing this would be a hell of a lot easier if
                  /* Writing this would be a hell of a lot easier if
                     we had some decent documentation on bfd, and
                     we had some decent documentation on bfd, and
Line 6339... Line 6398...
                      _bfd_stringtab_free (stt);
                      _bfd_stringtab_free (stt);
                      return FALSE;
                      return FALSE;
                    }
                    }
 
 
                  shndx = _bfd_elf_section_from_bfd_section (abfd, sec2);
                  shndx = _bfd_elf_section_from_bfd_section (abfd, sec2);
                  BFD_ASSERT (shndx != -1);
                  BFD_ASSERT (shndx != SHN_BAD);
                }
                }
            }
            }
 
 
          sym.st_shndx = shndx;
          sym.st_shndx = shndx;
        }
        }
 
 
      if ((flags & BSF_THREAD_LOCAL) != 0)
      if ((flags & BSF_THREAD_LOCAL) != 0)
        type = STT_TLS;
        type = STT_TLS;
 
      else if ((flags & BSF_GNU_INDIRECT_FUNCTION) != 0)
 
        type = STT_GNU_IFUNC;
      else if ((flags & BSF_FUNCTION) != 0)
      else if ((flags & BSF_FUNCTION) != 0)
        type = STT_FUNC;
        type = STT_FUNC;
      else if ((flags & BSF_OBJECT) != 0)
      else if ((flags & BSF_OBJECT) != 0)
        type = STT_OBJECT;
        type = STT_OBJECT;
      else if ((flags & BSF_RELC) != 0)
      else if ((flags & BSF_RELC) != 0)
Line 6381... Line 6442...
        {
        {
#ifdef USE_STT_COMMON
#ifdef USE_STT_COMMON
          if (type == STT_OBJECT)
          if (type == STT_OBJECT)
            sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_COMMON);
            sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_COMMON);
          else
          else
#else
 
            sym.st_info = ELF_ST_INFO (STB_GLOBAL, type);
 
#endif
#endif
 
            sym.st_info = ELF_ST_INFO (STB_GLOBAL, type);
        }
        }
      else if (bfd_is_und_section (syms[idx]->section))
      else if (bfd_is_und_section (syms[idx]->section))
        sym.st_info = ELF_ST_INFO (((flags & BSF_WEAK)
        sym.st_info = ELF_ST_INFO (((flags & BSF_WEAK)
                                    ? STB_WEAK
                                    ? STB_WEAK
                                    : STB_GLOBAL),
                                    : STB_GLOBAL),
Line 6398... Line 6458...
        {
        {
          int bind = STB_LOCAL;
          int bind = STB_LOCAL;
 
 
          if (flags & BSF_LOCAL)
          if (flags & BSF_LOCAL)
            bind = STB_LOCAL;
            bind = STB_LOCAL;
 
          else if (flags & BSF_GNU_UNIQUE)
 
            bind = STB_GNU_UNIQUE;
          else if (flags & BSF_WEAK)
          else if (flags & BSF_WEAK)
            bind = STB_WEAK;
            bind = STB_WEAK;
          else if (flags & BSF_GLOBAL)
          else if (flags & BSF_GLOBAL)
            bind = STB_GLOBAL;
            bind = STB_GLOBAL;
 
 
Line 6546... Line 6608...
      return -1;
      return -1;
    }
    }
 
 
  ret = sizeof (arelent *);
  ret = sizeof (arelent *);
  for (s = abfd->sections; s != NULL; s = s->next)
  for (s = abfd->sections; s != NULL; s = s->next)
    if ((s->flags & SEC_LOAD) != 0
    if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
        && elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
 
        && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
        && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
            || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
            || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
      ret += ((s->size / elf_section_data (s)->this_hdr.sh_entsize)
      ret += ((s->size / elf_section_data (s)->this_hdr.sh_entsize)
              * sizeof (arelent *));
              * sizeof (arelent *));
 
 
Line 6583... Line 6644...
 
 
  slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
  slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
  ret = 0;
  ret = 0;
  for (s = abfd->sections; s != NULL; s = s->next)
  for (s = abfd->sections; s != NULL; s = s->next)
    {
    {
      if ((s->flags & SEC_LOAD) != 0
      if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
          && elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
 
          && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
          && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
              || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
              || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
        {
        {
          arelent *p;
          arelent *p;
          long count, i;
          long count, i;
Line 6624... Line 6684...
      unsigned int i;
      unsigned int i;
      bfd_byte *contents_end;
      bfd_byte *contents_end;
 
 
      hdr = &elf_tdata (abfd)->dynverref_hdr;
      hdr = &elf_tdata (abfd)->dynverref_hdr;
 
 
      elf_tdata (abfd)->verref = bfd_zalloc2 (abfd, hdr->sh_info,
      elf_tdata (abfd)->verref = (Elf_Internal_Verneed *)
                                              sizeof (Elf_Internal_Verneed));
          bfd_zalloc2 (abfd, hdr->sh_info, sizeof (Elf_Internal_Verneed));
      if (elf_tdata (abfd)->verref == NULL)
      if (elf_tdata (abfd)->verref == NULL)
        goto error_return;
        goto error_return;
 
 
      elf_tdata (abfd)->cverrefs = hdr->sh_info;
      elf_tdata (abfd)->cverrefs = hdr->sh_info;
 
 
      contents = bfd_malloc (hdr->sh_size);
      contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
      if (contents == NULL)
      if (contents == NULL)
        {
        {
error_return_verref:
error_return_verref:
          elf_tdata (abfd)->verref = NULL;
          elf_tdata (abfd)->verref = NULL;
          elf_tdata (abfd)->cverrefs = 0;
          elf_tdata (abfd)->cverrefs = 0;
Line 6671... Line 6731...
 
 
          if (iverneed->vn_cnt == 0)
          if (iverneed->vn_cnt == 0)
            iverneed->vn_auxptr = NULL;
            iverneed->vn_auxptr = NULL;
          else
          else
            {
            {
              iverneed->vn_auxptr = bfd_alloc2 (abfd, iverneed->vn_cnt,
              iverneed->vn_auxptr = (struct elf_internal_vernaux *)
 
                  bfd_alloc2 (abfd, iverneed->vn_cnt,
                                                sizeof (Elf_Internal_Vernaux));
                                                sizeof (Elf_Internal_Vernaux));
              if (iverneed->vn_auxptr == NULL)
              if (iverneed->vn_auxptr == NULL)
                goto error_return_verref;
                goto error_return_verref;
            }
            }
 
 
Line 6740... Line 6801...
      unsigned int maxidx;
      unsigned int maxidx;
      bfd_byte *contents_end_def, *contents_end_aux;
      bfd_byte *contents_end_def, *contents_end_aux;
 
 
      hdr = &elf_tdata (abfd)->dynverdef_hdr;
      hdr = &elf_tdata (abfd)->dynverdef_hdr;
 
 
      contents = bfd_malloc (hdr->sh_size);
      contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
      if (contents == NULL)
      if (contents == NULL)
        goto error_return;
        goto error_return;
      if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
      if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
          || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
          || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
        goto error_return;
        goto error_return;
Line 6784... Line 6845...
          if (freeidx > maxidx)
          if (freeidx > maxidx)
            maxidx = ++freeidx;
            maxidx = ++freeidx;
          else
          else
            freeidx = ++maxidx;
            freeidx = ++maxidx;
        }
        }
      elf_tdata (abfd)->verdef = bfd_zalloc2 (abfd, maxidx,
      elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *)
                                              sizeof (Elf_Internal_Verdef));
          bfd_zalloc2 (abfd, maxidx, sizeof (Elf_Internal_Verdef));
      if (elf_tdata (abfd)->verdef == NULL)
      if (elf_tdata (abfd)->verdef == NULL)
        goto error_return;
        goto error_return;
 
 
      elf_tdata (abfd)->cverdefs = maxidx;
      elf_tdata (abfd)->cverdefs = maxidx;
 
 
Line 6818... Line 6879...
 
 
          if (iverdef->vd_cnt == 0)
          if (iverdef->vd_cnt == 0)
            iverdef->vd_auxptr = NULL;
            iverdef->vd_auxptr = NULL;
          else
          else
            {
            {
              iverdef->vd_auxptr = bfd_alloc2 (abfd, iverdef->vd_cnt,
              iverdef->vd_auxptr = (struct elf_internal_verdaux *)
 
                  bfd_alloc2 (abfd, iverdef->vd_cnt,
                                               sizeof (Elf_Internal_Verdaux));
                                               sizeof (Elf_Internal_Verdaux));
              if (iverdef->vd_auxptr == NULL)
              if (iverdef->vd_auxptr == NULL)
                goto error_return_verdef;
                goto error_return_verdef;
            }
            }
 
 
Line 6876... Line 6938...
      if (freeidx < 3)
      if (freeidx < 3)
        freeidx = 3;
        freeidx = 3;
      else
      else
        freeidx++;
        freeidx++;
 
 
      elf_tdata (abfd)->verdef = bfd_zalloc2 (abfd, freeidx,
      elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *)
                                              sizeof (Elf_Internal_Verdef));
          bfd_zalloc2 (abfd, freeidx, sizeof (Elf_Internal_Verdef));
      if (elf_tdata (abfd)->verdef == NULL)
      if (elf_tdata (abfd)->verdef == NULL)
        goto error_return;
        goto error_return;
 
 
      elf_tdata (abfd)->cverdefs = freeidx;
      elf_tdata (abfd)->cverdefs = freeidx;
    }
    }
Line 6903... Line 6965...
 
 
      iverdef->vd_nodename = bfd_elf_get_dt_soname (abfd);
      iverdef->vd_nodename = bfd_elf_get_dt_soname (abfd);
      if (iverdef->vd_nodename == NULL)
      if (iverdef->vd_nodename == NULL)
        goto error_return_verdef;
        goto error_return_verdef;
      iverdef->vd_nextdef = NULL;
      iverdef->vd_nextdef = NULL;
      iverdef->vd_auxptr = bfd_alloc (abfd, sizeof (Elf_Internal_Verdaux));
      iverdef->vd_auxptr = (struct elf_internal_verdaux *)
 
          bfd_alloc (abfd, sizeof (Elf_Internal_Verdaux));
      if (iverdef->vd_auxptr == NULL)
      if (iverdef->vd_auxptr == NULL)
        goto error_return_verdef;
        goto error_return_verdef;
 
 
      iverdaux = iverdef->vd_auxptr;
      iverdaux = iverdef->vd_auxptr;
      iverdaux->vda_nodename = iverdef->vd_nodename;
      iverdaux->vda_nodename = iverdef->vd_nodename;
Line 6926... Line 6989...
_bfd_elf_make_empty_symbol (bfd *abfd)
_bfd_elf_make_empty_symbol (bfd *abfd)
{
{
  elf_symbol_type *newsym;
  elf_symbol_type *newsym;
  bfd_size_type amt = sizeof (elf_symbol_type);
  bfd_size_type amt = sizeof (elf_symbol_type);
 
 
  newsym = bfd_zalloc (abfd, amt);
  newsym = (elf_symbol_type *) bfd_zalloc (abfd, amt);
  if (!newsym)
  if (!newsym)
    return NULL;
    return NULL;
  else
  else
    {
    {
      newsym->symbol.the_bfd = abfd;
      newsym->symbol.the_bfd = abfd;
Line 7000... Line 7063...
 
 
/* Find the function to a particular section and offset,
/* Find the function to a particular section and offset,
   for error reporting.  */
   for error reporting.  */
 
 
static bfd_boolean
static bfd_boolean
elf_find_function (bfd *abfd ATTRIBUTE_UNUSED,
elf_find_function (bfd *abfd,
                   asection *section,
                   asection *section,
                   asymbol **symbols,
                   asymbol **symbols,
                   bfd_vma offset,
                   bfd_vma offset,
                   const char **filename_ptr,
                   const char **filename_ptr,
                   const char **functionname_ptr)
                   const char **functionname_ptr)
Line 7020... Line 7083...
     file symbol must sort before other local symbols, but currently
     file symbol must sort before other local symbols, but currently
     ld -r doesn't do this.  So, for ld -r output, it is possible to
     ld -r doesn't do this.  So, for ld -r output, it is possible to
     make a better choice of file name for local symbols by ignoring
     make a better choice of file name for local symbols by ignoring
     file symbols appearing after a given local symbol.  */
     file symbols appearing after a given local symbol.  */
  enum { nothing_seen, symbol_seen, file_after_symbol_seen } state;
  enum { nothing_seen, symbol_seen, file_after_symbol_seen } state;
 
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
 
  filename = NULL;
  filename = NULL;
  func = NULL;
  func = NULL;
  file = NULL;
  file = NULL;
  low_func = 0;
  low_func = 0;
  state = nothing_seen;
  state = nothing_seen;
 
 
  for (p = symbols; *p != NULL; p++)
  for (p = symbols; *p != NULL; p++)
    {
    {
      elf_symbol_type *q;
      elf_symbol_type *q;
 
      unsigned int type;
 
 
      q = (elf_symbol_type *) *p;
      q = (elf_symbol_type *) *p;
 
 
      switch (ELF_ST_TYPE (q->internal_elf_sym.st_info))
      type = ELF_ST_TYPE (q->internal_elf_sym.st_info);
 
      switch (type)
        {
        {
        default:
 
          break;
 
        case STT_FILE:
        case STT_FILE:
          file = &q->symbol;
          file = &q->symbol;
          if (state == symbol_seen)
          if (state == symbol_seen)
            state = file_after_symbol_seen;
            state = file_after_symbol_seen;
          continue;
          continue;
 
        default:
 
          if (!bed->is_function_type (type))
 
            break;
        case STT_NOTYPE:
        case STT_NOTYPE:
        case STT_FUNC:
 
          if (bfd_get_section (&q->symbol) == section
          if (bfd_get_section (&q->symbol) == section
              && q->symbol.value >= low_func
              && q->symbol.value >= low_func
              && q->symbol.value <= offset)
              && q->symbol.value <= offset)
            {
            {
              func = (asymbol *) q;
              func = (asymbol *) q;
Line 7408... Line 7474...
 
 
  /* Build the section name.  */
  /* Build the section name.  */
 
 
  sprintf (buf, "%s/%d", name, elfcore_make_pid (abfd));
  sprintf (buf, "%s/%d", name, elfcore_make_pid (abfd));
  len = strlen (buf) + 1;
  len = strlen (buf) + 1;
  threaded_name = bfd_alloc (abfd, len);
  threaded_name = (char *) bfd_alloc (abfd, len);
  if (threaded_name == NULL)
  if (threaded_name == NULL)
    return FALSE;
    return FALSE;
  memcpy (threaded_name, buf, len);
  memcpy (threaded_name, buf, len);
 
 
  sect = bfd_make_section_anyway_with_flags (abfd, threaded_name,
  sect = bfd_make_section_anyway_with_flags (abfd, threaded_name,
Line 7538... Line 7604...
elfcore_grok_ppc_vmx (bfd *abfd, Elf_Internal_Note *note)
elfcore_grok_ppc_vmx (bfd *abfd, Elf_Internal_Note *note)
{
{
  return elfcore_make_note_pseudosection (abfd, ".reg-ppc-vmx", note);
  return elfcore_make_note_pseudosection (abfd, ".reg-ppc-vmx", note);
}
}
 
 
 
static bfd_boolean
 
elfcore_grok_ppc_vsx (bfd *abfd, Elf_Internal_Note *note)
 
{
 
  return elfcore_make_note_pseudosection (abfd, ".reg-ppc-vsx", note);
 
}
 
 
#if defined (HAVE_PRPSINFO_T)
#if defined (HAVE_PRPSINFO_T)
typedef prpsinfo_t   elfcore_psinfo_t;
typedef prpsinfo_t   elfcore_psinfo_t;
#if defined (HAVE_PRPSINFO32_T)         /* Sparc64 cross Sparc32 */
#if defined (HAVE_PRPSINFO32_T)         /* Sparc64 cross Sparc32 */
typedef prpsinfo32_t elfcore_psinfo32_t;
typedef prpsinfo32_t elfcore_psinfo32_t;
Line 7561... Line 7632...
 
 
char *
char *
_bfd_elfcore_strndup (bfd *abfd, char *start, size_t max)
_bfd_elfcore_strndup (bfd *abfd, char *start, size_t max)
{
{
  char *dups;
  char *dups;
  char *end = memchr (start, '\0', max);
  char *end = (char *) memchr (start, '\0', max);
  size_t len;
  size_t len;
 
 
  if (end == NULL)
  if (end == NULL)
    len = max;
    len = max;
  else
  else
    len = end - start;
    len = end - start;
 
 
  dups = bfd_alloc (abfd, len + 1);
  dups = (char *) bfd_alloc (abfd, len + 1);
  if (dups == NULL)
  if (dups == NULL)
    return NULL;
    return NULL;
 
 
  memcpy (dups, start, len);
  memcpy (dups, start, len);
  dups[len] = '\0';
  dups[len] = '\0';
Line 7789... Line 7860...
      /* Make a ".reg/999" section.  */
      /* Make a ".reg/999" section.  */
      /* thread_info.tid */
      /* thread_info.tid */
      sprintf (buf, ".reg/%ld", (long) bfd_get_32 (abfd, note->descdata + 8));
      sprintf (buf, ".reg/%ld", (long) bfd_get_32 (abfd, note->descdata + 8));
 
 
      len = strlen (buf) + 1;
      len = strlen (buf) + 1;
      name = bfd_alloc (abfd, len);
      name = (char *) bfd_alloc (abfd, len);
      if (name == NULL)
      if (name == NULL)
        return FALSE;
        return FALSE;
 
 
      memcpy (name, buf, len);
      memcpy (name, buf, len);
 
 
Line 7817... Line 7888...
 
 
    case 3 /* NOTE_INFO_MODULE */:
    case 3 /* NOTE_INFO_MODULE */:
      /* Make a ".module/xxxxxxxx" section.  */
      /* Make a ".module/xxxxxxxx" section.  */
      /* module_info.base_address */
      /* module_info.base_address */
      base_addr = bfd_get_32 (abfd, note->descdata + 4);
      base_addr = bfd_get_32 (abfd, note->descdata + 4);
      sprintf (buf, ".module/%08lx", (long) base_addr);
      sprintf (buf, ".module/%08lx", (unsigned long) base_addr);
 
 
      len = strlen (buf) + 1;
      len = strlen (buf) + 1;
      name = bfd_alloc (abfd, len);
      name = (char *) bfd_alloc (abfd, len);
      if (name == NULL)
      if (name == NULL)
        return FALSE;
        return FALSE;
 
 
      memcpy (name, buf, len);
      memcpy (name, buf, len);
 
 
Line 7893... Line 7964...
          && strcmp (note->namedata, "LINUX") == 0)
          && strcmp (note->namedata, "LINUX") == 0)
        return elfcore_grok_ppc_vmx (abfd, note);
        return elfcore_grok_ppc_vmx (abfd, note);
      else
      else
        return TRUE;
        return TRUE;
 
 
 
    case NT_PPC_VSX:
 
      if (note->namesz == 6
 
          && strcmp (note->namedata, "LINUX") == 0)
 
        return elfcore_grok_ppc_vsx (abfd, note);
 
      else
 
        return TRUE;
 
 
    case NT_PRPSINFO:
    case NT_PRPSINFO:
    case NT_PSINFO:
    case NT_PSINFO:
      if (bed->elf_backend_grok_psinfo)
      if (bed->elf_backend_grok_psinfo)
        if ((*bed->elf_backend_grok_psinfo) (abfd, note))
        if ((*bed->elf_backend_grok_psinfo) (abfd, note))
          return TRUE;
          return TRUE;
Line 7924... Line 8002...
 
 
static bfd_boolean
static bfd_boolean
elfobj_grok_gnu_build_id (bfd *abfd, Elf_Internal_Note *note)
elfobj_grok_gnu_build_id (bfd *abfd, Elf_Internal_Note *note)
{
{
  elf_tdata (abfd)->build_id_size = note->descsz;
  elf_tdata (abfd)->build_id_size = note->descsz;
  elf_tdata (abfd)->build_id = bfd_alloc (abfd, note->descsz);
  elf_tdata (abfd)->build_id = (bfd_byte *) bfd_alloc (abfd, note->descsz);
  if (elf_tdata (abfd)->build_id == NULL)
  if (elf_tdata (abfd)->build_id == NULL)
    return FALSE;
    return FALSE;
 
 
  memcpy (elf_tdata (abfd)->build_id, note->descdata, note->descsz);
  memcpy (elf_tdata (abfd)->build_id, note->descdata, note->descsz);
 
 
Line 8045... Line 8123...
    }
    }
    /* NOTREACHED */
    /* NOTREACHED */
}
}
 
 
static bfd_boolean
static bfd_boolean
 
elfcore_grok_openbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
 
{
 
  /* Signal number at offset 0x08. */
 
  elf_tdata (abfd)->core_signal
 
    = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);
 
 
 
  /* Process ID at offset 0x20. */
 
  elf_tdata (abfd)->core_pid
 
    = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x20);
 
 
 
  /* Command name at 0x48 (max 32 bytes, including nul). */
 
  elf_tdata (abfd)->core_command
 
    = _bfd_elfcore_strndup (abfd, note->descdata + 0x48, 31);
 
 
 
  return TRUE;
 
}
 
 
 
static bfd_boolean
 
elfcore_grok_openbsd_note (bfd *abfd, Elf_Internal_Note *note)
 
{
 
  if (note->type == NT_OPENBSD_PROCINFO)
 
    return elfcore_grok_openbsd_procinfo (abfd, note);
 
 
 
  if (note->type == NT_OPENBSD_REGS)
 
    return elfcore_make_note_pseudosection (abfd, ".reg", note);
 
 
 
  if (note->type == NT_OPENBSD_FPREGS)
 
    return elfcore_make_note_pseudosection (abfd, ".reg2", note);
 
 
 
  if (note->type == NT_OPENBSD_XFPREGS)
 
    return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note);
 
 
 
  if (note->type == NT_OPENBSD_AUXV)
 
    {
 
      asection *sect = bfd_make_section_anyway_with_flags (abfd, ".auxv",
 
                                                           SEC_HAS_CONTENTS);
 
 
 
      if (sect == NULL)
 
        return FALSE;
 
      sect->size = note->descsz;
 
      sect->filepos = note->descpos;
 
      sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32;
 
 
 
      return TRUE;
 
    }
 
 
 
  if (note->type == NT_OPENBSD_WCOOKIE)
 
    {
 
      asection *sect = bfd_make_section_anyway_with_flags (abfd, ".wcookie",
 
                                                           SEC_HAS_CONTENTS);
 
 
 
      if (sect == NULL)
 
        return FALSE;
 
      sect->size = note->descsz;
 
      sect->filepos = note->descpos;
 
      sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32;
 
 
 
      return TRUE;
 
    }
 
 
 
  return TRUE;
 
}
 
 
 
static bfd_boolean
elfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, long *tid)
elfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, long *tid)
{
{
  void *ddata = note->descdata;
  void *ddata = note->descdata;
  char buf[100];
  char buf[100];
  char *name;
  char *name;
Line 8079... Line 8221...
    elf_tdata (abfd)->core_lwpid = *tid;
    elf_tdata (abfd)->core_lwpid = *tid;
 
 
  /* Make a ".qnx_core_status/%d" section.  */
  /* Make a ".qnx_core_status/%d" section.  */
  sprintf (buf, ".qnx_core_status/%ld", *tid);
  sprintf (buf, ".qnx_core_status/%ld", *tid);
 
 
  name = bfd_alloc (abfd, strlen (buf) + 1);
  name = (char *) bfd_alloc (abfd, strlen (buf) + 1);
  if (name == NULL)
  if (name == NULL)
    return FALSE;
    return FALSE;
  strcpy (name, buf);
  strcpy (name, buf);
 
 
  sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
  sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
Line 8108... Line 8250...
  asection *sect;
  asection *sect;
 
 
  /* Make a "(base)/%d" section.  */
  /* Make a "(base)/%d" section.  */
  sprintf (buf, "%s/%ld", base, tid);
  sprintf (buf, "%s/%ld", base, tid);
 
 
  name = bfd_alloc (abfd, strlen (buf) + 1);
  name = (char *) bfd_alloc (abfd, strlen (buf) + 1);
  if (name == NULL)
  if (name == NULL)
    return FALSE;
    return FALSE;
  strcpy (name, buf);
  strcpy (name, buf);
 
 
  sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
  sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
Line 8165... Line 8307...
  asection *sect;
  asection *sect;
  size_t len;
  size_t len;
 
 
  /* Use note name as section name.  */
  /* Use note name as section name.  */
  len = note->namesz;
  len = note->namesz;
  name = bfd_alloc (abfd, len);
  name = (char *) bfd_alloc (abfd, len);
  if (name == NULL)
  if (name == NULL)
    return FALSE;
    return FALSE;
  memcpy (name, note->namedata, len);
  memcpy (name, note->namedata, len);
  name[len - 1] = '\0';
  name[len - 1] = '\0';
 
 
Line 8219... Line 8361...
  if (name != NULL)
  if (name != NULL)
    namesz = strlen (name) + 1;
    namesz = strlen (name) + 1;
 
 
  newspace = 12 + ((namesz + 3) & -4) + ((size + 3) & -4);
  newspace = 12 + ((namesz + 3) & -4) + ((size + 3) & -4);
 
 
  buf = realloc (buf, *bufsiz + newspace);
  buf = (char *) realloc (buf, *bufsiz + newspace);
  if (buf == NULL)
  if (buf == NULL)
    return buf;
    return buf;
  dest = buf + *bufsiz;
  dest = buf + *bufsiz;
  *bufsiz += newspace;
  *bufsiz += newspace;
  xnp = (Elf_External_Note *) dest;
  xnp = (Elf_External_Note *) dest;
Line 8459... Line 8601...
  char *note_name = "LINUX";
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
  return elfcore_write_note (abfd, buf, bufsiz,
                             note_name, NT_PPC_VMX, ppc_vmx, size);
                             note_name, NT_PPC_VMX, ppc_vmx, size);
}
}
 
 
 
char *
 
elfcore_write_ppc_vsx (bfd *abfd,
 
                       char *buf,
 
                       int *bufsiz,
 
                       const void *ppc_vsx,
 
                       int size)
 
{
 
  char *note_name = "LINUX";
 
  return elfcore_write_note (abfd, buf, bufsiz,
 
                             note_name, NT_PPC_VSX, ppc_vsx, size);
 
}
 
 
 
char *
 
elfcore_write_register_note (bfd *abfd,
 
                             char *buf,
 
                             int *bufsiz,
 
                             const char *section,
 
                             const void *data,
 
                             int size)
 
{
 
  if (strcmp (section, ".reg2") == 0)
 
    return elfcore_write_prfpreg (abfd, buf, bufsiz, data, size);
 
  if (strcmp (section, ".reg-xfp") == 0)
 
    return elfcore_write_prxfpreg (abfd, buf, bufsiz, data, size);
 
  if (strcmp (section, ".reg-ppc-vmx") == 0)
 
    return elfcore_write_ppc_vmx (abfd, buf, bufsiz, data, size);
 
  if (strcmp (section, ".reg-ppc-vsx") == 0)
 
    return elfcore_write_ppc_vsx (abfd, buf, bufsiz, data, size);
 
  return NULL;
 
}
 
 
static bfd_boolean
static bfd_boolean
elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset)
elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset)
{
{
  char *p;
  char *p;
 
 
Line 8471... Line 8644...
    {
    {
      /* FIXME: bad alignment assumption.  */
      /* FIXME: bad alignment assumption.  */
      Elf_External_Note *xnp = (Elf_External_Note *) p;
      Elf_External_Note *xnp = (Elf_External_Note *) p;
      Elf_Internal_Note in;
      Elf_Internal_Note in;
 
 
 
      if (offsetof (Elf_External_Note, name) > buf - p + size)
 
        return FALSE;
 
 
      in.type = H_GET_32 (abfd, xnp->type);
      in.type = H_GET_32 (abfd, xnp->type);
 
 
      in.namesz = H_GET_32 (abfd, xnp->namesz);
      in.namesz = H_GET_32 (abfd, xnp->namesz);
      in.namedata = xnp->name;
      in.namedata = xnp->name;
 
      if (in.namesz > buf - in.namedata + size)
 
        return FALSE;
 
 
      in.descsz = H_GET_32 (abfd, xnp->descsz);
      in.descsz = H_GET_32 (abfd, xnp->descsz);
      in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4);
      in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4);
      in.descpos = offset + (in.descdata - buf);
      in.descpos = offset + (in.descdata - buf);
 
      if (in.descsz != 0
 
          && (in.descdata >= buf + size
 
              || in.descsz > buf - in.descdata + size))
 
        return FALSE;
 
 
      switch (bfd_get_format (abfd))
      switch (bfd_get_format (abfd))
        {
        {
        default:
        default:
          return TRUE;
          return TRUE;
Line 8491... Line 8673...
          if (CONST_STRNEQ (in.namedata, "NetBSD-CORE"))
          if (CONST_STRNEQ (in.namedata, "NetBSD-CORE"))
            {
            {
              if (! elfcore_grok_netbsd_note (abfd, &in))
              if (! elfcore_grok_netbsd_note (abfd, &in))
                return FALSE;
                return FALSE;
            }
            }
 
          else if (CONST_STRNEQ (in.namedata, "OpenBSD"))
 
            {
 
              if (! elfcore_grok_openbsd_note (abfd, &in))
 
                return FALSE;
 
            }
          else if (CONST_STRNEQ (in.namedata, "QNX"))
          else if (CONST_STRNEQ (in.namedata, "QNX"))
            {
            {
              if (! elfcore_grok_nto_note (abfd, &in))
              if (! elfcore_grok_nto_note (abfd, &in))
                return FALSE;
                return FALSE;
            }
            }
Line 8534... Line 8721...
    return TRUE;
    return TRUE;
 
 
  if (bfd_seek (abfd, offset, SEEK_SET) != 0)
  if (bfd_seek (abfd, offset, SEEK_SET) != 0)
    return FALSE;
    return FALSE;
 
 
  buf = bfd_malloc (size);
  buf = (char *) bfd_malloc (size);
  if (buf == NULL)
  if (buf == NULL)
    return FALSE;
    return FALSE;
 
 
  if (bfd_bread (buf, size, abfd) != size
  if (bfd_bread (buf, size, abfd) != size
      || !elf_parse_notes (abfd, buf, size, offset))
      || !elf_parse_notes (abfd, buf, size, offset))
Line 8730... Line 8917...
  if (!bed->plt_sym_val)
  if (!bed->plt_sym_val)
    return 0;
    return 0;
 
 
  relplt_name = bed->relplt_name;
  relplt_name = bed->relplt_name;
  if (relplt_name == NULL)
  if (relplt_name == NULL)
    relplt_name = bed->default_use_rela_p ? ".rela.plt" : ".rel.plt";
    relplt_name = bed->rela_plts_and_copies_p ? ".rela.plt" : ".rel.plt";
  relplt = bfd_get_section_by_name (abfd, relplt_name);
  relplt = bfd_get_section_by_name (abfd, relplt_name);
  if (relplt == NULL)
  if (relplt == NULL)
    return 0;
    return 0;
 
 
  hdr = &elf_section_data (relplt)->this_hdr;
  hdr = &elf_section_data (relplt)->this_hdr;
Line 8751... Line 8938...
    return -1;
    return -1;
 
 
  count = relplt->size / hdr->sh_entsize;
  count = relplt->size / hdr->sh_entsize;
  size = count * sizeof (asymbol);
  size = count * sizeof (asymbol);
  p = relplt->relocation;
  p = relplt->relocation;
  for (i = 0; i < count; i++, p++)
  for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel)
 
    {
    size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
    size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
 
      if (p->addend != 0)
 
        {
 
#ifdef BFD64
 
          size += sizeof ("+0x") - 1 + 8 + 8 * (bed->s->elfclass == ELFCLASS64);
 
#else
 
          size += sizeof ("+0x") - 1 + 8;
 
#endif
 
        }
 
    }
 
 
  s = *ret = bfd_malloc (size);
  s = *ret = (asymbol *) bfd_malloc (size);
  if (s == NULL)
  if (s == NULL)
    return -1;
    return -1;
 
 
  names = (char *) (s + count);
  names = (char *) (s + count);
  p = relplt->relocation;
  p = relplt->relocation;
  n = 0;
  n = 0;
  for (i = 0; i < count; i++, p++)
  for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel)
    {
    {
      size_t len;
      size_t len;
      bfd_vma addr;
      bfd_vma addr;
 
 
      addr = bed->plt_sym_val (i, plt, p);
      addr = bed->plt_sym_val (i, plt, p);
Line 8775... Line 8972...
      *s = **p->sym_ptr_ptr;
      *s = **p->sym_ptr_ptr;
      /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set.  Since
      /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set.  Since
         we are defining a symbol, ensure one of them is set.  */
         we are defining a symbol, ensure one of them is set.  */
      if ((s->flags & BSF_LOCAL) == 0)
      if ((s->flags & BSF_LOCAL) == 0)
        s->flags |= BSF_GLOBAL;
        s->flags |= BSF_GLOBAL;
 
      s->flags |= BSF_SYNTHETIC;
      s->section = plt;
      s->section = plt;
      s->value = addr - plt->vma;
      s->value = addr - plt->vma;
      s->name = names;
      s->name = names;
      s->udata.p = NULL;
      s->udata.p = NULL;
      len = strlen ((*p->sym_ptr_ptr)->name);
      len = strlen ((*p->sym_ptr_ptr)->name);
      memcpy (names, (*p->sym_ptr_ptr)->name, len);
      memcpy (names, (*p->sym_ptr_ptr)->name, len);
      names += len;
      names += len;
 
      if (p->addend != 0)
 
        {
 
          char buf[30], *a;
 
          int len;
 
          memcpy (names, "+0x", sizeof ("+0x") - 1);
 
          names += sizeof ("+0x") - 1;
 
          bfd_sprintf_vma (abfd, buf, p->addend);
 
          for (a = buf; *a == '0'; ++a)
 
            ;
 
          len = strlen (a);
 
          memcpy (names, a, len);
 
          names += len;
 
        }
      memcpy (names, "@plt", sizeof ("@plt"));
      memcpy (names, "@plt", sizeof ("@plt"));
      names += sizeof ("@plt");
      names += sizeof ("@plt");
      ++s, ++n;
      ++s, ++n;
    }
    }
 
 
Line 8804... Line 9015...
  Elf_Internal_Ehdr * i_ehdrp;  /* ELF file header, internal form.  */
  Elf_Internal_Ehdr * i_ehdrp;  /* ELF file header, internal form.  */
 
 
  i_ehdrp = elf_elfheader (abfd);
  i_ehdrp = elf_elfheader (abfd);
 
 
  i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
  i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
 
 
 
  /* To make things simpler for the loader on Linux systems we set the
 
     osabi field to ELFOSABI_LINUX if the binary contains symbols of
 
     the STT_GNU_IFUNC type.  */
 
  if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE
 
      && elf_tdata (abfd)->has_ifunc_symbols)
 
    i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_LINUX;
}
}
 
 
 
 
/* Return TRUE for ELF symbol types that represent functions.
/* Return TRUE for ELF symbol types that represent functions.
   This is the default version of this function, which is sufficient for
   This is the default version of this function, which is sufficient for
   most targets.  It returns true if TYPE is STT_FUNC.  */
   most targets.  It returns true if TYPE is STT_FUNC or STT_GNU_IFUNC.  */
 
 
bfd_boolean
bfd_boolean
_bfd_elf_is_function_type (unsigned int type)
_bfd_elf_is_function_type (unsigned int type)
{
{
  return (type == STT_FUNC);
  return (type == STT_FUNC
 
          || type == STT_GNU_IFUNC);
}
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.