* elf-bfd.h (struct elf_backend_data): Added
authorAlexandre Oliva <aoliva@redhat.com>
Sat, 28 Feb 2004 00:35:45 +0000 (00:35 +0000)
committerAlexandre Oliva <aoliva@redhat.com>
Sat, 28 Feb 2004 00:35:45 +0000 (00:35 +0000)
elf_backend_can_make_relative_eh_frame,
elf_backend_can_make_lsda_relative_eh_frame and
elf_backend_encode_eh_address.
(_bfd_elf_encode_eh_address): Declare.
(_bfd_elf_can_make_relative): Declare.
* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Use new
hooks to decide whether to attempt to make_relative and
make_lsda_relative.
(_bfd_elf_write_section_eh_frame_hdr): Call encode_eh_address.
(_bfd_elf_can_make_relative): New.
(_bfd_elf_encode_eh_address): New.
* elf32-frv.c (frv_elf_use_relative_eh_frame): New.
(frv_elf_encode_eh_address): New.
(elf_backend_can_make_relative_eh_frame): Define.
(elf_backend_can_make_lsda_relative_eh_frame): Define.
(elf_backend_encode_eh_address): Define.
* elfxx-target.h
(elf_backend_can_make_relative_eh_frame): Define.
(elf_backend_can_make_lsda_relative_eh_frame): Define.
(elf_backend_encode_eh_address): Define.
(elfNN_bed): Add them.

bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf-eh-frame.c
bfd/elf32-frv.c
bfd/elfxx-target.h

index 113dc22071e51af824f7b7fa4f49ec296f5778e7..249f266f30e3024b538c2ea091464b987ad8f023 100644 (file)
@@ -1,3 +1,28 @@
+2004-02-27  Alexandre Oliva  <aoliva@redhat.com>
+
+       * elf-bfd.h (struct elf_backend_data): Added
+       elf_backend_can_make_relative_eh_frame,
+       elf_backend_can_make_lsda_relative_eh_frame and
+       elf_backend_encode_eh_address.
+       (_bfd_elf_encode_eh_address): Declare.
+       (_bfd_elf_can_make_relative): Declare.
+       * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Use new
+       hooks to decide whether to attempt to make_relative and
+       make_lsda_relative.
+       (_bfd_elf_write_section_eh_frame_hdr): Call encode_eh_address.
+       (_bfd_elf_can_make_relative): New.
+       (_bfd_elf_encode_eh_address): New.
+       * elf32-frv.c (frv_elf_use_relative_eh_frame): New.
+       (frv_elf_encode_eh_address): New.
+       (elf_backend_can_make_relative_eh_frame): Define.
+       (elf_backend_can_make_lsda_relative_eh_frame): Define.
+       (elf_backend_encode_eh_address): Define.
+       * elfxx-target.h
+       (elf_backend_can_make_relative_eh_frame): Define.
+       (elf_backend_can_make_lsda_relative_eh_frame): Define.
+       (elf_backend_encode_eh_address): Define.
+       (elfNN_bed): Add them.
+
 2004-02-27  Alexandre Oliva  <aoliva@redhat.com>
 
        * elf32-frv.c (elf32_frv_howto_table) <R_FRV_LABEL16>: Set
index 6bbacade36f599519f09c7563d2c10712695ae10..3e861ea74d1194b73f209a797b242e3e7608e9df 100644 (file)
@@ -860,6 +860,24 @@ struct elf_backend_data
   bfd_boolean (*elf_backend_ignore_discarded_relocs)
     (asection *);
 
+  /* These functions tell elf-eh-frame whether to attempt to turn
+     absolute or lsda encodings into pc-relative ones.  The default
+     definition enables these transformations.  */
+  bfd_boolean (*elf_backend_can_make_relative_eh_frame)
+     (bfd *, struct bfd_link_info *, asection *);
+  bfd_boolean (*elf_backend_can_make_lsda_relative_eh_frame)
+     (bfd *, struct bfd_link_info *, asection *);
+
+  /* This function returns an encoding after computing the encoded
+     value (and storing it in ENCODED) for the given OFFSET into OSEC,
+     to be stored in at LOC_OFFSET into the LOC_SEC input section.
+     The default definition chooses a 32-bit PC-relative encoding.  */
+  bfd_byte (*elf_backend_encode_eh_address)
+     (bfd *abfd, struct bfd_link_info *info,
+      asection *osec, bfd_vma offset,
+      asection *loc_sec, bfd_vma loc_offset,
+      bfd_vma *encoded);
+
   /* This function, if defined, may write out the given section.
      Returns TRUE if it did so and FALSE if the caller should.  */
   bfd_boolean (*elf_backend_write_section)
