daily update
[deliverable/binutils-gdb.git] / bfd / elf32-ppc.c
index 353f288b18a5caf3455668f96dacabbf5a102aac..6e80a1e29c289fad723f880ffbece3403d4d8079 100644 (file)
@@ -1,6 +1,6 @@
 /* PowerPC-specific support for 32-bit ELF
    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2005 Free Software Foundation, Inc.
+   2004, 2005, 2006 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -1708,11 +1708,14 @@ struct ppc_elf_obj_tdata
 static bfd_boolean
 ppc_elf_mkobject (bfd *abfd)
 {
-  bfd_size_type amt = sizeof (struct ppc_elf_obj_tdata);
-  abfd->tdata.any = bfd_zalloc (abfd, amt);
   if (abfd->tdata.any == NULL)
-    return FALSE;
-  return TRUE;
+    {
+      bfd_size_type amt = sizeof (struct ppc_elf_obj_tdata);
+      abfd->tdata.any = bfd_zalloc (abfd, amt);
+      if (abfd->tdata.any == NULL)
+       return FALSE;
+    }
+  return bfd_elf_mkobject (abfd);
 }
 
 /* Fix bad default arch selected for a 32 bit input bfd when the
@@ -1869,7 +1872,8 @@ ppc_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
    need to bump up the number of section headers.  */
 
 static int
-ppc_elf_additional_program_headers (bfd *abfd)
+ppc_elf_additional_program_headers (bfd *abfd,
+                                   struct bfd_link_info *info ATTRIBUTE_UNUSED)
 {
   asection *s;
   int ret = 0;
@@ -2430,8 +2434,9 @@ ppc_elf_link_hash_table_create (bfd *abfd)
   if (ret == NULL)
     return NULL;
 
-  if (! _bfd_elf_link_hash_table_init (&ret->elf, abfd,
-                                      ppc_elf_link_hash_newfunc))
+  if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
+                                     ppc_elf_link_hash_newfunc,
+                                     sizeof (struct ppc_elf_link_hash_entry)))
     {
       free (ret);
       return NULL;
@@ -2548,19 +2553,9 @@ ppc_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
        return FALSE;
     }
 
-  /* Create the section for VxWorks static plt relocations.  */
-  if (htab->is_vxworks && !info->shared)
-    {
-      s = bfd_make_section (abfd, ".rela.plt.unloaded");
-      flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY
-              | SEC_LINKER_CREATED);
-      if (s == NULL
-         || ! bfd_set_section_flags (abfd, s, flags)
-         || ! bfd_set_section_alignment (abfd, s,
-                 get_elf_backend_data (abfd)->s->log_file_align))
-       return FALSE;
-      htab->srelplt2 = s;
-    }
+  if (htab->is_vxworks
+      && !elf_vxworks_create_dynamic_sections (abfd, info, &htab->srelplt2))
+    return FALSE;
 
   htab->relplt = bfd_get_section_by_name (abfd, ".rela.plt");
   htab->plt = s = bfd_get_section_by_name (abfd, ".plt");
@@ -2689,9 +2684,12 @@ static bfd_boolean
 is_ppc_elf_target (const struct bfd_target *targ)
 {
   extern const bfd_target bfd_elf32_powerpc_vec;
+  extern const bfd_target bfd_elf32_powerpc_vxworks_vec;
   extern const bfd_target bfd_elf32_powerpcle_vec;
 
-  return targ == &bfd_elf32_powerpc_vec || targ == &bfd_elf32_powerpcle_vec;
+  return (targ == &bfd_elf32_powerpc_vec
+         || targ == &bfd_elf32_powerpc_vxworks_vec
+         || targ == &bfd_elf32_powerpcle_vec);
 }
 
 /* Hook called by the linker routine which adds symbols from an object
@@ -3342,7 +3340,9 @@ ppc_elf_check_relocs (bfd *abfd,
              if (s == got2)
                htab->plt_type = PLT_OLD;
            }
-         /* fall through */
+         if (h == NULL || h == htab->elf.hgot)
+           break;
+         goto dodyn1;
 
        case R_PPC_REL24:
        case R_PPC_REL14:
@@ -3350,9 +3350,10 @@ ppc_elf_check_relocs (bfd *abfd,
        case R_PPC_REL14_BRNTAKEN:
          if (h == NULL)
            break;
-         if (h == htab->elf.hgot && htab->plt_type == PLT_UNSET)
+         if (h == htab->elf.hgot)
            {
-             htab->plt_type = PLT_OLD;
+             if (htab->plt_type == PLT_UNSET)
+               htab->plt_type = PLT_OLD;
              break;
            }
          /* fall through */
@@ -3368,6 +3369,7 @@ ppc_elf_check_relocs (bfd *abfd,
        case R_PPC_ADDR14_BRNTAKEN:
        case R_PPC_UADDR32:
        case R_PPC_UADDR16:
+       dodyn1:
          if (h != NULL && !info->shared)
            {
              /* We may need a plt entry if the symbol turns out to be
@@ -4764,21 +4766,6 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
   else
     htab->tlsld_got.offset = (bfd_vma) -1;
 
-  if (htab->is_vxworks)
-    {
-      /* Mark the GOT and PLT symbols as having relocations; they might
-        not, but we won't know for sure until we build the GOT in
-        finish_dynamic_symbol.  */
-      if (htab->elf.hgot)
-       htab->elf.hgot->indx = -2;
-      if (htab->elf.hplt)
-       {
-         htab->elf.hplt->indx = -2;
-         if (htab->plt->flags & SEC_CODE)
-           htab->elf.hplt->type = STT_FUNC;
-       }
-    }
-
   /* Allocate space for global sym dynamic relocs.  */
   elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
 
@@ -5198,6 +5185,10 @@ ppc_elf_relax_section (bfd *abfd,
       else if (r_type != R_PPC_PLTREL24)
        toff += irel->r_addend;
 
+      /* Attempted -shared link of non-pic code loses.  */
+      if (tsec->output_section == NULL)
+       continue;
+
       symaddr = tsec->output_section->vma + tsec->output_offset + toff;
 
       roff = irel->r_offset;
@@ -5785,6 +5776,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
                      insn1 |= 32 << 26;        /* lwz */
                      insn2 = 0x7c631214;       /* add 3,3,2 */
                      rel[1].r_info = ELF32_R_INFO (r_symndx2, R_PPC_NONE);
+                     rel[1].r_addend = 0;
                      r_type = (((r_type - (R_PPC_GOT_TLSGD16 & 3)) & 3)
                                + R_PPC_GOT_TPREL16);
                      rel->r_info = ELF32_R_INFO (r_symndx, r_type);
@@ -5799,13 +5791,13 @@ ppc_elf_relocate_section (bfd *output_bfd,
                          /* Was an LD reloc.  */
                          r_symndx = 0;
                          rel->r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
-                         rel[1].r_addend = htab->elf.tls_sec->vma + DTP_OFFSET;
                        }
                      r_type = R_PPC_TPREL16_HA;
                      rel->r_info = ELF32_R_INFO (r_symndx, r_type);
                      rel[1].r_info = ELF32_R_INFO (r_symndx,
                                                    R_PPC_TPREL16_LO);
                      rel[1].r_offset += 2;
+                     rel[1].r_addend = rel->r_addend;
                    }
                  bfd_put_32 (output_bfd, insn1, contents + rel->r_offset - 2);
                  bfd_put_32 (output_bfd, insn2, contents + offset);
@@ -6309,7 +6301,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
                          BFD_ASSERT (indx > 0);
 #ifdef DEBUG
                          if (indx <= 0)
-                           printf ("indx=%d section=%s flags=%08x name=%s\n",
+                           printf ("indx=%ld section=%s flags=%08x name=%s\n",
                                    indx, osec->name, osec->flags,
                                    h->root.root.string);
 #endif
@@ -6617,25 +6609,28 @@ ppc_elf_relocate_section (bfd *output_bfd,
 
        case R_PPC_ADDR16_HA:
        case R_PPC_REL16_HA:
-       case R_PPC_GOT16_HA:
-       case R_PPC_PLT16_HA:
        case R_PPC_SECTOFF_HA:
        case R_PPC_TPREL16_HA:
        case R_PPC_DTPREL16_HA:
-       case R_PPC_GOT_TLSGD16_HA:
-       case R_PPC_GOT_TLSLD16_HA:
-       case R_PPC_GOT_TPREL16_HA:
-       case R_PPC_GOT_DTPREL16_HA:
        case R_PPC_EMB_NADDR16_HA:
        case R_PPC_EMB_RELST_HA:
          /* It's just possible that this symbol is a weak symbol
             that's not actually defined anywhere.  In that case,
             'sec' would be NULL, and we should leave the symbol
             alone (it will be set to zero elsewhere in the link).  */
-         if (sec != NULL)
-           /* Add 0x10000 if sign bit in 0:15 is set.
-              Bits 0:15 are not used.  */
-           addend += 0x8000;
+         if (sec == NULL)
+           break;
+         /* Fall thru */
+
+       case R_PPC_PLT16_HA:
+       case R_PPC_GOT16_HA:
+       case R_PPC_GOT_TLSGD16_HA:
+       case R_PPC_GOT_TLSLD16_HA:
+       case R_PPC_GOT_TPREL16_HA:
+       case R_PPC_GOT_DTPREL16_HA:
+         /* Add 0x10000 if sign bit in 0:15 is set.
+            Bits 0:15 are not used.  */
+         addend += 0x8000;
          break;
        }
 
@@ -7448,6 +7443,7 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
 #define ELF_MAXPAGESIZE                0x10000
 #endif
 #define ELF_MINPAGESIZE                0x1000
+#define ELF_COMMONPAGESIZE     0x1000
 #define elf_info_to_howto      ppc_elf_info_to_howto
 
 #ifdef  EM_CYGNUS_POWERPC
This page took 0.029065 seconds and 4 git commands to generate.