OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [elf64-ppc.c] - Diff between revs 148 and 161

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

Rev 148 Rev 161
Line 32... Line 32...
#include "bfdlink.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf-bfd.h"
#include "elf/ppc64.h"
#include "elf/ppc64.h"
#include "elf64-ppc.h"
#include "elf64-ppc.h"
 
#include "dwarf2.h"
 
 
static bfd_reloc_status_type ppc64_elf_ha_reloc
static bfd_reloc_status_type ppc64_elf_ha_reloc
  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_reloc_status_type ppc64_elf_branch_reloc
static bfd_reloc_status_type ppc64_elf_branch_reloc
  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
Line 78... Line 79...
#define elf_backend_default_execstack 0
#define elf_backend_default_execstack 0
 
 
#define bfd_elf64_mkobject                    ppc64_elf_mkobject
#define bfd_elf64_mkobject                    ppc64_elf_mkobject
#define bfd_elf64_bfd_reloc_type_lookup       ppc64_elf_reloc_type_lookup
#define bfd_elf64_bfd_reloc_type_lookup       ppc64_elf_reloc_type_lookup
#define bfd_elf64_bfd_reloc_name_lookup       ppc64_elf_reloc_name_lookup
#define bfd_elf64_bfd_reloc_name_lookup       ppc64_elf_reloc_name_lookup
#define bfd_elf64_bfd_merge_private_bfd_data  ppc64_elf_merge_private_bfd_data
#define bfd_elf64_bfd_merge_private_bfd_data  _bfd_generic_verify_endian_match
#define bfd_elf64_new_section_hook            ppc64_elf_new_section_hook
#define bfd_elf64_new_section_hook            ppc64_elf_new_section_hook
#define bfd_elf64_bfd_link_hash_table_create  ppc64_elf_link_hash_table_create
#define bfd_elf64_bfd_link_hash_table_create  ppc64_elf_link_hash_table_create
#define bfd_elf64_bfd_link_hash_table_free    ppc64_elf_link_hash_table_free
#define bfd_elf64_bfd_link_hash_table_free    ppc64_elf_link_hash_table_free
#define bfd_elf64_get_synthetic_symtab        ppc64_elf_get_synthetic_symtab
#define bfd_elf64_get_synthetic_symtab        ppc64_elf_get_synthetic_symtab
#define bfd_elf64_bfd_link_just_syms          ppc64_elf_link_just_syms
#define bfd_elf64_bfd_link_just_syms          ppc64_elf_link_just_syms
Line 2725... Line 2726...
                                   "CORE", note_type, data, sizeof (data));
                                   "CORE", note_type, data, sizeof (data));
      }
      }
    }
    }
}
}
 
 
/* Merge backend specific data from an object file to the output
 
   object file when linking.  */
 
 
 
static bfd_boolean
 
ppc64_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
 
{
 
  /* Check if we have the same endianness.  */
 
  if (ibfd->xvec->byteorder != obfd->xvec->byteorder
 
      && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
 
      && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
 
    {
 
      const char *msg;
 
 
 
      if (bfd_big_endian (ibfd))
 
        msg = _("%B: compiled for a big endian system "
 
                "and target is little endian");
 
      else
 
        msg = _("%B: compiled for a little endian system "
 
                "and target is big endian");
 
 
 
      (*_bfd_error_handler) (msg, ibfd);
 
 
 
      bfd_set_error (bfd_error_wrong_format);
 
      return FALSE;
 
    }
 
 
 
  return TRUE;
 
}
 
 
 
/* Add extra PPC sections.  */
/* Add extra PPC sections.  */
 
 
static const struct bfd_elf_special_section ppc64_elf_special_sections[]=
static const struct bfd_elf_special_section ppc64_elf_special_sections[]=
{
{
  { STRING_COMMA_LEN (".plt"),    0, SHT_NOBITS,   0 },
  { STRING_COMMA_LEN (".plt"),    0, SHT_NOBITS,   0 },
Line 3747... Line 3719...
  asection *relbss;
  asection *relbss;
  asection *glink;
  asection *glink;
  asection *sfpr;
  asection *sfpr;
  asection *brlt;
  asection *brlt;
  asection *relbrlt;
  asection *relbrlt;
 
  asection *glink_eh_frame;
 
 
  /* Shortcut to .__tls_get_addr and __tls_get_addr.  */
  /* Shortcut to .__tls_get_addr and __tls_get_addr.  */
  struct ppc_link_hash_entry *tls_get_addr;
  struct ppc_link_hash_entry *tls_get_addr;
  struct ppc_link_hash_entry *tls_get_addr_fd;
  struct ppc_link_hash_entry *tls_get_addr_fd;
 
 
Line 3761... Line 3734...
  unsigned long stub_count[ppc_stub_plt_call];
  unsigned long stub_count[ppc_stub_plt_call];
 
 
  /* Number of stubs against global syms.  */
  /* Number of stubs against global syms.  */
  unsigned long stub_globals;
  unsigned long stub_globals;
 
 
 
  /* Set if PLT call stubs should load r11.  */
 
  unsigned int plt_static_chain:1;
 
 
  /* Set if we should emit symbols for stubs.  */
  /* Set if we should emit symbols for stubs.  */
  unsigned int emit_stub_syms:1;
  unsigned int emit_stub_syms:1;
 
 
  /* Set if __tls_get_addr optimization should not be done.  */
  /* Set if __tls_get_addr optimization should not be done.  */
  unsigned int no_tls_get_addr_opt:1;
  unsigned int no_tls_get_addr_opt:1;
Line 4155... Line 4131...
  /* Enter this entry into the linker stub hash table.  */
  /* Enter this entry into the linker stub hash table.  */
  stub_entry = ppc_stub_hash_lookup (&htab->stub_hash_table, stub_name,
  stub_entry = ppc_stub_hash_lookup (&htab->stub_hash_table, stub_name,
                                     TRUE, FALSE);
                                     TRUE, FALSE);
  if (stub_entry == NULL)
  if (stub_entry == NULL)
    {
    {
      info->callbacks->einfo (_("%B: cannot create stub entry %s\n"),
      info->callbacks->einfo (_("%P: %B: cannot create stub entry %s\n"),
                              section->owner, stub_name);
                              section->owner, stub_name);
      return NULL;
      return NULL;
    }
    }
 
 
  stub_entry->stub_sec = stub_sec;
  stub_entry->stub_sec = stub_sec;
Line 4194... Line 4170...
                                                    flags);
                                                    flags);
  if (htab->glink == NULL
  if (htab->glink == NULL
      || ! bfd_set_section_alignment (dynobj, htab->glink, 3))
      || ! bfd_set_section_alignment (dynobj, htab->glink, 3))
    return FALSE;
    return FALSE;
 
 
 
  if (!info->no_ld_generated_unwind_info)
 
    {
 
      flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS
 
               | SEC_IN_MEMORY | SEC_LINKER_CREATED);
 
      htab->glink_eh_frame = bfd_make_section_anyway_with_flags (dynobj,
 
                                                                 ".eh_frame",
 
                                                                 flags);
 
      if (htab->glink_eh_frame == NULL
 
          || !bfd_set_section_alignment (abfd, htab->glink_eh_frame, 2))
 
        return FALSE;
 
    }
 
 
  flags = SEC_ALLOC | SEC_LINKER_CREATED;
  flags = SEC_ALLOC | SEC_LINKER_CREATED;
  htab->iplt = bfd_make_section_anyway_with_flags (dynobj, ".iplt", flags);
  htab->iplt = bfd_make_section_anyway_with_flags (dynobj, ".iplt", flags);
  if (htab->iplt == NULL
  if (htab->iplt == NULL
      || ! bfd_set_section_alignment (dynobj, htab->iplt, 3))
      || ! bfd_set_section_alignment (dynobj, htab->iplt, 3))
    return FALSE;
    return FALSE;
