* 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:
parent
e6deed0a00
commit
ec3391e704
5 changed files with 158 additions and 3 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue