OSDN Git Service

PR 4454
authoramodra <amodra>
Thu, 10 May 2007 15:08:02 +0000 (15:08 +0000)
committeramodra <amodra>
Thu, 10 May 2007 15:08:02 +0000 (15:08 +0000)
* elf-eh-frame.c (struct cie): Make "personality" a bfd_vma.
(_bfd_elf_discard_section_eh_frame): Handle local syms on
personality relocation.

bfd/ChangeLog
bfd/elf-eh-frame.c

index 667a962..095fa48 100644 (file)
@@ -1,3 +1,10 @@
+2007-05-11  Alan Modra  <amodra@bigpond.net.au>
+
+       PR 4454
+       * elf-eh-frame.c (struct cie): Make "personality" a bfd_vma.
+       (_bfd_elf_discard_section_eh_frame): Handle local syms on
+       personality relocation.
+
 2007-05-10  Richard Sandiford  <richard@codesourcery.com>
 
        * elf.c (assign_file_positions_for_load_sections): Use p_memsz
index 63640f1..ae07f37 100644 (file)
@@ -37,7 +37,7 @@ struct cie
   bfd_signed_vma data_align;
   bfd_vma ra_column;
   bfd_vma augmentation_size;
-  struct elf_link_hash_entry *personality;
+  bfd_vma personality;
   asection *output_sec;
   struct eh_cie_fde *cie_inf;
   unsigned char per_encoding;
@@ -675,6 +675,7 @@ _bfd_elf_discard_section_eh_frame
                      if (GET_RELOC (buf) != NULL)
                        {
                          unsigned long r_symndx;
+                         asection *sym_sec = NULL;
 
 #ifdef BFD64
                          if (ptr_size == 8)
@@ -694,8 +695,34 @@ _bfd_elf_discard_section_eh_frame
                                h = (struct elf_link_hash_entry *)
                                    h->root.u.i.link;
 
-                             cie->personality = h;
+                             if (h->root.type == bfd_link_hash_defined
+                                 || h->root.type == bfd_link_hash_defweak)
+                               {
+                                 cie->personality = h->root.u.def.value;
+                                 sym_sec = h->root.u.def.section;
+                               }
                            }
+                         else
+                           {
+                             Elf_Internal_Shdr *symtab_hdr;
+                             Elf_Internal_Sym *sym;
+
+                             symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+                             sym = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+                                                         1, r_symndx,
+                                                         NULL, NULL, NULL);
+                             if (sym != NULL)
+                               {
+                                 cie->personality = sym->st_value;
+                                 sym_sec = (bfd_section_from_elf_index
+                                            (abfd, sym->st_shndx));
+                                 free (sym);
+                               }
+                           }
+                         if (sym_sec != NULL)
+                           cie->personality += (sym_sec->output_section->vma
+                                                + sym_sec->output_offset);
+
                          /* Cope with MIPS-style composite relocations.  */
                          do
                            cookie->rel++;