Line 4376... Line 4364...
  struct ppc_link_hash_entry *edir, *eind;
  struct ppc_link_hash_entry *edir, *eind;
 
 
  edir = (struct ppc_link_hash_entry *) dir;
  edir = (struct ppc_link_hash_entry *) dir;
  eind = (struct ppc_link_hash_entry *) ind;
  eind = (struct ppc_link_hash_entry *) ind;
 
 
 
  edir->is_func |= eind->is_func;
 
  edir->is_func_descriptor |= eind->is_func_descriptor;
 
  edir->tls_mask |= eind->tls_mask;
 
  if (eind->oh != NULL)
 
    edir->oh = ppc_follow_link (eind->oh);
 
 
 
  /* If called to transfer flags for a weakdef during processing
 
     of elf_adjust_dynamic_symbol, don't copy NON_GOT_REF.
 
     We clear it ourselves for ELIMINATE_COPY_RELOCS.  */
 
  if (!(ELIMINATE_COPY_RELOCS
 
        && eind->elf.root.type != bfd_link_hash_indirect
 
        && edir->elf.dynamic_adjusted))
 
    edir->elf.non_got_ref |= eind->elf.non_got_ref;
 
 
 
  edir->elf.ref_dynamic |= eind->elf.ref_dynamic;
 
  edir->elf.ref_regular |= eind->elf.ref_regular;
 
  edir->elf.ref_regular_nonweak |= eind->elf.ref_regular_nonweak;
 
  edir->elf.needs_plt |= eind->elf.needs_plt;
 
 
 
  /* If we were called to copy over info for a weak sym, that's all.  */
 
  if (eind->elf.root.type != bfd_link_hash_indirect)
 
    return;
 
 
  /* Copy over any dynamic relocs we may have on the indirect sym.  */
  /* Copy over any dynamic relocs we may have on the indirect sym.  */
  if (eind->dyn_relocs != NULL)
  if (eind->dyn_relocs != NULL)
    {
    {
      if (edir->dyn_relocs != NULL)
      if (edir->dyn_relocs != NULL)
        {
        {
Line 4408... Line 4419...
 
 
      edir->dyn_relocs = eind->dyn_relocs;
      edir->dyn_relocs = eind->dyn_relocs;
      eind->dyn_relocs = NULL;
      eind->dyn_relocs = NULL;
    }
    }
 
 
  edir->is_func |= eind->is_func;
 
  edir->is_func_descriptor |= eind->is_func_descriptor;
 
  edir->tls_mask |= eind->tls_mask;
 
  if (eind->oh != NULL)
 
    edir->oh = ppc_follow_link (eind->oh);
 
 
 
  /* If called to transfer flags for a weakdef during processing
 
     of elf_adjust_dynamic_symbol, don't copy NON_GOT_REF.
 
     We clear it ourselves for ELIMINATE_COPY_RELOCS.  */
 
  if (!(ELIMINATE_COPY_RELOCS
 
        && eind->elf.root.type != bfd_link_hash_indirect
 
        && edir->elf.dynamic_adjusted))
 
    edir->elf.non_got_ref |= eind->elf.non_got_ref;
 
 
 
  edir->elf.ref_dynamic |= eind->elf.ref_dynamic;
 
  edir->elf.ref_regular |= eind->elf.ref_regular;
 
  edir->elf.ref_regular_nonweak |= eind->elf.ref_regular_nonweak;
 
  edir->elf.needs_plt |= eind->elf.needs_plt;
 
 
 
  /* If we were called to copy over info for a weak sym, that's all.  */
 
  if (eind->elf.root.type != bfd_link_hash_indirect)
 
    return;
 
 
 
  /* Copy over got entries that we may have already seen to the
  /* Copy over got entries that we may have already seen to the
     symbol which just became indirect.  */
     symbol which just became indirect.  */
  if (eind->elf.got.glist != NULL)
  if (eind->elf.got.glist != NULL)
    {
    {
      if (edir->elf.got.glist != NULL)
      if (edir->elf.got.glist != NULL)
Line 6473... Line 6461...
         of gcc out there that improperly (for this ABI) put initialized
         of gcc out there that improperly (for this ABI) put initialized
         function pointers, vtable refs and suchlike in read-only
         function pointers, vtable refs and suchlike in read-only
         sections.  Allow them to proceed, but warn that this might
         sections.  Allow them to proceed, but warn that this might
         break at runtime.  */
         break at runtime.  */
      info->callbacks->einfo
      info->callbacks->einfo
        (_("copy reloc against `%s' requires lazy plt linking; "
        (_("%P: copy reloc against `%s' requires lazy plt linking; "
           "avoid setting LD_BIND_NOW=1 or upgrade gcc\n"),
           "avoid setting LD_BIND_NOW=1 or upgrade gcc\n"),
         h->root.root.string);
         h->root.root.string);
    }
    }
 
 
  /* This is a reference to a symbol defined by a dynamic object which
  /* This is a reference to a symbol defined by a dynamic object which
     is not a function.  */
     is not a function.  */
 
 
  if (h->size == 0)
  if (h->size == 0)
    {
    {
      info->callbacks->einfo (_("dynamic variable `%s' is zero size\n"),
      info->callbacks->einfo (_("%P: dynamic variable `%s' is zero size\n"),
                              h->root.root.string);
                              h->root.root.string);
      return TRUE;
      return TRUE;
    }
    }
 
 
  /* We must allocate the symbol in our .dynbss section, which will
  /* We must allocate the symbol in our .dynbss section, which will
Line 6898... Line 6886...
          return TRUE;
          return TRUE;
        }
        }
      pp = &p->next;
      pp = &p->next;
    }
    }
 
 
  info->callbacks->einfo (_("dynreloc miscount for %B, section %A\n"),
  info->callbacks->einfo (_("%P: dynreloc miscount for %B, section %A\n"),
                          sec->owner, sec);
                          sec->owner, sec);
  bfd_set_error (bfd_error_bad_value);
  bfd_set_error (bfd_error_bad_value);
  return FALSE;
  return FALSE;
}
}
 
 
Line 8277... Line 8265...
              *drop &= ~ref_from_discarded;
              *drop &= ~ref_from_discarded;
              if ((*drop & can_optimize) != 0)
              if ((*drop & can_optimize) != 0)
                some_unused = 1;
                some_unused = 1;
              last = 0;
              last = 0;
            }
            }
          else if (*drop)
          else if (*drop & ref_from_discarded)
            {
            {
              some_unused = 1;
              some_unused = 1;
              last = ref_from_discarded;
              last = ref_from_discarded;
            }
            }
          else
          else
Line 9049... Line 9037...
               || s == htab->dynbss)
               || s == htab->dynbss)
        {
        {
          /* Strip this section if we don't need it; see the
          /* Strip this section if we don't need it; see the
             comment below.  */
             comment below.  */
        }
        }
 
      else if (s == htab->glink_eh_frame)
 
        {
 
          if (!bfd_is_abs_section (s->output_section))
 
            /* Not sized yet.  */
 
            continue;
 
        }
      else if (CONST_STRNEQ (s->name, ".rela"))
      else if (CONST_STRNEQ (s->name, ".rela"))
        {
        {
          if (s->size != 0)
          if (s->size != 0)
            {
            {
              if (s != htab->relplt)
              if (s != htab->relplt)
Line 9280... Line 9274...
}
}
 
 
/* Build a .plt call stub.  */
/* Build a .plt call stub.  */
 
 
static inline bfd_byte *
static inline bfd_byte *
build_plt_stub (bfd *obfd, bfd_byte *p, int offset, Elf_Internal_Rela *r)
build_plt_stub (bfd *obfd, bfd_byte *p, int offset, Elf_Internal_Rela *r,
 
                bfd_boolean plt_static_chain)
{
{
#define PPC_LO(v) ((v) & 0xffff)
#define PPC_LO(v) ((v) & 0xffff)
#define PPC_HI(v) (((v) >> 16) & 0xffff)
#define PPC_HI(v) (((v) >> 16) & 0xffff)
#define PPC_HA(v) PPC_HI ((v) + 0x8000)
#define PPC_HA(v) PPC_HI ((v) + 0x8000)
 
 
Line 9294... Line 9289...
        {
        {
          r[0].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_HA);
          r[0].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_HA);
          r[1].r_offset = r[0].r_offset + 8;
          r[1].r_offset = r[0].r_offset + 8;
          r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
          r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
          r[1].r_addend = r[0].r_addend;
          r[1].r_addend = r[0].r_addend;
          if (PPC_HA (offset + 16) != PPC_HA (offset))
          if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
            {
            {
              r[2].r_offset = r[1].r_offset + 4;
              r[2].r_offset = r[1].r_offset + 4;
              r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO);
              r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO);
              r[2].r_addend = r[0].r_addend;
              r[2].r_addend = r[0].r_addend;
            }
            }
          else
          else
            {
            {
              r[2].r_offset = r[1].r_offset + 8;
              r[2].r_offset = r[1].r_offset + 8;
              r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
              r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
              r[2].r_addend = r[0].r_addend + 8;
              r[2].r_addend = r[0].r_addend + 8;
 
              if (plt_static_chain)
 
                {
              r[3].r_offset = r[2].r_offset + 4;
              r[3].r_offset = r[2].r_offset + 4;
              r[3].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
              r[3].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
              r[3].r_addend = r[0].r_addend + 16;
              r[3].r_addend = r[0].r_addend + 16;
            }
            }
        }
        }
 
        }
      bfd_put_32 (obfd, ADDIS_R12_R2 | PPC_HA (offset), p),     p += 4;
      bfd_put_32 (obfd, ADDIS_R12_R2 | PPC_HA (offset), p),     p += 4;
      bfd_put_32 (obfd, STD_R2_40R1, p),                        p += 4;
      bfd_put_32 (obfd, STD_R2_40R1, p),                        p += 4;
      bfd_put_32 (obfd, LD_R11_0R12 | PPC_LO (offset), p),      p += 4;
      bfd_put_32 (obfd, LD_R11_0R12 | PPC_LO (offset), p),      p += 4;
      if (PPC_HA (offset + 16) != PPC_HA (offset))
      if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
        {
        {
          bfd_put_32 (obfd, ADDI_R12_R12 | PPC_LO (offset), p), p += 4;
          bfd_put_32 (obfd, ADDI_R12_R12 | PPC_LO (offset), p), p += 4;
          offset = 0;
          offset = 0;
        }
        }
      bfd_put_32 (obfd, MTCTR_R11, p),                          p += 4;
      bfd_put_32 (obfd, MTCTR_R11, p),                          p += 4;
      bfd_put_32 (obfd, LD_R2_0R12 | PPC_LO (offset + 8), p),   p += 4;
      bfd_put_32 (obfd, LD_R2_0R12 | PPC_LO (offset + 8), p),   p += 4;
 
      if (plt_static_chain)
      bfd_put_32 (obfd, LD_R11_0R12 | PPC_LO (offset + 16), p), p += 4;
      bfd_put_32 (obfd, LD_R11_0R12 | PPC_LO (offset + 16), p), p += 4;
      bfd_put_32 (obfd, BCTR, p),                               p += 4;
      bfd_put_32 (obfd, BCTR, p),                               p += 4;
    }
    }
  else
  else
    {
    {
      if (r != NULL)
      if (r != NULL)
        {
        {
          r[0].r_offset += 4;
          r[0].r_offset += 4;
          r[0].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
          r[0].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
          if (PPC_HA (offset + 16) != PPC_HA (offset))
          if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
            {
            {
              r[1].r_offset = r[0].r_offset + 4;
              r[1].r_offset = r[0].r_offset + 4;
              r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16);
              r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16);
              r[1].r_addend = r[0].r_addend;
              r[1].r_addend = r[0].r_addend;
            }
            }
          else
          else
            {
            {
              r[1].r_offset = r[0].r_offset + 8;
              r[1].r_offset = r[0].r_offset + 8;
              r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
              r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
              r[1].r_addend = r[0].r_addend + 16;
              r[1].r_addend = r[0].r_addend + 8 + 8 * plt_static_chain;
 
              if (plt_static_chain)
 
                {
              r[2].r_offset = r[1].r_offset + 4;
              r[2].r_offset = r[1].r_offset + 4;
              r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
              r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
              r[2].r_addend = r[0].r_addend + 8;
              r[2].r_addend = r[0].r_addend + 8;
            }
            }
        }
        }
 
        }
      bfd_put_32 (obfd, STD_R2_40R1, p),                        p += 4;
      bfd_put_32 (obfd, STD_R2_40R1, p),                        p += 4;
      bfd_put_32 (obfd, LD_R11_0R2 | PPC_LO (offset), p),       p += 4;
      bfd_put_32 (obfd, LD_R11_0R2 | PPC_LO (offset), p),       p += 4;
      if (PPC_HA (offset + 16) != PPC_HA (offset))
      if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
        {
        {
          bfd_put_32 (obfd, ADDI_R2_R2 | PPC_LO (offset), p),   p += 4;
          bfd_put_32 (obfd, ADDI_R2_R2 | PPC_LO (offset), p),   p += 4;
          offset = 0;
          offset = 0;
        }
        }
      bfd_put_32 (obfd, MTCTR_R11, p),                          p += 4;
      bfd_put_32 (obfd, MTCTR_R11, p),                          p += 4;
 
      if (plt_static_chain)
      bfd_put_32 (obfd, LD_R11_0R2 | PPC_LO (offset + 16), p),  p += 4;
      bfd_put_32 (obfd, LD_R11_0R2 | PPC_LO (offset + 16), p),  p += 4;
      bfd_put_32 (obfd, LD_R2_0R2 | PPC_LO (offset + 8), p),    p += 4;
      bfd_put_32 (obfd, LD_R2_0R2 | PPC_LO (offset + 8), p),    p += 4;
      bfd_put_32 (obfd, BCTR, p),                               p += 4;
      bfd_put_32 (obfd, BCTR, p),                               p += 4;
    }
    }
  return p;
  return p;
