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)
{ NULL, 0, 0, 0, 0 }
};
-static const struct bfd_elf_special_section *special_sections[] =
+static const struct bfd_elf_special_section * const special_sections[] =
{
special_sections_b, /* 'b' */
special_sections_c, /* 'c' */
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)
if (this_hdr->sh_type != SHT_NOBITS)
off += this_hdr->sh_size;
}
+ else if (this_hdr->sh_type == SHT_NOBITS
+ && (this_hdr->sh_flags & SHF_TLS) != 0
+ && this_hdr->sh_offset == 0)
+ {
+ /* This is a .tbss section that didn't get a PT_LOAD.
+ (See _bfd_elf_map_sections_to_segments "Create a
+ final PT_LOAD".) Set sh_offset to the value it
+ would have if we had created a zero p_filesz and
+ p_memsz PT_LOAD header for the section. This
+ also makes the PT_TLS header have the same
+ p_offset value. */
+ bfd_vma adjust = vma_page_aligned_bias (this_hdr->sh_addr,
+ off, align);
+ this_hdr->sh_offset = sec->filepos = off + adjust;
+ }
if (this_hdr->sh_type != SHT_NOBITS)
{
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"),
&& (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)
|| obfd->xvec->flavour != bfd_target_elf_flavour)
return TRUE;
+ BFD_ASSERT (elf_section_data (osec) != NULL);
+
/* For objcopy and relocatable link, don't copy the output ELF
section type from input if the output BFD section flags have been
set to something different. For a final link allow some flags
enum { nothing_seen, symbol_seen, file_after_symbol_seen } state;
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ if (symbols == NULL)
+ return FALSE;
+
filename = NULL;
func = NULL;
file = NULL;
return TRUE;
}
- if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
+ if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections,
+ section, symbols, offset,
filename_ptr, functionname_ptr,
line_ptr, 0,
&elf_tdata (abfd)->dwarf2_find_line_info))
bfd_boolean
_bfd_elf_close_and_cleanup (bfd *abfd)
{
- if (bfd_get_format (abfd) == bfd_object)
+ struct elf_obj_tdata *tdata = elf_tdata (abfd);
+ if (bfd_get_format (abfd) == bfd_object && tdata != NULL)
{
- if (elf_tdata (abfd) != NULL && elf_shstrtab (abfd) != NULL)
+ if (elf_shstrtab (abfd) != NULL)
_bfd_elf_strtab_free (elf_shstrtab (abfd));
- _bfd_dwarf2_cleanup_debug_info (abfd);
+ _bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info);
}
return _bfd_generic_close_and_cleanup (abfd);
return elfcore_make_note_pseudosection (abfd, ".reg-s390-prefix", note);
}
+static bfd_boolean
+elfcore_grok_s390_last_break (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-s390-last-break", note);
+}
+
+static bfd_boolean
+elfcore_grok_s390_system_call (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-s390-system-call", note);
+}
+
+static bfd_boolean
+elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-arm-vfp", note);
+}
+
#if defined (HAVE_PRPSINFO_T)
typedef prpsinfo_t elfcore_psinfo_t;
#if defined (HAVE_PRPSINFO32_T) /* Sparc64 cross Sparc32 */
memcpy (&psinfo, note->descdata, sizeof (psinfo));
+#if defined (HAVE_PSINFO_T_PR_PID) || defined (HAVE_PRPSINFO_T_PR_PID)
+ elf_tdata (abfd)->core_pid = psinfo.pr_pid;
+#endif
elf_tdata (abfd)->core_program
= _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
sizeof (psinfo.pr_fname));
memcpy (&psinfo, note->descdata, sizeof (psinfo));
+#if defined (HAVE_PSINFO32_T_PR_PID) || defined (HAVE_PRPSINFO32_T_PR_PID)
+ elf_tdata (abfd)->core_pid = psinfo.pr_pid;
+#endif
elf_tdata (abfd)->core_program
= _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
sizeof (psinfo.pr_fname));
else
return TRUE;
+ case NT_S390_LAST_BREAK:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_s390_last_break (abfd, note);
+ else
+ return TRUE;
+
+ case NT_S390_SYSTEM_CALL:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_s390_system_call (abfd, note);
+ else
+ return TRUE;
+
+ case NT_ARM_VFP:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_arm_vfp (abfd, note);
+ else
+ return TRUE;
+
case NT_PRPSINFO:
case NT_PSINFO:
if (bed->elf_backend_grok_psinfo)
note_name, NT_S390_PREFIX, s390_prefix, size);
}
+char *
+elfcore_write_s390_last_break (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *s390_last_break,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_S390_LAST_BREAK,
+ s390_last_break, size);
+}
+
+char *
+elfcore_write_s390_system_call (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *s390_system_call,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_S390_SYSTEM_CALL,
+ s390_system_call, size);
+}
+
+char *
+elfcore_write_arm_vfp (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *arm_vfp,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_ARM_VFP, arm_vfp, size);
+}
+
char *
elfcore_write_register_note (bfd *abfd,
char *buf,
return elfcore_write_s390_ctrs (abfd, buf, bufsiz, data, size);
if (strcmp (section, ".reg-s390-prefix") == 0)
return elfcore_write_s390_prefix (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-s390-last-break") == 0)
+ return elfcore_write_s390_last_break (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-s390-system-call") == 0)
+ return elfcore_write_s390_system_call (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-arm-vfp") == 0)
+ return elfcore_write_arm_vfp (abfd, buf, bufsiz, data, size);
return NULL;
}
case ELF_INFO_TYPE_EH_FRAME:
return _bfd_elf_eh_frame_section_offset (abfd, info, sec, offset);
default:
+ if ((sec->flags & SEC_ELF_REVERSE_COPY) != 0)
+ {
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ bfd_size_type address_size = bed->s->arch_size / 8;
+ offset = sec->size - offset - address_size;
+ }
return offset;
}
}
i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
/* To make things simpler for the loader on Linux systems we set the
- osabi field to ELFOSABI_LINUX if the binary contains symbols of
+ osabi field to ELFOSABI_GNU if the binary contains symbols of
the STT_GNU_IFUNC type or STB_GNU_UNIQUE binding. */
if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE
&& elf_tdata (abfd)->has_gnu_symbols)
- i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_LINUX;
+ i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_GNU;
}