From 92e4ec35d9f6f98ed6b131b9be9cd548572874a1 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 14 Oct 2004 23:38:08 +0000 Subject: [PATCH] * 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. --- bfd/ChangeLog | 9 +++++++++ bfd/elf-bfd.h | 2 +- bfd/elf-eh-frame.c | 18 ++++++++++++++++-- bfd/elf.c | 4 ++-- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index cc331a97ff8..06c75bea7b2 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 f452d3b62a3..ff266139985 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 6302cf08110..c4cf46f65cc 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 27142a1dc41..b7674e316e6 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; } -- 2.30.2