Line 9378... Line 9381...
#define LD_R2_0R1       0xe8410000
#define LD_R2_0R1       0xe8410000
#define MTLR_R11        0x7d6803a6
#define MTLR_R11        0x7d6803a6
 
 
static inline bfd_byte *
static inline bfd_byte *
build_tls_get_addr_stub (bfd *obfd, bfd_byte *p, int offset,
build_tls_get_addr_stub (bfd *obfd, bfd_byte *p, int offset,
                         Elf_Internal_Rela *r)
                         Elf_Internal_Rela *r, bfd_boolean plt_static_chain)
{
{
  bfd_put_32 (obfd, LD_R11_0R3 + 0, p),          p += 4;
  bfd_put_32 (obfd, LD_R11_0R3 + 0, p),          p += 4;
  bfd_put_32 (obfd, LD_R12_0R3 + 8, p),         p += 4;
  bfd_put_32 (obfd, LD_R12_0R3 + 8, p),         p += 4;
  bfd_put_32 (obfd, MR_R0_R3, p),               p += 4;
  bfd_put_32 (obfd, MR_R0_R3, p),               p += 4;
  bfd_put_32 (obfd, CMPDI_R11_0, p),            p += 4;
  bfd_put_32 (obfd, CMPDI_R11_0, p),            p += 4;
Line 9392... Line 9395...
  bfd_put_32 (obfd, MFLR_R11, p),               p += 4;
  bfd_put_32 (obfd, MFLR_R11, p),               p += 4;
  bfd_put_32 (obfd, STD_R11_0R1 + 32, p),       p += 4;
  bfd_put_32 (obfd, STD_R11_0R1 + 32, p),       p += 4;
 
 
  if (r != NULL)
  if (r != NULL)
    r[0].r_offset += 9 * 4;
    r[0].r_offset += 9 * 4;
  p = build_plt_stub (obfd, p, offset, r);
  p = build_plt_stub (obfd, p, offset, r, plt_static_chain);
  bfd_put_32 (obfd, BCTRL, p - 4);
  bfd_put_32 (obfd, BCTRL, p - 4);
 
 
  bfd_put_32 (obfd, LD_R11_0R1 + 32, p),        p += 4;
  bfd_put_32 (obfd, LD_R11_0R1 + 32, p),        p += 4;
  bfd_put_32 (obfd, LD_R2_0R1 + 40, p),         p += 4;
  bfd_put_32 (obfd, LD_R2_0R1 + 40, p),         p += 4;
  bfd_put_32 (obfd, MTLR_R11, p),               p += 4;
  bfd_put_32 (obfd, MTLR_R11, p),               p += 4;
Line 9451... Line 9454...
      bfd_vma opd_off = stub_entry->h->elf.root.u.def.value;
      bfd_vma opd_off = stub_entry->h->elf.root.u.def.value;
 
 
      if (strcmp (opd->name, ".opd") != 0
      if (strcmp (opd->name, ".opd") != 0
          || opd->reloc_count != 0)
          || opd->reloc_count != 0)
        {
        {
          info->callbacks->einfo (_("cannot find opd entry toc for %s\n"),
          info->callbacks->einfo (_("%P: cannot find opd entry toc for %s\n"),
                                  stub_entry->h->elf.root.root.string);
                                  stub_entry->h->elf.root.root.string);
          bfd_set_error (bfd_error_bad_value);
          bfd_set_error (bfd_error_bad_value);
          return 0;
          return 0;
        }
        }
      if (!bfd_get_section_contents (opd->owner, opd, buf, opd_off + 8, 8))
      if (!bfd_get_section_contents (opd->owner, opd, buf, opd_off + 8, 8))
Line 9533... Line 9536...
        }
        }
      bfd_put_32 (htab->stub_bfd, B_DOT | (off & 0x3fffffc), loc);
      bfd_put_32 (htab->stub_bfd, B_DOT | (off & 0x3fffffc), loc);
 
 
      if (off + (1 << 25) >= (bfd_vma) (1 << 26))
      if (off + (1 << 25) >= (bfd_vma) (1 << 26))
        {
        {
          info->callbacks->einfo (_("long branch stub `%s' offset overflow\n"),
          info->callbacks->einfo (_("%P: long branch stub `%s' offset overflow\n"),
                                  stub_entry->root.string);
                                  stub_entry->root.string);
          htab->stub_error = TRUE;
          htab->stub_error = TRUE;
          return FALSE;
          return FALSE;
        }
        }
 
 
