diff options
Diffstat (limited to 'bfd/elf-eh-frame.c')
-rw-r--r-- | bfd/elf-eh-frame.c | 52 |
1 files changed, 39 insertions, 13 deletions
diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c index 7c126743d94..77640748da9 100644 --- a/bfd/elf-eh-frame.c +++ b/bfd/elf-eh-frame.c @@ -1,5 +1,5 @@ /* .eh_frame section optimization. - Copyright 2001, 2002 Free Software Foundation, Inc. + Copyright 2001, 2002, 2003 Free Software Foundation, Inc. Written by Jakub Jelinek <jakub@redhat.com>. This file is part of BFD, the Binary File Descriptor library. @@ -33,7 +33,7 @@ static bfd_signed_vma read_signed_leb128 static int get_DW_EH_PE_width PARAMS ((int, int)); static bfd_vma read_value - PARAMS ((bfd *, bfd_byte *, int)); + PARAMS ((bfd *, bfd_byte *, int, int)); static void write_value PARAMS ((bfd *, bfd_byte *, bfd_vma, int)); static int cie_compare @@ -141,22 +141,42 @@ int get_DW_EH_PE_width (encoding, ptr_size) return 0; } +#define get_DW_EH_PE_signed(encoding) (((encoding) & DW_EH_PE_signed) != 0) + /* Read a width sized value from memory. */ static bfd_vma -read_value (abfd, buf, width) +read_value (abfd, buf, width, is_signed) bfd *abfd; bfd_byte *buf; int width; + int is_signed; { bfd_vma value; switch (width) { - case 2: value = bfd_get_16 (abfd, buf); break; - case 4: value = bfd_get_32 (abfd, buf); break; - case 8: value = bfd_get_64 (abfd, buf); break; - default: BFD_FAIL (); return 0; + case 2: + if (is_signed) + value = bfd_get_signed_16 (abfd, buf); + else + value = bfd_get_16 (abfd, buf); + break; + case 4: + if (is_signed) + value = bfd_get_signed_32 (abfd, buf); + else + value = bfd_get_32 (abfd, buf); + break; + case 8: + if (is_signed) + value = bfd_get_signed_64 (abfd, buf); + else + value = bfd_get_64 (abfd, buf); + break; + default: + BFD_FAIL (); + return 0; } return value; @@ -605,7 +625,7 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec, } elf_section_data (sec)->sec_info = sec_info; - elf_section_data (sec)->sec_info_type = ELF_INFO_TYPE_EH_FRAME; + sec->sec_info_type = ELF_INFO_TYPE_EH_FRAME; /* Ok, now we can assign new offsets. */ offset = 0; @@ -758,7 +778,7 @@ _bfd_elf_eh_frame_section_offset (output_bfd, sec, offset) struct eh_frame_sec_info *sec_info; unsigned int lo, hi, mid; - if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_EH_FRAME) + if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME) return offset; sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info; @@ -828,7 +848,7 @@ _bfd_elf_write_section_eh_frame (abfd, info, sec, contents) ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS] == ELFCLASS64) ? 8 : 4; - if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_EH_FRAME) + if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME) return bfd_set_section_contents (abfd, sec->output_section, contents, (file_ptr) sec->output_offset, @@ -925,7 +945,9 @@ _bfd_elf_write_section_eh_frame (abfd, info, sec, contents) { bfd_vma value; - value = read_value (abfd, buf, per_width); + value = read_value (abfd, buf, per_width, + get_DW_EH_PE_signed + (per_encoding)); value += (sec_info->entry[i].offset - sec_info->entry[i].new_offset); write_value (abfd, buf, value, per_width); @@ -961,7 +983,9 @@ _bfd_elf_write_section_eh_frame (abfd, info, sec, contents) buf += 4; width = get_DW_EH_PE_width (sec_info->entry[i].fde_encoding, ptr_size); - address = value = read_value (abfd, buf, width); + address = value = read_value (abfd, buf, width, + get_DW_EH_PE_signed + (sec_info->entry[i].fde_encoding)); if (value) { switch (sec_info->entry[i].fde_encoding & 0xf0) @@ -1005,7 +1029,9 @@ _bfd_elf_write_section_eh_frame (abfd, info, sec, contents) buf += sec_info->entry[i].lsda_offset; width = get_DW_EH_PE_width (sec_info->entry[i].lsda_encoding, ptr_size); - value = read_value (abfd, buf, width); + value = read_value (abfd, buf, width, + get_DW_EH_PE_signed + (sec_info->entry[i].lsda_encoding)); if (value) { if ((sec_info->entry[i].lsda_encoding & 0xf0) |