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/] [elf32-hppa.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...
/* BFD back-end for HP PA-RISC ELF files.
/* BFD back-end for HP PA-RISC ELF files.
   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001,
   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001,
   2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
   2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
 
   Free Software Foundation, Inc.
 
 
   Original code by
   Original code by
        Center for Software Science
        Center for Software Science
        Department of Computer Science
        Department of Computer Science
        University of Utah
        University of Utah
Line 298... Line 299...
  unsigned int has_22bit_branch:1;
  unsigned int has_22bit_branch:1;
 
 
  /* Set if we need a .plt stub to support lazy dynamic linking.  */
  /* Set if we need a .plt stub to support lazy dynamic linking.  */
  unsigned int need_plt_stub:1;
  unsigned int need_plt_stub:1;
 
 
  /* Small local sym to section mapping cache.  */
  /* Small local sym cache.  */
  struct sym_sec_cache sym_sec;
  struct sym_cache sym_cache;
 
 
  /* Data for LDM relocations.  */
  /* Data for LDM relocations.  */
  union
  union
  {
  {
    bfd_signed_vma refcount;
    bfd_signed_vma refcount;
Line 457... Line 458...
  htab->multi_subspace = 0;
  htab->multi_subspace = 0;
  htab->has_12bit_branch = 0;
  htab->has_12bit_branch = 0;
  htab->has_17bit_branch = 0;
  htab->has_17bit_branch = 0;
  htab->has_22bit_branch = 0;
  htab->has_22bit_branch = 0;
  htab->need_plt_stub = 0;
  htab->need_plt_stub = 0;
  htab->sym_sec.abfd = NULL;
  htab->sym_cache.abfd = NULL;
  htab->tls_ldm_got.refcount = 0;
  htab->tls_ldm_got.refcount = 0;
 
 
  return &htab->etab.root;
  return &htab->etab.root;
}
}
 
 
Line 1008... Line 1009...
 
 
  htab->splt = bfd_get_section_by_name (abfd, ".plt");
  htab->splt = bfd_get_section_by_name (abfd, ".plt");
  htab->srelplt = bfd_get_section_by_name (abfd, ".rela.plt");
  htab->srelplt = bfd_get_section_by_name (abfd, ".rela.plt");
 
 
  htab->sgot = bfd_get_section_by_name (abfd, ".got");
  htab->sgot = bfd_get_section_by_name (abfd, ".got");
  htab->srelgot = bfd_make_section_with_flags (abfd, ".rela.got",
  htab->srelgot = bfd_get_section_by_name (abfd, ".rela.got");
                                               (SEC_ALLOC
 
                                                | SEC_LOAD
 
                                                | SEC_HAS_CONTENTS
 
                                                | SEC_IN_MEMORY
 
                                                | SEC_LINKER_CREATED
 
                                                | SEC_READONLY));
 
  if (htab->srelgot == NULL
 
      || ! bfd_set_section_alignment (abfd, htab->srelgot, 2))
 
    return FALSE;
 
 
 
  htab->sdynbss = bfd_get_section_by_name (abfd, ".dynbss");
  htab->sdynbss = bfd_get_section_by_name (abfd, ".dynbss");
  htab->srelbss = bfd_get_section_by_name (abfd, ".rela.bss");
  htab->srelbss = bfd_get_section_by_name (abfd, ".rela.bss");
 
 
  /* hppa-linux needs _GLOBAL_OFFSET_TABLE_ to be visible from the main
  /* hppa-linux needs _GLOBAL_OFFSET_TABLE_ to be visible from the main
Line 1110... Line 1102...
{
{
  /* For now we don't support linker optimizations.  */
  /* For now we don't support linker optimizations.  */
  return r_type;
  return r_type;
}
}
 
 
 
/* Return a pointer to the local GOT, PLT and TLS reference counts
 
   for ABFD.  Returns NULL if the storage allocation fails.  */
 
 
 
static bfd_signed_vma *
 
hppa32_elf_local_refcounts (bfd *abfd)
 
{
 
  Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
 
  bfd_signed_vma *local_refcounts;
 
 
 
  local_refcounts = elf_local_got_refcounts (abfd);
 
  if (local_refcounts == NULL)
 
    {
 
      bfd_size_type size;
 
 
 
      /* Allocate space for local GOT and PLT reference
 
         counts.  Done this way to save polluting elf_obj_tdata
 
         with another target specific pointer.  */
 
      size = symtab_hdr->sh_info;
 
      size *= 2 * sizeof (bfd_signed_vma);
 
      /* Add in space to store the local GOT TLS types.  */
 
      size += symtab_hdr->sh_info;
 
      local_refcounts = bfd_zalloc (abfd, size);
 
      if (local_refcounts == NULL)
 
        return NULL;
 
      elf_local_got_refcounts (abfd) = local_refcounts;
 
      memset (hppa_elf_local_got_tls_type (abfd), GOT_UNKNOWN,
 
              symtab_hdr->sh_info);
 
    }
 
  return local_refcounts;
 
}
 
 
 
 
/* Look through the relocs for a section during the first phase, and
/* Look through the relocs for a section during the first phase, and
   calculate needed space in the global offset table, procedure linkage
   calculate needed space in the global offset table, procedure linkage
   table, and dynamic reloc sections.  At this point we haven't
   table, and dynamic reloc sections.  At this point we haven't
   necessarily read all the input files.  */
   necessarily read all the input files.  */
 
 
