daily update
[deliverable/binutils-gdb.git] / bfd / elf32-tic6x.c
index efacfb9fb93ac5c7dd015ed99f1612f5a09dc5ed..ef0d1555a9976eba0313c649c3c9ddc550d3fb1f 100644 (file)
@@ -1,5 +1,5 @@
 /* 32-bit ELF support for TI C6X
-   Copyright 2010, 2011
+   Copyright 2010, 2011, 2012
    Free Software Foundation, Inc.
    Contributed by Joseph Myers <joseph@codesourcery.com>
                  Bernd Schmidt  <bernds@codesourcery.com>
@@ -528,8 +528,32 @@ static reloc_howto_type elf32_tic6x_howto_table[] =
         0,                     /* src_mask */
         0xffffffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
-  EMPTY_HOWTO (29),
-  EMPTY_HOWTO (30),
+  HOWTO (R_C6000_PCR_H16,      /* type */
+        16,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        TRUE,                  /* pc_relative */
+        7,                     /* bitpos */
+        complain_overflow_dont,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_C6000_PCR_H16",     /* name */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x007fff80,            /* dst_mask */
+        TRUE),                 /* pcrel_offset */
+  HOWTO (R_C6000_PCR_L16,      /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        TRUE,                  /* pc_relative */
+        7,                     /* bitpos */
+        complain_overflow_dont,/* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_C6000_PCR_L16",     /* name */
+        FALSE,                 /* partial_inplace */
+        0,                     /* src_mask */
+        0x007fff80,            /* dst_mask */
+        TRUE),                 /* pcrel_offset */
   EMPTY_HOWTO (31),
   EMPTY_HOWTO (32),
   EMPTY_HOWTO (33),
@@ -1112,8 +1136,8 @@ static reloc_howto_type elf32_tic6x_howto_table_rel[] =
         0,                     /* src_mask */
         0xffffffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
-  EMPTY_HOWTO (29),
-  EMPTY_HOWTO (30),
+  EMPTY_HOWTO (R_C6000_PCR_H16),
+  EMPTY_HOWTO (R_C6000_PCR_L16),
   EMPTY_HOWTO (31),
   EMPTY_HOWTO (32),
   EMPTY_HOWTO (33),
@@ -1646,9 +1670,9 @@ elf32_tic6x_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
       || ! bfd_set_section_alignment (dynobj, htab->elf.splt, 5))
     return FALSE;
 
-  htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
+  htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
   if (!info->shared)
-    htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss");
+    htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
 
   if (!htab->sdynbss
       || (!info->shared && !htab->srelbss))