Line 9592... Line 9595...
      br_entry = ppc_branch_hash_lookup (&htab->branch_hash_table,
      br_entry = ppc_branch_hash_lookup (&htab->branch_hash_table,
                                         stub_entry->root.string + 9,
                                         stub_entry->root.string + 9,
                                         FALSE, FALSE);
                                         FALSE, FALSE);
      if (br_entry == NULL)
      if (br_entry == NULL)
        {
        {
          info->callbacks->einfo (_("can't find branch stub `%s'\n"),
          info->callbacks->einfo (_("%P: can't find branch stub `%s'\n"),
                                  stub_entry->root.string);
                                  stub_entry->root.string);
          htab->stub_error = TRUE;
          htab->stub_error = TRUE;
          return FALSE;
          return FALSE;
        }
        }
 
 
Line 9654... Line 9657...
             - htab->stub_group[stub_entry->id_sec->id].toc_off);
             - htab->stub_group[stub_entry->id_sec->id].toc_off);
 
 
      if (off + 0x80008000 > 0xffffffff || (off & 7) != 0)
      if (off + 0x80008000 > 0xffffffff || (off & 7) != 0)
        {
        {
          info->callbacks->einfo
          info->callbacks->einfo
            (_("linkage table error against `%s'\n"),
            (_("%P: linkage table error against `%s'\n"),
             stub_entry->root.string);
             stub_entry->root.string);
          bfd_set_error (bfd_error_bad_value);
          bfd_set_error (bfd_error_bad_value);
          htab->stub_error = TRUE;
          htab->stub_error = TRUE;
          return FALSE;
          return FALSE;
        }
        }
