* elf-bfd.h (struct cie_header): Move from elf_eh-frame.c.

(struct cie, struct eh_cie_fde, struct eh_frame_sec_info): Likewise.
	(struct eh_frame_array_ent, struct eh_frame_hdr_info): Likewise.
	(enum elf_link_info_type): Remove ELF_INFO_TYPE_EH_FRAME_HDR.
	(struct eh_frame_hdr_info): Add "hdr_sec", remove "split".
	(struct elf_link_hash_table): Add eh_info.
	(struct elf_obj_tdata): Change eh_frame_hdr to an asection *.
	(_bfd_elf_discard_section_eh_frame): Update prototype.
	(_bfd_elf_discard_section_eh_frame_hdr): Likewise.
	(_bfd_elf_write_section_eh_frame): Likewise.
	(_bfd_elf_write_section_eh_frame_hdr): Likewise.
	* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Remove "ehdrsec"
	param.  Get "hdr_info" from link hash table.
	(_bfd_elf_discard_section_eh_frame_hdr): Remove "sec" param.  Get
	header section from link hash table.  Save header section to elf_tdata.
	(_bfd_elf_maybe_strip_eh_frame_hdr): Remove local "sec".  Use
	header section from link hash table.  Don't alloc hdr_info.  Clear
	hdr_sec instead of setting "strip".
	(_bfd_elf_eh_frame_section_offset): Formatting.
	(_bfd_elf_write_section_eh_frame): Remove "ehdrsec", add "info" param.
	Get header section from link hash table.
	(_bfd_elf_write_section_eh_frame_hdr): Remove "sec", add "info" param.
	Get header section from link hash table.
	* elf.c (map_sections_to_segments): Use cached eh_frame_hdr.
	(get_program_header_size): Likewise.
	(_bfd_elf_section_offset): Formatting.
	* elflink.h (elf_link_create_dynamic_sections): Stash eh frame header
	section pointer in link hash table.
	(elf_bfd_final_link): Adjust _bfd_elf_write_section_eh_frame_hdr
	and _bfd_elf_write_section_eh_frame calls.  Update comment about
	eh_frame entries.
	(elf_bfd_discard_info): Adjust _bfd_elf_discard_section_eh_frame and
	_bfd_elf_discard_section_eh_frame_hdr calls.  Remove "ehdr".

	* po/SRC-POTFILES.in: Regenerate.
This commit is contained in:
Alan Modra 2002-11-12 07:35:26 +00:00
parent 99eb2ac83d
commit 126495ed15
6 changed files with 199 additions and 189 deletions

View File

@ -1,5 +1,41 @@
2002-11-12 Alan Modra <amodra@bigpond.net.au> 2002-11-12 Alan Modra <amodra@bigpond.net.au>
* elf-bfd.h (struct cie_header): Move from elf_eh-frame.c.
(struct cie, struct eh_cie_fde, struct eh_frame_sec_info): Likewise.
(struct eh_frame_array_ent, struct eh_frame_hdr_info): Likewise.
(enum elf_link_info_type): Remove ELF_INFO_TYPE_EH_FRAME_HDR.
(struct eh_frame_hdr_info): Add "hdr_sec", remove "split".
(struct elf_link_hash_table): Add eh_info.
(struct elf_obj_tdata): Change eh_frame_hdr to an asection *.
(_bfd_elf_discard_section_eh_frame): Update prototype.
(_bfd_elf_discard_section_eh_frame_hdr): Likewise.
(_bfd_elf_write_section_eh_frame): Likewise.
(_bfd_elf_write_section_eh_frame_hdr): Likewise.
* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Remove "ehdrsec"
param. Get "hdr_info" from link hash table.
(_bfd_elf_discard_section_eh_frame_hdr): Remove "sec" param. Get
header section from link hash table. Save header section to elf_tdata.
(_bfd_elf_maybe_strip_eh_frame_hdr): Remove local "sec". Use
header section from link hash table. Don't alloc hdr_info. Clear
hdr_sec instead of setting "strip".
(_bfd_elf_eh_frame_section_offset): Formatting.
(_bfd_elf_write_section_eh_frame): Remove "ehdrsec", add "info" param.
Get header section from link hash table.
(_bfd_elf_write_section_eh_frame_hdr): Remove "sec", add "info" param.
Get header section from link hash table.
* elf.c (map_sections_to_segments): Use cached eh_frame_hdr.
(get_program_header_size): Likewise.
(_bfd_elf_section_offset): Formatting.
* elflink.h (elf_link_create_dynamic_sections): Stash eh frame header
section pointer in link hash table.
(elf_bfd_final_link): Adjust _bfd_elf_write_section_eh_frame_hdr
and _bfd_elf_write_section_eh_frame calls. Update comment about
eh_frame entries.
(elf_bfd_discard_info): Adjust _bfd_elf_discard_section_eh_frame and
_bfd_elf_discard_section_eh_frame_hdr calls. Remove "ehdr".
* po/SRC-POTFILES.in: Regenerate.
* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Don't zero * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Don't zero
relocs for discarded FDEs. Remove dead code. relocs for discarded FDEs. Remove dead code.
(_bfd_elf_write_section_eh_frame_hdr): Remove dead code. (_bfd_elf_write_section_eh_frame_hdr): Remove dead code.

