diff options
author | Jakub Jelinek <jakub@redhat.com> | 2001-12-13 11:09:34 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2001-12-13 11:09:34 +0000 |
commit | 6576570080f306b7799bd1deb2abffdbcc6dc0a5 (patch) | |
tree | 7195727fd9a8486b8f920c7dd3b39148ba67d838 /bfd/elf.c | |
parent | 49d5aff7e554f7aa7ce868f70d85f98ceed622bf (diff) | |
download | gdb-6576570080f306b7799bd1deb2abffdbcc6dc0a5.zip gdb-6576570080f306b7799bd1deb2abffdbcc6dc0a5.tar.gz 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.c | 52 |
1 files changed, 42 insertions, 10 deletions
@@ -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; + } } |