Line 9796... Line 9799...
             - htab->stub_group[stub_entry->id_sec->id].toc_off);
             - htab->stub_group[stub_entry->id_sec->id].toc_off);
 
 
      if (off + 0x80008000 > 0xffffffff || (off & 7) != 0)
      if (off + 0x80008000 > 0xffffffff || (off & 7) != 0)
        {
        {
          info->callbacks->einfo
          info->callbacks->einfo
            (_("linkage table error against `%s'\n"),
            (_("%P: linkage table error against `%s'\n"),
             stub_entry->h != NULL
             stub_entry->h != NULL
             ? stub_entry->h->elf.root.root.string
             ? stub_entry->h->elf.root.root.string
             : "<local sym>");
             : "<local sym>");
          bfd_set_error (bfd_error_bad_value);
          bfd_set_error (bfd_error_bad_value);
          htab->stub_error = TRUE;
          htab->stub_error = TRUE;
Line 9809... Line 9812...
 
 
      r = NULL;
      r = NULL;
      if (info->emitrelocations)
      if (info->emitrelocations)
        {
        {
          r = get_relocs (stub_entry->stub_sec,
          r = get_relocs (stub_entry->stub_sec,
                          (2 + (PPC_HA (off) != 0)
                          (2
                           + (PPC_HA (off + 16) == PPC_HA (off))));
                           + (PPC_HA (off) != 0)
 
                           + (htab->plt_static_chain
 
                              && PPC_HA (off + 16) == PPC_HA (off))));
          if (r == NULL)
          if (r == NULL)
            return FALSE;
            return FALSE;
          r[0].r_offset = loc - stub_entry->stub_sec->contents;
          r[0].r_offset = loc - stub_entry->stub_sec->contents;
          if (bfd_big_endian (info->output_bfd))
          if (bfd_big_endian (info->output_bfd))
            r[0].r_offset += 2;
            r[0].r_offset += 2;
Line 9822... Line 9827...
        }
        }
      if (stub_entry->h != NULL
      if (stub_entry->h != NULL
          && (stub_entry->h == htab->tls_get_addr_fd
          && (stub_entry->h == htab->tls_get_addr_fd
              || stub_entry->h == htab->tls_get_addr)
              || stub_entry->h == htab->tls_get_addr)
          && !htab->no_tls_get_addr_opt)
          && !htab->no_tls_get_addr_opt)
        p = build_tls_get_addr_stub (htab->stub_bfd, loc, off, r);
        p = build_tls_get_addr_stub (htab->stub_bfd, loc, off, r,
 
                                     htab->plt_static_chain);
      else
      else
        p = build_plt_stub (htab->stub_bfd, loc, off, r);
        p = build_plt_stub (htab->stub_bfd, loc, off, r,
 
                            htab->plt_static_chain);
      size = p - loc;
      size = p - loc;
      break;
      break;
 
 
    default:
    default:
      BFD_FAIL ();
      BFD_FAIL ();
Line 9911... Line 9918...
              + plt->output_section->vma
              + plt->output_section->vma
              - elf_gp (plt->output_section->owner)
              - elf_gp (plt->output_section->owner)
              - htab->stub_group[stub_entry->id_sec->id].toc_off);
              - htab->stub_group[stub_entry->id_sec->id].toc_off);
 
 
      size = PLT_CALL_STUB_SIZE;
      size = PLT_CALL_STUB_SIZE;
 
      if (!htab->plt_static_chain)
 
        size -= 4;
      if (PPC_HA (off) == 0)
      if (PPC_HA (off) == 0)
        size -= 4;
        size -= 4;
      if (PPC_HA (off + 16) != PPC_HA (off))
      if (PPC_HA (off + 8 + 8 * htab->plt_static_chain) != PPC_HA (off))
        size += 4;
        size += 4;
      if (stub_entry->h != NULL
      if (stub_entry->h != NULL
          && (stub_entry->h == htab->tls_get_addr_fd
          && (stub_entry->h == htab->tls_get_addr_fd
              || stub_entry->h == htab->tls_get_addr)
              || stub_entry->h == htab->tls_get_addr)
          && !htab->no_tls_get_addr_opt)
          && !htab->no_tls_get_addr_opt)
        size += 13 * 4;
        size += 13 * 4;
      if (info->emitrelocations)
      if (info->emitrelocations)
        {
        {
          stub_entry->stub_sec->reloc_count
          stub_entry->stub_sec->reloc_count
            += 2 + (PPC_HA (off) != 0) + (PPC_HA (off + 16) == PPC_HA (off));
            += (2
 
                + (PPC_HA (off) != 0)
 
                + (htab->plt_static_chain
 
                   && PPC_HA (off + 16) == PPC_HA (off)));
          stub_entry->stub_sec->flags |= SEC_RELOC;
          stub_entry->stub_sec->flags |= SEC_RELOC;
        }
        }
    }
    }
  else
  else
    {
    {
Line 9970... Line 9982...
          br_entry = ppc_branch_hash_lookup (&htab->branch_hash_table,
          br_entry = ppc_branch_hash_lookup (&htab->branch_hash_table,
                                             stub_entry->root.string + 9,
                                             stub_entry->root.string + 9,
                                             TRUE, FALSE);
                                             TRUE, FALSE);
          if (br_entry == NULL)
          if (br_entry == NULL)
            {
            {
              info->callbacks->einfo (_("can't build branch stub `%s'\n"),
              info->callbacks->einfo (_("%P: can't build branch stub `%s'\n"),
                                      stub_entry->root.string);
                                      stub_entry->root.string);
              htab->stub_error = TRUE;
              htab->stub_error = TRUE;
              return FALSE;
              return FALSE;
            }
            }
 
 
Line 10843... Line 10855...
  while (list-- != htab->input_list);
  while (list-- != htab->input_list);
  free (htab->input_list);
  free (htab->input_list);
#undef PREV_SEC
#undef PREV_SEC
}
}
 
 
 
