diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 12 | ||||
-rw-r--r-- | bfd/elf-bfd.h | 2 | ||||
-rw-r--r-- | bfd/elf-eh-frame.c | 24 |
3 files changed, 29 insertions, 9 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 77510cb..cc743c7 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,15 @@ +2004-10-01 Alan Modra <amodra@bigpond.net.au> + + * elf-bfd.h (struct eh_cie_fde): Add need_relative and + need_lsda_relative. + * elf-eh-frame.c (_bfd_elf_eh_frame_section_offset): Set + need_relative or need_lsda_relative if we are processing an + offset for a reloc on a FDE initial loc or LSDA field + respectively. + (_bfd_elf_write_section_eh_frame): Test need_relative and + need_lsda_relative in place of corresponding make_* field + when deciding to use pc-relative encodings. + 2004-09-30 Paul Brook <paul@codesourcery.com> * elf32-arm.h (bfd_elf32_arm_set_target_relocs): Handle "abs" diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 8a1b6da..bfee05d 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -297,6 +297,8 @@ struct eh_cie_fde unsigned int removed : 1; unsigned int make_relative : 1; unsigned int make_lsda_relative : 1; + unsigned int need_relative : 1; + unsigned int need_lsda_relative : 1; unsigned int per_encoding_relative : 1; }; diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c index be4e307..12eef61 100644 --- a/bfd/elf-eh-frame.c +++ b/bfd/elf-eh-frame.c @@ -775,7 +775,10 @@ _bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, if (sec_info->entry[mid].make_relative && ! sec_info->entry[mid].cie && offset == sec_info->entry[mid].offset + 8) - return (bfd_vma) -2; + { + sec_info->entry[mid].need_relative = 1; + return (bfd_vma) -2; + } /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need for run-time relocation against LSDA field. */ @@ -783,7 +786,10 @@ _bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, && ! sec_info->entry[mid].cie && (offset == (sec_info->entry[mid].offset + 8 + sec_info->entry[mid].lsda_offset))) - return (bfd_vma) -2; + { + sec_info->entry[mid].need_lsda_relative = 1; + return (bfd_vma) -2; + } return (offset + sec_info->entry[mid].new_offset - sec_info->entry[mid].offset); @@ -850,8 +856,8 @@ _bfd_elf_write_section_eh_frame (bfd *abfd, { /* CIE */ cie_offset = sec_info->entry[i].new_offset; - if (sec_info->entry[i].make_relative - || sec_info->entry[i].make_lsda_relative + if (sec_info->entry[i].need_relative + || sec_info->entry[i].need_lsda_relative || sec_info->entry[i].per_encoding_relative) { unsigned char *aug; @@ -860,8 +866,8 @@ _bfd_elf_write_section_eh_frame (bfd *abfd, /* Need to find 'R' or 'L' augmentation's argument and modify DW_EH_PE_* value. */ - action = (sec_info->entry[i].make_relative ? 1 : 0) - | (sec_info->entry[i].make_lsda_relative ? 2 : 0) + action = (sec_info->entry[i].need_relative ? 1 : 0) + | (sec_info->entry[i].need_lsda_relative ? 2 : 0) | (sec_info->entry[i].per_encoding_relative ? 4 : 0); buf = contents + sec_info->entry[i].offset; /* Skip length, id and version. */ @@ -968,7 +974,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd, + sec_info->entry[i].offset + 8); break; } - if (sec_info->entry[i].make_relative) + if (sec_info->entry[i].need_relative) value -= (sec->output_section->vma + sec->output_offset + sec_info->entry[i].new_offset + 8); write_value (abfd, buf, value, width); @@ -983,7 +989,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd, } if ((sec_info->entry[i].lsda_encoding & 0xf0) == DW_EH_PE_pcrel - || sec_info->entry[i].make_lsda_relative) + || sec_info->entry[i].need_lsda_relative) { buf += sec_info->entry[i].lsda_offset; width = get_DW_EH_PE_width (sec_info->entry[i].lsda_encoding, @@ -997,7 +1003,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd, == DW_EH_PE_pcrel) value += (sec_info->entry[i].offset - sec_info->entry[i].new_offset); - else if (sec_info->entry[i].make_lsda_relative) + else if (sec_info->entry[i].need_lsda_relative) value -= (sec->output_section->vma + sec->output_offset + sec_info->entry[i].new_offset + 8 + sec_info->entry[i].lsda_offset); |