/* ELF executable support for BFD.
- Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012,
- 2013
- Free Software Foundation, Inc.
+ Copyright 1993-2014 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
return FALSE;
elf_object_id (abfd) = object_id;
- elf_program_header_size (abfd) = (bfd_size_type) -1;
+ if (abfd->direction != read_direction)
+ {
+ struct output_elf_obj_tdata *o = bfd_zalloc (abfd, sizeof *o);
+ if (o == NULL)
+ return FALSE;
+ elf_tdata (abfd)->o = o;
+ elf_program_header_size (abfd) = (bfd_size_type) -1;
+ }
return TRUE;
}
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour)
return TRUE;
- BFD_ASSERT (!elf_flags_init (obfd)
- || (elf_elfheader (obfd)->e_flags
- == elf_elfheader (ibfd)->e_flags));
+ if (!elf_flags_init (obfd))
+ {
+ elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
+ elf_flags_init (obfd) = TRUE;
+ }
elf_gp (obfd) = elf_gp (ibfd);
- elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
- elf_flags_init (obfd) = TRUE;
+
+ /* Also copy the EI_OSABI field. */
+ elf_elfheader (obfd)->e_ident[EI_OSABI] =
+ elf_elfheader (ibfd)->e_ident[EI_OSABI];
/* Copy object attributes. */
_bfd_elf_copy_obj_attributes (ibfd, obfd);
USE_RELA_P is TRUE, we use RELA relocations; otherwise, we use REL
relocations. */
-bfd_boolean
+static bfd_boolean
_bfd_elf_init_reloc_shdr (bfd *abfd,
struct bfd_elf_section_reloc_data *reldata,
asection *asect,
{
d->rel.hdr->sh_link = elf_onesymtab (abfd);
d->rel.hdr->sh_info = d->this_idx;
+ d->rel.hdr->sh_flags |= SHF_INFO_LINK;
}
if (d->rela.idx != 0)
{
d->rela.hdr->sh_link = elf_onesymtab (abfd);
d->rela.hdr->sh_info = d->this_idx;
+ d->rela.hdr->sh_flags |= SHF_INFO_LINK;
}
/* We need to set up sh_link for SHF_LINK_ORDER. */
name += 5;
s = bfd_get_section_by_name (abfd, name);
if (s != NULL)
- d->this_hdr.sh_info = elf_section_data (s)->this_idx;
+ {
+ d->this_hdr.sh_info = elf_section_data (s)->this_idx;
+ d->this_hdr.sh_flags |= SHF_INFO_LINK;
+ }
break;
case SHT_STRTAB:
return FALSE;
/* Post process the headers if necessary. */
- if (bed->elf_backend_post_process_headers)
- (*bed->elf_backend_post_process_headers) (abfd, link_info);
+ (*bed->elf_backend_post_process_headers) (abfd, link_info);
fsargs.failed = FALSE;
fsargs.link_info = link_info;
/* Mandated PF_R. */
m->p_flags = PF_R;
m->p_flags_valid = 1;
+ s = first_tls;
for (i = 0; i < (unsigned int) tls_count; ++i)
{
- BFD_ASSERT (first_tls->flags & SEC_THREAD_LOCAL);
- m->sections[i] = first_tls;
- first_tls = first_tls->next;
+ if ((s->flags & SEC_THREAD_LOCAL) == 0)
+ {
+ _bfd_error_handler
+ (_("%B: TLS sections are not adjacent:"), abfd);
+ s = first_tls;
+ i = 0;
+ while (i < (unsigned int) tls_count)
+ {
+ if ((s->flags & SEC_THREAD_LOCAL) != 0)
+ {
+ _bfd_error_handler (_(" TLS: %A"), s);
+ i++;
+ }
+ else
+ _bfd_error_handler (_(" non-TLS: %A"), s);
+ s = s->next;
+ }
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+ m->sections[i] = s;
+ s = s->next;
}
*pm = m;
== (SEC_LOAD | SEC_HAS_CONTENTS))
break;
- if (i == (unsigned) -1)
- continue;
-
- if (m->sections[i]->vma + m->sections[i]->size
- >= info->relro_end)
+ if (i != (unsigned) -1)
break;
}
}
static file_ptr
vma_page_aligned_bias (bfd_vma vma, ufile_ptr off, bfd_vma maxpagesize)
{
+ /* PR binutils/16199: Handle an alignment of zero. */
+ if (maxpagesize == 0)
+ maxpagesize = 1;
return ((vma - off) % maxpagesize);
}
p->p_flags |= PF_W;
}
}
+
off -= off_adjust;
/* Check that all sections are in a PT_LOAD segment.
{
if (lp->p_type == PT_LOAD
&& lp->p_vaddr < link_info->relro_end
- && lp->p_vaddr + lp->p_filesz >= link_info->relro_end
&& lm->count != 0
&& lm->sections[0]->vma >= link_info->relro_start)
break;
}
- /* PR ld/14207. If the RELRO segment doesn't fit in the
- LOAD segment, it should be removed. */
BFD_ASSERT (lm != NULL);
}
else
return FALSE;
}
+ /* Set e_type in ELF header to ET_EXEC for -pie -Ttext-segment=. */
+ if (link_info != NULL
+ && link_info->executable
+ && link_info->shared)
+ {
+ unsigned int num_segments = elf_elfheader (abfd)->e_phnum;
+ Elf_Internal_Phdr *segment = elf_tdata (abfd)->phdr;
+ Elf_Internal_Phdr *end_segment = &segment[num_segments];
+
+ /* Find the lowest p_vaddr in PT_LOAD segments. */
+ bfd_vma p_vaddr = (bfd_vma) -1;
+ for (; segment < end_segment; segment++)
+ if (segment->p_type == PT_LOAD && p_vaddr > segment->p_vaddr)
+ p_vaddr = segment->p_vaddr;
+
+ /* Set e_type to ET_EXEC if the lowest p_vaddr in PT_LOAD
+ segments is non-zero. */
+ if (p_vaddr)
+ i_ehdrp->e_type = ET_EXEC;
+ }
+
/* Write out the program headers. */
alloc = elf_program_header_size (abfd) / bed->s->sizeof_phdr;
if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0
return FALSE;
/* This is last since write_shdrs_and_ehdr can touch i_shdrp[0]. */
- if (t->build_id != NULL
- && t->build_id->u.o.zero == 0)
- return (*t->build_id->u.o.after_write_object_contents) (abfd);
+ if (t->o->build_id.after_write_object_contents != NULL)
+ return (*t->o->build_id.after_write_object_contents) (abfd);
return TRUE;
}
if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
{
map->sections[isec++] = section->output_section;
- if (section->lma < lowest_section->lma)
- lowest_section = section;
if ((section->flags & SEC_ALLOC) != 0)
{
bfd_vma seg_off;
+ if (section->lma < lowest_section->lma)
+ lowest_section = section;
+
/* Section lmas are set up from PT_LOAD header
p_paddr in _bfd_elf_make_section_from_shdr.
If this header has a p_paddr that disagrees
struct elf_obj_tdata *tdata = elf_tdata (abfd);
if (bfd_get_format (abfd) == bfd_object && tdata != NULL)
{
- if (elf_shstrtab (abfd) != NULL)
+ if (elf_tdata (abfd)->o != NULL && elf_shstrtab (abfd) != NULL)
_bfd_elf_strtab_free (elf_shstrtab (abfd));
_bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info);
}
return elfcore_make_note_pseudosection (abfd, ".reg-s390-system-call", note);
}
+static bfd_boolean
+elfcore_grok_s390_tdb (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-s390-tdb", note);
+}
+
static bfd_boolean
elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
{
else
return TRUE;
+ case NT_S390_TDB:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_s390_tdb (abfd, note);
+ else
+ return TRUE;
+
case NT_ARM_VFP:
if (note->namesz == 6
&& strcmp (note->namedata, "LINUX") == 0)
return FALSE;
t = elf_tdata (abfd);
- t->build_id = bfd_alloc (abfd, sizeof (t->build_id->u.i) - 1 + note->descsz);
+ t->build_id = bfd_alloc (abfd, sizeof (*t->build_id) - 1 + note->descsz);
if (t->build_id == NULL)
return FALSE;
- t->build_id->u.i.size = note->descsz;
- memcpy (t->build_id->u.i.data, note->descdata, note->descsz);
+ t->build_id->size = note->descsz;
+ memcpy (t->build_id->data, note->descdata, note->descsz);
return TRUE;
}
s390_system_call, size);
}
+char *
+elfcore_write_s390_tdb (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *s390_tdb,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_S390_TDB, s390_tdb, size);
+}
+
char *
elfcore_write_arm_vfp (bfd *abfd,
char *buf,
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-s390-tdb") == 0)
+ return elfcore_write_s390_tdb (abfd, buf, bufsiz, data, size);
if (strcmp (section, ".reg-arm-vfp") == 0)
return elfcore_write_arm_vfp (abfd, buf, bufsiz, data, size);
if (strcmp (section, ".reg-aarch-tls") == 0)
}
enum elf_reloc_type_class
-_bfd_elf_reloc_type_class (const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED)
+_bfd_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ const asection *rel_sec ATTRIBUTE_UNUSED,
+ const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED)
{
return reloc_class_normal;
}
SEC_IS_COMMON, NULL, "LARGE_COMMON", 0);
void
-_bfd_elf_set_osabi (bfd * abfd,
- struct bfd_link_info * link_info ATTRIBUTE_UNUSED)
+_bfd_elf_post_process_headers (bfd * abfd,
+ struct bfd_link_info * link_info ATTRIBUTE_UNUSED)
{
Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form. */