static const unsigned char glink_eh_frame_cie[] =
 
{
 
  0, 0, 0, 16,                             /* length.  */
 
  0, 0, 0, 0,                               /* id.  */
 
  1,                                    /* CIE version.  */
 
  'z', 'R', 0,                           /* Augmentation string.  */
 
  4,                                    /* Code alignment.  */
 
  0x78,                                 /* Data alignment.  */
 
  65,                                   /* RA reg.  */
 
  1,                                    /* Augmentation size.  */
 
  DW_EH_PE_pcrel | DW_EH_PE_sdata4,     /* FDE encoding.  */
 
  DW_CFA_def_cfa, 1, 0                   /* def_cfa: r1 offset 0.  */
 
};
 
 
 
/* Stripping output sections is normally done before dynamic section
 
   symbols have been allocated.  This function is called later, and
 
   handles cases like htab->brlt which is mapped to its own output
 
   section.  */
 
 
 
static void
 
maybe_strip_output (struct bfd_link_info *info, asection *isec)
 
{
 
  if (isec->size == 0
 
      && isec->output_section->size == 0
 
      && !bfd_section_removed_from_list (info->output_bfd,
 
                                         isec->output_section)
 
      && elf_section_data (isec->output_section)->dynindx == 0)
 
    {
 
      isec->output_section->flags |= SEC_EXCLUDE;
 
      bfd_section_list_remove (info->output_bfd, isec->output_section);
 
      info->output_bfd->section_count--;
 
    }
 
}
 
 
/* Determine and set the size of the stub section for a final link.
/* Determine and set the size of the stub section for a final link.
 
 
   The basic idea here is to examine all the relocations looking for
   The basic idea here is to examine all the relocations looking for
   PC-relative calls to a target that is unreachable with a "bl"
   PC-relative calls to a target that is unreachable with a "bl"
   instruction.  */
   instruction.  */
 
 
bfd_boolean
bfd_boolean
ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size)
ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
 
                      bfd_boolean plt_static_chain)
{
{
  bfd_size_type stub_group_size;
  bfd_size_type stub_group_size;
  bfd_boolean stubs_always_before_branch;
  bfd_boolean stubs_always_before_branch;
  struct ppc_link_hash_table *htab = ppc_hash_table (info);
  struct ppc_link_hash_table *htab = ppc_hash_table (info);
 
 
  if (htab == NULL)
  if (htab == NULL)
    return FALSE;
    return FALSE;
 
 
 
  htab->plt_static_chain = plt_static_chain;
  stubs_always_before_branch = group_size < 0;
  stubs_always_before_branch = group_size < 0;
  if (group_size < 0)
  if (group_size < 0)
    stub_group_size = -group_size;
    stub_group_size = -group_size;
  else
  else
    stub_group_size = group_size;
    stub_group_size = group_size;
Line 11184... Line 11232...
        {
        {
          htab->glink->reloc_count = 1;
          htab->glink->reloc_count = 1;
          htab->glink->flags |= SEC_RELOC;
          htab->glink->flags |= SEC_RELOC;
        }
        }
 
 
 
      if (htab->glink_eh_frame != NULL
 
          && !bfd_is_abs_section (htab->glink_eh_frame->output_section)
 
          && (htab->glink_eh_frame->flags & SEC_EXCLUDE) == 0)
 
        {
 
          bfd_size_type size = 0;
 
 
 
          for (stub_sec = htab->stub_bfd->sections;
 
               stub_sec != NULL;
 
               stub_sec = stub_sec->next)
 
            if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
 
              size += 20;
 
          if (htab->glink != NULL && htab->glink->size != 0)
 
            size += 24;
 
          if (size != 0)
 
            size += sizeof (glink_eh_frame_cie);
 
          htab->glink_eh_frame->rawsize = htab->glink_eh_frame->size;
 
          htab->glink_eh_frame->size = size;
 
        }
 
 
      for (stub_sec = htab->stub_bfd->sections;
      for (stub_sec = htab->stub_bfd->sections;
           stub_sec != NULL;
           stub_sec != NULL;
           stub_sec = stub_sec->next)
           stub_sec = stub_sec->next)
        if ((stub_sec->flags & SEC_LINKER_CREATED) == 0
        if ((stub_sec->flags & SEC_LINKER_CREATED) == 0
            && stub_sec->rawsize != stub_sec->size)
            && stub_sec->rawsize != stub_sec->size)
          break;
          break;
 
 
      /* Exit from this loop when no stubs have been added, and no stubs
      /* Exit from this loop when no stubs have been added, and no stubs
         have changed size.  */
         have changed size.  */
      if (stub_sec == NULL)
      if (stub_sec == NULL
 
          && (htab->glink_eh_frame == NULL
 
              || htab->glink_eh_frame->rawsize == htab->glink_eh_frame->size))
        break;
        break;
 
 
      /* Ask the linker to do its stuff.  */
      /* Ask the linker to do its stuff.  */
      (*htab->layout_sections_again) ();
      (*htab->layout_sections_again) ();
    }
    }
 
 
  /* It would be nice to strip htab->brlt from the output if the
  maybe_strip_output (info, htab->brlt);
     section is empty, but it's too late.  If we strip sections here,
  if (htab->glink_eh_frame != NULL)
     the dynamic symbol table is corrupted since the section symbol
    maybe_strip_output (info, htab->glink_eh_frame);
     for the stripped section isn't written.  */
 
 
 
  return TRUE;
  return TRUE;
}
}
 
 
/* Called after we have determined section placement.  If sections
/* Called after we have determined section placement.  If sections
Line 11408... Line 11476...
                                            htab->relbrlt->size);
                                            htab->relbrlt->size);
      if (htab->relbrlt->contents == NULL)
      if (htab->relbrlt->contents == NULL)
        return FALSE;
        return FALSE;
    }
    }
 
 
 
  if (htab->glink_eh_frame != NULL
 
      && htab->glink_eh_frame->size != 0)
 
    {
 
      bfd_vma val;
 
 
 
      p = bfd_zalloc (htab->glink_eh_frame->owner, htab->glink_eh_frame->size);
 
      if (p == NULL)
 
        return FALSE;
 
      htab->glink_eh_frame->contents = p;
 
 
 
      htab->glink_eh_frame->rawsize = htab->glink_eh_frame->size;
 
 
 
      memcpy (p, glink_eh_frame_cie, sizeof (glink_eh_frame_cie));
 
      /* CIE length (rewrite in case little-endian).  */
 
      bfd_put_32 (htab->elf.dynobj, sizeof (glink_eh_frame_cie) - 4, p);
 
      p += sizeof (glink_eh_frame_cie);
 
 
 
      for (stub_sec = htab->stub_bfd->sections;
 
           stub_sec != NULL;
 
           stub_sec = stub_sec->next)
 
        if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
 
          {
 
            /* FDE length.  */
 
            bfd_put_32 (htab->elf.dynobj, 16, p);
 
            p += 4;
 
            /* CIE pointer.  */
 
            val = p - htab->glink_eh_frame->contents;
 
            bfd_put_32 (htab->elf.dynobj, val, p);
 
            p += 4;
 
            /* Offset to stub section.  */
 
            val = (stub_sec->output_section->vma
 
                   + stub_sec->output_offset);
 
            val -= (htab->glink_eh_frame->output_section->vma
 
                    + htab->glink_eh_frame->output_offset);
 
            val -= p - htab->glink_eh_frame->contents;
 
            if (val + 0x80000000 > 0xffffffff)
 
              {
 
                info->callbacks->einfo
 
                  (_("%P: %s offset too large for .eh_frame sdata4 encoding"),
 
                   stub_sec->name);
 
                return FALSE;
 
              }
 
            bfd_put_32 (htab->elf.dynobj, val, p);
 
            p += 4;
 
            /* stub section size.  */
 
            bfd_put_32 (htab->elf.dynobj, stub_sec->rawsize, p);
 
            p += 4;
 
            /* Augmentation.  */
 
            p += 1;
 
            /* Pad.  */
 
            p += 3;
 
          }
 
      if (htab->glink != NULL && htab->glink->size != 0)
 
        {
 
          /* FDE length.  */
 
          bfd_put_32 (htab->elf.dynobj, 20, p);
 
          p += 4;
 
          /* CIE pointer.  */
 
          val = p - htab->glink_eh_frame->contents;
 
          bfd_put_32 (htab->elf.dynobj, val, p);
 
          p += 4;
 
          /* Offset to .glink.  */
 
          val = (htab->glink->output_section->vma
 
                 + htab->glink->output_offset
 
                 + 8);
 
          val -= (htab->glink_eh_frame->output_section->vma
 
                  + htab->glink_eh_frame->output_offset);
 
          val -= p - htab->glink_eh_frame->contents;
 
          if (val + 0x80000000 > 0xffffffff)
 
            {
 
              info->callbacks->einfo
 
                (_("%P: %s offset too large for .eh_frame sdata4 encoding"),
 
                 htab->glink->name);
 
              return FALSE;
 
            }
 
          bfd_put_32 (htab->elf.dynobj, val, p);
 
          p += 4;
 
          /* .glink size.  */
 
          bfd_put_32 (htab->elf.dynobj, htab->glink->rawsize - 8, p);
 
          p += 4;
 
          /* Augmentation.  */
 
          p += 1;
 
 
 
          *p++ = DW_CFA_advance_loc + 1;
 
          *p++ = DW_CFA_register;
 
          *p++ = 65;
 
          *p++ = 12;
 
          *p++ = DW_CFA_advance_loc + 4;
 
          *p++ = DW_CFA_restore_extended;
 
          *p++ = 65;
 
        }
 
      htab->glink_eh_frame->size = p - htab->glink_eh_frame->contents;
 
    }
 
 
  /* Build the stubs as directed by the stub hash table.  */
  /* Build the stubs as directed by the stub hash table.  */
  bfd_hash_traverse (&htab->stub_hash_table, ppc_build_one_stub, info);
  bfd_hash_traverse (&htab->stub_hash_table, ppc_build_one_stub, info);
 
 
  if (htab->relbrlt != NULL)
  if (htab->relbrlt != NULL)
    htab->relbrlt->reloc_count = 0;
    htab->relbrlt->reloc_count = 0;
