From 86b2281fde235816619a26af3c59ce24b949b2f8 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 20 May 2011 15:32:24 +0000 Subject: [PATCH] PR 12763 * elf.c (_bfd_elf_make_section_from_shdr): Set up TLS section LMAs from PT_TLS header. (_bfd_elf_map_sections_to_segments): Don't create a final PT_LOAD segment if just for .tbss. (assign_file_positions_for_load_sections): Don't report "can't allocate in segment" errors for .tbss. (assign_file_positions_for_non_load_sections): Don't set p_filesz from SHT_NOBITS section filepos. --- bfd/ChangeLog | 12 ++++++++++++ bfd/elf.c | 35 +++++++++++++++++++++++------------ 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7cdd2156f0..4517a4f46e 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,15 @@ +2011-05-21 Alan Modra + + PR 12763 + * elf.c (_bfd_elf_make_section_from_shdr): Set up TLS section LMAs + from PT_TLS header. + (_bfd_elf_map_sections_to_segments): Don't create a final PT_LOAD + segment if just for .tbss. + (assign_file_positions_for_load_sections): Don't report "can't + allocate in segment" errors for .tbss. + (assign_file_positions_for_non_load_sections): Don't set p_filesz + from SHT_NOBITS section filepos. + 2011-05-20 Bernd Schmidt * elf32-tic6x.c (elf32_tic6x_howto_table): Add entries for diff --git a/bfd/elf.c b/bfd/elf.c index 33a3a7d8cf..ffc9c8e2d5 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -976,7 +976,9 @@ _bfd_elf_make_section_from_shdr (bfd *abfd, phdr = elf_tdata (abfd)->phdr; for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++) { - if (phdr->p_type == PT_LOAD + if (((phdr->p_type == PT_LOAD + && (hdr->sh_flags & SHF_TLS) == 0) + || phdr->p_type == PT_TLS) && ELF_SECTION_IN_SEGMENT (hdr, phdr)) { if ((flags & SEC_LOAD) == 0) @@ -3987,8 +3989,12 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) phdr_in_segment = FALSE; } - /* Create a final PT_LOAD program segment. */ - if (last_hdr != NULL) + /* Create a final PT_LOAD program segment, but not if it's just + for .tbss. */ + if (last_hdr != NULL + && (i - phdr_index != 1 + || ((last_hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) + != SEC_THREAD_LOCAL))) { m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment); if (m == NULL) @@ -4748,7 +4754,8 @@ assign_file_positions_for_load_sections (bfd *abfd, sec = m->sections[i]; this_hdr = &(elf_section_data(sec)->this_hdr); - if (!ELF_SECTION_IN_SEGMENT_1 (this_hdr, p, check_vma, 0)) + if (!ELF_SECTION_IN_SEGMENT_1 (this_hdr, p, check_vma, 0) + && !ELF_TBSS_SPECIAL (this_hdr, p)) { (*_bfd_error_handler) (_("%B: section `%A' can't be allocated in segment %d"), @@ -4919,17 +4926,21 @@ assign_file_positions_for_non_load_sections (bfd *abfd, && (p->p_type != PT_NOTE || bfd_get_format (abfd) != bfd_core)) { - Elf_Internal_Shdr *hdr; - asection *sect; - BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs); - sect = m->sections[m->count - 1]; - hdr = &elf_section_data (sect)->this_hdr; - p->p_filesz = sect->filepos - m->sections[0]->filepos; - if (hdr->sh_type != SHT_NOBITS) - p->p_filesz += hdr->sh_size; + p->p_filesz = 0; p->p_offset = m->sections[0]->filepos; + for (i = m->count; i-- != 0;) + { + asection *sect = m->sections[i]; + Elf_Internal_Shdr *hdr = &elf_section_data (sect)->this_hdr; + if (hdr->sh_type != SHT_NOBITS) + { + p->p_filesz = (sect->filepos - m->sections[0]->filepos + + hdr->sh_size); + break; + } + } } } else if (m->includes_filehdr)