* 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>
|
2004-02-27 Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
|
||||||
* elf32-frv.c (elf32_frv_howto_table) <R_FRV_LABEL16>: Set
|
* 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)
|
bfd_boolean (*elf_backend_ignore_discarded_relocs)
|
||||||
(asection *);
|
(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.
|
/* This function, if defined, may write out the given section.
|
||||||
Returns TRUE if it did so and FALSE if the caller should. */
|
Returns TRUE if it did so and FALSE if the caller should. */
|
||||||
bfd_boolean (*elf_backend_write_section)
|
bfd_boolean (*elf_backend_write_section)
|
||||||
|
@ -1301,6 +1319,12 @@ extern void _bfd_elf_sprintf_vma
|
||||||
extern void _bfd_elf_fprintf_vma
|
extern void _bfd_elf_fprintf_vma
|
||||||
(bfd *, void *, bfd_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
|
extern enum elf_reloc_type_class _bfd_elf_reloc_type_class
|
||||||
(const Elf_Internal_Rela *);
|
(const Elf_Internal_Rela *);
|
||||||
extern bfd_vma _bfd_elf_rela_local_sym
|
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
|
/* For shared libraries, try to get rid of as many RELATIVE relocs
|
||||||
as possible. */
|
as possible. */
|
||||||
if (info->shared
|
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.fde_encoding & 0xf0) == DW_EH_PE_absptr)
|
||||||
cie.make_relative = 1;
|
cie.make_relative = 1;
|
||||||
|
|
||||||
if (info->shared
|
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.lsda_encoding & 0xf0) == DW_EH_PE_absptr)
|
||||||
cie.make_lsda_relative = 1;
|
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;
|
asection *eh_frame_sec;
|
||||||
bfd_size_type size;
|
bfd_size_type size;
|
||||||
bfd_boolean retval;
|
bfd_boolean retval;
|
||||||
|
bfd_vma encoded_eh_frame;
|
||||||
|
|
||||||
htab = elf_hash_table (info);
|
htab = elf_hash_table (info);
|
||||||
hdr_info = &htab->eh_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);
|
memset (contents, 0, EH_FRAME_HDR_SIZE);
|
||||||
contents[0] = 1; /* Version. */
|
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)
|
if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
|
||||||
{
|
{
|
||||||
contents[2] = DW_EH_PE_udata4; /* FDE count encoding. */
|
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[2] = DW_EH_PE_omit;
|
||||||
contents[3] = DW_EH_PE_omit;
|
contents[3] = DW_EH_PE_omit;
|
||||||
}
|
}
|
||||||
bfd_put_32 (abfd, eh_frame_sec->vma - sec->output_section->vma - 4,
|
bfd_put_32 (abfd, encoded_eh_frame, contents + 4);
|
||||||
contents + 4);
|
|
||||||
if (contents[2] != DW_EH_PE_omit)
|
if (contents[2] != DW_EH_PE_omit)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -1181,3 +1191,29 @@ _bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
|
||||||
free (contents);
|
free (contents);
|
||||||
return retval;
|
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 "libbfd.h"
|
||||||
#include "elf-bfd.h"
|
#include "elf-bfd.h"
|
||||||
#include "elf/frv.h"
|
#include "elf/frv.h"
|
||||||
|
#include "elf/dwarf2.h"
|
||||||
#include "hashtab.h"
|
#include "hashtab.h"
|
||||||
|
|
||||||
/* Forward declarations. */
|
/* Forward declarations. */
|
||||||
|
@ -3700,6 +3701,57 @@ elf32_frv_finish_dynamic_symbol (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||||||
return TRUE;
|
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.
|
/* Look through the relocs for a section during the first phase.
|
||||||
|
|
||||||
Besides handling virtual table relocs for gc, we have to deal with
|
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_want_plt_sym 0
|
||||||
#define elf_backend_plt_header_size 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_rel_p 1
|
||||||
#define elf_backend_may_use_rela_p 1
|
#define elf_backend_may_use_rela_p 1
|
||||||
/* We use REL for dynamic relocations only. */
|
/* We use REL for dynamic relocations only. */
|
||||||
|
|
|
@ -391,6 +391,15 @@
|
||||||
#ifndef elf_backend_ignore_discarded_relocs
|
#ifndef elf_backend_ignore_discarded_relocs
|
||||||
#define elf_backend_ignore_discarded_relocs NULL
|
#define elf_backend_ignore_discarded_relocs NULL
|
||||||
#endif
|
#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
|
#ifndef elf_backend_write_section
|
||||||
#define elf_backend_write_section NULL
|
#define elf_backend_write_section NULL
|
||||||
#endif
|
#endif
|
||||||
|
@ -497,6 +506,9 @@ static const struct elf_backend_data elfNN_bed =
|
||||||
elf_backend_reloc_type_class,
|
elf_backend_reloc_type_class,
|
||||||
elf_backend_discard_info,
|
elf_backend_discard_info,
|
||||||
elf_backend_ignore_discarded_relocs,
|
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_write_section,
|
||||||
elf_backend_mips_irix_compat,
|
elf_backend_mips_irix_compat,
|
||||||
elf_backend_mips_rtype_to_howto,
|
elf_backend_mips_rtype_to_howto,
|
||||||
|
|
Loading…
Reference in a new issue