/* Intel 80386/80486-specific support for 32-bit ELF
- Copyright (C) 1993-2017 Free Software Foundation, Inc.
+ Copyright (C) 1993-2021 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
MA 02110-1301, USA. */
#include "elfxx-x86.h"
-#include "elf-nacl.h"
#include "elf-vxworks.h"
#include "dwarf2.h"
#include "opcode/i386.h"
static reloc_howto_type elf_howto_table[]=
{
- HOWTO(R_386_NONE, 0, 3, 0, FALSE, 0, complain_overflow_dont,
+ HOWTO(R_386_NONE, 0, 3, 0, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_NONE",
- TRUE, 0x00000000, 0x00000000, FALSE),
- HOWTO(R_386_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ true, 0x00000000, 0x00000000, false),
+ HOWTO(R_386_32, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_32",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_PC32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_PC32, 0, 2, 32, true, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_PC32",
- TRUE, 0xffffffff, 0xffffffff, TRUE),
- HOWTO(R_386_GOT32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, true),
+ HOWTO(R_386_GOT32, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_GOT32",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_PLT32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_PLT32, 0, 2, 32, true, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_PLT32",
- TRUE, 0xffffffff, 0xffffffff, TRUE),
- HOWTO(R_386_COPY, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, true),
+ HOWTO(R_386_COPY, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_COPY",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_GLOB_DAT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_GLOB_DAT, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_GLOB_DAT",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_JUMP_SLOT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_JUMP_SLOT, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_JUMP_SLOT",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_RELATIVE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_RELATIVE, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_RELATIVE",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_GOTOFF, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_GOTOFF, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_GOTOFF",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_GOTPC, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_GOTPC, 0, 2, 32, true, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_GOTPC",
- TRUE, 0xffffffff, 0xffffffff, TRUE),
+ true, 0xffffffff, 0xffffffff, true),
/* We have a gap in the reloc numbers here.
R_386_standard counts the number up to this point, and
#define R_386_ext_offset (R_386_TLS_TPOFF - R_386_standard)
/* These relocs are a GNU extension. */
- HOWTO(R_386_TLS_TPOFF, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ HOWTO(R_386_TLS_TPOFF, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_TLS_TPOFF",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_TLS_IE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_TLS_IE, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_TLS_IE",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_TLS_GOTIE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_TLS_GOTIE, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_TLS_GOTIE",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_TLS_LE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_TLS_LE, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_TLS_LE",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_TLS_GD, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_TLS_GD, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_TLS_GD",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_TLS_LDM, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_TLS_LDM, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_TLS_LDM",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_16, 0, 1, 16, false, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_386_16",
- TRUE, 0xffff, 0xffff, FALSE),
- HOWTO(R_386_PC16, 0, 1, 16, TRUE, 0, complain_overflow_bitfield,
+ true, 0xffff, 0xffff, false),
+ HOWTO(R_386_PC16, 0, 1, 16, true, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_386_PC16",
- TRUE, 0xffff, 0xffff, TRUE),
- HOWTO(R_386_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffff, 0xffff, true),
+ HOWTO(R_386_8, 0, 0, 8, false, 0, complain_overflow_bitfield,
bfd_elf_generic_reloc, "R_386_8",
- TRUE, 0xff, 0xff, FALSE),
- HOWTO(R_386_PC8, 0, 0, 8, TRUE, 0, complain_overflow_signed,
+ true, 0xff, 0xff, false),
+ HOWTO(R_386_PC8, 0, 0, 8, true, 0, complain_overflow_signed,
bfd_elf_generic_reloc, "R_386_PC8",
- TRUE, 0xff, 0xff, TRUE),
+ true, 0xff, 0xff, true),
#define R_386_ext (R_386_PC8 + 1 - R_386_ext_offset)
#define R_386_tls_offset (R_386_TLS_LDO_32 - R_386_ext)
/* These are common with Solaris TLS implementation. */
- HOWTO(R_386_TLS_LDO_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ HOWTO(R_386_TLS_LDO_32, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_TLS_LDO_32",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_TLS_IE_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_TLS_IE_32, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_TLS_IE_32",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_TLS_LE_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_TLS_LE_32, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_TLS_LE_32",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_TLS_DTPMOD32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_TLS_DTPMOD32, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_TLS_DTPMOD32",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_TLS_DTPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_TLS_DTPOFF32, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_TLS_DTPOFF32",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_TLS_TPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_TLS_TPOFF32, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_TLS_TPOFF32",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_SIZE32, 0, 2, 32, FALSE, 0, complain_overflow_unsigned,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_SIZE32, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_SIZE32",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_TLS_GOTDESC, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_TLS_GOTDESC, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_TLS_GOTDESC",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_TLS_DESC_CALL, 0, 0, 0, FALSE, 0, complain_overflow_dont,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_TLS_DESC_CALL, 0, 3, 0, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_TLS_DESC_CALL",
- FALSE, 0, 0, FALSE),
- HOWTO(R_386_TLS_DESC, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ false, 0, 0, false),
+ HOWTO(R_386_TLS_DESC, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_TLS_DESC",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_IRELATIVE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_IRELATIVE, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_IRELATIVE",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
- HOWTO(R_386_GOT32X, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
+ true, 0xffffffff, 0xffffffff, false),
+ HOWTO(R_386_GOT32X, 0, 2, 32, false, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "R_386_GOT32X",
- TRUE, 0xffffffff, 0xffffffff, FALSE),
+ true, 0xffffffff, 0xffffffff, false),
/* Another gap. */
#define R_386_ext2 (R_386_GOT32X + 1 - R_386_tls_offset)
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
NULL, /* special_function */
"R_386_GNU_VTINHERIT", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
- FALSE), /* pcrel_offset */
+ false), /* pcrel_offset */
/* GNU extension to record C++ vtable member usage. */
HOWTO (R_386_GNU_VTENTRY, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
0, /* bitsize */
- FALSE, /* pc_relative */
+ false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
_bfd_elf_rel_vtable_reloc_fn, /* special_function */
"R_386_GNU_VTENTRY", /* name */
- FALSE, /* partial_inplace */
+ false, /* partial_inplace */
0, /* src_mask */
0, /* dst_mask */
- FALSE) /* pcrel_offset */
+ false) /* pcrel_offset */
#define R_386_vt (R_386_GNU_VTENTRY + 1 - R_386_vt_offset)
#endif
static reloc_howto_type *
-elf_i386_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+elf_i386_reloc_type_lookup (bfd *abfd,
bfd_reloc_code_real_type code)
{
switch (code)
return &elf_howto_table[R_386_GNU_VTENTRY - R_386_vt_offset];
default:
- break;
+ TRACE ("Unknown");
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%pB: unsupported relocation type: %#x"),
+ abfd, (int) code);
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
}
-
- TRACE ("Unknown");
- return 0;
}
static reloc_howto_type *
}
static reloc_howto_type *
-elf_i386_rtype_to_howto (bfd *abfd, unsigned r_type)
+elf_i386_rtype_to_howto (unsigned r_type)
{
unsigned int indx;
>= R_386_ext2 - R_386_ext)
&& ((indx = r_type - R_386_vt_offset) - R_386_ext2
>= R_386_vt - R_386_ext2))
- {
- /* xgettext:c-format */
- _bfd_error_handler (_("%B: invalid relocation type %d"),
- abfd, (int) r_type);
- indx = R_386_NONE;
- }
+ return NULL;
/* PR 17512: file: 0f67f69d. */
if (elf_howto_table [indx].type != r_type)
return NULL;
return &elf_howto_table[indx];
}
-static void
-elf_i386_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+static bool
+elf_i386_info_to_howto_rel (bfd *abfd,
arelent *cache_ptr,
Elf_Internal_Rela *dst)
{
unsigned int r_type = ELF32_R_TYPE (dst->r_info);
- cache_ptr->howto = elf_i386_rtype_to_howto (abfd, r_type);
+
+ if ((cache_ptr->howto = elf_i386_rtype_to_howto (r_type)) == NULL)
+ {
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+ abfd, r_type);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ return true;
}
/* Return whether a symbol name implies a local label. The UnixWare
If so, we should move the .X recognition into
_bfd_elf_is_local_label_name. */
-static bfd_boolean
+static bool
elf_i386_is_local_label_name (bfd *abfd, const char *name)
{
if (name[0] == '.' && name[1] == 'X')
- return TRUE;
+ return true;
return _bfd_elf_is_local_label_name (abfd, name);
}
\f
/* Support for core dump NOTE sections. */
-static bfd_boolean
+static bool
elf_i386_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
{
int offset;
int pr_version = bfd_get_32 (abfd, note->descdata);
if (pr_version != 1)
- return FALSE;
+ return false;
/* pr_cursig */
elf_tdata (abfd)->core->signal = bfd_get_32 (abfd, note->descdata + 20);
switch (note->descsz)
{
default:
- return FALSE;
+ return false;
case 144: /* Linux/i386 */
/* pr_cursig */
size, note->descpos + offset);
}
-static bfd_boolean
+static bool
elf_i386_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
{
if (note->namesz == 8 && strcmp (note->namedata, "FreeBSD") == 0)
int pr_version = bfd_get_32 (abfd, note->descdata);
if (pr_version != 1)
- return FALSE;
+ return false;
elf_tdata (abfd)->core->program
= _bfd_elfcore_strndup (abfd, note->descdata + 8, 17);
switch (note->descsz)
{
default:
- return FALSE;
+ return false;
case 124: /* Linux/i386 elf_prpsinfo. */
elf_tdata (abfd)->core->pid
command[n - 1] = '\0';
}
- return TRUE;
+ return true;
}
\f
/* Functions for the i386 ELF linker.
static const bfd_byte elf_i386_lazy_ibt_plt0_entry[LAZY_PLT_ENTRY_SIZE] =
{
- 0xff, 0x35, 0, 0, 0, 0, /* pushl GOT[1] */
- 0xff, 0x25, 0, 0, 0, 0, /* jmp *GOT[2] */
- 0x0f, 0x1f, 0x40, 0x00 /* nopl 0(%rax) */
+ 0xff, 0x35, 0, 0, 0, 0, /* pushl GOT[1] */
+ 0xff, 0x25, 0, 0, 0, 0, /* jmp *GOT[2] */
+ 0x0f, 0x1f, 0x40, 0x00 /* nopl 0(%rax) */
};
/* Subsequent entries for an absolute IBT-enabled lazy procedure linkage
static const bfd_byte elf_i386_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
{
- 0xf3, 0x0f, 0x1e, 0xfb, /* endbr32 */
- 0x68, 0, 0, 0, 0, /* pushl immediate */
- 0xe9, 0, 0, 0, 0, /* jmp relative */
- 0x66, 0x90 /* xchg %ax,%ax */
+ 0xf3, 0x0f, 0x1e, 0xfb, /* endbr32 */
+ 0x68, 0, 0, 0, 0, /* pushl immediate */
+ 0xe9, 0, 0, 0, 0, /* jmp relative */
+ 0x66, 0x90 /* xchg %ax,%ax */
};
/* The first entry in a PIC IBT-enabled lazy procedure linkage table
static const bfd_byte elf_i386_pic_lazy_ibt_plt0_entry[LAZY_PLT_ENTRY_SIZE] =
{
0xff, 0xb3, 4, 0, 0, 0, /* pushl 4(%ebx) */
- 0xff, 0xa3, 8, 0, 0, 0, /* jmp *8(%ebx) */
- 0x0f, 0x1f, 0x40, 0x00 /* nopl 0(%rax) */
+ 0xff, 0xa3, 8, 0, 0, 0, /* jmp *8(%ebx) */
+ 0x0f, 0x1f, 0x40, 0x00 /* nopl 0(%rax) */
};
/* Entries for branches with IBT-enabled in the absolute non-lazey
static const bfd_byte elf_i386_non_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
{
- 0xf3, 0x0f, 0x1e, 0xfb, /* endbr32 */
+ 0xf3, 0x0f, 0x1e, 0xfb, /* endbr32 */
0xff, 0x25, 0, 0, 0, 0, /* jmp *name@GOT */
0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopw 0x0(%rax,%rax,1) */
};
static const bfd_byte elf_i386_pic_non_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
{
- 0xf3, 0x0f, 0x1e, 0xfb, /* endbr32 */
+ 0xf3, 0x0f, 0x1e, 0xfb, /* endbr32 */
0xff, 0xa3, 0, 0, 0, 0, /* jmp *name@GOT(%ebx) */
0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopw 0x0(%rax,%rax,1) */
};
/* These are the standard parameters. */
static const struct elf_x86_lazy_plt_layout elf_i386_lazy_plt =
{
- elf_i386_lazy_plt0_entry, /* plt0_entry */
- sizeof (elf_i386_lazy_plt0_entry), /* plt0_entry_size */
- elf_i386_lazy_plt_entry, /* plt_entry */
- LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
- 2, /* plt0_got1_offset */
- 8, /* plt0_got2_offset */
- 0, /* plt0_got2_insn_end */
- 2, /* plt_got_offset */
- 7, /* plt_reloc_offset */
- 12, /* plt_plt_offset */
- 0, /* plt_got_insn_size */
- 0, /* plt_plt_insn_end */
- 6, /* plt_lazy_offset */
- elf_i386_pic_lazy_plt0_entry, /* pic_plt0_entry */
- elf_i386_pic_lazy_plt_entry, /* pic_plt_entry */
- elf_i386_eh_frame_lazy_plt, /* eh_frame_plt */
+ elf_i386_lazy_plt0_entry, /* plt0_entry */
+ sizeof (elf_i386_lazy_plt0_entry), /* plt0_entry_size */
+ elf_i386_lazy_plt_entry, /* plt_entry */
+ LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
+ NULL, /* plt_tlsdesc_entry */
+ 0, /* plt_tlsdesc_entry_size*/
+ 0, /* plt_tlsdesc_got1_offset */
+ 0, /* plt_tlsdesc_got2_offset */
+ 0, /* plt_tlsdesc_got1_insn_end */
+ 0, /* plt_tlsdesc_got2_insn_end */
+ 2, /* plt0_got1_offset */
+ 8, /* plt0_got2_offset */
+ 0, /* plt0_got2_insn_end */
+ 2, /* plt_got_offset */
+ 7, /* plt_reloc_offset */
+ 12, /* plt_plt_offset */
+ 0, /* plt_got_insn_size */
+ 0, /* plt_plt_insn_end */
+ 6, /* plt_lazy_offset */
+ elf_i386_pic_lazy_plt0_entry, /* pic_plt0_entry */
+ elf_i386_pic_lazy_plt_entry, /* pic_plt_entry */
+ elf_i386_eh_frame_lazy_plt, /* eh_frame_plt */
sizeof (elf_i386_eh_frame_lazy_plt) /* eh_frame_plt_size */
};
static const struct elf_x86_non_lazy_plt_layout elf_i386_non_lazy_plt =
{
- elf_i386_non_lazy_plt_entry, /* plt_entry */
- elf_i386_pic_non_lazy_plt_entry, /* pic_plt_entry */
- NON_LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
- 2, /* plt_got_offset */
- 0, /* plt_got_insn_size */
- elf_i386_eh_frame_non_lazy_plt, /* eh_frame_plt */
+ elf_i386_non_lazy_plt_entry, /* plt_entry */
+ elf_i386_pic_non_lazy_plt_entry, /* pic_plt_entry */
+ NON_LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
+ 2, /* plt_got_offset */
+ 0, /* plt_got_insn_size */
+ elf_i386_eh_frame_non_lazy_plt, /* eh_frame_plt */
sizeof (elf_i386_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
};
static const struct elf_x86_lazy_plt_layout elf_i386_lazy_ibt_plt =
{
- elf_i386_lazy_ibt_plt0_entry, /* plt0_entry */
+ elf_i386_lazy_ibt_plt0_entry, /* plt0_entry */
sizeof (elf_i386_lazy_ibt_plt0_entry), /* plt0_entry_size */
- elf_i386_lazy_ibt_plt_entry, /* plt_entry */
- LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
- 2, /* plt0_got1_offset */
- 8, /* plt0_got2_offset */
- 0, /* plt0_got2_insn_end */
- 4+2, /* plt_got_offset */
- 4+1, /* plt_reloc_offset */
- 4+6, /* plt_plt_offset */
- 0, /* plt_got_insn_size */
- 0, /* plt_plt_insn_end */
- 0, /* plt_lazy_offset */
- elf_i386_pic_lazy_ibt_plt0_entry, /* pic_plt0_entry */
- elf_i386_lazy_ibt_plt_entry, /* pic_plt_entry */
- elf_i386_eh_frame_lazy_ibt_plt, /* eh_frame_plt */
+ elf_i386_lazy_ibt_plt_entry, /* plt_entry */
+ LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
+ NULL, /* plt_tlsdesc_entry */
+ 0, /* plt_tlsdesc_entry_size*/
+ 0, /* plt_tlsdesc_got1_offset */
+ 0, /* plt_tlsdesc_got2_offset */
+ 0, /* plt_tlsdesc_got1_insn_end */
+ 0, /* plt_tlsdesc_got2_insn_end */
+ 2, /* plt0_got1_offset */
+ 8, /* plt0_got2_offset */
+ 0, /* plt0_got2_insn_end */
+ 4+2, /* plt_got_offset */
+ 4+1, /* plt_reloc_offset */
+ 4+6, /* plt_plt_offset */
+ 0, /* plt_got_insn_size */
+ 0, /* plt_plt_insn_end */
+ 0, /* plt_lazy_offset */
+ elf_i386_pic_lazy_ibt_plt0_entry, /* pic_plt0_entry */
+ elf_i386_lazy_ibt_plt_entry, /* pic_plt_entry */
+ elf_i386_eh_frame_lazy_ibt_plt, /* eh_frame_plt */
sizeof (elf_i386_eh_frame_lazy_ibt_plt) /* eh_frame_plt_size */
};
static const struct elf_x86_non_lazy_plt_layout elf_i386_non_lazy_ibt_plt =
{
- elf_i386_non_lazy_ibt_plt_entry, /* plt_entry */
+ elf_i386_non_lazy_ibt_plt_entry, /* plt_entry */
elf_i386_pic_non_lazy_ibt_plt_entry,/* pic_plt_entry */
- LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
- 4+2, /* plt_got_offset */
- 0, /* plt_got_insn_size */
- elf_i386_eh_frame_non_lazy_plt, /* eh_frame_plt */
+ LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
+ 4+2, /* plt_got_offset */
+ 0, /* plt_got_insn_size */
+ elf_i386_eh_frame_non_lazy_plt, /* eh_frame_plt */
sizeof (elf_i386_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
};
\f
#define PLTRESOLVE_RELOCS 2
#define PLT_NON_JUMP_SLOT_RELOCS 2
-/* Architecture-specific backend data for i386. */
-
-struct elf_i386_backend_data
-{
- /* Value used to fill the unused bytes of the first PLT entry. */
- bfd_byte plt0_pad_byte;
-
- /* Target system. */
- enum
- {
- is_normal,
- is_vxworks,
- is_nacl
- } os;
-};
-
-#define get_elf_i386_backend_data(abfd) \
- ((const struct elf_i386_backend_data *) \
- get_elf_backend_data (abfd)->arch_data)
-
-/* These are the standard parameters. */
-static const struct elf_i386_backend_data elf_i386_arch_bed =
- {
- 0, /* plt0_pad_byte */
- is_normal /* os */
- };
-
-#define elf_backend_arch_data &elf_i386_arch_bed
-
/* Return TRUE if the TLS access code sequence support transition
from R_TYPE. */
-static bfd_boolean
+static bool
elf_i386_check_tls_transition (asection *sec,
bfd_byte *contents,
Elf_Internal_Shdr *symtab_hdr,
struct elf_link_hash_entry *h;
bfd_vma offset;
bfd_byte *call;
- bfd_boolean indirect_call;
+ bool indirect_call;
offset = rel->r_offset;
switch (r_type)
case R_386_TLS_GD:
case R_386_TLS_LDM:
if (offset < 2 || (rel + 1) >= relend)
- return FALSE;
+ return false;
- indirect_call = FALSE;
+ indirect_call = false;
call = contents + offset + 4;
val = *(call - 5);
type = *(call - 6);
can transit to different access model. */
if ((offset + 10) > sec->size
|| (type != 0x8d && type != 0x04))
- return FALSE;
+ return false;
if (type == 0x04)
{
/* leal foo@tlsgd(,%ebx,1), %eax
call ___tls_get_addr@PLT */
if (offset < 3)
- return FALSE;
+ return false;
if (*(call - 7) != 0x8d
|| val != 0x1d
|| call[0] != 0xe8)
- return FALSE;
+ return false;
}
else
{
is used to pass parameter to ___tls_get_addr. */
reg = val & 7;
if ((val & 0xf8) != 0x80 || reg == 4 || reg == 0)
- return FALSE;
+ return false;
indirect_call = call[0] == 0xff;
if (!(reg == 3 && call[0] == 0xe8 && call[5] == 0x90)
&& !(indirect_call
&& (call[1] & 0xf8) == 0x90
&& (call[1] & 0x7) == reg))
- return FALSE;
+ return false;
}
}
else
addr32 call ___tls_get_addr
can transit to different access model. */
if (type != 0x8d || (offset + 9) > sec->size)
- return FALSE;
+ return false;
/* %eax can't be used as the GOT base register since it is
used to pass parameter to ___tls_get_addr. */
reg = val & 7;
if ((val & 0xf8) != 0x80 || reg == 4 || reg == 0)
- return FALSE;
+ return false;
indirect_call = call[0] == 0xff;
if (!(reg == 3 && call[0] == 0xe8)
&& !(indirect_call
&& (call[1] & 0xf8) == 0x90
&& (call[1] & 0x7) == reg))
- return FALSE;
+ return false;
}
r_symndx = ELF32_R_SYM (rel[1].r_info);
if (r_symndx < symtab_hdr->sh_info)
- return FALSE;
+ return false;
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
if (h == NULL
|| !((struct elf_x86_link_hash_entry *) h)->tls_get_addr)
- return FALSE;
+ return false;
else if (indirect_call)
return (ELF32_R_TYPE (rel[1].r_info) == R_386_GOT32X);
else
*/
if (offset < 1 || (offset + 4) > sec->size)
- return FALSE;
+ return false;
/* Check "movl foo@tpoff(%rip), %eax" first. */
val = bfd_get_8 (abfd, contents + offset - 1);
if (val == 0xa1)
- return TRUE;
+ return true;
if (offset < 2)
- return FALSE;
+ return false;
/* Check movl|addl foo@tpoff(%rip), %reg. */
type = bfd_get_8 (abfd, contents + offset - 2);
*/
if (offset < 2 || (offset + 4) > sec->size)
- return FALSE;
+ return false;
val = bfd_get_8 (abfd, contents + offset - 1);
if ((val & 0xc0) != 0x80 || (val & 7) == 4)
- return FALSE;
+ return false;
type = bfd_get_8 (abfd, contents + offset - 2);
return type == 0x8b || type == 0x2b || type == 0x03;
going to be eax. */
if (offset < 2 || (offset + 4) > sec->size)
- return FALSE;
+ return false;
if (bfd_get_8 (abfd, contents + offset - 2) != 0x8d)
- return FALSE;
+ return false;
val = bfd_get_8 (abfd, contents + offset - 1);
return (val & 0xc7) == 0x83;
return call[0] == 0xff && call[1] == 0x10;
}
- return FALSE;
+ return false;
default:
abort ();
/* Return TRUE if the TLS access transition is OK or no transition
will be performed. Update R_TYPE if there is a transition. */
-static bfd_boolean
+static bool
elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd,
asection *sec, bfd_byte *contents,
Elf_Internal_Shdr *symtab_hdr,
const Elf_Internal_Rela *relend,
struct elf_link_hash_entry *h,
unsigned long r_symndx,
- bfd_boolean from_relocate_section)
+ bool from_relocate_section)
{
unsigned int from_type = *r_type;
unsigned int to_type = from_type;
- bfd_boolean check = TRUE;
+ bool check = true;
/* Skip TLS transition for functions. */
if (h != NULL
&& (h->type == STT_FUNC
|| h->type == STT_GNU_IFUNC))
- return TRUE;
+ return true;
switch (from_type)
{
break;
default:
- return TRUE;
+ return true;
}
/* Return TRUE if there is no transition. */
if (from_type == to_type)
- return TRUE;
+ return true;
/* Check if the transition can be performed. */
if (check
reloc_howto_type *from, *to;
const char *name;
- from = elf_i386_rtype_to_howto (abfd, from_type);
- to = elf_i386_rtype_to_howto (abfd, to_type);
+ from = elf_i386_rtype_to_howto (from_type);
+ to = elf_i386_rtype_to_howto (to_type);
if (h)
name = h->root.root.string;
{
Elf_Internal_Sym *isym;
- isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
abfd, r_symndx);
name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
}
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: TLS transition from %s to %s against `%s' at %#Lx "
- "in section `%A' failed"),
+ (_("%pB: TLS transition from %s to %s against `%s'"
+ " at %#" PRIx64 " in section `%pA' failed"),
abfd, from->name, to->name, name,
- rel->r_offset, sec);
+ (uint64_t) rel->r_offset, sec);
bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ return false;
}
*r_type = to_type;
- return TRUE;
+ return true;
}
/* With the local symbol, foo, we convert
instructions. */
static
-bfd_boolean
+bool
elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
bfd_byte *contents,
unsigned int *r_type_p,
Elf_Internal_Rela *irel,
struct elf_link_hash_entry *h,
- bfd_boolean *converted,
+ bool *converted,
struct bfd_link_info *link_info)
{
struct elf_x86_link_hash_table *htab;
unsigned int opcode;
unsigned int modrm;
- bfd_boolean baseless;
+ bool baseless;
Elf_Internal_Sym *isym;
unsigned int addend;
unsigned int nop;
bfd_vma nop_offset;
- bfd_boolean is_pic;
- bfd_boolean to_reloc_32;
+ bool is_pic;
+ bool to_reloc_32;
+ bool abs_symbol;
unsigned int r_type;
unsigned int r_symndx;
bfd_vma roff = irel->r_offset;
- bfd_boolean local_ref;
+ bool local_ref;
struct elf_x86_link_hash_entry *eh;
if (roff < 2)
- return TRUE;
+ return true;
/* Addend for R_386_GOT32X relocations must be 0. */
addend = bfd_get_32 (abfd, contents + roff);
if (addend != 0)
- return TRUE;
+ return true;
htab = elf_x86_hash_table (link_info, I386_ELF_DATA);
is_pic = bfd_link_pic (link_info);
modrm = bfd_get_8 (abfd, contents + roff - 1);
baseless = (modrm & 0xc7) == 0x5;
+ if (h)
+ {
+ /* NB: Also set linker_def via SYMBOL_REFERENCES_LOCAL_P. */
+ local_ref = SYMBOL_REFERENCES_LOCAL_P (link_info, h);
+ isym = NULL;
+ abs_symbol = ABS_SYMBOL_P (h);
+ }
+ else
+ {
+ local_ref = true;
+ isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd,
+ r_symndx);
+ abs_symbol = isym->st_shndx == SHN_ABS;
+ }
+
if (baseless && is_pic)
{
/* For PIC, disallow R_386_GOT32X without a base register
const char *name;
if (h == NULL)
- {
- isym = bfd_sym_from_r_symndx (&htab->sym_cache, abfd,
- r_symndx);
- name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
- }
+ name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
else
name = h->root.root.string;
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: direct GOT relocation R_386_GOT32X against `%s' without base"
+ (_("%pB: direct GOT relocation R_386_GOT32X against `%s' without base"
" register can not be used when making a shared object"),
abfd, name);
- return FALSE;
+ return false;
}
opcode = bfd_get_8 (abfd, contents + roff - 2);
goto convert_load;
}
- /* NB: Also set linker_def via SYMBOL_REFERENCES_LOCAL_P. */
- local_ref = SYMBOL_REFERENCES_LOCAL_P (link_info, h);
-
/* Undefined weak symbol is only bound locally in executable
and its reference is resolved as 0. */
if (h->root.type == bfd_link_hash_undefweak
{
/* No direct branch to 0 for PIC. */
if (is_pic)
- return TRUE;
+ return true;
else
goto convert_branch;
}
else
{
/* We can convert load of address 0 to R_386_32. */
- to_reloc_32 = TRUE;
+ to_reloc_32 = true;
goto convert_load;
}
}
&& local_ref)
{
/* The function is locally defined. */
-convert_branch:
+ convert_branch:
/* Convert R_386_GOT32X to R_386_PC32. */
if (modrm == 0x15 || (modrm & 0xf8) == 0x90)
{
}
else
{
- nop = link_info->call_nop_byte;
- if (link_info->call_nop_as_suffix)
+ nop = htab->params->call_nop_byte;
+ if (htab->params->call_nop_as_suffix)
{
nop_offset = roff + 3;
irel->r_offset -= 1;
bfd_put_32 (abfd, -4, contents + irel->r_offset);
irel->r_info = ELF32_R_INFO (r_symndx, R_386_PC32);
*r_type_p = R_386_PC32;
- *converted = TRUE;
+ *converted = true;
}
}
else
Avoid optimizing _DYNAMIC since ld.so may use its
link-time address. */
if (h == htab->elf.hdynamic)
- return TRUE;
+ return true;
/* def_regular is set by an assignment in a linker script in
bfd_elf_record_link_assignment. start_stop is set on
|| h->root.type == bfd_link_hash_defweak)
&& local_ref))
{
-convert_load:
+ convert_load:
if (opcode == 0x8b)
{
+ if (abs_symbol && local_ref)
+ to_reloc_32 = true;
+
if (to_reloc_32)
{
/* Convert "mov foo@GOT[(%reg1)], %reg2" to
{
/* Only R_386_32 is supported. */
if (!to_reloc_32)
- return TRUE;
+ return true;
if (opcode == 0x85)
{
bfd_put_8 (abfd, opcode, contents + roff - 2);
irel->r_info = ELF32_R_INFO (r_symndx, r_type);
*r_type_p = r_type;
- *converted = TRUE;
+ *converted = true;
}
}
- return TRUE;
+ return true;
}
/* Rename some of the generic section flags to better document how they
calculate needed space in the global offset table, procedure linkage
table, and dynamic reloc sections. */
-static bfd_boolean
+static bool
elf_i386_check_relocs (bfd *abfd,
struct bfd_link_info *info,
asection *sec,
const Elf_Internal_Rela *rel_end;
asection *sreloc;
bfd_byte *contents;
- bfd_boolean converted;
+ bool converted;
if (bfd_link_relocatable (info))
- return TRUE;
-
- /* Don't do anything special with non-loaded, non-alloced sections.
- In particular, any relocs in such sections should not affect GOT
- and PLT reference counting (ie. we don't allow them to create GOT
- or PLT entries), there's no possibility or desire to optimize TLS
- relocs, and there's not much point in propagating relocs to shared
- libs that the dynamic linker won't relocate. */
- if ((sec->flags & SEC_ALLOC) == 0)
- return TRUE;
+ return true;
htab = elf_x86_hash_table (info, I386_ELF_DATA);
if (htab == NULL)
{
sec->check_relocs_failed = 1;
- return FALSE;
+ return false;
}
BFD_ASSERT (is_x86_elf (abfd, htab));
else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
{
sec->check_relocs_failed = 1;
- return FALSE;
+ return false;
}
symtab_hdr = &elf_symtab_hdr (abfd);
sym_hashes = elf_sym_hashes (abfd);
- converted = FALSE;
+ converted = false;
sreloc = NULL;
struct elf_x86_link_hash_entry *eh;
Elf_Internal_Sym *isym;
const char *name;
- bfd_boolean size_reloc;
+ bool size_reloc;
+ bool no_dynreloc;
r_symndx = ELF32_R_SYM (rel->r_info);
r_type = ELF32_R_TYPE (rel->r_info);
if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
{
/* xgettext:c-format */
- _bfd_error_handler (_("%B: bad symbol index: %d"),
+ _bfd_error_handler (_("%pB: bad symbol index: %d"),
abfd, r_symndx);
goto error_return;
}
if (r_symndx < symtab_hdr->sh_info)
{
/* A local symbol. */
- isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
abfd, r_symndx);
if (isym == NULL)
goto error_return;
/* Check relocation against local STT_GNU_IFUNC symbol. */
if (ELF32_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
{
- h = _bfd_elf_x86_get_local_sym_hash (htab, abfd, rel, TRUE);
+ h = _bfd_elf_x86_get_local_sym_hash (htab, abfd, rel, true);
if (h == NULL)
goto error_return;
/* It is referenced by a non-shared object. */
h->ref_regular = 1;
- h->root.non_ir_ref_regular = 1;
-
- if (h->type == STT_GNU_IFUNC)
- elf_tdata (info->output_bfd)->has_gnu_symbols
- |= elf_gnu_symbol_ifunc;
}
if (r_type == R_386_GOT32X
goto error_return;
}
+ if (!_bfd_elf_x86_valid_reloc_p (sec, info, htab, rel, h, isym,
+ symtab_hdr, &no_dynreloc))
+ return false;
+
if (! elf_i386_tls_transition (info, abfd, sec, contents,
symtab_hdr, sym_hashes,
&r_type, GOT_UNKNOWN,
- rel, rel_end, h, r_symndx, FALSE))
+ rel, rel_end, h, r_symndx, false))
goto error_return;
+ /* Check if _GLOBAL_OFFSET_TABLE_ is referenced. */
+ if (h == htab->elf.hgot)
+ htab->got_referenced = true;
+
switch (r_type)
{
case R_386_TLS_LDM:
- htab->tls_ld_or_ldm_got.refcount += 1;
+ htab->tls_ld_or_ldm_got.refcount = 1;
goto create_got;
case R_386_PLT32:
if (h == NULL)
continue;
- eh->has_got_reloc = 1;
+ eh->zero_undefweak &= 0x2;
h->needs_plt = 1;
- h->plt.refcount += 1;
+ h->plt.refcount = 1;
break;
case R_386_SIZE32:
- size_reloc = TRUE;
+ size_reloc = true;
goto do_size;
case R_386_TLS_IE_32:
if (h != NULL)
{
- h->got.refcount += 1;
+ h->got.refcount = 1;
old_tls_type = elf_x86_hash_entry (h)->tls_type;
}
else
size *= (sizeof (bfd_signed_vma)
+ sizeof (bfd_vma) + sizeof(char));
local_got_refcounts = (bfd_signed_vma *)
- bfd_zalloc (abfd, size);
+ bfd_zalloc (abfd, size);
if (local_got_refcounts == NULL)
goto error_return;
elf_local_got_refcounts (abfd) = local_got_refcounts;
elf_x86_local_got_tls_type (abfd)
= (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info);
}
- local_got_refcounts[r_symndx] += 1;
+ local_got_refcounts[r_symndx] = 1;
old_tls_type = elf_x86_local_got_tls_type (abfd) [r_symndx];
}
NULL);
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: `%s' accessed both as normal and "
+ (_("%pB: `%s' accessed both as normal and "
"thread local symbol"),
abfd, name);
bfd_set_error (bfd_error_bad_value);
if (r_type != R_386_TLS_IE)
{
if (eh != NULL)
- eh->has_got_reloc = 1;
+ {
+ eh->zero_undefweak &= 0x2;
+
+ /* Need GOT to resolve undefined weak symbol to 0. */
+ if (r_type == R_386_GOTOFF
+ && h->root.type == bfd_link_hash_undefweak
+ && bfd_link_executable (info))
+ htab->got_referenced = true;
+ }
break;
}
/* Fall through */
case R_386_TLS_LE_32:
case R_386_TLS_LE:
if (eh != NULL)
- eh->has_got_reloc = 1;
+ eh->zero_undefweak &= 0x2;
if (bfd_link_executable (info))
break;
info->flags |= DF_STATIC_TLS;
case R_386_32:
case R_386_PC32:
if (eh != NULL && (sec->flags & SEC_CODE) != 0)
- eh->has_non_got_reloc = 1;
-do_relocation:
+ eh->zero_undefweak |= 0x2;
+ do_relocation:
/* We are called after all symbols have been resolved. Only
relocation against STT_GNU_IFUNC symbol must go through
PLT. */
&& (bfd_link_executable (info)
|| h->type == STT_GNU_IFUNC))
{
- /* If this reloc is in a read-only section, we might
- need a copy reloc. We can't check reliably at this
- stage whether the section is read-only, as input
- sections have not yet been mapped to output sections.
- Tentatively set the flag for now, and correct in
- adjust_dynamic_symbol. */
- h->non_got_ref = 1;
-
- /* We may need a .plt entry if the symbol is a function
- defined in a shared lib or is a STT_GNU_IFUNC function
- referenced from the code or read-only section. */
- if (!h->def_regular
- || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
- h->plt.refcount += 1;
+ bool func_pointer_ref = false;
if (r_type == R_386_PC32)
{
{
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: unsupported non-PIC call to IFUNC `%s'"),
+ (_("%pB: unsupported non-PIC call to IFUNC `%s'"),
abfd, h->root.root.string);
bfd_set_error (bfd_error_bad_value);
goto error_return;
/* R_386_32 can be resolved at run-time. */
if (r_type == R_386_32
&& (sec->flags & SEC_READONLY) == 0)
- eh->func_pointer_refcount += 1;
+ func_pointer_ref = true;
+ }
+
+ if (!func_pointer_ref)
+ {
+ /* If this reloc is in a read-only section, we might
+ need a copy reloc. We can't check reliably at this
+ stage whether the section is read-only, as input
+ sections have not yet been mapped to output sections.
+ Tentatively set the flag for now, and correct in
+ adjust_dynamic_symbol. */
+ h->non_got_ref = 1;
+
+ /* We may need a .plt entry if the symbol is a function
+ defined in a shared lib or is a function referenced
+ from the code or read-only section. */
+ if (!h->def_regular
+ || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
+ h->plt.refcount = 1;
}
}
- size_reloc = FALSE;
-do_size:
- if (NEED_DYNAMIC_RELOCATION_P (info, h, sec, r_type,
- R_386_32))
+ size_reloc = false;
+ do_size:
+ if (!no_dynreloc
+ && NEED_DYNAMIC_RELOCATION_P (info, false, h, sec, r_type,
+ R_386_32))
{
struct elf_dyn_relocs *p;
struct elf_dyn_relocs **head;
if (sreloc == NULL)
{
sreloc = _bfd_elf_make_dynamic_reloc_section
- (sec, htab->elf.dynobj, 2, abfd, /*rela?*/ FALSE);
+ (sec, htab->elf.dynobj, 2, abfd, /*rela?*/ false);
if (sreloc == NULL)
goto error_return;
relocations we need for this symbol. */
if (h != NULL)
{
- head = &eh->dyn_relocs;
+ head = &h->dyn_relocs;
}
else
{
void **vpp;
asection *s;
- isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+ isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
abfd, r_symndx);
if (isym == NULL)
goto error_return;
p = *head;
if (p == NULL || p->sec != sec)
{
- bfd_size_type amt = sizeof *p;
+ size_t amt = sizeof *p;
p = (struct elf_dyn_relocs *) bfd_alloc (htab->elf.dynobj,
- amt);
+ amt);
if (p == NULL)
goto error_return;
p->next = *head;
/* This relocation describes which C++ vtable entries are actually
used. Record for later use during GC. */
case R_386_GNU_VTENTRY:
- BFD_ASSERT (h != NULL);
- if (h != NULL
- && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
goto error_return;
break;
if (elf_section_data (sec)->relocs != relocs && converted)
elf_section_data (sec)->relocs = (Elf_Internal_Rela *) relocs;
- return TRUE;
+ return true;
-error_return:
+ error_return:
if (elf_section_data (sec)->this_hdr.contents != contents)
free (contents);
sec->check_relocs_failed = 1;
- return FALSE;
+ return false;
}
/* Set the correct type for an x86 ELF section. We do this by the
section name, which is a hack, but ought to work. */
-static bfd_boolean
+static bool
elf_i386_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
Elf_Internal_Shdr *hdr,
asection *sec)
{
const char *name;
- name = bfd_get_section_name (abfd, sec);
+ name = bfd_section_name (sec);
/* This is an ugly, but unfortunately necessary hack that is
needed when producing EFI binaries on x86. It tells
if (strcmp (name, ".reloc") == 0)
hdr->sh_type = SHT_PROGBITS;
- return TRUE;
+ return true;
}
/* Return the relocation value for @tpoff relocation
/* Relocate an i386 ELF section. */
-static bfd_boolean
+static int
elf_i386_relocate_section (bfd *output_bfd,
struct bfd_link_info *info,
bfd *input_bfd,
Elf_Internal_Rela *rel;
Elf_Internal_Rela *wrel;
Elf_Internal_Rela *relend;
- bfd_boolean is_vxworks_tls;
+ bool is_vxworks_tls;
unsigned plt_entry_size;
/* Skip if check_relocs failed. */
if (input_section->check_relocs_failed)
- return FALSE;
+ return false;
htab = elf_x86_hash_table (info, I386_ELF_DATA);
if (htab == NULL)
- return FALSE;
+ return false;
- BFD_ASSERT (is_x86_elf (input_bfd, htab));
+ if (!is_x86_elf (input_bfd, htab))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
symtab_hdr = &elf_symtab_hdr (input_bfd);
sym_hashes = elf_sym_hashes (input_bfd);
local_tlsdesc_gotents = elf_x86_local_tlsdesc_gotent (input_bfd);
/* We have to handle relocations in vxworks .tls_vars sections
specially, because the dynamic loader is 'weird'. */
- is_vxworks_tls = (htab->is_vxworks
- && bfd_link_pic (info)
+ is_vxworks_tls = (htab->elf.target_os == is_vxworks
+ && bfd_link_pic (info)
&& !strcmp (input_section->output_section->name,
".tls_vars"));
asection *sec;
bfd_vma off, offplt, plt_offset;
bfd_vma relocation;
- bfd_boolean unresolved_reloc;
+ bool unresolved_reloc;
bfd_reloc_status_type r;
unsigned int indx;
int tls_type;
bfd_vma st_size;
asection *resolved_plt;
- bfd_boolean resolved_to_zero;
- bfd_boolean relative_reloc;
+ bool resolved_to_zero;
+ bool relative_reloc;
r_type = ELF32_R_TYPE (rel->r_info);
if (r_type == R_386_GNU_VTINHERIT
continue;
}
- if ((indx = r_type) >= R_386_standard
- && ((indx = r_type - R_386_ext_offset) - R_386_standard
- >= R_386_ext - R_386_standard)
- && ((indx = r_type - R_386_tls_offset) - R_386_ext
- >= R_386_ext2 - R_386_ext))
+ howto = elf_i386_rtype_to_howto (r_type);
+ if (howto == NULL)
return _bfd_unrecognized_reloc (input_bfd, input_section, r_type);
- howto = elf_howto_table + indx;
-
r_symndx = ELF32_R_SYM (rel->r_info);
h = NULL;
sym = NULL;
sec = NULL;
- unresolved_reloc = FALSE;
+ unresolved_reloc = false;
if (r_symndx < symtab_hdr->sh_info)
{
sym = local_syms + r_symndx;
{
/* Relocate against local STT_GNU_IFUNC symbol. */
h = _bfd_elf_x86_get_local_sym_hash (htab, input_bfd, rel,
- FALSE);
+ false);
if (h == NULL)
abort ();
}
else
{
- bfd_boolean warned ATTRIBUTE_UNUSED;
- bfd_boolean ignored ATTRIBUTE_UNUSED;
+ bool warned ATTRIBUTE_UNUSED;
+ bool ignored ATTRIBUTE_UNUSED;
RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
r_symndx, symtab_hdr, sym_hashes,
if (sec != NULL && discarded_section (sec))
{
_bfd_clear_contents (howto, input_bfd, input_section,
- contents + rel->r_offset);
+ contents, rel->r_offset);
wrel->r_offset = rel->r_offset;
wrel->r_info = 0;
wrel->r_addend = 0;
if ((input_section->flags & SEC_ALLOC) == 0)
{
+ /* If this is a SHT_NOTE section without SHF_ALLOC, treat
+ STT_GNU_IFUNC symbol as STT_FUNC. */
+ if (elf_section_type (input_section) == SHT_NOTE)
+ goto skip_ifunc;
/* Dynamic relocs are not propagated for SEC_DEBUGGING
sections because such sections are not SEC_ALLOC and
thus ld.so will not process them. */
switch (r_type)
{
default:
-bad_ifunc_reloc:
+ bad_ifunc_reloc:
if (h->root.root.string)
name = h->root.root.string;
else
NULL);
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: relocation %s against STT_GNU_IFUNC "
+ (_("%pB: relocation %s against STT_GNU_IFUNC "
"symbol `%s' isn't supported"), input_bfd,
howto->name, name);
bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ return false;
case R_386_32:
/* Generate dynamic relcoation only when there is a
asection *sreloc;
bfd_vma offset;
-do_ifunc_pointer:
+ do_ifunc_pointer:
/* Need a dynamic relocation to get the real function
adddress. */
offset = _bfd_elf_section_offset (output_bfd,
if (POINTER_LOCAL_IFUNC_P (info, h))
{
- info->callbacks->minfo (_("Local IFUNC function `%s' in %B\n"),
+ info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"),
h->root.root.string,
h->root.u.def.section->owner);
/* This symbol is resolved locally. */
outrel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);
+
+ if (htab->params->report_relative_reloc)
+ _bfd_x86_elf_link_report_relative_reloc
+ (info, input_section, h, sym,
+ "R_386_IRELATIVE", &outrel);
+
bfd_put_32 (output_bfd,
(h->root.u.def.value
+ h->root.u.def.section->output_section->vma
}
}
+ skip_ifunc:
resolved_to_zero = (eh != NULL
&& UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh));
switch (r_type)
{
case R_386_GOT32X:
- /* Avoid optimizing _DYNAMIC since ld.so may use its
- link-time address. */
- if (h == htab->elf.hdynamic)
- goto r_386_got32;
-
- if (bfd_link_pic (info))
- {
- /* It is OK to convert mov to lea and convert indirect
- branch to direct branch. It is OK to convert adc,
- add, and, cmp, or, sbb, sub, test, xor only when PIC
- is false. */
- unsigned int opcode, addend;
- addend = bfd_get_32 (input_bfd, contents + rel->r_offset);
- if (addend != 0)
- goto r_386_got32;
- opcode = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
- if (opcode != 0x8b && opcode != 0xff)
- goto r_386_got32;
- }
-
- /* Resolve "mov GOT[(%reg)], %reg",
- "call/jmp *GOT[(%reg)]", "test %reg, foo@GOT[(%reg)]"
- and "binop foo@GOT[(%reg)], %reg". */
- if (h == NULL
- || (h->plt.offset == (bfd_vma) -1
- && h->got.offset == (bfd_vma) -1)
- || htab->elf.sgotplt == NULL)
- abort ();
-
- offplt = (htab->elf.sgotplt->output_section->vma
- + htab->elf.sgotplt->output_offset);
-
- /* It is relative to .got.plt section. */
- if (h->got.offset != (bfd_vma) -1)
- /* Use GOT entry. Mask off the least significant bit in
- GOT offset which may be set by R_386_GOT32 processing
- below. */
- relocation = (htab->elf.sgot->output_section->vma
- + htab->elf.sgot->output_offset
- + (h->got.offset & ~1) - offplt);
- else
- /* Use GOTPLT entry. */
- relocation = (h->plt.offset / plt_entry_size
- - htab->plt.has_plt0 + 3) * 4;
-
- if (!bfd_link_pic (info))
- {
- /* If not PIC, add the .got.plt section address for
- baseless addressing. */
- unsigned int modrm;
- modrm = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
- if ((modrm & 0xc7) == 0x5)
- relocation += offplt;
- }
-
- unresolved_reloc = FALSE;
- break;
-
case R_386_GOT32:
-r_386_got32:
/* Relocation is to the entry for this symbol in the global
offset table. */
if (htab->elf.sgot == NULL)
abort ();
- relative_reloc = FALSE;
+ relative_reloc = false;
if (h != NULL)
{
off = h->got.offset;
/* PR ld/21402: If this symbol isn't dynamic
in PIC, generate R_386_RELATIVE here. */
eh->no_finish_dynamic_symbol = 1;
- relative_reloc = TRUE;
+ relative_reloc = true;
}
}
}
else
- unresolved_reloc = FALSE;
+ unresolved_reloc = false;
}
else
{
local_got_offsets[r_symndx] |= 1;
if (bfd_link_pic (info))
- relative_reloc = TRUE;
+ relative_reloc = true;
}
}
+ htab->elf.sgot->output_offset
+ off);
outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
+
+ if (htab->params->report_relative_reloc)
+ _bfd_x86_elf_link_report_relative_reloc
+ (info, input_section, h, sym, "R_386_RELATIVE",
+ &outrel);
+
elf_append_rel (output_bfd, s, &outrel);
}
we don't know what the GOT base is. */
const char *name;
-disallow_got32:
+ disallow_got32:
if (h == NULL || h->root.root.string == NULL)
name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
NULL);
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: direct GOT relocation %s against `%s'"
+ (_("%pB: direct GOT relocation %s against `%s'"
" without base register can not be used"
" when making a shared object"),
input_bfd, howto->name, name);
bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ return false;
}
}
else
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: relocation R_386_GOTOFF against undefined %s"
+ (_("%pB: relocation R_386_GOTOFF against undefined %s"
" `%s' can not be used when making a shared object"),
input_bfd, v, h->root.root.string);
bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ return false;
}
else if (!SYMBOL_REFERENCES_LOCAL_P (info, h)
&& (h->type == STT_FUNC
{
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: relocation R_386_GOTOFF against protected %s"
+ (_("%pB: relocation R_386_GOTOFF against protected %s"
" `%s' can not be used when making a shared object"),
input_bfd,
h->type == STT_FUNC ? "function" : "data",
h->root.root.string);
bfd_set_error (bfd_error_bad_value);
- return FALSE;
+ return false;
}
}
/* Use global offset table as symbol value. */
relocation = htab->elf.sgotplt->output_section->vma
+ htab->elf.sgotplt->output_offset;
- unresolved_reloc = FALSE;
+ unresolved_reloc = false;
break;
case R_386_PLT32:
relocation = (resolved_plt->output_section->vma
+ resolved_plt->output_offset
+ plt_offset);
- unresolved_reloc = FALSE;
+ unresolved_reloc = false;
break;
case R_386_SIZE32:
|| is_vxworks_tls)
break;
- if (GENERATE_DYNAMIC_RELOCATION_P (info, eh, r_type,
- FALSE, resolved_to_zero,
+ if (GENERATE_DYNAMIC_RELOCATION_P (info, eh, r_type, sec,
+ false, resolved_to_zero,
(r_type == R_386_PC32)))
{
Elf_Internal_Rela outrel;
- bfd_boolean skip, relocate;
+ bool skip, relocate;
asection *sreloc;
/* When generating a shared object, these relocations
are copied into the output file to be resolved at run
time. */
- skip = FALSE;
- relocate = FALSE;
+ skip = false;
+ relocate = false;
outrel.r_offset =
_bfd_elf_section_offset (output_bfd, info, input_section,
rel->r_offset);
if (outrel.r_offset == (bfd_vma) -1)
- skip = TRUE;
+ skip = true;
else if (outrel.r_offset == (bfd_vma) -2)
- skip = TRUE, relocate = TRUE;
+ skip = true, relocate = true;
outrel.r_offset += (input_section->output_section->vma
+ input_section->output_offset);
else
{
/* This symbol is local, or marked to become local. */
- relocate = TRUE;
+ relocate = true;
outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
+
+ if (htab->params->report_relative_reloc)
+ _bfd_x86_elf_link_report_relative_reloc
+ (info, input_section, h, sym, "R_386_RELATIVE",
+ &outrel);
}
sreloc = elf_section_data (input_section)->sreloc;
+ input_section->output_section->vma
+ input_section->output_offset;
outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
+
+ if (htab->params->report_relative_reloc)
+ _bfd_x86_elf_link_report_relative_reloc
+ (info, input_section, h, sym, "R_386_RELATIVE",
+ &outrel);
+
sreloc = elf_section_data (input_section)->sreloc;
if (sreloc == NULL)
abort ();
input_section, contents,
symtab_hdr, sym_hashes,
&r_type_tls, tls_type, rel,
- relend, h, r_symndx, TRUE))
- return FALSE;
+ relend, h, r_symndx, true))
+ return false;
if (r_type_tls == R_386_TLS_LE_32)
{
{
if (indx == 0)
{
- BFD_ASSERT (! unresolved_reloc);
+ BFD_ASSERT (! unresolved_reloc);
bfd_put_32 (output_bfd,
relocation - _bfd_x86_elf_dtpoff_base (info),
htab->elf.sgot->contents + off + 4);
|| r_type_tls == R_386_TLS_DESC_CALL)
{
relocation = htab->sgotplt_jump_table_size + offplt;
- unresolved_reloc = FALSE;
+ unresolved_reloc = false;
}
else if (r_type_tls == r_type)
{
relocation += 4;
if (r_type == R_386_TLS_IE)
relocation += g_o_t;
- unresolved_reloc = FALSE;
+ unresolved_reloc = false;
}
else if (r_type == R_386_TLS_GD)
{
continue;
}
else
- BFD_ASSERT (FALSE);
+ BFD_ASSERT (false);
break;
case R_386_TLS_LDM:
input_section, contents,
symtab_hdr, sym_hashes,
&r_type, GOT_UNKNOWN, rel,
- relend, h, r_symndx, TRUE))
- return FALSE;
+ relend, h, r_symndx, true))
+ return false;
if (r_type != R_386_TLS_LDM)
{
+ htab->elf.sgot->output_offset + off
- htab->elf.sgotplt->output_section->vma
- htab->elf.sgotplt->output_offset;
- unresolved_reloc = FALSE;
+ unresolved_reloc = false;
break;
case R_386_TLS_LDO_32:
{
_bfd_error_handler
/* xgettext:c-format */
- (_("%B(%A+%#Lx): unresolvable %s relocation against symbol `%s'"),
+ (_("%pB(%pA+%#" PRIx64 "): unresolvable %s relocation against symbol `%s'"),
input_bfd,
input_section,
- rel->r_offset,
+ (uint64_t) rel->r_offset,
howto->name,
h->root.root.string);
- return FALSE;
+ return false;
}
-do_relocation:
+ do_relocation:
r = _bfd_final_link_relocate (howto, input_bfd, input_section,
contents, rel->r_offset,
relocation, 0);
-check_relocation_error:
+ check_relocation_error:
if (r != bfd_reloc_ok)
{
const char *name;
symtab_hdr->sh_link,
sym->st_name);
if (name == NULL)
- return FALSE;
+ return false;
if (*name == '\0')
- name = bfd_section_name (input_bfd, sec);
+ name = bfd_section_name (sec);
}
if (r == bfd_reloc_overflow)
{
_bfd_error_handler
/* xgettext:c-format */
- (_("%B(%A+%#Lx): reloc against `%s': error %d"),
+ (_("%pB(%pA+%#" PRIx64 "): reloc against `%s': error %d"),
input_bfd, input_section,
- rel->r_offset, name, (int) r);
- return FALSE;
+ (uint64_t) rel->r_offset, name, (int) r);
+ return false;
}
}
input_section->reloc_count -= deleted;
}
- return TRUE;
+ return true;
}
/* Finish up dynamic symbol handling. We set the contents of various
dynamic sections here. */
-static bfd_boolean
+static bool
elf_i386_finish_dynamic_symbol (bfd *output_bfd,
struct bfd_link_info *info,
struct elf_link_hash_entry *h,
struct elf_x86_link_hash_table *htab;
unsigned plt_entry_size;
struct elf_x86_link_hash_entry *eh;
- bfd_boolean local_undefweak;
- bfd_boolean use_plt_second;
+ bool local_undefweak;
+ bool use_plt_second;
htab = elf_x86_hash_table (info, I386_ELF_DATA);
if (htab == NULL)
- return FALSE;
+ return false;
plt_entry_size = htab->plt.plt_entry_size;
+ gotplt->output_offset
+ got_offset),
resolved_plt->contents + plt_offset
- + htab->plt.plt_got_offset);
+ + htab->plt.plt_got_offset);
- if (htab->is_vxworks)
+ if (htab->elf.target_os == is_vxworks)
{
int s, k, reloc_index;
/* S: Current slot number (zero-based). */
s = ((h->plt.offset - htab->plt.plt_entry_size)
- / htab->plt.plt_entry_size);
+ / htab->plt.plt_entry_size);
/* K: Number of relocations for PLTResolve. */
if (bfd_link_pic (info))
k = PLTRESOLVE_RELOCS_SHLIB;
{
bfd_put_32 (output_bfd, got_offset,
resolved_plt->contents + plt_offset
- + htab->plt.plt_got_offset);
+ + htab->plt.plt_got_offset);
}
/* Fill in the entry in the global offset table. Leave the entry
+ got_offset);
if (PLT_LOCAL_IFUNC_P (info, h))
{
- info->callbacks->minfo (_("Local IFUNC function `%s' in %B\n"),
+ info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"),
h->root.root.string,
h->root.u.def.section->owner);
+ h->root.u.def.section->output_offset),
gotplt->contents + got_offset);
rel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);
+
+ if (htab->params->report_relative_reloc)
+ _bfd_x86_elf_link_report_relative_reloc
+ (info, relplt, h, sym, "R_386_IRELATIVE", &rel);
+
/* R_386_IRELATIVE comes last. */
plt_index = htab->next_irelative_index--;
}
sym->st_value = 0;
}
+ _bfd_x86_elf_link_fixup_ifunc_symbol (info, htab, h, sym);
+
/* Don't generate dynamic GOT relocation against undefined weak
symbol in executable. */
if (h->got.offset != (bfd_vma) -1
{
Elf_Internal_Rela rel;
asection *relgot = htab->elf.srelgot;
+ const char *relative_reloc_name = NULL;
/* This symbol has an entry in the global offset table. Set it
up. */
}
if (SYMBOL_REFERENCES_LOCAL_P (info, h))
{
- info->callbacks->minfo (_("Local IFUNC function `%s' in %B\n"),
+ info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"),
h->root.root.string,
h->root.u.def.section->owner);
+ h->root.u.def.section->output_offset),
htab->elf.sgot->contents + h->got.offset);
rel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);
+ relative_reloc_name = "R_386_IRELATIVE";
}
else
goto do_glob_dat;
(plt->output_section->vma
+ plt->output_offset + plt_offset),
htab->elf.sgot->contents + h->got.offset);
- return TRUE;
+ return true;
}
}
else if (bfd_link_pic (info)
{
BFD_ASSERT((h->got.offset & 1) != 0);
rel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
+ relative_reloc_name = "R_386_RELATIVE";
}
else
{
BFD_ASSERT((h->got.offset & 1) == 0);
-do_glob_dat:
+ do_glob_dat:
bfd_put_32 (output_bfd, (bfd_vma) 0,
htab->elf.sgot->contents + h->got.offset);
rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT);
}
+ if (relative_reloc_name != NULL
+ && htab->params->report_relative_reloc)
+ _bfd_x86_elf_link_report_relative_reloc
+ (info, relgot, h, sym, relative_reloc_name, &rel);
+
elf_append_rel (output_bfd, relgot, &rel);
}
asection *s;
/* This symbol needs a copy reloc. Set it up. */
-
- if (h->dynindx == -1
- || (h->root.type != bfd_link_hash_defined
- && h->root.type != bfd_link_hash_defweak)
- || htab->elf.srelbss == NULL
- || htab->elf.sreldynrelro == NULL)
- abort ();
+ VERIFY_COPY_RELOC (h, htab)
rel.r_offset = (h->root.u.def.value
+ h->root.u.def.section->output_section->vma
elf_append_rel (output_bfd, s, &rel);
}
- return TRUE;
+ return true;
}
/* Finish up local dynamic symbol handling. We set the contents of
various dynamic sections here. */
-static bfd_boolean
+static int
elf_i386_finish_local_dynamic_symbol (void **slot, void *inf)
{
struct elf_link_hash_entry *h
here since undefined weak symbol may not be dynamic and may not be
called for elf_i386_finish_dynamic_symbol. */
-static bfd_boolean
+static bool
elf_i386_pie_finish_undefweak_symbol (struct bfd_hash_entry *bh,
void *inf)
{
if (h->root.type != bfd_link_hash_undefweak
|| h->dynindx != -1)
- return TRUE;
+ return true;
return elf_i386_finish_dynamic_symbol (info->output_bfd,
info, h, NULL);
&& htab->dynsym->contents != NULL)
{
/* Check relocation against STT_GNU_IFUNC symbol if there are
- dynamic symbols. */
+ dynamic symbols. */
unsigned long r_symndx = ELF32_R_SYM (rela->r_info);
if (r_symndx != STN_UNDEF)
{
/* Finish up the dynamic sections. */
-static bfd_boolean
+static bool
elf_i386_finish_dynamic_sections (bfd *output_bfd,
struct bfd_link_info *info)
{
struct elf_x86_link_hash_table *htab;
- bfd *dynobj;
- asection *sdyn;
- const struct elf_i386_backend_data *abed;
- htab = elf_x86_hash_table (info, I386_ELF_DATA);
+ htab = _bfd_x86_elf_finish_dynamic_sections (output_bfd, info);
if (htab == NULL)
- return FALSE;
+ return false;
- dynobj = htab->elf.dynobj;
- sdyn = bfd_get_linker_section (dynobj, ".dynamic");
- abed = get_elf_i386_backend_data (output_bfd);
+ if (!htab->elf.dynamic_sections_created)
+ return true;
- if (htab->elf.dynamic_sections_created)
+ if (htab->elf.splt && htab->elf.splt->size > 0)
{
- Elf32_External_Dyn *dyncon, *dynconend;
-
- if (sdyn == NULL || htab->elf.sgot == NULL)
- abort ();
+ /* UnixWare sets the entsize of .plt to 4, although that doesn't
+ really seem like the right value. */
+ elf_section_data (htab->elf.splt->output_section)
+ ->this_hdr.sh_entsize = 4;
- dyncon = (Elf32_External_Dyn *) sdyn->contents;
- dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
- for (; dyncon < dynconend; dyncon++)
+ if (htab->plt.has_plt0)
{
- Elf_Internal_Dyn dyn;
- asection *s;
-
- bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
-
- switch (dyn.d_tag)
+ /* Fill in the special first entry in the procedure linkage
+ table. */
+ memcpy (htab->elf.splt->contents, htab->plt.plt0_entry,
+ htab->lazy_plt->plt0_entry_size);
+ memset (htab->elf.splt->contents + htab->lazy_plt->plt0_entry_size,
+ htab->plt0_pad_byte,
+ htab->plt.plt_entry_size - htab->lazy_plt->plt0_entry_size);
+ if (!bfd_link_pic (info))
{
- default:
- if (htab->is_vxworks
- && elf_vxworks_finish_dynamic_entry (output_bfd, &dyn))
- break;
- continue;
-
- case DT_PLTGOT:
- s = htab->elf.sgotplt;
- dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
- break;
-
- case DT_JMPREL:
- s = htab->elf.srelplt;
- dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
- break;
-
- case DT_PLTRELSZ:
- s = htab->elf.srelplt;
- dyn.d_un.d_val = s->size;
- break;
- }
-
- bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
- }
-
- if (htab->elf.splt && htab->elf.splt->size > 0)
- {
- /* UnixWare sets the entsize of .plt to 4, although that doesn't
- really seem like the right value. */
- elf_section_data (htab->elf.splt->output_section)
- ->this_hdr.sh_entsize = 4;
+ bfd_put_32 (output_bfd,
+ (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset
+ + 4),
+ htab->elf.splt->contents
+ + htab->lazy_plt->plt0_got1_offset);
+ bfd_put_32 (output_bfd,
+ (htab->elf.sgotplt->output_section->vma
+ + htab->elf.sgotplt->output_offset
+ + 8),
+ htab->elf.splt->contents
+ + htab->lazy_plt->plt0_got2_offset);
- if (htab->plt.has_plt0)
- {
- /* Fill in the special first entry in the procedure linkage
- table. */
- memcpy (htab->elf.splt->contents, htab->plt.plt0_entry,
- htab->lazy_plt->plt0_entry_size);
- memset (htab->elf.splt->contents + htab->lazy_plt->plt0_entry_size,
- abed->plt0_pad_byte,
- htab->plt.plt_entry_size - htab->lazy_plt->plt0_entry_size);
- if (!bfd_link_pic (info))
+ if (htab->elf.target_os == is_vxworks)
{
- bfd_put_32 (output_bfd,
- (htab->elf.sgotplt->output_section->vma
- + htab->elf.sgotplt->output_offset
- + 4),
- htab->elf.splt->contents
- + htab->lazy_plt->plt0_got1_offset);
- bfd_put_32 (output_bfd,
- (htab->elf.sgotplt->output_section->vma
- + htab->elf.sgotplt->output_offset
- + 8),
- htab->elf.splt->contents
- + htab->lazy_plt->plt0_got2_offset);
+ Elf_Internal_Rela rel;
+ int num_plts = (htab->elf.splt->size
+ / htab->plt.plt_entry_size) - 1;
+ unsigned char *p;
+ asection *srelplt2 = htab->srelplt2;
+
+ /* Generate a relocation for _GLOBAL_OFFSET_TABLE_
+ + 4. On IA32 we use REL relocations so the
+ addend goes in the PLT directly. */
+ rel.r_offset = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + htab->lazy_plt->plt0_got1_offset);
+ rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
+ R_386_32);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel,
+ srelplt2->contents);
+ /* Generate a relocation for _GLOBAL_OFFSET_TABLE_
+ + 8. */
+ rel.r_offset = (htab->elf.splt->output_section->vma
+ + htab->elf.splt->output_offset
+ + htab->lazy_plt->plt0_got2_offset);
+ rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
+ R_386_32);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel,
+ srelplt2->contents +
+ sizeof (Elf32_External_Rel));
+ /* Correct the .rel.plt.unloaded relocations. */
+ p = srelplt2->contents;
+ if (bfd_link_pic (info))
+ p += PLTRESOLVE_RELOCS_SHLIB * sizeof (Elf32_External_Rel);
+ else
+ p += PLTRESOLVE_RELOCS * sizeof (Elf32_External_Rel);
- if (htab->is_vxworks)
+ for (; num_plts; num_plts--)
{
- Elf_Internal_Rela rel;
- int num_plts = (htab->elf.splt->size
- / htab->plt.plt_entry_size) - 1;
- unsigned char *p;
- asection *srelplt2 = htab->srelplt2;
-
- /* Generate a relocation for _GLOBAL_OFFSET_TABLE_
- + 4. On IA32 we use REL relocations so the
- addend goes in the PLT directly. */
- rel.r_offset = (htab->elf.splt->output_section->vma
- + htab->elf.splt->output_offset
- + htab->lazy_plt->plt0_got1_offset);
+ bfd_elf32_swap_reloc_in (output_bfd, p, &rel);
rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
R_386_32);
- bfd_elf32_swap_reloc_out (output_bfd, &rel,
- srelplt2->contents);
- /* Generate a relocation for _GLOBAL_OFFSET_TABLE_
- + 8. */
- rel.r_offset = (htab->elf.splt->output_section->vma
- + htab->elf.splt->output_offset
- + htab->lazy_plt->plt0_got2_offset);
- rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
- R_386_32);
- bfd_elf32_swap_reloc_out (output_bfd, &rel,
- srelplt2->contents +
- sizeof (Elf32_External_Rel));
- /* Correct the .rel.plt.unloaded relocations. */
- p = srelplt2->contents;
- if (bfd_link_pic (info))
- p += PLTRESOLVE_RELOCS_SHLIB * sizeof (Elf32_External_Rel);
- else
- p += PLTRESOLVE_RELOCS * sizeof (Elf32_External_Rel);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel, p);
+ p += sizeof (Elf32_External_Rel);
- for (; num_plts; num_plts--)
- {
- bfd_elf32_swap_reloc_in (output_bfd, p, &rel);
- rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
- R_386_32);
- bfd_elf32_swap_reloc_out (output_bfd, &rel, p);
- p += sizeof (Elf32_External_Rel);
-
- bfd_elf32_swap_reloc_in (output_bfd, p, &rel);
- rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx,
- R_386_32);
- bfd_elf32_swap_reloc_out (output_bfd, &rel, p);
- p += sizeof (Elf32_External_Rel);
- }
+ bfd_elf32_swap_reloc_in (output_bfd, p, &rel);
+ rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx,
+ R_386_32);
+ bfd_elf32_swap_reloc_out (output_bfd, &rel, p);
+ p += sizeof (Elf32_External_Rel);
}
}
}
}
-
- if (htab->plt_got != NULL && htab->plt_got->size > 0)
- elf_section_data (htab->plt_got->output_section)
- ->this_hdr.sh_entsize = htab->non_lazy_plt->plt_entry_size;
-
- if (htab->plt_second != NULL && htab->plt_second->size > 0)
- elf_section_data (htab->plt_second->output_section)
- ->this_hdr.sh_entsize = htab->non_lazy_plt->plt_entry_size;
- }
-
- /* Fill in the first three entries in the global offset table. */
- if (htab->elf.sgotplt && htab->elf.sgotplt->size > 0)
- {
- if (bfd_is_abs_section (htab->elf.sgotplt->output_section))
- {
- _bfd_error_handler
- (_("discarded output section: `%A'"), htab->elf.sgotplt);
- return FALSE;
- }
-
- bfd_put_32 (output_bfd,
- (sdyn == NULL ? 0
- : sdyn->output_section->vma + sdyn->output_offset),
- htab->elf.sgotplt->contents);
- bfd_put_32 (output_bfd, 0, htab->elf.sgotplt->contents + 4);
- bfd_put_32 (output_bfd, 0, htab->elf.sgotplt->contents + 8);
-
- elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize = 4;
}
- /* Adjust .eh_frame for .plt section. */
- if (htab->plt_eh_frame != NULL
- && htab->plt_eh_frame->contents != NULL)
- {
- if (htab->elf.splt != NULL
- && htab->elf.splt->size != 0
- && (htab->elf.splt->flags & SEC_EXCLUDE) == 0
- && htab->elf.splt->output_section != NULL
- && htab->plt_eh_frame->output_section != NULL)
- {
- bfd_vma plt_start = htab->elf.splt->output_section->vma;
- bfd_vma eh_frame_start = htab->plt_eh_frame->output_section->vma
- + htab->plt_eh_frame->output_offset
- + PLT_FDE_START_OFFSET;
- bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
- htab->plt_eh_frame->contents
- + PLT_FDE_START_OFFSET);
- }
- if (htab->plt_eh_frame->sec_info_type
- == SEC_INFO_TYPE_EH_FRAME)
- {
- if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
- htab->plt_eh_frame,
- htab->plt_eh_frame->contents))
- return FALSE;
- }
- }
-
- /* Adjust .eh_frame for .plt.got section. */
- if (htab->plt_got_eh_frame != NULL
- && htab->plt_got_eh_frame->contents != NULL)
- {
- if (htab->plt_got != NULL
- && htab->plt_got->size != 0
- && (htab->plt_got->flags & SEC_EXCLUDE) == 0
- && htab->plt_got->output_section != NULL
- && htab->plt_got_eh_frame->output_section != NULL)
- {
- bfd_vma plt_start = htab->plt_got->output_section->vma;
- bfd_vma eh_frame_start = htab->plt_got_eh_frame->output_section->vma
- + htab->plt_got_eh_frame->output_offset
- + PLT_FDE_START_OFFSET;
- bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
- htab->plt_got_eh_frame->contents
- + PLT_FDE_START_OFFSET);
- }
- if (htab->plt_got_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
- {
- if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
- htab->plt_got_eh_frame,
- htab->plt_got_eh_frame->contents))
- return FALSE;
- }
- }
-
- /* Adjust .eh_frame for the second PLT section. */
- if (htab->plt_second_eh_frame != NULL
- && htab->plt_second_eh_frame->contents != NULL)
- {
- if (htab->plt_second != NULL
- && htab->plt_second->size != 0
- && (htab->plt_second->flags & SEC_EXCLUDE) == 0
- && htab->plt_second->output_section != NULL
- && htab->plt_second_eh_frame->output_section != NULL)
- {
- bfd_vma plt_start = htab->plt_second->output_section->vma;
- bfd_vma eh_frame_start
- = (htab->plt_second_eh_frame->output_section->vma
- + htab->plt_second_eh_frame->output_offset
- + PLT_FDE_START_OFFSET);
- bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
- htab->plt_second_eh_frame->contents
- + PLT_FDE_START_OFFSET);
- }
- if (htab->plt_second_eh_frame->sec_info_type
- == SEC_INFO_TYPE_EH_FRAME)
- {
- if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
- htab->plt_second_eh_frame,
- htab->plt_second_eh_frame->contents))
- return FALSE;
- }
- }
-
- if (htab->elf.sgot && htab->elf.sgot->size > 0)
- elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 4;
-
/* Fill PLT entries for undefined weak symbols in PIE. */
if (bfd_link_pie (info))
bfd_hash_traverse (&info->hash->table,
elf_i386_pie_finish_undefweak_symbol,
info);
- return TRUE;
+ return true;
}
/* Fill PLT/GOT entries and allocate dynamic relocations for local
It has to be done before elf_link_sort_relocs is called so that
dynamic relocations are properly sorted. */
-static bfd_boolean
+static bool
elf_i386_output_arch_local_syms
(bfd *output_bfd ATTRIBUTE_UNUSED,
struct bfd_link_info *info,
struct elf_x86_link_hash_table *htab
= elf_x86_hash_table (info, I386_ELF_DATA);
if (htab == NULL)
- return FALSE;
+ return false;
/* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
htab_traverse (htab->loc_hash_table,
elf_i386_finish_local_dynamic_symbol,
info);
- return TRUE;
+ return true;
}
-/* Forward declaration. */
-static const struct elf_x86_lazy_plt_layout elf_i386_nacl_plt;
-
/* Similar to _bfd_elf_get_synthetic_symtab. Support PLTs with all
dynamic relocations. */
lazy_plt = NULL;
non_lazy_ibt_plt = NULL;
lazy_ibt_plt = NULL;
- switch (get_elf_i386_backend_data (abfd)->os)
+ switch (get_elf_backend_data (abfd)->target_os)
{
case is_normal:
+ case is_solaris:
non_lazy_plt = &elf_i386_non_lazy_plt;
lazy_ibt_plt = &elf_i386_lazy_ibt_plt;
non_lazy_ibt_plt = &elf_i386_non_lazy_ibt_plt;
case is_vxworks:
lazy_plt = &elf_i386_lazy_plt;
break;
- case is_nacl:
- lazy_plt = &elf_i386_nacl_plt;
- break;
+ default:
+ abort ();
}
got_addr = 0;
{
struct elf_x86_init_table init_table;
- init_table.normal_target = FALSE;
- init_table.is_vxworks = FALSE;
- switch (get_elf_i386_backend_data (info->output_bfd)->os)
+ switch (get_elf_backend_data (info->output_bfd)->target_os)
{
case is_normal:
+ case is_solaris:
+ init_table.plt0_pad_byte = 0x0;
init_table.lazy_plt = &elf_i386_lazy_plt;
init_table.non_lazy_plt = &elf_i386_non_lazy_plt;
init_table.lazy_ibt_plt = &elf_i386_lazy_ibt_plt;
init_table.non_lazy_ibt_plt = &elf_i386_non_lazy_ibt_plt;
- init_table.normal_target = TRUE;
break;
case is_vxworks:
+ init_table.plt0_pad_byte = 0x90;
init_table.lazy_plt = &elf_i386_lazy_plt;
init_table.non_lazy_plt = NULL;
init_table.lazy_ibt_plt = NULL;
init_table.non_lazy_ibt_plt = NULL;
- init_table.is_vxworks = TRUE;
- break;
- case is_nacl:
- init_table.lazy_plt = &elf_i386_nacl_plt;
- init_table.non_lazy_plt = NULL;
- init_table.lazy_ibt_plt = NULL;
- init_table.non_lazy_ibt_plt = NULL;
break;
+ default:
+ abort ();
}
init_table.r_info = elf32_r_info;
#define elf_backend_reloc_type_class elf_i386_reloc_type_class
#define elf_backend_relocate_section elf_i386_relocate_section
#define elf_backend_setup_gnu_properties elf_i386_link_setup_gnu_properties
+#define elf_backend_hide_symbol _bfd_x86_elf_hide_symbol
+
+#define elf_backend_linux_prpsinfo32_ugid16 true
+
+#define elf32_bed elf32_i386_bed
#include "elf32-target.h"
"FreeBSD" label in the ELF header. So we put this label on all
executables and (for simplicity) also all other object files. */
-static void
-elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info)
+static bool
+elf_i386_fbsd_init_file_header (bfd *abfd, struct bfd_link_info *info)
{
- _bfd_elf_post_process_headers (abfd, info);
+ if (!_bfd_elf_init_file_header (abfd, info))
+ return false;
#ifdef OLD_FREEBSD_ABI_LABEL
{
memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8);
}
#endif
+ return true;
}
-#undef elf_backend_post_process_headers
-#define elf_backend_post_process_headers elf_i386_fbsd_post_process_headers
+#undef elf_backend_init_file_header
+#define elf_backend_init_file_header elf_i386_fbsd_init_file_header
#undef elf32_bed
#define elf32_bed elf32_i386_fbsd_bed
#include "elf32-target.h"
+#undef elf_backend_init_file_header
+
/* Solaris 2. */
#undef TARGET_LITTLE_SYM
#undef TARGET_LITTLE_NAME
#define TARGET_LITTLE_NAME "elf32-i386-sol2"
-#undef elf_backend_post_process_headers
+#undef ELF_TARGET_OS
+#define ELF_TARGET_OS is_solaris
/* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE
objects won't be recognized. */
#define elf_backend_strtab_flags SHF_STRINGS
/* Called to set the sh_flags, sh_link and sh_info fields of OSECTION which
- has a type >= SHT_LOOS. Returns TRUE if these fields were initialised
+ has a type >= SHT_LOOS. Returns TRUE if these fields were initialised
FALSE otherwise. ISECTION is the best guess matching section from the
input bfd IBFD, but it might be NULL. */
-static bfd_boolean
+static bool
elf32_i386_copy_solaris_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED,
bfd *obfd ATTRIBUTE_UNUSED,
const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED,
{
/* PR 19938: FIXME: Need to add code for setting the sh_info
and sh_link fields of Solaris specific section types. */
- return FALSE;
+ return false;
/* Based upon Oracle Solaris 11.3 Linkers and Libraries Guide, Ch. 13,
Object File Format, Table 13-9 ELF sh_link and sh_info Interpretation:
http://docs.oracle.com/cd/E53394_01/html/E54813/chapter6-94076.html#scrolltoc
The following values should be set:
-
-Type Link Info
+
+Type Link Info
-----------------------------------------------------------------------------
SHT_SUNW_ancillary The section header index of 0
- [0x6fffffee] the associated string table.
-
+ [0x6fffffee] the associated string table.
+
SHT_SUNW_capinfo The section header index of For a dynamic object, the
- [0x6ffffff0] the associated symbol table. section header index of
- the associated
+ [0x6ffffff0] the associated symbol table. section header index of
+ the associated
SHT_SUNW_capchain table,
otherwise 0.
SHT_SUNW_symsort The section header index of 0
- [0x6ffffff1] the associated symbol table.
+ [0x6ffffff1] the associated symbol table.
SHT_SUNW_tlssort The section header index of 0
- [0x6ffffff2] the associated symbol table.
-
-SHT_SUNW_LDYNSYM The section header index of One greater than the
- [0x6ffffff3] the associated string table. symbol table index of the
- This index is the same string last local symbol,
+ [0x6ffffff2] the associated symbol table.
+
+SHT_SUNW_LDYNSYM The section header index of One greater than the
+ [0x6ffffff3] the associated string table. symbol table index of the
+ This index is the same string last local symbol,
table used by the SHT_DYNSYM STB_LOCAL. Since
- section. SHT_SUNW_LDYNSYM only
- contains local symbols,
+ section. SHT_SUNW_LDYNSYM only
+ contains local symbols,
sh_info is equivalent to
the number of symbols in
the table.
-SHT_SUNW_cap If symbol capabilities exist, If any capabilities refer
- [0x6ffffff5] the section header index of to named strings, the
- the associated section header index of
- SHT_SUNW_capinfo table, the associated string
- otherwise 0. table, otherwise 0.
+SHT_SUNW_cap If symbol capabilities exist, If any capabilities refer
+ [0x6ffffff5] the section header index of to named strings, the
+ the associated section header index of
+ SHT_SUNW_capinfo table, the associated string
+ otherwise 0. table, otherwise 0.
+
+SHT_SUNW_move The section header index of 0
+ [0x6ffffffa] the associated symbol table.
-SHT_SUNW_move The section header index of 0
- [0x6ffffffa] the associated symbol table.
-
-SHT_SUNW_COMDAT 0 0
+SHT_SUNW_COMDAT 0 0
[0x6ffffffb]
SHT_SUNW_syminfo The section header index of The section header index
- [0x6ffffffc] the associated symbol table. of the associated
- .dynamic section.
+ [0x6ffffffc] the associated symbol table. of the associated
+ .dynamic section.
-SHT_SUNW_verdef The section header index of The number of version
- [0x6ffffffd] the associated string table. definitions within the
- section.
+SHT_SUNW_verdef The section header index of The number of version
+ [0x6ffffffd] the associated string table. definitions within the
+ section.
SHT_SUNW_verneed The section header index of The number of version
- [0x6ffffffe] the associated string table. dependencies within the
- section.
+ [0x6ffffffe] the associated string table. dependencies within the
+ section.
-SHT_SUNW_versym The section header index of 0
- [0x6fffffff] the associated symbol table. */
+SHT_SUNW_versym The section header index of 0
+ [0x6fffffff] the associated symbol table. */
}
#undef elf_backend_copy_special_section_fields
/* Intel MCU support. */
-static bfd_boolean
+static bool
elf32_iamcu_elf_object_p (bfd *abfd)
{
/* Set the right machine number for an IAMCU elf32 file. */
bfd_default_set_arch_mach (abfd, bfd_arch_iamcu, bfd_mach_i386_iamcu);
- return TRUE;
+ return true;
}
#undef TARGET_LITTLE_SYM
#undef ELF_MACHINE_CODE
#define ELF_MACHINE_CODE EM_IAMCU
+#undef ELF_TARGET_OS
#undef ELF_OSABI
#undef elf32_bed
#undef elf_backend_static_tls_alignment
#undef elf_backend_want_plt_sym
-#define elf_backend_want_plt_sym 0
+#define elf_backend_want_plt_sym 0
#undef elf_backend_strtab_flags
#undef elf_backend_copy_special_section_fields
#define ELF_ARCH bfd_arch_i386
#undef ELF_MACHINE_CODE
#define ELF_MACHINE_CODE EM_386
-
-/* Native Client support. */
-
-#undef TARGET_LITTLE_SYM
-#define TARGET_LITTLE_SYM i386_elf32_nacl_vec
-#undef TARGET_LITTLE_NAME
-#define TARGET_LITTLE_NAME "elf32-i386-nacl"
-#undef elf32_bed
-#define elf32_bed elf32_i386_nacl_bed
-
-#undef ELF_MAXPAGESIZE
-#define ELF_MAXPAGESIZE 0x10000
-
-/* Restore defaults. */
-#undef ELF_OSABI
-#undef elf_backend_want_plt_sym
-#define elf_backend_want_plt_sym 0
-#undef elf_backend_post_process_headers
-#undef elf_backend_static_tls_alignment
-
-/* NaCl uses substantially different PLT entries for the same effects. */
-
-#undef elf_backend_plt_alignment
-#define elf_backend_plt_alignment 5
-#define NACL_PLT_ENTRY_SIZE 64
-#define NACLMASK 0xe0 /* 32-byte alignment mask. */
-
-static const bfd_byte elf_i386_nacl_plt0_entry[] =
- {
- 0xff, 0x35, /* pushl contents of address */
- 0, 0, 0, 0, /* replaced with address of .got + 4. */
- 0x8b, 0x0d, /* movl contents of address, %ecx */
- 0, 0, 0, 0, /* replaced with address of .got + 8. */
- 0x83, 0xe1, NACLMASK, /* andl $NACLMASK, %ecx */
- 0xff, 0xe1 /* jmp *%ecx */
- };
-
-static const bfd_byte elf_i386_nacl_plt_entry[NACL_PLT_ENTRY_SIZE] =
- {
- 0x8b, 0x0d, /* movl contents of address, %ecx */
- 0, 0, 0, 0, /* replaced with GOT slot address. */
- 0x83, 0xe1, NACLMASK, /* andl $NACLMASK, %ecx */
- 0xff, 0xe1, /* jmp *%ecx */
-
- /* Pad to the next 32-byte boundary with nop instructions. */
- 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-
- /* Lazy GOT entries point here (32-byte aligned). */
- 0x68, /* pushl immediate */
- 0, 0, 0, 0, /* replaced with reloc offset. */
- 0xe9, /* jmp relative */
- 0, 0, 0, 0, /* replaced with offset to .plt. */
-
- /* Pad to the next 32-byte boundary with nop instructions. */
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90
- };
-
-static const bfd_byte
-elf_i386_nacl_pic_plt0_entry[sizeof (elf_i386_nacl_plt0_entry)] =
- {
- 0xff, 0x73, 0x04, /* pushl 4(%ebx) */
- 0x8b, 0x4b, 0x08, /* mov 0x8(%ebx), %ecx */
- 0x83, 0xe1, 0xe0, /* and $NACLMASK, %ecx */
- 0xff, 0xe1, /* jmp *%ecx */
-
- /* 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] =
- {
- 0x8b, 0x8b, /* movl offset(%ebx), %ecx */
- 0, 0, 0, 0, /* replaced with offset of this symbol in .got. */
- 0x83, 0xe1, 0xe0, /* andl $NACLMASK, %ecx */
- 0xff, 0xe1, /* jmp *%ecx */
-
- /* Pad to the next 32-byte boundary with nop instructions. */
- 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-
- /* Lazy GOT entries point here (32-byte aligned). */
- 0x68, /* pushl immediate */
- 0, 0, 0, 0, /* replaced with offset into relocation table. */
- 0xe9, /* jmp relative */
- 0, 0, 0, 0, /* replaced with offset to start of .plt. */
-
- /* Pad to the next 32-byte boundary with nop instructions. */
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90
- };
-
-static const bfd_byte elf_i386_nacl_eh_frame_plt[] =
- {
-#if (PLT_CIE_LENGTH != 20 \
- || PLT_FDE_LENGTH != 36 \
- || PLT_FDE_START_OFFSET != 4 + PLT_CIE_LENGTH + 8 \
- || PLT_FDE_LEN_OFFSET != 4 + PLT_CIE_LENGTH + 12)
-# error "Need elf_i386_backend_data parameters for eh_frame_plt offsets!"
-#endif
- PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
- 0, 0, 0, 0, /* CIE ID */
- 1, /* CIE version */
- 'z', 'R', 0, /* Augmentation string */
- 1, /* Code alignment factor */
- 0x7c, /* Data alignment factor: -4 */
- 8, /* Return address column */
- 1, /* Augmentation size */
- DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
- DW_CFA_def_cfa, 4, 4, /* DW_CFA_def_cfa: r4 (esp) ofs 4 */
- DW_CFA_offset + 8, 1, /* DW_CFA_offset: r8 (eip) at cfa-4 */
- DW_CFA_nop, DW_CFA_nop,
-
- PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */
- PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
- 0, 0, 0, 0, /* R_386_PC32 .plt goes here */
- 0, 0, 0, 0, /* .plt size goes here */
- 0, /* Augmentation size */
- DW_CFA_def_cfa_offset, 8, /* DW_CFA_def_cfa_offset: 8 */
- DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
- DW_CFA_def_cfa_offset, 12, /* DW_CFA_def_cfa_offset: 12 */
- DW_CFA_advance_loc + 58, /* DW_CFA_advance_loc: 58 to __PLT__+64 */
- DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */
- 13, /* Block length */
- DW_OP_breg4, 4, /* DW_OP_breg4 (esp): 4 */
- DW_OP_breg8, 0, /* DW_OP_breg8 (eip): 0 */
- DW_OP_const1u, 63, DW_OP_and, DW_OP_const1u, 37, DW_OP_ge,
- DW_OP_lit2, DW_OP_shl, DW_OP_plus,
- DW_CFA_nop, DW_CFA_nop
- };
-
-static const struct elf_x86_lazy_plt_layout elf_i386_nacl_plt =
- {
- elf_i386_nacl_plt0_entry, /* plt0_entry */
- sizeof (elf_i386_nacl_plt0_entry), /* plt0_entry_size */
- elf_i386_nacl_plt_entry, /* plt_entry */
- NACL_PLT_ENTRY_SIZE, /* plt_entry_size */
- 2, /* plt0_got1_offset */
- 8, /* plt0_got2_offset */
- 0, /* plt0_got2_insn_end */
- 2, /* plt_got_offset */
- 33, /* plt_reloc_offset */
- 38, /* plt_plt_offset */
- 0, /* plt_got_insn_size */
- 0, /* plt_plt_insn_end */
- 32, /* plt_lazy_offset */
- elf_i386_nacl_pic_plt0_entry, /* pic_plt0_entry */
- elf_i386_nacl_pic_plt_entry, /* pic_plt_entry */
- elf_i386_nacl_eh_frame_plt, /* eh_frame_plt */
- sizeof (elf_i386_nacl_eh_frame_plt) /* eh_frame_plt_size */
- };
-
-static const struct elf_i386_backend_data elf_i386_nacl_arch_bed =
- {
- 0x90, /* plt0_pad_byte: nop insn */
- is_nacl /* os */
- };
-
-static bfd_boolean
-elf32_i386_nacl_elf_object_p (bfd *abfd)
-{
- /* Set the right machine number for a NaCl i386 ELF32 file. */
- bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_i386_i386_nacl);
- return TRUE;
-}
-
-#undef elf_backend_arch_data
-#define elf_backend_arch_data &elf_i386_nacl_arch_bed
-
-#undef elf_backend_object_p
-#define elf_backend_object_p elf32_i386_nacl_elf_object_p
-#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
-#undef elf_backend_final_write_processing
-#define elf_backend_final_write_processing nacl_final_write_processing
-
-#include "elf32-target.h"
-
-/* Restore defaults. */
#undef elf_backend_object_p
-#undef elf_backend_modify_segment_map
-#undef elf_backend_modify_program_headers
-#undef elf_backend_final_write_processing
/* VxWorks support. */
#undef elf_backend_plt_alignment
#define elf_backend_plt_alignment 4
-static const struct elf_i386_backend_data elf_i386_vxworks_arch_bed =
- {
- 0x90, /* plt0_pad_byte */
- is_vxworks /* os */
- };
-
-#undef elf_backend_arch_data
-#define elf_backend_arch_data &elf_i386_vxworks_arch_bed
+#undef ELF_TARGET_OS
+#define ELF_TARGET_OS is_vxworks
#undef elf_backend_relocs_compatible
#undef elf_backend_add_symbol_hook