aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2001-12-13 11:09:34 +0000
committerJakub Jelinek <jakub@redhat.com>2001-12-13 11:09:34 +0000
commit6576570080f306b7799bd1deb2abffdbcc6dc0a5 (patch)
tree7195727fd9a8486b8f920c7dd3b39148ba67d838 /bfd/elf.c
parent49d5aff7e554f7aa7ce868f70d85f98ceed622bf (diff)
downloadfsf-binutils-gdb-6576570080f306b7799bd1deb2abffdbcc6dc0a5.zip
fsf-binutils-gdb-6576570080f306b7799bd1deb2abffdbcc6dc0a5.tar.gz
fsf-binutils-gdb-6576570080f306b7799bd1deb2abffdbcc6dc0a5.tar.bz2
* elf-bfd.h (enum elf_link_info_type): New.
(struct bfd_elf_section_data): Remove stab_info and merge_info fields, add sec_info and sec_info_type. (struct elf_obj_tdata): Add eh_frame_hdr field. (_bfd_elf_discard_section_eh_frame): New prototype. (_bfd_elf_discard_section_eh_frame_hdr): Likewise. (_bfd_elf_eh_frame_section_offset): Likewise. (_bfd_elf_write_section_eh_frame): Likewise. (_bfd_elf_write_section_eh_frame_hdr): Likewise. * Makefile.am (BFD32_BACKENDS): Add elf-eh-frame.lo. (BFD32_BACKENDS_CFILES): Add elf-eh-frame.c. (elf-eh-frame.lo): New. * Makefile.in: Rebuilt. * configure.in (elf): Add elf-eh-frame.lo. * configure: Rebuilt. * elf.c (_bfd_elf_print_private_bfd_data): Support PT_GNU_EH_FRAME. (map_sections_to_segments): Create PT_GNU_EH_FRAME if requested. (get_program_header_size): Take into account PT_GNU_EH_FRAME segment. (_bfd_elf_rela_local_sym): Use sec_info_type and sec_info. (_bfd_elf_rel_local_sym): Likewise. (_bfd_elf_section_offset): Likewise. Call _bfd_elf_eh_frame_section_offset too. * elfxx-ia64.c (elfNN_ia64_relocate_section): Use sec_info_type and sec_info. * elf64-alpha.c (elf64_alpha_relocate_section): Likewise. * elf-eh-frame.c: New file. * elflink.h (elf_link_add_object_symbols): Don't optimize SHF_MERGE .stab sections. Set sec_info_type, use sec_info instead of merge_info and stab_info. (elf_link_create_dynamic_sections): Create .eh_frame_hdr section if --eh-frame-hdr. (elf_bfd_final_link): Write .eh_frame_hdr section. (elf_link_sec_merge_syms): Use sec_info_type and sec_info. (elf_link_input_bfd): Likewise. Call _bfd_elf_write_section_eh_frame to write .eh_frame sections. (elf_bfd_discard_info): Add output_bfd argument. Call _bfd_elf_discard_section_eh_frame and _bfd_elf_discard_section_eh_frame_hdr. (elf_section_ignore_discarded_relocs): Use sec_info_type, not section names. * bfd-in.h (bfd_elf32_discard_info, bfd_elf64_discard_info): Adjust prototypes. * bfd-in2.h (bfd_elf32_discard_info, bfd_elf64_discard_info): Likewise. * elf/common.h (PT_GNU_EH_FRAME): Define. * bfdlink.h (struct bfd_link_info): Add eh_frame_hdr field. * emultempl/elf32.em (finish): Supply output_bfd to bfd_elf*_discard_info. (OPTION_EH_FRAME_HDR): Define. (longopts): Add --eh-frame-hdr. (parse_args): Handle it. (list_options): Add --eh-frame-hdr to help. * emultempl/hppaelf.em (finish): Supply output_bfd to bfd_elf*_discard_info. * scripttempl/elf.sc (.eh_frame_hdr): Add. * readelf.c (get_segment_type): Support PT_GNU_EH_FRAME.
Diffstat (limited to 'bfd/elf.c')
-rw-r--r--bfd/elf.c52
1 files changed, 42 insertions, 10 deletions
diff --git a/bfd/elf.c b/bfd/elf.c
index a473366..98d3cd2 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -812,6 +812,7 @@ _bfd_elf_print_private_bfd_data (abfd, farg)
case PT_NOTE: pt = "NOTE"; break;
case PT_SHLIB: pt = "SHLIB"; break;
case PT_PHDR: pt = "PHDR"; break;
+ case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break;
default: sprintf (buf, "0x%lx", p->p_type); pt = buf; break;
}
fprintf (f, "%8s off 0x", pt);
@@ -2794,7 +2795,7 @@ map_sections_to_segments (abfd)
asection **hdrpp;
boolean phdr_in_segment = true;
boolean writable;
- asection *dynsec;
+ asection *dynsec, *eh_frame_hdr;
bfd_size_type amt;
if (elf_tdata (abfd)->segment_map != NULL)
@@ -3034,6 +3035,24 @@ map_sections_to_segments (abfd)
}
}
+ /* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME
+ segment. */
+ eh_frame_hdr = bfd_get_section_by_name (abfd, ".eh_frame_hdr");
+ if (eh_frame_hdr != NULL && (eh_frame_hdr->flags & SEC_LOAD))
+ {
+ amt = sizeof (struct elf_segment_map);
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
+ if (m == NULL)
+ goto error_return;
+ m->next = NULL;
+ m->p_type = PT_GNU_EH_FRAME;
+ m->count = 1;
+ m->sections[0] = eh_frame_hdr;
+
+ *pm = m;
+ pm = &m->next;
+ }
+
free (sections);
sections = NULL;
@@ -3548,6 +3567,13 @@ get_program_header_size (abfd)
++segs;
}
+ 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. */
+ ++segs;
+ }
+
for (s = abfd->sections; s != NULL; s = s->next)
{
if ((s->flags & SEC_LOAD) != 0
@@ -6392,14 +6418,14 @@ _bfd_elf_rela_local_sym (abfd, sym, sec, rel)
+ sym->st_value);
if ((sec->flags & SEC_MERGE)
&& ELF_ST_TYPE (sym->st_info) == STT_SECTION
- && elf_section_data (sec)->merge_info)
+ && elf_section_data (sec)->sec_info_type == ELF_INFO_TYPE_MERGE)
{
asection *msec;
msec = sec;
rel->r_addend =
_bfd_merged_section_offset (abfd, &msec,
- elf_section_data (sec)->merge_info,
+ elf_section_data (sec)->sec_info,
sym->st_value + rel->r_addend,
(bfd_vma) 0)
- relocation;
@@ -6417,11 +6443,11 @@ _bfd_elf_rel_local_sym (abfd, sym, psec, addend)
{
asection *sec = *psec;
- if (elf_section_data (sec)->merge_info == NULL)
+ if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_MERGE)
return sym->st_value + addend;
return _bfd_merged_section_offset (abfd, psec,
- elf_section_data (sec)->merge_info,
+ elf_section_data (sec)->sec_info,
sym->st_value + addend, (bfd_vma) 0);
}
@@ -6435,9 +6461,15 @@ _bfd_elf_section_offset (abfd, info, sec, offset)
struct bfd_elf_section_data *sec_data;
sec_data = elf_section_data (sec);
- if (sec_data->stab_info != NULL)
- return _bfd_stab_section_offset
- (abfd, &elf_hash_table (info)->stab_info,
- sec, &sec_data->stab_info, offset);
- return offset;
+ switch (sec_data->sec_info_type)
+ {
+ case ELF_INFO_TYPE_STABS:
+ return _bfd_stab_section_offset
+ (abfd, &elf_hash_table (info)->merge_info, sec, &sec_data->sec_info,
+ offset);
+ case ELF_INFO_TYPE_EH_FRAME:
+ return _bfd_elf_eh_frame_section_offset (abfd, sec, offset);
+ default:
+ return offset;
+ }
}