View File

@ -235,11 +235,79 @@ enum elf_link_info_type
ELF_INFO_TYPE_STABS, ELF_INFO_TYPE_STABS,
ELF_INFO_TYPE_MERGE, ELF_INFO_TYPE_MERGE,
ELF_INFO_TYPE_EH_FRAME, ELF_INFO_TYPE_EH_FRAME,
ELF_INFO_TYPE_EH_FRAME_HDR,
ELF_INFO_TYPE_JUST_SYMS, ELF_INFO_TYPE_JUST_SYMS,
ELF_INFO_TYPE_LAST ELF_INFO_TYPE_LAST
}; };
/* Structures used by the eh_frame optimization code. */
struct cie_header
{
unsigned int length;
unsigned int id;
};
struct cie
{
struct cie_header hdr;
unsigned char version;
unsigned char augmentation[20];
unsigned int code_align;
int data_align;
unsigned int ra_column;
unsigned int augmentation_size;
struct elf_link_hash_entry *personality;
unsigned char per_encoding;
unsigned char lsda_encoding;
unsigned char fde_encoding;
unsigned char initial_insn_length;
unsigned char make_relative;
unsigned char make_lsda_relative;
unsigned char initial_instructions[50];
};
struct eh_cie_fde
{
unsigned int offset;
unsigned int size;
asection *sec;
unsigned int new_offset;
unsigned char fde_encoding;
unsigned char lsda_encoding;
unsigned char lsda_offset;
unsigned char cie : 1;
unsigned char removed : 1;
unsigned char make_relative : 1;
unsigned char make_lsda_relative : 1;
unsigned char per_encoding_relative : 1;
};
struct eh_frame_sec_info
{
unsigned int count;
unsigned int alloced;
struct eh_cie_fde entry[1];
};
struct eh_frame_array_ent
{
bfd_vma initial_loc;
bfd_vma fde;
};
struct eh_frame_hdr_info
{
struct cie last_cie;
asection *last_cie_sec;
asection *hdr_sec;
unsigned int last_cie_offset;
unsigned int fde_count, array_count;
struct eh_frame_array_ent *array;
/* TRUE if .eh_frame_hdr should contain the sorted search table.
We build it if we successfully read all .eh_frame input sections
and recognize them. */
boolean table;
};
/* Cached start, size and alignment of PT_TLS segment. */ /* Cached start, size and alignment of PT_TLS segment. */
struct elf_link_tls_segment struct elf_link_tls_segment
{ {
@ -294,6 +362,9 @@ struct elf_link_hash_table
/* A pointer to information used to merge SEC_MERGE sections. */ /* A pointer to information used to merge SEC_MERGE sections. */
PTR merge_info; PTR merge_info;
/* Used by eh_frame code when editing .eh_frame. */
struct eh_frame_hdr_info eh_info;
/* A linked list of local symbols to be added to .dynsym. */ /* A linked list of local symbols to be added to .dynsym. */
struct elf_link_local_dynamic_entry *dynlocal; struct elf_link_local_dynamic_entry *dynlocal;
@ -1118,12 +1189,12 @@ struct elf_obj_tdata
include this field for a MIPS ELF target. */ include this field for a MIPS ELF target. */
asection **local_stubs; asection **local_stubs;
/* Used to determine if the e_flags field has been initialized */
boolean flags_init;
/* Used to determine if PT_GNU_EH_FRAME segment header should be /* Used to determine if PT_GNU_EH_FRAME segment header should be
created. */ created. */
boolean eh_frame_hdr; asection *eh_frame_hdr;
/* Used to determine if the e_flags field has been initialized */
boolean flags_init;
/* Number of symbol version definitions we are about to emit. */ /* Number of symbol version definitions we are about to emit. */
unsigned int cverdefs; unsigned int cverdefs;
@ -1366,16 +1437,16 @@ extern void _bfd_elf_strtab_finalize
PARAMS ((struct elf_strtab_hash *)); PARAMS ((struct elf_strtab_hash *));
extern boolean _bfd_elf_discard_section_eh_frame extern boolean _bfd_elf_discard_section_eh_frame
PARAMS ((bfd *, struct bfd_link_info *, asection *, asection *, PARAMS ((bfd *, struct bfd_link_info *, asection *,
boolean (*) (bfd_vma, PTR), struct elf_reloc_cookie *)); boolean (*) (bfd_vma, PTR), struct elf_reloc_cookie *));
extern boolean _bfd_elf_discard_section_eh_frame_hdr extern boolean _bfd_elf_discard_section_eh_frame_hdr
PARAMS ((bfd *, struct bfd_link_info *, asection *)); PARAMS ((bfd *, struct bfd_link_info *));
extern bfd_vma _bfd_elf_eh_frame_section_offset extern bfd_vma _bfd_elf_eh_frame_section_offset
PARAMS ((bfd *, asection *, bfd_vma)); PARAMS ((bfd *, asection *, bfd_vma));
extern boolean _bfd_elf_write_section_eh_frame extern boolean _bfd_elf_write_section_eh_frame
PARAMS ((bfd *, asection *, asection *, bfd_byte *)); PARAMS ((bfd *, struct bfd_link_info *, asection *, bfd_byte *));
extern boolean _bfd_elf_write_section_eh_frame_hdr extern boolean _bfd_elf_write_section_eh_frame_hdr
PARAMS ((bfd *, asection *)); PARAMS ((bfd *, struct bfd_link_info *));
extern boolean _bfd_elf_maybe_strip_eh_frame_hdr extern boolean _bfd_elf_maybe_strip_eh_frame_hdr
PARAMS ((struct bfd_link_info *)); PARAMS ((struct bfd_link_info *));

View File

@ -26,74 +26,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define EH_FRAME_HDR_SIZE 8 #define EH_FRAME_HDR_SIZE 8
struct cie_header
{
unsigned int length;
unsigned int id;
};
struct cie
{
struct cie_header hdr;
unsigned char version;
unsigned char augmentation[20];
unsigned int code_align;
int data_align;
unsigned int ra_column;
unsigned int augmentation_size;
struct elf_link_hash_entry *personality;
unsigned char per_encoding;
unsigned char lsda_encoding;
unsigned char fde_encoding;
unsigned char initial_insn_length;
unsigned char make_relative;
unsigned char make_lsda_relative;
unsigned char initial_instructions[50];
};
struct eh_cie_fde
{
unsigned int offset;
unsigned int size;
asection *sec;
unsigned int new_offset;
unsigned char fde_encoding;
unsigned char lsda_encoding;
unsigned char lsda_offset;
unsigned char cie : 1;
unsigned char removed : 1;
unsigned char make_relative : 1;
unsigned char make_lsda_relative : 1;
unsigned char per_encoding_relative : 1;
};
struct eh_frame_sec_info
{
unsigned int count;
unsigned int alloced;
struct eh_cie_fde entry[1];
};
struct eh_frame_array_ent
{
bfd_vma initial_loc;
bfd_vma fde;
};
struct eh_frame_hdr_info
{
struct cie last_cie;
asection *last_cie_sec;
unsigned int last_cie_offset;
unsigned int fde_count, array_count;
struct eh_frame_array_ent *array;
/* TRUE if .eh_frame_hdr should contain the sorted search table.
We build it if we successfully read all .eh_frame input sections
and recognize them. */
boolean table;
boolean strip;
};
static bfd_vma read_unsigned_leb128 static bfd_vma read_unsigned_leb128
PARAMS ((bfd *, char *, unsigned int *)); PARAMS ((bfd *, char *, unsigned int *));
static bfd_signed_vma read_signed_leb128 static bfd_signed_vma read_signed_leb128
@ -282,11 +214,11 @@ int cie_compare (c1, c2)
deleted. */ deleted. */
boolean boolean
_bfd_elf_discard_section_eh_frame (abfd, info, sec, ehdrsec, _bfd_elf_discard_section_eh_frame (abfd, info, sec,
reloc_symbol_deleted_p, cookie) reloc_symbol_deleted_p, cookie)
bfd *abfd; bfd *abfd;
struct bfd_link_info *info; struct bfd_link_info *info;
asection *sec, *ehdrsec; asection *sec;
boolean (*reloc_symbol_deleted_p) PARAMS ((bfd_vma, PTR)); boolean (*reloc_symbol_deleted_p) PARAMS ((bfd_vma, PTR));
struct elf_reloc_cookie *cookie; struct elf_reloc_cookie *cookie;
{ {
@ -294,6 +226,7 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec, ehdrsec,
bfd_byte *last_cie, *last_fde; bfd_byte *last_cie, *last_fde;
struct cie_header hdr; struct cie_header hdr;
struct cie cie; struct cie cie;
struct elf_link_hash_table *htab;
struct eh_frame_hdr_info *hdr_info; struct eh_frame_hdr_info *hdr_info;
struct eh_frame_sec_info *sec_info = NULL; struct eh_frame_sec_info *sec_info = NULL;
unsigned int leb128_tmp; unsigned int leb128_tmp;
@ -316,10 +249,8 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec, ehdrsec,
return false; return false;
} }
BFD_ASSERT (elf_section_data (ehdrsec)->sec_info_type htab = elf_hash_table (info);
== ELF_INFO_TYPE_EH_FRAME_HDR); hdr_info = &htab->eh_info;
hdr_info = (struct eh_frame_hdr_info *)
elf_section_data (ehdrsec)->sec_info;
/* Read the frame unwind information from abfd. */ /* Read the frame unwind information from abfd. */
@ -740,32 +671,27 @@ free_no_table:
input sections. It finalizes the size of .eh_frame_hdr section. */ input sections. It finalizes the size of .eh_frame_hdr section. */
boolean boolean
_bfd_elf_discard_section_eh_frame_hdr (abfd, info, sec) _bfd_elf_discard_section_eh_frame_hdr (abfd, info)
bfd *abfd; bfd *abfd;
struct bfd_link_info *info; struct bfd_link_info *info;
asection *sec;
{ {
struct elf_link_hash_table *htab;
struct eh_frame_hdr_info *hdr_info; struct eh_frame_hdr_info *hdr_info;
asection *sec;
if ((elf_section_data (sec)->sec_info_type htab = elf_hash_table (info);
!= ELF_INFO_TYPE_EH_FRAME_HDR) hdr_info = &htab->eh_info;
|| ! info->eh_frame_hdr) sec = hdr_info->hdr_sec;
{ if (sec == NULL)
_bfd_strip_section_from_output (info, sec);
return false;
}
hdr_info = (struct eh_frame_hdr_info *)
elf_section_data (sec)->sec_info;
if (hdr_info->strip)
return false; return false;
sec->_cooked_size = EH_FRAME_HDR_SIZE; sec->_cooked_size = EH_FRAME_HDR_SIZE;
if (hdr_info->table) if (hdr_info->table)
sec->_cooked_size += 4 + hdr_info->fde_count * 8; sec->_cooked_size += 4 + hdr_info->fde_count * 8;
/* Request program headers to be recalculated. */ /* Request program headers to be recalculated. */
elf_tdata (abfd)->program_header_size = 0; elf_tdata (abfd)->program_header_size = 0;
elf_tdata (abfd)->eh_frame_hdr = true; elf_tdata (abfd)->eh_frame_hdr = sec;
return true; return true;
} }
@ -778,21 +704,21 @@ boolean
_bfd_elf_maybe_strip_eh_frame_hdr (info) _bfd_elf_maybe_strip_eh_frame_hdr (info)
struct bfd_link_info *info; struct bfd_link_info *info;
{ {
asection *sec, *o; asection *o;
bfd *abfd; bfd *abfd;
struct elf_link_hash_table *htab;
struct eh_frame_hdr_info *hdr_info; struct eh_frame_hdr_info *hdr_info;
sec = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".eh_frame_hdr"); htab = elf_hash_table (info);
if (sec == NULL || bfd_is_abs_section (sec->output_section)) hdr_info = &htab->eh_info;
if (hdr_info->hdr_sec == NULL)
return true; return true;
hdr_info if (bfd_is_abs_section (hdr_info->hdr_sec->output_section))
= bfd_zmalloc (sizeof (struct eh_frame_hdr_info)); {
if (hdr_info == NULL) hdr_info->hdr_sec = NULL;
return false; return true;
}
elf_section_data (sec)->sec_info = hdr_info;
elf_section_data (sec)->sec_info_type = ELF_INFO_TYPE_EH_FRAME_HDR;
abfd = NULL; abfd = NULL;
if (info->eh_frame_hdr) if (info->eh_frame_hdr)
@ -807,11 +733,12 @@ _bfd_elf_maybe_strip_eh_frame_hdr (info)
if (abfd == NULL) if (abfd == NULL)
{ {
_bfd_strip_section_from_output (info, sec); _bfd_strip_section_from_output (info, hdr_info->hdr_sec);
hdr_info->strip = true; hdr_info->hdr_sec = NULL;
return true;
} }
else
hdr_info->table = true; hdr_info->table = true;
return true; return true;
} }
@ -869,9 +796,8 @@ _bfd_elf_eh_frame_section_offset (output_bfd, sec, offset)
for run-time relocation against LSDA field. */ for run-time relocation against LSDA field. */
if (sec_info->entry[mid].make_lsda_relative if (sec_info->entry[mid].make_lsda_relative
&& ! sec_info->entry[mid].cie && ! sec_info->entry[mid].cie
&& (offset && (offset == (sec_info->entry[mid].offset + 8
== (sec_info->entry[mid].offset + 8 + sec_info->entry[mid].lsda_offset)))
+ sec_info->entry[mid].lsda_offset)))
return (bfd_vma) -2; return (bfd_vma) -2;
return (offset + sec_info->entry[mid].new_offset return (offset + sec_info->entry[mid].new_offset
@ -882,12 +808,14 @@ _bfd_elf_eh_frame_section_offset (output_bfd, sec, offset)
contents. */ contents. */
boolean boolean
_bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents) _bfd_elf_write_section_eh_frame (abfd, info, sec, contents)
bfd *abfd; bfd *abfd;
asection *sec, *ehdrsec; struct bfd_link_info *info;
asection *sec;
bfd_byte *contents; bfd_byte *contents;
{ {
struct eh_frame_sec_info *sec_info; struct eh_frame_sec_info *sec_info;
struct elf_link_hash_table *htab;
struct eh_frame_hdr_info *hdr_info; struct eh_frame_hdr_info *hdr_info;
unsigned int i; unsigned int i;
bfd_byte *p, *buf; bfd_byte *p, *buf;
@ -905,19 +833,13 @@ _bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents)
sec->_raw_size); sec->_raw_size);
sec_info = (struct eh_frame_sec_info *) sec_info = (struct eh_frame_sec_info *)
elf_section_data (sec)->sec_info; elf_section_data (sec)->sec_info;
hdr_info = NULL; htab = elf_hash_table (info);
if (ehdrsec hdr_info = &htab->eh_info;
&& (elf_section_data (ehdrsec)->sec_info_type if (hdr_info->table && hdr_info->array == NULL)
== ELF_INFO_TYPE_EH_FRAME_HDR)) hdr_info->array
{ = bfd_malloc (hdr_info->fde_count * sizeof(*hdr_info->array));
hdr_info = (struct eh_frame_hdr_info *) if (hdr_info->array == NULL)
elf_section_data (ehdrsec)->sec_info; hdr_info = NULL;
if (hdr_info->table && hdr_info->array == NULL)
hdr_info->array
= bfd_malloc (hdr_info->fde_count * sizeof(*hdr_info->array));
if (hdr_info->array == NULL)
hdr_info = NULL;
}
p = contents; p = contents;
for (i = 0; i < sec_info->count; ++i) for (i = 0; i < sec_info->count; ++i)
@ -1165,20 +1087,21 @@ vma_compare (a, b)
sorted by increasing initial_loc) */ sorted by increasing initial_loc) */
boolean boolean
_bfd_elf_write_section_eh_frame_hdr (abfd, sec) _bfd_elf_write_section_eh_frame_hdr (abfd, info)
bfd *abfd; bfd *abfd;
asection *sec; struct bfd_link_info *info;
{ {
struct elf_link_hash_table *htab;
struct eh_frame_hdr_info *hdr_info; struct eh_frame_hdr_info *hdr_info;
asection *sec;
bfd_byte *contents; bfd_byte *contents;
asection *eh_frame_sec; asection *eh_frame_sec;
bfd_size_type size; bfd_size_type size;
BFD_ASSERT (elf_section_data (sec)->sec_info_type htab = elf_hash_table (info);
== ELF_INFO_TYPE_EH_FRAME_HDR); hdr_info = &htab->eh_info;
hdr_info = (struct eh_frame_hdr_info *) sec = hdr_info->hdr_sec;
elf_section_data (sec)->sec_info; if (sec == NULL)
if (hdr_info->strip)
return true; return true;
size = EH_FRAME_HDR_SIZE; size = EH_FRAME_HDR_SIZE;

View File

@ -3449,10 +3449,9 @@ map_sections_to_segments (abfd)
/* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME /* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME
segment. */ segment. */
eh_frame_hdr = NULL; eh_frame_hdr = elf_tdata (abfd)->eh_frame_hdr;
if (elf_tdata (abfd)->eh_frame_hdr) if (eh_frame_hdr != NULL
eh_frame_hdr = bfd_get_section_by_name (abfd, ".eh_frame_hdr"); && (eh_frame_hdr->output_section->flags & SEC_LOAD) != 0)
if (eh_frame_hdr != NULL && (eh_frame_hdr->flags & SEC_LOAD))
{ {
amt = sizeof (struct elf_segment_map); amt = sizeof (struct elf_segment_map);
m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
@ -3461,7 +3460,7 @@ map_sections_to_segments (abfd)
m->next = NULL; m->next = NULL;
m->p_type = PT_GNU_EH_FRAME; m->p_type = PT_GNU_EH_FRAME;
m->count = 1; m->count = 1;
m->sections[0] = eh_frame_hdr; m->sections[0] = eh_frame_hdr->output_section;
*pm = m; *pm = m;
pm = &m->next; pm = &m->next;
@ -4032,8 +4031,7 @@ get_program_header_size (abfd)
++segs; ++segs;
} }
if (elf_tdata (abfd)->eh_frame_hdr if (elf_tdata (abfd)->eh_frame_hdr)
&& bfd_get_section_by_name (abfd, ".eh_frame_hdr") != NULL)
{ {
/* We need a PT_GNU_EH_FRAME segment. */ /* We need a PT_GNU_EH_FRAME segment. */
++segs; ++segs;
@ -7327,9 +7325,9 @@ _bfd_elf_section_offset (abfd, info, sec, offset)
switch (sec_data->sec_info_type) switch (sec_data->sec_info_type)
{ {
case ELF_INFO_TYPE_STABS: case ELF_INFO_TYPE_STABS:
return _bfd_stab_section_offset return _bfd_stab_section_offset (abfd,
(abfd, &elf_hash_table (info)->merge_info, sec, &sec_data->sec_info, &elf_hash_table (info)->merge_info,
offset); sec, &sec_data->sec_info, offset);
case ELF_INFO_TYPE_EH_FRAME: case ELF_INFO_TYPE_EH_FRAME:
return _bfd_elf_eh_frame_section_offset (abfd, sec, offset); return _bfd_elf_eh_frame_section_offset (abfd, sec, offset);
default: default:

View File

@ -2342,6 +2342,7 @@ elf_link_create_dynamic_sections (abfd, info)
|| ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
|| ! bfd_set_section_alignment (abfd, s, 2)) || ! bfd_set_section_alignment (abfd, s, 2))
return false; return false;
elf_hash_table (info)->eh_info.hdr_sec = s;
} }
/* Create sections to hold version informations. These are removed /* Create sections to hold version informations. These are removed
@ -5854,17 +5855,10 @@ elf_bfd_final_link (abfd, info)
goto error_return; goto error_return;
} }
if (info->eh_frame_hdr && elf_hash_table (info)->dynobj) if (info->eh_frame_hdr)
{ {
o = bfd_get_section_by_name (elf_hash_table (info)->dynobj, if (! _bfd_elf_write_section_eh_frame_hdr (abfd, info))
".eh_frame_hdr"); goto error_return;
if (o
&& (elf_section_data (o)->sec_info_type
== ELF_INFO_TYPE_EH_FRAME_HDR))
{
if (! _bfd_elf_write_section_eh_frame_hdr (abfd, o))
goto error_return;
}
} }
if (finfo.symstrtab != NULL) if (finfo.symstrtab != NULL)
@ -6839,12 +6833,7 @@ elf_link_input_bfd (finfo, input_bfd)
from discarded sections and section symbols from from discarded sections and section symbols from
removed link-once sections. Complain about relocs removed link-once sections. Complain about relocs
against discarded sections. Zero relocs against removed against discarded sections. Zero relocs against removed
link-once sections. We should really complain if link-once sections. */
anything in the final link tries to use it, but
DWARF-based exception handling might have an entry in
.eh_frame to describe a routine in the linkonce section,
and it turns out to be hard to remove the .eh_frame
entry too. FIXME. */
if (!finfo->info->relocateable if (!finfo->info->relocateable
&& !elf_section_ignore_discarded_relocs (o)) && !elf_section_ignore_discarded_relocs (o))
{ {
@ -7166,19 +7155,14 @@ elf_link_input_bfd (finfo, input_bfd)
return false; return false;
break; break;
case ELF_INFO_TYPE_MERGE: case ELF_INFO_TYPE_MERGE:
if (! (_bfd_write_merged_section if (! _bfd_write_merged_section (output_bfd, o,
(output_bfd, o, elf_section_data (o)->sec_info))) elf_section_data (o)->sec_info))
return false; return false;
break; break;
case ELF_INFO_TYPE_EH_FRAME: case ELF_INFO_TYPE_EH_FRAME:
{ {
asection *ehdrsec; if (! _bfd_elf_write_section_eh_frame (output_bfd, finfo->info,
o, contents))
ehdrsec
= bfd_get_section_by_name (elf_hash_table (finfo->info)->dynobj,
".eh_frame_hdr");
if (! (_bfd_elf_write_section_eh_frame (output_bfd, o, ehdrsec,
contents)))
return false; return false;
} }
break; break;
@ -8409,7 +8393,7 @@ elf_bfd_discard_info (output_bfd, info)
struct bfd_link_info *info; struct bfd_link_info *info;
{ {
struct elf_reloc_cookie cookie; struct elf_reloc_cookie cookie;
asection *stab, *eh, *ehdr; asection *stab, *eh;
Elf_Internal_Shdr *symtab_hdr; Elf_Internal_Shdr *symtab_hdr;
struct elf_backend_data *bed; struct elf_backend_data *bed;
bfd *abfd; bfd *abfd;
@ -8422,11 +8406,6 @@ elf_bfd_discard_info (output_bfd, info)
|| ! is_elf_hash_table (info)) || ! is_elf_hash_table (info))
return false; return false;
ehdr = NULL;
if (elf_hash_table (info)->dynobj != NULL)
ehdr = bfd_get_section_by_name (elf_hash_table (info)->dynobj,
".eh_frame_hdr");
for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next) for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
{ {
if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
@ -8437,15 +8416,11 @@ elf_bfd_discard_info (output_bfd, info)
if ((abfd->flags & DYNAMIC) != 0) if ((abfd->flags & DYNAMIC) != 0)
continue; continue;
eh = NULL; eh = bfd_get_section_by_name (abfd, ".eh_frame");
if (ehdr != NULL) if (eh != NULL
{ && (eh->_raw_size == 0
eh = bfd_get_section_by_name (abfd, ".eh_frame"); || bfd_is_abs_section (eh->output_section)))
if (eh != NULL eh = NULL;
&& (eh->_raw_size == 0
|| bfd_is_abs_section (eh->output_section)))
eh = NULL;
}
stab = bfd_get_section_by_name (abfd, ".stab"); stab = bfd_get_section_by_name (abfd, ".stab");
if (stab != NULL if (stab != NULL
@ -8520,7 +8495,7 @@ elf_bfd_discard_info (output_bfd, info)
if (cookie.rels != NULL) if (cookie.rels != NULL)
cookie.relend += count * bed->s->int_rels_per_ext_rel; cookie.relend += count * bed->s->int_rels_per_ext_rel;
if (_bfd_elf_discard_section_eh_frame (abfd, info, eh, ehdr, if (_bfd_elf_discard_section_eh_frame (abfd, info, eh,
elf_reloc_symbol_deleted_p, elf_reloc_symbol_deleted_p,
&cookie)) &cookie))
ret = true; ret = true;
@ -8544,8 +8519,8 @@ elf_bfd_discard_info (output_bfd, info)
} }
} }
if (ehdr != NULL if (info->eh_frame_hdr
&& _bfd_elf_discard_section_eh_frame_hdr (output_bfd, info, ehdr)) && _bfd_elf_discard_section_eh_frame_hdr (output_bfd, info))
ret = true; ret = true;
return ret; return ret;

View File

@ -223,6 +223,8 @@ m68klinux.c
m68klynx.c m68klynx.c
m68knetbsd.c m68knetbsd.c
m88kmach3.c m88kmach3.c
mach-o.c
mach-o.h
merge.c merge.c
mipsbsd.c mipsbsd.c
mmo.c mmo.c
@ -251,6 +253,9 @@ pe-mcore.c
pe-mips.c pe-mips.c
pe-ppc.c pe-ppc.c
pe-sh.c pe-sh.c
pef-traceback.h
pef.c
pef.h
pei-arm.c pei-arm.c
pei-i386.c pei-i386.c
pei-mcore.c pei-mcore.c
@ -291,3 +296,5 @@ vms.c
vms.h vms.h
xcoff-target.h xcoff-target.h
xcofflink.c xcofflink.c
xsym.c
xsym.h