diff options
-rw-r--r-- | bfd/ChangeLog | 7 | ||||
-rw-r--r-- | bfd/elf-eh-frame.c | 31 |
2 files changed, 36 insertions, 2 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 667a962e84..095fa48f1c 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -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 diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c index 63640f1baf..ae07f374a8 100644 --- a/bfd/elf-eh-frame.c +++ b/bfd/elf-eh-frame.c @@ -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++; |