@@ -1301,6 +1319,12 @@ extern void _bfd_elf_sprintf_vma
 extern void _bfd_elf_fprintf_vma
   (bfd *, void *, bfd_vma);
 
+extern bfd_byte _bfd_elf_encode_eh_address
+  (bfd *abfd, struct bfd_link_info *info, asection *osec, bfd_vma offset,
+   asection *loc_sec, bfd_vma loc_offset, bfd_vma *encoded);
+extern bfd_boolean _bfd_elf_can_make_relative
+  (bfd *input_bfd, struct bfd_link_info *info, asection *eh_frame_section);
+
 extern enum elf_reloc_type_class _bfd_elf_reloc_type_class
   (const Elf_Internal_Rela *);
 extern bfd_vma _bfd_elf_rela_local_sym
index 28e0b55fefdf3cc73b2e143ed816ec48bcfcd0b6..d3777b44118a0fc37136ac2cebc3f3cc3a9990e7 100644 (file)
@@ -518,10 +518,16 @@ _bfd_elf_discard_section_eh_frame
          /* For shared libraries, try to get rid of as many RELATIVE relocs
             as possible.  */
           if (info->shared
+             && (get_elf_backend_data (abfd)
+                 ->elf_backend_can_make_relative_eh_frame
+                 (abfd, info, sec))
              && (cie.fde_encoding & 0xf0) == DW_EH_PE_absptr)
            cie.make_relative = 1;
 
          if (info->shared
+             && (get_elf_backend_data (abfd)
+                 ->elf_backend_can_make_lsda_relative_eh_frame
+                 (abfd, info, sec))
              && (cie.lsda_encoding & 0xf0) == DW_EH_PE_absptr)
            cie.make_lsda_relative = 1;
 
@@ -1120,6 +1126,7 @@ _bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
   asection *eh_frame_sec;
   bfd_size_type size;
   bfd_boolean retval;
+  bfd_vma encoded_eh_frame;
 
   htab = elf_hash_table (info);
   hdr_info = &htab->eh_info;
@@ -1143,7 +1150,10 @@ _bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
 
   memset (contents, 0, EH_FRAME_HDR_SIZE);
   contents[0] = 1;                             /* Version.  */
