Index: bfd/ChangeLog from Alexandre Oliva Merge from mainline: 2004-02-27 Alexandre Oliva * 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. Index: bfd/elf-bfd.h =================================================================== RCS file: /cvs/src/src/bfd/elf-bfd.h,v retrieving revision 1.125.4.1 diff -u -p -r1.125.4.1 elf-bfd.h --- bfd/elf-bfd.h 8 Apr 2004 12:41:35 -0000 1.125.4.1 +++ bfd/elf-bfd.h 6 May 2004 01:53:10 -0000 @@ -861,6 +861,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) @@ -1295,6 +1313,12 @@ extern void _bfd_elf_sprintf_vma (bfd *, char *, bfd_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 *); Index: bfd/elf-eh-frame.c =================================================================== RCS file: /cvs/src/src/bfd/elf-eh-frame.c,v retrieving revision 1.27 diff -u -p -r1.27 elf-eh-frame.c --- bfd/elf-eh-frame.c 16 Oct 2003 21:04:04 -0000 1.27 +++ bfd/elf-eh-frame.c 6 May 2004 01:53:11 -0000 @@ -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 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 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 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; @@ -1180,4 +1190,30 @@ _bfd_elf_write_section_eh_frame_hdr (bfd sec->_cooked_size); 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: bfd/elf32-frv.c =================================================================== RCS file: /cvs/src/src/bfd/elf32-frv.c,v retrieving revision 1.12.4.2 diff -u -p -r1.12.4.2 elf32-frv.c --- bfd/elf32-frv.c 9 Apr 2004 18:28:00 -0000 1.12.4.2 +++ bfd/elf32-frv.c 6 May 2004 01:53:14 -0000 @@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suit #include "libbfd.h" #include "elf-bfd.h" #include "elf/frv.h" +#include "elf/dwarf2.h" #include "hashtab.h" /* Forward declarations. */ @@ -3803,6 +3804,57 @@ elf32_frv_finish_dynamic_symbol (bfd *ou 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 @@ -4521,6 +4573,12 @@ frv_elf_print_private_bfd_data (abfd, pt #define elf_backend_plt_readonly 1 #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 Index: bfd/elfxx-target.h =================================================================== RCS file: /cvs/src/src/bfd/elfxx-target.h,v retrieving revision 1.59.4.1 diff -u -p -r1.59.4.1 elfxx-target.h --- bfd/elfxx-target.h 8 Apr 2004 12:41:46 -0000 1.59.4.1 +++ bfd/elfxx-target.h 6 May 2004 01:53:14 -0000 @@ -401,6 +401,15 @@ #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 @@ -507,6 +516,9 @@ static const struct elf_backend_data elf 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,