Line 11425... Line 11587...
        if (stub_sec->rawsize != stub_sec->size)
        if (stub_sec->rawsize != stub_sec->size)
          break;
          break;
      }
      }
 
 
  if (stub_sec != NULL
  if (stub_sec != NULL
      || htab->glink->rawsize != htab->glink->size)
      || htab->glink->rawsize != htab->glink->size
 
      || (htab->glink_eh_frame != NULL
 
          && htab->glink_eh_frame->rawsize != htab->glink_eh_frame->size))
    {
    {
      htab->stub_error = TRUE;
      htab->stub_error = TRUE;
      info->callbacks->einfo (_("stubs don't match calculated size\n"));
      info->callbacks->einfo (_("%P: stubs don't match calculated size\n"));
    }
    }
 
 
  if (htab->stub_error)
  if (htab->stub_error)
    return FALSE;
    return FALSE;
 
 
Line 11787... Line 11951...
            /* R_PPC64_TLS is OK against a symbol in the TOC.  */
            /* R_PPC64_TLS is OK against a symbol in the TOC.  */
            ;
            ;
          else
          else
            info->callbacks->einfo
            info->callbacks->einfo
              (!IS_PPC64_TLS_RELOC (r_type)
              (!IS_PPC64_TLS_RELOC (r_type)
               ? _("%H: %s used with TLS symbol %s\n")
               ? _("%P: %H: %s used with TLS symbol %s\n")
               : _("%H: %s used with non-TLS symbol %s\n"),
               : _("%P: %H: %s used with non-TLS symbol %s\n"),
               input_bfd, input_section, rel->r_offset,
               input_bfd, input_section, rel->r_offset,
               ppc64_elf_howto_table[r_type]->name,
               ppc64_elf_howto_table[r_type]->name,
               sym_name);
               sym_name);
        }
        }
 
 
