aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog12
-rw-r--r--bfd/elf-bfd.h2
-rw-r--r--bfd/elf-eh-frame.c24
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);