* elf-eh-frame.c (struct eh_cie_fde): Add per_encoding_relative.
authorJakub Jelinek <jakub@redhat.com>
Mon, 22 Apr 2002 12:06:01 +0000 (12:06 +0000)
committerJakub Jelinek <jakub@redhat.com>
Mon, 22 Apr 2002 12:06:01 +0000 (12:06 +0000)
(_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.

bfd/ChangeLog
bfd/elf-eh-frame.c

index d09f7e8d90d8a44c4fb5a668015e344780adee3d..78eec86852ba75a84fdd6272b5d899b3570276d4 100644 (file)
@@ -1,3 +1,12 @@
+2002-04-22  Richard Smith  <richard@ex-parrot.com>
+           Jakub Jelinek  <jakub@redhat.com>
+
+       * 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.
+
 2002-04-20  Tom Rix  <trix@redhat.com>
 
        * coff64-rs6000.c (_bfd_xcoff64_swap_aux_in): Fix C_FILE auxent.
index 20cbfb22c8305a429bcd407168cd0297520b8cd6..83ccfe9c54ec67550135f68ef76d993854364dcb 100644 (file)
@@ -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':