From: Alan Modra Date: Thu, 14 Oct 2004 23:38:08 +0000 (+0000) Subject: * elf-eh-frame.c (_bfd_elf_eh_frame_section_offset): Add "info" X-Git-Url: http://git.efficios.com/?a=commitdiff_plain;h=92e4ec35d9f6f98ed6b131b9be9cd548572874a1;p=deliverable%2Fbinutils-gdb.git * elf-eh-frame.c (_bfd_elf_eh_frame_section_offset): Add "info" parameter. If called after _bfd_elf_write_section_eh_frame, don't allow a -2 return unless need_* bit is already set, and handle offsets adjusted for output_offset. * elf-bfd.h (_bfd_elf_eh_frame_section_offset): Update prototype. * elf.c (_bfd_elf_section_offset): Update call. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index cc331a97ff..06c75bea7b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2004-10-15 Alan Modra + + * elf-eh-frame.c (_bfd_elf_eh_frame_section_offset): Add "info" + parameter. If called after _bfd_elf_write_section_eh_frame, + don't allow a -2 return unless need_* bit is already set, and + handle offsets adjusted for output_offset. + * elf-bfd.h (_bfd_elf_eh_frame_section_offset): Update prototype. + * elf.c (_bfd_elf_section_offset): Update call. + 2004-10-13 H.J. Lu PR 440 diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index f452d3b62a..ff26613998 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1532,7 +1532,7 @@ extern bfd_boolean _bfd_elf_discard_section_eh_frame extern bfd_boolean _bfd_elf_discard_section_eh_frame_hdr (bfd *, struct bfd_link_info *); extern bfd_vma _bfd_elf_eh_frame_section_offset - (bfd *, asection *, bfd_vma); + (bfd *, struct bfd_link_info *, asection *, bfd_vma); extern bfd_boolean _bfd_elf_write_section_eh_frame (bfd *, struct bfd_link_info *, asection *, bfd_byte *); extern bfd_boolean _bfd_elf_write_section_eh_frame_hdr diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c index 6302cf0811..c4cf46f65c 100644 --- a/bfd/elf-eh-frame.c +++ b/bfd/elf-eh-frame.c @@ -713,10 +713,13 @@ _bfd_elf_maybe_strip_eh_frame_hdr (struct bfd_link_info *info) bfd_vma _bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info, asection *sec, bfd_vma offset) { struct eh_frame_sec_info *sec_info; + struct elf_link_hash_table *htab; + struct eh_frame_hdr_info *hdr_info; unsigned int lo, hi, mid; if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME) @@ -726,6 +729,11 @@ _bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, if (offset >= sec->rawsize) return offset - sec->rawsize + sec->size; + htab = elf_hash_table (info); + hdr_info = &htab->eh_info; + if (hdr_info->offsets_adjusted) + offset += sec->output_offset; + lo = 0; hi = sec_info->count; mid = 0; @@ -751,7 +759,9 @@ _bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, relocation against FDE's initial_location field. */ if (!sec_info->entry[mid].cie && sec_info->entry[mid].cie_inf->make_relative - && offset == sec_info->entry[mid].offset + 8) + && offset == sec_info->entry[mid].offset + 8 + && (sec_info->entry[mid].cie_inf->need_relative + || !hdr_info->offsets_adjusted)) { sec_info->entry[mid].cie_inf->need_relative = 1; return (bfd_vma) -2; @@ -762,12 +772,16 @@ _bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, if (!sec_info->entry[mid].cie && sec_info->entry[mid].cie_inf->make_lsda_relative && (offset == (sec_info->entry[mid].offset + 8 - + sec_info->entry[mid].lsda_offset))) + + sec_info->entry[mid].lsda_offset)) + && (sec_info->entry[mid].cie_inf->need_lsda_relative + || !hdr_info->offsets_adjusted)) { sec_info->entry[mid].cie_inf->need_lsda_relative = 1; return (bfd_vma) -2; } + if (hdr_info->offsets_adjusted) + offset -= sec->output_offset; return (offset + sec_info->entry[mid].new_offset - sec_info->entry[mid].offset); } diff --git a/bfd/elf.c b/bfd/elf.c index 27142a1dc4..b7674e316e 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -7746,7 +7746,7 @@ _bfd_elf_rel_local_sym (bfd *abfd, bfd_vma _bfd_elf_section_offset (bfd *abfd, - struct bfd_link_info *info ATTRIBUTE_UNUSED, + struct bfd_link_info *info, asection *sec, bfd_vma offset) { @@ -7756,7 +7756,7 @@ _bfd_elf_section_offset (bfd *abfd, return _bfd_stab_section_offset (sec, elf_section_data (sec)->sec_info, offset); case ELF_INFO_TYPE_EH_FRAME: - return _bfd_elf_eh_frame_section_offset (abfd, sec, offset); + return _bfd_elf_eh_frame_section_offset (abfd, info, sec, offset); default: return offset; }