-  contents[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4; /* .eh_frame offset.  */
+  contents[1] = get_elf_backend_data (abfd)->elf_backend_encode_eh_address
+    (abfd, info, eh_frame_sec, 0, sec, 4,
+     &encoded_eh_frame);                       /* .eh_frame offset.  */
+
   if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
     {
       contents[2] = DW_EH_PE_udata4;           /* FDE count encoding.  */
@@ -1154,8 +1164,8 @@ _bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
       contents[2] = DW_EH_PE_omit;
       contents[3] = DW_EH_PE_omit;
     }
-  bfd_put_32 (abfd, eh_frame_sec->vma - sec->output_section->vma - 4,
-             contents + 4);
+  bfd_put_32 (abfd, encoded_eh_frame, contents + 4);
+
   if (contents[2] != DW_EH_PE_omit)
     {
       unsigned int i;
@@ -1181,3 +1191,29 @@ _bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
   free (contents);
   return retval;
 }
+
+/* Decide whether we can use a PC-relative encoding within the given
+   EH frame section.  This is the default implementation.  */
+
+bfd_boolean
+_bfd_elf_can_make_relative (bfd *input_bfd ATTRIBUTE_UNUSED,
+                           struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                           asection *eh_frame_section ATTRIBUTE_UNUSED)
+{
+  return TRUE;
+}
+
+/* Select an encoding for the given address.  Preference is given to
+   PC-relative addressing modes.  */
+
+bfd_byte
+_bfd_elf_encode_eh_address (bfd *abfd ATTRIBUTE_UNUSED,
+                           struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                           asection *osec, bfd_vma offset,
+                           asection *loc_sec, bfd_vma loc_offset,
+                           bfd_vma *encoded)
+{
+  *encoded = osec->vma + offset -
+    (loc_sec->output_section->vma + loc_sec->output_offset + loc_offset);
+  return DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+}
index 78a4a4c129f656845b4c274abcc07b925ed6cfd8..a813ddcd8cc131654616226308fc8a17af38c823 100644 (file)
@@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "elf/frv.h"
+#include "elf/dwarf2.h"
 #include "hashtab.h"
 
 /* Forward declarations.  */
@@ -3700,6 +3701,57 @@ elf32_frv_finish_dynamic_symbol (bfd *output_bfd ATTRIBUTE_UNUSED,
   return TRUE;
 }
 
+/* Decide whether to attempt to turn absptr or lsda encodings in
+   shared libraries into pcrel within the given input section.  */
+
+static bfd_boolean
+frv_elf_use_relative_eh_frame (bfd *input_bfd,
+                              struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                              asection *eh_frame_section ATTRIBUTE_UNUSED)
+{
+  /* We can't use PC-relative encodings in FDPIC binaries, in general.  */
+  if (elf_elfheader (input_bfd)->e_flags & EF_FRV_FDPIC)
+    return FALSE;
+
+  return TRUE;
+}
+
+/* Adjust the contents of an eh_frame_hdr section before they're output.  */
+
+static bfd_byte
+frv_elf_encode_eh_address (bfd *abfd,
+                          struct bfd_link_info *info,
+                          asection *osec, bfd_vma offset,
+                          asection *loc_sec, bfd_vma loc_offset,
+                          bfd_vma *encoded)
+{
+  struct elf_link_hash_entry *h;
+
+  /* Non-FDPIC binaries can use PC-relative encodings.  */
+  if (! (elf_elfheader (abfd)->e_flags & EF_FRV_FDPIC))
+    return _bfd_elf_encode_eh_address (abfd, info, osec, offset,
+                                      loc_sec, loc_offset, encoded);
+
+  h = elf_hash_table (info)->hgot;
+  BFD_ASSERT (h && h->root.type == bfd_link_hash_defined);
+
+  if (! h || (_frv_osec_to_segment (abfd, osec)
+             == _frv_osec_to_segment (abfd, loc_sec->output_section)))
+    return _bfd_elf_encode_eh_address (abfd, info, osec, offset,
+                                      loc_sec, loc_offset, encoded);
+
+  BFD_ASSERT (_frv_osec_to_segment (abfd, osec)
+             == _frv_osec_to_segment (abfd,
+                                      h->root.u.def.section->output_section));
+
+  *encoded = osec->vma + offset
+    - (h->root.u.def.value
+       + h->root.u.def.section->output_section->vma
+       + h->root.u.def.section->output_offset);
+
+  return DW_EH_PE_datarel | DW_EH_PE_sdata4;
+}
+
 /* Look through the relocs for a section during the first phase.
 
    Besides handling virtual table relocs for gc, we have to deal with
@@ -4419,6 +4471,12 @@ frv_elf_print_private_bfd_data (abfd, ptr)
 #define elf_backend_want_plt_sym       0
 #define elf_backend_plt_header_size    0
 
+#define elf_backend_can_make_relative_eh_frame \
+               frv_elf_use_relative_eh_frame
+#define elf_backend_can_make_lsda_relative_eh_frame \
+               frv_elf_use_relative_eh_frame
+#define elf_backend_encode_eh_address  frv_elf_encode_eh_address
+
 #define elf_backend_may_use_rel_p       1
 #define elf_backend_may_use_rela_p      1
 /* We use REL for dynamic relocations only.  */
index ca0e47b32e709f12a5c3f424effd1098e74951d2..5bf8f4d31d6ae225049f761156e7f43f1f557fb2 100644 (file)
 #ifndef elf_backend_ignore_discarded_relocs
 #define elf_backend_ignore_discarded_relocs    NULL
 #endif
+#ifndef elf_backend_can_make_relative_eh_frame
+#define elf_backend_can_make_relative_eh_frame _bfd_elf_can_make_relative
+#endif
+#ifndef elf_backend_can_make_lsda_relative_eh_frame
+#define elf_backend_can_make_lsda_relative_eh_frame    _bfd_elf_can_make_relative
+#endif
+#ifndef elf_backend_encode_eh_address
+#define elf_backend_encode_eh_address          _bfd_elf_encode_eh_address
+#endif
 #ifndef elf_backend_write_section
 #define elf_backend_write_section              NULL
 #endif
@@ -497,6 +506,9 @@ static const struct elf_backend_data elfNN_bed =
   elf_backend_reloc_type_class,
   elf_backend_discard_info,
   elf_backend_ignore_discarded_relocs,
+  elf_backend_can_make_relative_eh_frame,
+  elf_backend_can_make_lsda_relative_eh_frame,
+  elf_backend_encode_eh_address,
   elf_backend_write_section,
   elf_backend_mips_irix_compat,
   elf_backend_mips_rtype_to_howto,
This page took 0.031991 seconds and 4 git commands to generate.