OSDN Git Service

2009-06-22 Christophe Lyon <christophe.lyon@st.com>
authorclyon <clyon>
Mon, 22 Jun 2009 10:55:32 +0000 (10:55 +0000)
committerclyon <clyon>
Mon, 22 Jun 2009 10:55:32 +0000 (10:55 +0000)
bfd/
* elf32-arm.c (elf32_arm_size_stubs): Use PLT address as
destination for defined dynamic symbols when deciding whether to
insert a stub or not.
(allocate_dynrelocs): Make sure functions are not marked as Thumb
when actually accessed through a PLT, even when generating a
shared lib.

ld/testsuite:
* ld-arm/farcall-mixed-app.s: Add new references to check more
modes switching.
* ld-arm/farcall-mixed-lib1.s: Likewise.
* ld-arm/farcall-mixed-app-v5.d: Update expected result.
* farcall-mixed-app.d: Likewise.
* ld-arm/farcall-mixed-lib.d: Likewise.

bfd/ChangeLog
bfd/elf32-arm.c

index 7e7b526..563f454 100644 (file)
@@ -1,3 +1,12 @@
+2009-06-22  Christophe Lyon  <christophe.lyon@st.com>
+
+       * elf32-arm.c (elf32_arm_size_stubs): Use PLT address as
+       destination for defined dynamic symbols when deciding whether to
+       insert a stub or not.
+       (allocate_dynrelocs): Make sure functions are not marked as Thumb
+       when actually accessed through a PLT, even when generating a
+       shared lib.
+
 2009-06-22  Tristan Gingold  <gingold@adacore.com>
 
        * mach-o.c (bfd_mach_o_canonicalize_reloc): Append a sentinel to
index bdb895a..cd40eef 100644 (file)
@@ -4361,7 +4361,25 @@ elf32_arm_size_stubs (bfd *output_bfd,
                        {
                          sym_sec = hash->root.root.u.def.section;
                          sym_value = hash->root.root.u.def.value;
-                         if (sym_sec->output_section != NULL)
+
+                         struct elf32_arm_link_hash_table *globals =
+                                                 elf32_arm_hash_table (info);
+
+                         /* For a destination in a shared library,
+                            use the PLT stub as target address to
+                            decide whether a branch stub is
+                            needed.  */
+                         if (globals->splt != NULL && hash != NULL
+                             && hash->root.plt.offset != (bfd_vma) -1)
+                           {
+                             sym_sec = globals->splt;
+                             sym_value = hash->root.plt.offset;
+                             if (sym_sec->output_section != NULL)
+                               destination = (sym_value
+                                              + sym_sec->output_offset
+                                              + sym_sec->output_section->vma);
+                           }
+                         else if (sym_sec->output_section != NULL)
                            destination = (sym_value + irela->r_addend
                                           + sym_sec->output_offset
                                           + sym_sec->output_section->vma);
@@ -11277,14 +11295,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
            {
              h->root.u.def.section = s;
              h->root.u.def.value = h->plt.offset;
-
-             /* Make sure the function is not marked as Thumb, in case
-                it is the target of an ABS32 relocation, which will
-                point to the PLT entry.  */
-             if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC)
-               h->type = ELF_ST_INFO (ELF_ST_BIND (h->type), STT_FUNC);
            }
 
+         /* Make sure the function is not marked as Thumb, in case
+            it is the target of an ABS32 relocation, which will
+            point to the PLT entry.  */
+         if (ELF_ST_TYPE (h->type) == STT_ARM_TFUNC)
+           h->type = ELF_ST_INFO (ELF_ST_BIND (h->type), STT_FUNC);
+
          /* Make room for this entry.  */
          s->size += htab->plt_entry_size;