* 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.
This commit is contained in:
Alexandre Oliva 2004-02-28 00:35:45 +00:00
parent e6deed0a00
commit ec3391e704
5 changed files with 158 additions and 3 deletions

View 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

View 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

View 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;
}

View 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. */

View File

@ -391,6 +391,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
@ -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,