@@ -1825,8 +1849,8 @@ elf32_tic6x_finish_dynamic_symbol (bfd * output_bfd,
       /* This symbol has an entry in the global offset table.
          Set it up.  */
 
-      sgot = bfd_get_section_by_name (dynobj, ".got");
-      srela = bfd_get_section_by_name (dynobj, ".rela.got");
+      sgot = bfd_get_linker_section (dynobj, ".got");
+      srela = bfd_get_linker_section (dynobj, ".rela.got");
       BFD_ASSERT (sgot != NULL && srela != NULL);
 
       /* If this is a -Bsymbolic link, and the symbol is defined
@@ -1879,7 +1903,7 @@ elf32_tic6x_finish_dynamic_symbol (bfd * output_bfd,
     }
 
   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
-  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
+  if (h == elf_hash_table (info)->hdynamic
       || h == elf_hash_table (info)->hgot)
     sym->st_shndx = SHN_ABS;
 
@@ -1897,6 +1921,8 @@ elf32_tic6x_gc_mark_extra_sections (struct bfd_link_info *info,
   Elf_Internal_Shdr **elf_shdrp;
   bfd_boolean again;
 
+  _bfd_elf_gc_mark_extra_sections (info, gc_mark_hook);
+
   /* Marking EH data may cause additional code sections to be marked,
      requiring multiple passes.  */
   again = TRUE;
@@ -2131,13 +2157,6 @@ elf32_tic6x_adjust_dynamic_symbol (struct bfd_link_info *info,
   if (htab == NULL)
     return FALSE;
 
-  if (h->size == 0)
-    {
-      (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"),
-                            h->root.root.string);
-      return TRUE;
-    }
-
   /* We must allocate the symbol in our .dynbss section, which will
      become part of the .bss section of the executable.  There will be
      an entry for this symbol in the .dynsym section.  The dynamic
@@ -2151,7 +2170,7 @@ elf32_tic6x_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* We must generate a R_C6000_COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the
      runtime process image.  */
-  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
       htab->srelbss->size += sizeof (Elf32_External_Rela);
       h->needs_copy = 1;
@@ -2264,7 +2283,7 @@ elf32_tic6x_relocate_section (bfd *output_bfd,
       Elf_Internal_Sym *sym;
       asection *sec;
       struct elf_link_hash_entry *h;
-      bfd_vma off, relocation;
+      bfd_vma off, off2, relocation;
       bfd_boolean unresolved_reloc;
       bfd_reloc_status_type r;
       struct bfd_link_hash_entry *sbh;
@@ -2308,9 +2327,9 @@ elf32_tic6x_relocate_section (bfd *output_bfd,
                                   unresolved_reloc, warned);
        }
 
-      if (sec != NULL && elf_discarded_section (sec))
+      if (sec != NULL && discarded_section (sec))
        RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
-                                        rel, relend, howto, contents);
+                                        rel, 1, relend, howto, 0, contents);
 
       if (info->relocatable)
        {
@@ -2378,6 +2397,20 @@ elf32_tic6x_relocate_section (bfd *output_bfd,
          unresolved_reloc = FALSE;
          break;
 
+       case R_C6000_PCR_H16:
+       case R_C6000_PCR_L16:
+         off = (input_section->output_section->vma
+                + input_section->output_offset
+                + rel->r_offset);
+         /* These must be calculated as R = S - FP(FP(PC) - A).
+            PC, here, is the value we just computed in OFF.  RELOCATION
+            has the address of S + A. */
+         relocation -= rel->r_addend;
+         off2 = ((off & ~(bfd_vma)0x1f) - rel->r_addend) & (bfd_vma)~0x1f;
+         off2 = relocation - off2;
+         relocation = off + off2;
+         break;
+
        case R_C6000_DSBT_INDEX:
          relocation = elf32_tic6x_hash_table (info)->params.dsbt_index;
          if (!info->shared || relocation != 0)
@@ -3089,13 +3122,7 @@ elf32_tic6x_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
   if (h->root.type == bfd_link_hash_indirect)
     return TRUE;
 
-  if (h->root.type == bfd_link_hash_warning)
-    /* When warning symbols are created, they **replace** the "real"
-       entry in the hash table, thus we never get to see the real
-       symbol in a hash traversal.  So look at it now.  */
-    h = (struct elf_link_hash_entry *) h->root.u.i.link;
   eh = (struct elf32_tic6x_link_hash_entry *) h;
-
   info = (struct bfd_link_info *) inf;
   htab = elf32_tic6x_hash_table (info);
 
@@ -3239,9 +3266,6 @@ elf32_tic6x_readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
   struct elf32_tic6x_link_hash_entry *eh;
   struct elf_dyn_relocs *p;
 
-  if (h->root.type == bfd_link_hash_warning)
-    h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
   eh = (struct elf32_tic6x_link_hash_entry *) h;
   for (p = eh->dyn_relocs; p != NULL; p = p->next)
     {
@@ -3281,7 +3305,7 @@ elf32_tic6x_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
       /* Set the contents of the .interp section to the interpreter.  */
       if (info->executable)
        {
-         s = bfd_get_section_by_name (dynobj, ".interp");
+         s = bfd_get_linker_section (dynobj, ".interp");
          if (s == NULL)
            abort ();
          s->size = sizeof ELF_DYNAMIC_INTERPRETER;
@@ -3583,7 +3607,7 @@ elf32_tic6x_finish_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 
   htab = elf32_tic6x_hash_table (info);
   dynobj = htab->elf.dynobj;
-  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+  sdyn = bfd_get_linker_section (dynobj, ".dynamic");
 
   if (elf_hash_table (info)->dynamic_sections_created)
     {
@@ -3987,6 +4011,9 @@ elf32_tic6x_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
   if (!_bfd_generic_verify_endian_match (ibfd, obfd))
     return FALSE;
 
+  if (! is_tic6x_elf (ibfd) || ! is_tic6x_elf (obfd))
+    return TRUE;
+
   if (!elf32_tic6x_merge_attributes (ibfd, obfd))
     return FALSE;
 
@@ -4442,7 +4469,7 @@ elf32_tic6x_write_section (bfd *output_bfd,
 static void
 elf32_tic6x_set_osabi (bfd *abfd, struct bfd_link_info *link_info)
 {
-  if (link_info == NULL || link_info->relocatable)
+  if (link_info != NULL && link_info->relocatable)
     return;
   _bfd_elf_set_osabi (abfd, link_info);
 }
This page took 0.026374 seconds and 4 git commands to generate.