aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf-eh-frame.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/elf-eh-frame.c')
-rw-r--r--bfd/elf-eh-frame.c177
1 files changed, 50 insertions, 127 deletions
diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
index d5f4cc5..fa152ab 100644
--- a/bfd/elf-eh-frame.c
+++ b/bfd/elf-eh-frame.c
@@ -26,74 +26,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#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
PARAMS ((bfd *, char *, unsigned int *));
static bfd_signed_vma read_signed_leb128
@@ -282,11 +214,11 @@ int cie_compare (c1, c2)
deleted. */
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)
bfd *abfd;
struct bfd_link_info *info;
- asection *sec, *ehdrsec;
+ asection *sec;
boolean (*reloc_symbol_deleted_p) PARAMS ((bfd_vma, PTR));
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;
struct cie_header hdr;
struct cie cie;
+ struct elf_link_hash_table *htab;
struct eh_frame_hdr_info *hdr_info;
struct eh_frame_sec_info *sec_info = NULL;
unsigned int leb128_tmp;
@@ -316,10 +249,8 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec, ehdrsec,
return false;
}
- BFD_ASSERT (elf_section_data (ehdrsec)->sec_info_type
- == ELF_INFO_TYPE_EH_FRAME_HDR);
- hdr_info = (struct eh_frame_hdr_info *)
- elf_section_data (ehdrsec)->sec_info;
+ htab = elf_hash_table (info);
+ hdr_info = &htab->eh_info;
/* 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. */
boolean
-_bfd_elf_discard_section_eh_frame_hdr (abfd, info, sec)
+_bfd_elf_discard_section_eh_frame_hdr (abfd, info)
bfd *abfd;
struct bfd_link_info *info;
- asection *sec;
{
+ struct elf_link_hash_table *htab;
struct eh_frame_hdr_info *hdr_info;
+ asection *sec;
- if ((elf_section_data (sec)->sec_info_type
- != ELF_INFO_TYPE_EH_FRAME_HDR)
- || ! info->eh_frame_hdr)
- {
- _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)
+ htab = elf_hash_table (info);
+ hdr_info = &htab->eh_info;
+ sec = hdr_info->hdr_sec;
+ if (sec == NULL)
return false;
+
sec->_cooked_size = EH_FRAME_HDR_SIZE;
if (hdr_info->table)
sec->_cooked_size += 4 + hdr_info->fde_count * 8;
/* Request program headers to be recalculated. */
elf_tdata (abfd)->program_header_size = 0;
- elf_tdata (abfd)->eh_frame_hdr = true;
+ elf_tdata (abfd)->eh_frame_hdr = sec;
return true;
}
@@ -778,21 +704,21 @@ boolean
_bfd_elf_maybe_strip_eh_frame_hdr (info)
struct bfd_link_info *info;
{
- asection *sec, *o;
+ asection *o;
bfd *abfd;
+ struct elf_link_hash_table *htab;
struct eh_frame_hdr_info *hdr_info;
- sec = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".eh_frame_hdr");
- if (sec == NULL || bfd_is_abs_section (sec->output_section))
+ htab = elf_hash_table (info);
+ hdr_info = &htab->eh_info;
+ if (hdr_info->hdr_sec == NULL)
return true;
- hdr_info
- = bfd_zmalloc (sizeof (struct eh_frame_hdr_info));
- if (hdr_info == NULL)
- return false;
-
- elf_section_data (sec)->sec_info = hdr_info;
- elf_section_data (sec)->sec_info_type = ELF_INFO_TYPE_EH_FRAME_HDR;
+ if (bfd_is_abs_section (hdr_info->hdr_sec->output_section))
+ {
+ hdr_info->hdr_sec = NULL;
+ return true;
+ }
abfd = NULL;
if (info->eh_frame_hdr)
@@ -807,11 +733,12 @@ _bfd_elf_maybe_strip_eh_frame_hdr (info)
if (abfd == NULL)
{
- _bfd_strip_section_from_output (info, sec);
- hdr_info->strip = true;
+ _bfd_strip_section_from_output (info, hdr_info->hdr_sec);
+ hdr_info->hdr_sec = NULL;
+ return true;
}
- else
- hdr_info->table = true;
+
+ hdr_info->table = true;
return true;
}
@@ -869,9 +796,8 @@ _bfd_elf_eh_frame_section_offset (output_bfd, sec, offset)
for run-time relocation against LSDA field. */
if (sec_info->entry[mid].make_lsda_relative
&& ! sec_info->entry[mid].cie
- && (offset
- == (sec_info->entry[mid].offset + 8
- + sec_info->entry[mid].lsda_offset)))
+ && (offset == (sec_info->entry[mid].offset + 8
+ + sec_info->entry[mid].lsda_offset)))
return (bfd_vma) -2;
return (offset + sec_info->entry[mid].new_offset
@@ -882,12 +808,14 @@ _bfd_elf_eh_frame_section_offset (output_bfd, sec, offset)
contents. */
boolean
-_bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents)
+_bfd_elf_write_section_eh_frame (abfd, info, sec, contents)
bfd *abfd;
- asection *sec, *ehdrsec;
+ struct bfd_link_info *info;
+ asection *sec;
bfd_byte *contents;
{
struct eh_frame_sec_info *sec_info;
+ struct elf_link_hash_table *htab;
struct eh_frame_hdr_info *hdr_info;
unsigned int i;
bfd_byte *p, *buf;
@@ -905,19 +833,13 @@ _bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents)
sec->_raw_size);
sec_info = (struct eh_frame_sec_info *)
elf_section_data (sec)->sec_info;
- hdr_info = NULL;
- if (ehdrsec
- && (elf_section_data (ehdrsec)->sec_info_type
- == ELF_INFO_TYPE_EH_FRAME_HDR))
- {
- hdr_info = (struct eh_frame_hdr_info *)
- elf_section_data (ehdrsec)->sec_info;
- 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;
- }
+ htab = elf_hash_table (info);
+ hdr_info = &htab->eh_info;
+ 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;
for (i = 0; i < sec_info->count; ++i)
@@ -1165,20 +1087,21 @@ vma_compare (a, b)
sorted by increasing initial_loc) */
boolean
-_bfd_elf_write_section_eh_frame_hdr (abfd, sec)
+_bfd_elf_write_section_eh_frame_hdr (abfd, info)
bfd *abfd;
- asection *sec;
+ struct bfd_link_info *info;
{
+ struct elf_link_hash_table *htab;
struct eh_frame_hdr_info *hdr_info;
+ asection *sec;
bfd_byte *contents;
asection *eh_frame_sec;
bfd_size_type size;
- BFD_ASSERT (elf_section_data (sec)->sec_info_type
- == ELF_INFO_TYPE_EH_FRAME_HDR);
- hdr_info = (struct eh_frame_hdr_info *)
- elf_section_data (sec)->sec_info;
- if (hdr_info->strip)
+ htab = elf_hash_table (info);
+ hdr_info = &htab->eh_info;
+ sec = hdr_info->hdr_sec;
+ if (sec == NULL)
return true;
size = EH_FRAME_HDR_SIZE;