Line 1356... Line 1380...
              else
              else
                {
                {
                  bfd_signed_vma *local_got_refcounts;
                  bfd_signed_vma *local_got_refcounts;
 
 
                  /* This is a global offset table entry for a local symbol.  */
                  /* This is a global offset table entry for a local symbol.  */
                  local_got_refcounts = elf_local_got_refcounts (abfd);
                  local_got_refcounts = hppa32_elf_local_refcounts (abfd);
                  if (local_got_refcounts == NULL)
 
                    {
 
                      bfd_size_type size;
 
 
 
                      /* Allocate space for local got offsets and local
 
                         plt offsets.  Done this way to save polluting
 
                         elf_obj_tdata with another target specific
 
                         pointer.  */
 
                      size = symtab_hdr->sh_info;
 
                      size *= 2 * sizeof (bfd_signed_vma);
 
                      /* Add in space to store the local GOT TLS types.  */
 
                      size += symtab_hdr->sh_info;
 
                      local_got_refcounts = bfd_zalloc (abfd, size);
 
                      if (local_got_refcounts == NULL)
                      if (local_got_refcounts == NULL)
                        return FALSE;
                        return FALSE;
                      elf_local_got_refcounts (abfd) = local_got_refcounts;
 
                      memset (hppa_elf_local_got_tls_type (abfd),
 
                          GOT_UNKNOWN, symtab_hdr->sh_info);
 
                    }
 
                  local_got_refcounts[r_symndx] += 1;
                  local_got_refcounts[r_symndx] += 1;
 
 
                  old_tls_type = hppa_elf_local_got_tls_type (abfd) [r_symndx];
                  old_tls_type = hppa_elf_local_got_tls_type (abfd) [r_symndx];
                }
                }
 
 
Line 1422... Line 1429...
              else if (need_entry & PLT_PLABEL)
              else if (need_entry & PLT_PLABEL)
                {
                {
                  bfd_signed_vma *local_got_refcounts;
                  bfd_signed_vma *local_got_refcounts;
                  bfd_signed_vma *local_plt_refcounts;
                  bfd_signed_vma *local_plt_refcounts;
 
 
                  local_got_refcounts = elf_local_got_refcounts (abfd);
                  local_got_refcounts = hppa32_elf_local_refcounts (abfd);
                  if (local_got_refcounts == NULL)
 
                    {
 
                      bfd_size_type size;
 
 
 
                      /* Allocate space for local got offsets and local
 
                         plt offsets.  */
 
                      size = symtab_hdr->sh_info;
 
                      size *= 2 * sizeof (bfd_signed_vma);
 
                      /* Add in space to store the local GOT TLS types.  */
 
                      size += symtab_hdr->sh_info;
 
                      local_got_refcounts = bfd_zalloc (abfd, size);
 
                      if (local_got_refcounts == NULL)
                      if (local_got_refcounts == NULL)
                        return FALSE;
                        return FALSE;
                      elf_local_got_refcounts (abfd) = local_got_refcounts;
 
                    }
 
                  local_plt_refcounts = (local_got_refcounts
                  local_plt_refcounts = (local_got_refcounts
                                         + symtab_hdr->sh_info);
                                         + symtab_hdr->sh_info);
                  local_plt_refcounts[r_symndx] += 1;
                  local_plt_refcounts[r_symndx] += 1;
                }
                }
            }
            }
Line 1502... Line 1496...
 
 
              /* Create a reloc section in dynobj and make room for
              /* Create a reloc section in dynobj and make room for
                 this reloc.  */
                 this reloc.  */
              if (sreloc == NULL)
              if (sreloc == NULL)
                {
                {
                  char *name;
 
                  bfd *dynobj;
 
 
 
                  name = (bfd_elf_string_from_elf_section
 
                          (abfd,
 
                           elf_elfheader (abfd)->e_shstrndx,
 
                           elf_section_data (sec)->rel_hdr.sh_name));
 
                  if (name == NULL)
 
                    {
 
                      (*_bfd_error_handler)
 
                        (_("Could not find relocation section for %s"),
 
                         sec->name);
 
                      bfd_set_error (bfd_error_bad_value);
 
                      return FALSE;
 
                    }
 
 
 
                  if (htab->etab.dynobj == NULL)
                  if (htab->etab.dynobj == NULL)
                    htab->etab.dynobj = abfd;
                    htab->etab.dynobj = abfd;
 
 
                  dynobj = htab->etab.dynobj;
                  sreloc = _bfd_elf_make_dynamic_reloc_section
                  sreloc = bfd_get_section_by_name (dynobj, name);
                    (sec, htab->etab.dynobj, 2, abfd, /*rela?*/ TRUE);
 
 
                  if (sreloc == NULL)
                  if (sreloc == NULL)
                    {
                    {
                      flagword flags;
                      bfd_set_error (bfd_error_bad_value);
 
 
                      flags = (SEC_HAS_CONTENTS | SEC_READONLY
 
                               | SEC_IN_MEMORY | SEC_LINKER_CREATED);
 
                      if ((sec->flags & SEC_ALLOC) != 0)
 
                        flags |= SEC_ALLOC | SEC_LOAD;
 
                      sreloc = bfd_make_section_with_flags (dynobj,
 
                                                            name,
 
                                                            flags);
 
                      if (sreloc == NULL
 
                          || !bfd_set_section_alignment (dynobj, sreloc, 2))
 
                        return FALSE;
                        return FALSE;
                    }
                    }
 
 
                  elf_section_data (sec)->sreloc = sreloc;
 
                }
                }
 
 
              /* If this is a global symbol, we count the number of
              /* If this is a global symbol, we count the number of
                 relocations we need for this symbol.  */
                 relocations we need for this symbol.  */
              if (hh != NULL)
              if (hh != NULL)
