This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Fix ld/418
On Wed, Oct 13, 2004 at 10:48:01PM +0100, Richard Sandiford wrote:
> Should _bfd_elf_eh_frame_section_offset be modified to cope with
> the adjusted offsets
Yes, that would be easiest I think. I didn't consider that this
function might be called after writing eh_frame sections, which
means some extra checks are needed too.
Richard, this is the same as the patch I sent you privately yesterday.
* 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.
Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.161
diff -u -p -r1.161 elf-bfd.h
--- bfd/elf-bfd.h 10 Oct 2004 13:02:00 -0000 1.161
+++ bfd/elf-bfd.h 14 Oct 2004 13:58:14 -0000
@@ -1532,7 +1532,7 @@ extern bfd_boolean _bfd_elf_discard_sect
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
Index: bfd/elf-eh-frame.c
===================================================================
RCS file: /cvs/src/src/bfd/elf-eh-frame.c,v
retrieving revision 1.34
diff -u -p -r1.34 elf-eh-frame.c
--- bfd/elf-eh-frame.c 10 Oct 2004 13:02:01 -0000 1.34
+++ bfd/elf-eh-frame.c 14 Oct 2004 13:58:15 -0000
@@ -713,10 +713,13 @@ _bfd_elf_maybe_strip_eh_frame_hdr (struc
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 *o
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 *o
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 *o
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);
}
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.250
diff -u -p -r1.250 elf.c
--- bfd/elf.c 11 Oct 2004 13:48:36 -0000 1.250
+++ bfd/elf.c 14 Oct 2004 13:58:20 -0000
@@ -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;
}
--
Alan Modra
IBM OzLabs - Linux Technology Centre