| Index: bfd/elf32-i386.c
|
| diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
|
| index d1873051b4d9bc692b86b23b6277e3718f00864f..7d3652d81ce983ae3499e279427c61feb6db557a 100644
|
| --- a/bfd/elf32-i386.c
|
| +++ b/bfd/elf32-i386.c
|
| @@ -1,6 +1,6 @@
|
| /* 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.
|
| @@ -25,6 +25,7 @@
|
| #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"
|
| @@ -1000,9 +1001,9 @@ elf_i386_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
|
| 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))
|
| @@ -1014,22 +1015,17 @@ elf_i386_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
|
| 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;
|
| @@ -2177,13 +2173,6 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
|
| }
|
| }
|
|
|
| - 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
|
| @@ -2197,7 +2186,7 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
|
| /* 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;
|
| @@ -2570,7 +2559,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|
| /* 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;
|
| @@ -2709,7 +2698,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|
| 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)
|
| @@ -2730,7 +2719,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|
| 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
|
| @@ -2746,6 +2735,14 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|
| 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;
|
| @@ -2757,11 +2754,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|
| 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. */
|
| @@ -2772,6 +2765,14 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|
| 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
|
| @@ -2819,11 +2820,13 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|
| }
|
|
|
| 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)
|
| {
|
| @@ -3196,9 +3199,9 @@ elf_i386_relocate_section (bfd *output_bfd,
|
| 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;
|
| @@ -3257,7 +3260,6 @@ elf_i386_relocate_section (bfd *output_bfd,
|
| bfd_byte *loc;
|
| asection *sreloc;
|
| bfd_vma offset;
|
| - bfd_boolean relocate;
|
|
|
| /* Need a dynamic relocation to get the real function
|
| adddress. */
|
| @@ -3278,14 +3280,15 @@ elf_i386_relocate_section (bfd *output_bfd,
|
| || info->executable)
|
| {
|
| /* This symbol is resolved locally. */
|
| - outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
|
| - relocate = TRUE;
|
| + outrel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);
|
| + bfd_put_32 (output_bfd,
|
| + (h->root.u.def.value
|
| + + h->root.u.def.section->output_section->vma
|
| + + h->root.u.def.section->output_offset),
|
| + contents + offset);
|
| }
|
| else
|
| - {
|
| - outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
|
| - relocate = FALSE;
|
| - }
|
| + outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
|
|
|
| sreloc = htab->elf.irelifunc;
|
| loc = sreloc->contents;
|
| @@ -3298,8 +3301,7 @@ elf_i386_relocate_section (bfd *output_bfd,
|
| we need to include the symbol value so that it
|
| becomes an addend for the dynamic reloc. For an
|
| internal symbol, we have updated addend. */
|
| - if (! relocate)
|
| - continue;
|
| + continue;
|
| }
|
| /* FALLTHROUGH */
|
| case R_386_PC32:
|
| @@ -3511,6 +3513,7 @@ elf_i386_relocate_section (bfd *output_bfd,
|
| return FALSE;
|
| }
|
| else if (!info->executable
|
| + && !SYMBOLIC_BIND (info, h)
|
| && h->type == STT_FUNC
|
| && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
|
| {
|
| @@ -4606,17 +4609,6 @@ do_glob_dat:
|
| 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;
|
| }
|
|
|
| @@ -4670,7 +4662,7 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
|
| 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)
|
| @@ -4855,7 +4847,8 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
|
| }
|
|
|
| /* 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
|
| @@ -4872,7 +4865,7 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
|
| + 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,
|
| @@ -5117,7 +5110,10 @@ elf_i386_nacl_pic_plt0_entry[sizeof (elf_i386_nacl_plt0_entry)] =
|
| 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] =
|
| @@ -5211,8 +5207,17 @@ static const struct elf_i386_backend_data elf_i386_nacl_arch_bed =
|
| #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
|
|
|