/* Intel 80386/80486-specific support for 32-bit ELF
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+ 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
#include "bfdlink.h"
#include "libbfd.h"
#include "elf-bfd.h"
+#include "elf-nacl.h"
#include "elf-vxworks.h"
#include "bfd_stdint.h"
#include "objalloc.h"
if (htab == NULL)
return FALSE;
- htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
if (!info->shared)
- htab->srelbss = bfd_get_section_by_name (dynobj, ".rel.bss");
+ htab->srelbss = bfd_get_linker_section (dynobj, ".rel.bss");
if (!htab->sdynbss
|| (!info->shared && !htab->srelbss))
return FALSE;
if (!info->no_ld_generated_unwind_info
- && bfd_get_section_by_name (dynobj, ".eh_frame") == NULL
+ && htab->plt_eh_frame == NULL
&& htab->elf.splt != NULL)
{
- flagword flags = get_elf_backend_data (dynobj)->dynamic_sec_flags;
+ flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
+ | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
htab->plt_eh_frame
- = bfd_make_section_with_flags (dynobj, ".eh_frame",
- flags | SEC_READONLY);
+ = bfd_make_section_anyway_with_flags (dynobj, ".eh_frame", flags);
if (htab->plt_eh_frame == NULL
|| !bfd_set_section_alignment (dynobj, htab->plt_eh_frame, 2))
return FALSE;
-
- htab->plt_eh_frame->size = sizeof (elf_i386_eh_frame_plt);
- htab->plt_eh_frame->contents
- = bfd_alloc (dynobj, htab->plt_eh_frame->size);
- memcpy (htab->plt_eh_frame->contents, elf_i386_eh_frame_plt,
- sizeof (elf_i386_eh_frame_plt));
}
return TRUE;
}
}
- if (h->size == 0)
- {
- (*_bfd_error_handler) (_("dynamic variable `%s' is zero size"),
- h->root.root.string);
- return TRUE;
- }
-
/* We must allocate the symbol in our .dynbss section, which will
become part of the .bss section of the executable. There will be
an entry for this symbol in the .dynsym section. The dynamic
/* We must generate a R_386_COPY reloc to tell the dynamic linker to
copy the initial value out of the dynamic object and into the
runtime process image. */
- if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
{
htab->srelbss->size += sizeof (Elf32_External_Rel);
h->needs_copy = 1;
/* Set the contents of the .interp section to the interpreter. */
if (info->executable)
{
- s = bfd_get_section_by_name (dynobj, ".interp");
+ s = bfd_get_linker_section (dynobj, ".interp");
if (s == NULL)
abort ();
s->size = sizeof ELF_DYNAMIC_INTERPRETER;
it's not incremented, so in order to compute the space reserved
for them, it suffices to multiply the reloc count by the jump
slot size.
-
+
PR ld/13302: We start next_irelative_index at the end of .rela.plt
so that R_386_IRELATIVE entries come last. */
if (htab->elf.srelplt)
FALSE, FALSE, FALSE);
/* Don't allocate .got.plt section if there are no GOT nor PLT
- entries and there is no refeence to _GLOBAL_OFFSET_TABLE_. */
+ entries and there is no reference to _GLOBAL_OFFSET_TABLE_. */
if ((got == NULL
|| !got->ref_regular_nonweak)
&& (htab->elf.sgotplt->size
htab->elf.sgotplt->size = 0;
}
+
+ if (htab->plt_eh_frame != NULL
+ && htab->elf.splt != NULL
+ && htab->elf.splt->size != 0
+ && !bfd_is_abs_section (htab->elf.splt->output_section)
+ && _bfd_elf_eh_frame_present (info))
+ htab->plt_eh_frame->size = sizeof (elf_i386_eh_frame_plt);
+
/* We now have determined the sizes of the various dynamic sections.
Allocate memory for them. */
relocs = FALSE;
continue;
if (s == htab->elf.splt
- || s == htab->elf.sgot
- || s == htab->elf.sgotplt
- || s == htab->elf.iplt
- || s == htab->elf.igotplt
- || s == htab->sdynbss)
+ || s == htab->elf.sgot)
{
/* Strip this section if we don't need it; see the
comment below. */
if (htab->elf.hplt != NULL)
strip_section = FALSE;
}
+ else if (s == htab->elf.sgotplt
+ || s == htab->elf.iplt
+ || s == htab->elf.igotplt
+ || s == htab->plt_eh_frame
+ || s == htab->sdynbss)
+ {
+ /* Strip these too. */
+ }
else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rel"))
{
if (s->size != 0
}
if (htab->plt_eh_frame != NULL
- && htab->elf.splt != NULL
- && htab->elf.splt->size != 0
- && (htab->elf.splt->flags & SEC_EXCLUDE) == 0)
- bfd_put_32 (dynobj, htab->elf.splt->size,
- htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET);
+ && htab->plt_eh_frame->contents != NULL)
+ {
+ memcpy (htab->plt_eh_frame->contents, elf_i386_eh_frame_plt,
+ sizeof (elf_i386_eh_frame_plt));
+ bfd_put_32 (dynobj, htab->elf.splt->size,
+ htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET);
+ }
if (htab->elf.dynamic_sections_created)
{
unresolved_reloc, warned);
}
- if (sec != NULL && elf_discarded_section (sec))
+ if (sec != NULL && discarded_section (sec))
RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
- rel, relend, howto, contents);
+ rel, 1, relend, howto, 0, contents);
if (info->relocatable)
continue;
return FALSE;
}
else if (!info->executable
+ && !SYMBOLIC_BIND (info, h)
&& h->type == STT_FUNC
&& ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
{
bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
}
- /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. SYM may
- be NULL for local symbols.
-
- On VxWorks, the _GLOBAL_OFFSET_TABLE_ symbol is not absolute: it
- is relative to the ".got" section. */
- if (sym != NULL
- && (strcmp (h->root.root.string, "_DYNAMIC") == 0
- || (!abed->is_vxworks
- && h == htab->elf.hgot)))
- sym->st_shndx = SHN_ABS;
-
return TRUE;
}
return FALSE;
dynobj = htab->elf.dynobj;
- sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
abed = get_elf_i386_backend_data (output_bfd);
if (htab->elf.dynamic_sections_created)
}
/* Adjust .eh_frame for .plt section. */
- if (htab->plt_eh_frame != NULL)
+ if (htab->plt_eh_frame != NULL
+ && htab->plt_eh_frame->contents != NULL)
{
if (htab->elf.splt != NULL
&& htab->elf.splt->size != 0
+ PLT_FDE_START_OFFSET);
}
if (htab->plt_eh_frame->sec_info_type
- == ELF_INFO_TYPE_EH_FRAME)
+ == SEC_INFO_TYPE_EH_FRAME)
{
if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
htab->plt_eh_frame,
0x8b, 0x4b, 0x08, /* mov 0x8(%ebx), %ecx */
0x83, 0xe1, 0xe0, /* and $NACLMASK, %ecx */
0xff, 0xe1, /* jmp *%ecx */
- 0x90 /* nop */
+
+ /* This is expected to be the same size as elf_i386_nacl_plt0_entry,
+ so pad to that size with nop instructions. */
+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90
};
static const bfd_byte elf_i386_nacl_pic_plt_entry[NACL_PLT_ENTRY_SIZE] =
#undef elf_backend_arch_data
#define elf_backend_arch_data &elf_i386_nacl_arch_bed
+#undef elf_backend_modify_segment_map
+#define elf_backend_modify_segment_map nacl_modify_segment_map
+#undef elf_backend_modify_program_headers
+#define elf_backend_modify_program_headers nacl_modify_program_headers
+
#include "elf32-target.h"
+/* Restore defaults. */
+#undef elf_backend_modify_segment_map
+#undef elf_backend_modify_program_headers
+
/* VxWorks support. */
#undef TARGET_LITTLE_SYM