aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf-eh-frame.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2002-04-22 12:06:01 +0000
committerJakub Jelinek <jakub@redhat.com>2002-04-22 12:06:01 +0000
commit09ae86c21634e54692a2b63aac76f6d51bf582e5 (patch)
tree79fb338f2020cec5685836831149e6a5d13f3259 /bfd/elf-eh-frame.c
parenta0e8a2d152e4bd6114a378b6fbf3e3d09e99f6bf (diff)
downloadgdb-09ae86c21634e54692a2b63aac76f6d51bf582e5.zip
gdb-09ae86c21634e54692a2b63aac76f6d51bf582e5.tar.gz
gdb-09ae86c21634e54692a2b63aac76f6d51bf582e5.tar.bz2
* elf-eh-frame.c (struct eh_cie_fde): Add per_encoding_relative.
(_bfd_elf_discard_section_eh_frame): Set it for CIEs with pcrel encoded personality. (_bfd_elf_write_section_eh_frame): Adjust pcrel encoded personality for CIE/FDE removal.
Diffstat (limited to 'bfd/elf-eh-frame.c')
-rw-r--r--bfd/elf-eh-frame.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
index 20cbfb2..83ccfe9 100644
--- a/bfd/elf-eh-frame.c
+++ b/bfd/elf-eh-frame.c
@@ -64,6 +64,7 @@ struct eh_cie_fde
unsigned char removed : 1;
unsigned char make_relative : 1;
unsigned char make_lsda_relative : 1;
+ unsigned char per_encoding_relative : 1;
};
struct eh_frame_sec_info
@@ -469,6 +470,8 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec, ehdrsec,
= cie.make_relative;
sec_info->entry[last_cie_ndx].make_lsda_relative
= cie.make_lsda_relative;
+ sec_info->entry[last_cie_ndx].per_encoding_relative
+ = (cie.per_encoding & 0x70) == DW_EH_PE_pcrel;
}
}
@@ -689,6 +692,7 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec, ehdrsec,
{
sec_info->entry[i].make_relative = make_relative;
sec_info->entry[i].make_lsda_relative = make_lsda_relative;
+ sec_info->entry[i].per_encoding_relative = 0;
}
}
else if (sec_info->entry[i].cie && sec_info->entry[i].sec == sec)
@@ -947,7 +951,8 @@ _bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents)
/* CIE */
cie_offset = sec_info->entry[i].new_offset;
if (sec_info->entry[i].make_relative
- || sec_info->entry[i].make_lsda_relative)
+ || sec_info->entry[i].make_lsda_relative
+ || sec_info->entry[i].per_encoding_relative)
{
unsigned char *aug;
unsigned int action;
@@ -956,7 +961,8 @@ _bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents)
/* 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);
+ | (sec_info->entry[i].make_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. */
buf += 9;
@@ -988,10 +994,22 @@ _bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents)
per_width = get_DW_EH_PE_width (per_encoding,
ptr_size);
BFD_ASSERT (per_width != 0);
+ BFD_ASSERT (((per_encoding & 0x70) == DW_EH_PE_pcrel)
+ == sec_info->entry[i].per_encoding_relative);
if ((per_encoding & 0xf0) == DW_EH_PE_aligned)
buf = (contents
+ ((buf - contents + per_width - 1)
& ~((bfd_size_type) per_width - 1)));
+ if (action & 4)
+ {
+ bfd_vma value;
+
+ value = read_value (abfd, buf, per_width);
+ value += (sec_info->entry[i].offset
+ - sec_info->entry[i].new_offset);
+ write_value (abfd, buf, value, per_width);
+ action &= ~4;
+ }
buf += per_width;
break;
case 'R':