Line 1553... Line 1520...
              else
              else
                {
                {
                  /* Track dynamic relocs needed for local syms too.
                  /* Track dynamic relocs needed for local syms too.
                     We really need local syms available to do this
                     We really need local syms available to do this
                     easily.  Oh well.  */
                     easily.  Oh well.  */
 
 
                  asection *sr;
                  asection *sr;
                  void *vpp;
                  void *vpp;
 
                  Elf_Internal_Sym *isym;
 
 
                  sr = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
                  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
                                                       sec, r_symndx);
                                                abfd, r_symndx);
                  if (sr == NULL)
                  if (isym == NULL)
                    return FALSE;
                    return FALSE;
 
 
 
                  sr = bfd_section_from_elf_index (abfd, isym->st_shndx);
 
                  if (sr == NULL)
 
                    sr = sec;
 
 
                  vpp = &elf_section_data (sr)->local_dynrel;
                  vpp = &elf_section_data (sr)->local_dynrel;
                  hdh_head = (struct elf32_hppa_dyn_reloc_entry **) vpp;
                  hdh_head = (struct elf32_hppa_dyn_reloc_entry **) vpp;
                }
                }
 
 
              hdh_p = *hdh_head;
              hdh_p = *hdh_head;
Line 2974... Line 2945...
                  if (r_indx < symtab_hdr->sh_info)
                  if (r_indx < symtab_hdr->sh_info)
                    {
                    {
                      /* It's a local symbol.  */
                      /* It's a local symbol.  */
                      Elf_Internal_Sym *sym;
                      Elf_Internal_Sym *sym;
                      Elf_Internal_Shdr *hdr;
                      Elf_Internal_Shdr *hdr;
 
                      unsigned int shndx;
 
 
                      sym = local_syms + r_indx;
                      sym = local_syms + r_indx;
                      hdr = elf_elfsections (input_bfd)[sym->st_shndx];
 
                      sym_sec = hdr->bfd_section;
 
                      if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
                      if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
                        sym_value = sym->st_value;
                        sym_value = sym->st_value;
 
                      shndx = sym->st_shndx;
 
                      if (shndx < elf_numsections (input_bfd))
 
                        {
 
                          hdr = elf_elfsections (input_bfd)[shndx];
 
                          sym_sec = hdr->bfd_section;
                      destination = (sym_value + irela->r_addend
                      destination = (sym_value + irela->r_addend
                                     + sym_sec->output_offset
                                     + sym_sec->output_offset
                                     + sym_sec->output_section->vma);
                                     + sym_sec->output_section->vma);
                    }
                    }
 
                    }
                  else
                  else
                    {
                    {
                      /* It's an external symbol.  */
                      /* It's an external symbol.  */
                      int e_indx;
                      int e_indx;
 
 
Line 3428... Line 3404...
               error.  */
               error.  */
            (*_bfd_error_handler)
            (*_bfd_error_handler)
              (_("%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"),
              (_("%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"),
               input_bfd,
               input_bfd,
               input_section,
               input_section,
               offset,
               (long) offset,
               howto->name,
               howto->name,
               insn);
               insn);
        }
        }
      else if (orig_r_type == R_PARISC_DLTIND14F)
      else if (orig_r_type == R_PARISC_DLTIND14F)
        {
        {
Line 3592... Line 3568...
    {
    {
      (*_bfd_error_handler)
      (*_bfd_error_handler)
        (_("%B(%A+0x%lx): cannot reach %s, recompile with -ffunction-sections"),
        (_("%B(%A+0x%lx): cannot reach %s, recompile with -ffunction-sections"),
         input_bfd,
         input_bfd,
         input_section,
         input_section,
         offset,
         (long) offset,
         hsh->bh_root.string);
         hsh->bh_root.string);
      bfd_set_error (bfd_error_bad_value);
      bfd_set_error (bfd_error_bad_value);
      return bfd_reloc_notsupported;
      return bfd_reloc_notsupported;
    }
    }
 
 

powered by: WebSVN 2.1.0

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