mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:51:15 +08:00
Support multiple .eh_frame sections
This patch is based on MULTIPLE_FRAME_SECTIONS and EH_FRAME_LINKONCE, it allows backend to enable this feature and use '--gc-sections' simply. * gas/dw2gencfi.h (TARGET_MULTIPLE_EH_FRAME_SECTIONS): New. (MULTIPLE_FRAME_SECTIONS): Add TARGET_MULTIPLE_EH_FRAME_SECTIONS. * gas/dw2gencfi.c (EH_FRAME_LINKONCE): Add TARGET_MULTIPLE_EH_FRAME_SECTIONS. (is_now_linkonce_segment): Likewise. (get_cfi_seg): Create relocation info between .eh_frame.* and .text.* section. * bfd/elf-bfd.h (elf_backend_can_make_multiple_eh_frame): New. * bfd/elfxx-target.h (elf_backend_can_make_multiple_eh_frame): Likewise. * bfd/elflink.c (_bfd_elf_default_action_discarded): Add checking for elf_backend_can_make_multiple_eh_frame.
This commit is contained in:
parent
a494349e80
commit
853ba67882
@ -1432,6 +1432,9 @@ struct elf_backend_data
|
||||
bool (*elf_backend_can_make_lsda_relative_eh_frame)
|
||||
(bfd *, struct bfd_link_info *, asection *);
|
||||
|
||||
/* Tell linker to support multiple eh_frame sections. */
|
||||
bool elf_backend_can_make_multiple_eh_frame;
|
||||
|
||||
/* 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.
|
||||
|
@ -10924,12 +10924,19 @@ elf_section_ignore_discarded_relocs (asection *sec)
|
||||
unsigned int
|
||||
_bfd_elf_default_action_discarded (asection *sec)
|
||||
{
|
||||
const struct elf_backend_data *bed;
|
||||
bed = get_elf_backend_data (sec->owner);
|
||||
|
||||
if (sec->flags & SEC_DEBUGGING)
|
||||
return PRETEND;
|
||||
|
||||
if (strcmp (".eh_frame", sec->name) == 0)
|
||||
return 0;
|
||||
|
||||
if (bed->elf_backend_can_make_multiple_eh_frame
|
||||
&& strncmp (sec->name, ".eh_frame.", 10) == 0)
|
||||
return 0;
|
||||
|
||||
if (strcmp (".gcc_except_table", sec->name) == 0)
|
||||
return 0;
|
||||
|
||||
|
@ -658,6 +658,9 @@
|
||||
#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_can_make_multiple_eh_frame
|
||||
#define elf_backend_can_make_multiple_eh_frame 0
|
||||
#endif
|
||||
#ifndef elf_backend_encode_eh_address
|
||||
#define elf_backend_encode_eh_address _bfd_elf_encode_eh_address
|
||||
#endif
|
||||
@ -891,6 +894,7 @@ static const struct elf_backend_data elfNN_bed =
|
||||
elf_backend_eh_frame_address_size,
|
||||
elf_backend_can_make_relative_eh_frame,
|
||||
elf_backend_can_make_lsda_relative_eh_frame,
|
||||
elf_backend_can_make_multiple_eh_frame,
|
||||
elf_backend_encode_eh_address,
|
||||
elf_backend_write_section,
|
||||
elf_backend_elfsym_local_is_section,
|
||||
|
@ -1581,6 +1581,10 @@ If defined, GAS will check this macro before performing any optimizations on
|
||||
the DWARF call frame debug information that is emitted. Targets which
|
||||
implement link time relaxation may need to define this macro and set it to zero
|
||||
if it is possible to change the size of a function's prologue.
|
||||
|
||||
@item TARGET_MULTIPLE_EH_FRAME_SECTIONS
|
||||
If defined, GAS will create multiple .eh_frame.* sections according to
|
||||
the name of owner's function sections.
|
||||
@end table
|
||||
|
||||
@node Object format backend
|
||||
|
@ -75,7 +75,8 @@
|
||||
# define tc_cfi_endproc(fde) ((void) (fde))
|
||||
#endif
|
||||
|
||||
#define EH_FRAME_LINKONCE (SUPPORT_FRAME_LINKONCE || compact_eh)
|
||||
#define EH_FRAME_LINKONCE (SUPPORT_FRAME_LINKONCE || compact_eh \
|
||||
|| TARGET_MULTIPLE_EH_FRAME_SECTIONS)
|
||||
|
||||
#ifndef DWARF2_FORMAT
|
||||
#define DWARF2_FORMAT(SEC) dwarf2_format_32bit
|
||||
@ -277,6 +278,9 @@ is_now_linkonce_segment (void)
|
||||
if (compact_eh)
|
||||
return now_seg;
|
||||
|
||||
if (TARGET_MULTIPLE_EH_FRAME_SECTIONS)
|
||||
return now_seg;
|
||||
|
||||
if ((bfd_section_flags (now_seg)
|
||||
& (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
|
||||
| SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE
|
||||
@ -1333,14 +1337,33 @@ static segT
|
||||
get_cfi_seg (segT cseg, const char *base, flagword flags, int align)
|
||||
{
|
||||
/* Exclude .debug_frame sections for Compact EH. */
|
||||
if (SUPPORT_FRAME_LINKONCE || ((flags & SEC_DEBUGGING) == 0 && compact_eh))
|
||||
if (SUPPORT_FRAME_LINKONCE || ((flags & SEC_DEBUGGING) == 0 && compact_eh)
|
||||
|| ((flags & SEC_DEBUGGING) == 0 && TARGET_MULTIPLE_EH_FRAME_SECTIONS))
|
||||
{
|
||||
segT iseg = cseg;
|
||||
struct dwcfi_seg_list *l;
|
||||
|
||||
l = dwcfi_hash_find_or_make (cseg, base, flags);
|
||||
|
||||
cseg = l->seg;
|
||||
subseg_set (cseg, l->subseg);
|
||||
|
||||
if (TARGET_MULTIPLE_EH_FRAME_SECTIONS
|
||||
&& (flags & DWARF2_EH_FRAME_READ_ONLY))
|
||||
{
|
||||
const frchainS *ifrch = seg_info (iseg)->frchainP;
|
||||
const frchainS *frch = seg_info (cseg)->frchainP;
|
||||
expressionS exp;
|
||||
|
||||
exp.X_op = O_symbol;
|
||||
exp.X_add_symbol = (symbolS *) local_symbol_make (cseg->name, cseg, frch->frch_root, 0);
|
||||
exp.X_add_number = 0;
|
||||
subseg_set (iseg, ifrch->frch_subseg);
|
||||
fix_new_exp (ifrch->frch_root, 0, 0, &exp, 0, BFD_RELOC_NONE);
|
||||
|
||||
/* Restore the original segment info. */
|
||||
subseg_set (cseg, l->subseg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -66,7 +66,12 @@ extern void cfi_add_CFA_restore_state (void);
|
||||
#define SUPPORT_COMPACT_EH 0
|
||||
#endif
|
||||
|
||||
#define MULTIPLE_FRAME_SECTIONS (SUPPORT_FRAME_LINKONCE || SUPPORT_COMPACT_EH)
|
||||
#ifndef TARGET_MULTIPLE_EH_FRAME_SECTIONS
|
||||
#define TARGET_MULTIPLE_EH_FRAME_SECTIONS 0
|
||||
#endif
|
||||
|
||||
#define MULTIPLE_FRAME_SECTIONS (SUPPORT_FRAME_LINKONCE || SUPPORT_COMPACT_EH \
|
||||
|| TARGET_MULTIPLE_EH_FRAME_SECTIONS)
|
||||
|
||||
struct cfi_insn_data
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user