Line 12286... Line 12450...
                      if (strcmp (input_section->output_section->name,
                      if (strcmp (input_section->output_section->name,
                                  ".init") == 0
                                  ".init") == 0
                          || strcmp (input_section->output_section->name,
                          || strcmp (input_section->output_section->name,
                                     ".fini") == 0)
                                     ".fini") == 0)
                        info->callbacks->einfo
                        info->callbacks->einfo
                          (_("%H: automatic multiple TOCs "
                          (_("%P: %H: automatic multiple TOCs "
                             "not supported using your crt files; "
                             "not supported using your crt files; "
                             "recompile with -mminimal-toc or upgrade gcc\n"),
                             "recompile with -mminimal-toc or upgrade gcc\n"),
                           input_bfd, input_section, rel->r_offset);
                           input_bfd, input_section, rel->r_offset);
                      else
                      else
                        info->callbacks->einfo
                        info->callbacks->einfo
                          (_("%H: sibling call optimization to `%s' "
                          (_("%P: %H: sibling call optimization to `%s' "
                             "does not allow automatic multiple TOCs; "
                             "does not allow automatic multiple TOCs; "
                             "recompile with -mminimal-toc or "
                             "recompile with -mminimal-toc or "
                             "-fno-optimize-sibling-calls, "
                             "-fno-optimize-sibling-calls, "
                             "or make `%s' extern\n"),
                             "or make `%s' extern\n"),
                           input_bfd, input_section, rel->r_offset,
                           input_bfd, input_section, rel->r_offset,
Line 12399... Line 12563...
      tls_type = 0;
      tls_type = 0;
      switch (r_type)
      switch (r_type)
        {
        {
        default:
        default:
          info->callbacks->einfo
          info->callbacks->einfo
            (_("%B: unknown relocation type %d for symbol %s\n"),
            (_("%P: %B: unknown relocation type %d for symbol %s\n"),
             input_bfd, (int) r_type, sym_name);
             input_bfd, (int) r_type, sym_name);
 
 
          bfd_set_error (bfd_error_bad_value);
          bfd_set_error (bfd_error_bad_value);
          ret = FALSE;
          ret = FALSE;
          continue;
          continue;
Line 12904... Line 13068...
                      if (h != NULL
                      if (h != NULL
                          ? h->elf.type == STT_GNU_IFUNC
                          ? h->elf.type == STT_GNU_IFUNC
                          : ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
                          : ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
                        {
                        {
                          info->callbacks->einfo
                          info->callbacks->einfo
                            (_("%H: relocation %s for indirect "
                            (_("%P: %H: relocation %s for indirect "
                               "function %s unsupported\n"),
                               "function %s unsupported\n"),
                             input_bfd, input_section, rel->r_offset,
                             input_bfd, input_section, rel->r_offset,
                             ppc64_elf_howto_table[r_type]->name,
                             ppc64_elf_howto_table[r_type]->name,
                             sym_name);
                             sym_name);
                          ret = FALSE;
                          ret = FALSE;
Line 13009... Line 13173...
        case R_PPC64_PLTREL32:
        case R_PPC64_PLTREL32:
        case R_PPC64_PLTREL64:
        case R_PPC64_PLTREL64:
          /* These ones haven't been implemented yet.  */
          /* These ones haven't been implemented yet.  */
 
 
          info->callbacks->einfo
          info->callbacks->einfo
            (_("%B: relocation %s is not supported for symbol %s\n"),
            (_("%P: %B: relocation %s is not supported for symbol %s\n"),
             input_bfd,
             input_bfd,
             ppc64_elf_howto_table[r_type]->name, sym_name);
             ppc64_elf_howto_table[r_type]->name, sym_name);
 
 
          bfd_set_error (bfd_error_invalid_operation);
          bfd_set_error (bfd_error_invalid_operation);
          ret = FALSE;
          ret = FALSE;
Line 13186... Line 13350...
          if ((insn & (0x3f << 26)) == (56u << 26))
          if ((insn & (0x3f << 26)) == (56u << 26))
            mask = 15;
            mask = 15;
          if (((relocation + addend) & mask) != 0)
          if (((relocation + addend) & mask) != 0)
            {
            {
              info->callbacks->einfo
              info->callbacks->einfo
                (_("%H: error: %s not a multiple of %u\n"),
                (_("%P: %H: error: %s not a multiple of %u\n"),
                 input_bfd, input_section, rel->r_offset,
                 input_bfd, input_section, rel->r_offset,
                 ppc64_elf_howto_table[r_type]->name,
                 ppc64_elf_howto_table[r_type]->name,
                 mask + 1);
                 mask + 1);
              bfd_set_error (bfd_error_bad_value);
              bfd_set_error (bfd_error_bad_value);
              ret = FALSE;
              ret = FALSE;
Line 13205... Line 13369...
      if (unresolved_reloc
      if (unresolved_reloc
          && !((input_section->flags & SEC_DEBUGGING) != 0
          && !((input_section->flags & SEC_DEBUGGING) != 0
               && h->elf.def_dynamic))
               && h->elf.def_dynamic))
        {
        {
          info->callbacks->einfo
          info->callbacks->einfo
            (_("%H: unresolvable %s relocation against symbol `%s'\n"),
            (_("%P: %H: unresolvable %s relocation against symbol `%s'\n"),
             input_bfd, input_section, rel->r_offset,
             input_bfd, input_section, rel->r_offset,
             ppc64_elf_howto_table[(int) r_type]->name,
             ppc64_elf_howto_table[(int) r_type]->name,
             h->elf.root.root.string);
             h->elf.root.root.string);
          ret = FALSE;
          ret = FALSE;
        }
        }
Line 13250... Line 13414...
                return FALSE;
                return FALSE;
            }
            }
          else
          else
            {
            {
              info->callbacks->einfo
              info->callbacks->einfo
                (_("%H: %s reloc against `%s': error %d\n"),
                (_("%P: %H: %s reloc against `%s': error %d\n"),
                 input_bfd, input_section, rel->r_offset,
                 input_bfd, input_section, rel->r_offset,
                 ppc64_elf_howto_table[r_type]->name,
                 ppc64_elf_howto_table[r_type]->name,
                 sym_name,
                 sym_name,
                 (int) r);
                 (int) r);
              ret = FALSE;
              ret = FALSE;
Line 13574... Line 13738...
                                       elf_section_data (htab->glink)->rela.hdr,
                                       elf_section_data (htab->glink)->rela.hdr,
                                       elf_section_data (htab->glink)->relocs,
                                       elf_section_data (htab->glink)->relocs,
                                       NULL))
                                       NULL))
    return FALSE;
    return FALSE;
 
 
 
 
 
  if (htab->glink_eh_frame != NULL
 
      && htab->glink_eh_frame->sec_info_type == ELF_INFO_TYPE_EH_FRAME
 
      && !_bfd_elf_write_section_eh_frame (output_bfd, info,
 
                                           htab->glink_eh_frame,
 
                                           htab->glink_eh_frame->contents))
 
    return FALSE;
 
 
  /* We need to handle writing out multiple GOT sections ourselves,
  /* We need to handle writing out multiple GOT sections ourselves,
     since we didn't add them to DYNOBJ.  We know dynobj is the first
     since we didn't add them to DYNOBJ.  We know dynobj is the first
     bfd.  */
     bfd.  */
  while ((dynobj = dynobj->link_next) != NULL)
  while ((dynobj = dynobj->link_next) != NULL)
    {
    {

powered by: WebSVN 2.1.0

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