/* The first entry in an absolute procedure linkage table looks like
this. See the SVR4 ABI i386 supplement to see how this works. */
-static bfd_byte elf_i386_plt0_entry[PLT_ENTRY_SIZE] =
+static const bfd_byte elf_i386_plt0_entry[PLT_ENTRY_SIZE] =
{
0xff, 0x35, /* pushl contents of address */
0, 0, 0, 0, /* replaced with address of .got + 4. */
/* Subsequent entries in an absolute procedure linkage table look like
this. */
-static bfd_byte elf_i386_plt_entry[PLT_ENTRY_SIZE] =
+static const bfd_byte elf_i386_plt_entry[PLT_ENTRY_SIZE] =
{
0xff, 0x25, /* jmp indirect */
0, 0, 0, 0, /* replaced with address of this symbol in .got. */
/* The first entry in a PIC procedure linkage table look like this. */
-static bfd_byte elf_i386_pic_plt0_entry[PLT_ENTRY_SIZE] =
+static const bfd_byte elf_i386_pic_plt0_entry[PLT_ENTRY_SIZE] =
{
0xff, 0xb3, 4, 0, 0, 0, /* pushl 4(%ebx) */
0xff, 0xa3, 8, 0, 0, 0, /* jmp *8(%ebx) */
/* Subsequent entries in a PIC procedure linkage table look like this. */
-static bfd_byte elf_i386_pic_plt_entry[PLT_ENTRY_SIZE] =
+static const bfd_byte elf_i386_pic_plt_entry[PLT_ENTRY_SIZE] =
{
0xff, 0xa3, /* jmp *offset(%ebx) */
0, 0, 0, 0, /* replaced with offset of this symbol in .got. */
{
flagword flags;
register asection *s;
- struct elf_link_hash_entry *h;
/* We need to create .plt, .rel.plt, .got, .got.plt, .dynbss, and
.rel.bss sections. */
if (info->shared
&& (sec->flags & SEC_ALLOC) != 0)
{
- /* When creating a shared object, we must output a
- R_386_RELATIVE reloc for this location. We create a
- reloc section in dynobj and make room for this reloc. */
+ /* When creating a shared object, we must copy these
+ reloc types into the output file. We create a reloc
+ section in dynobj and make room for this reloc. */
if (sreloc == NULL)
{
const char *name;
/* Make sure we know what is going on here. */
BFD_ASSERT (dynobj != NULL
- && h->root.type == bfd_link_hash_defined
- && (bfd_get_flavour (h->root.u.def.section->owner)
- == bfd_target_elf_flavour)
&& ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
|| ((h->elf_link_hash_flags
& ELF_LINK_HASH_DEF_DYNAMIC) != 0
& ELF_LINK_HASH_DEF_REGULAR) == 0
&& (elf_elfheader (h->root.u.def.section->owner)->e_type
== ET_DYN)
+ && h->root.type == bfd_link_hash_defined
+ && (bfd_get_flavour (h->root.u.def.section->owner)
+ == bfd_target_elf_flavour)
&& h->root.u.def.section->output_section == NULL)));
/* If this is a function, put it in the procedure linkage table. We
if (s->_raw_size == 0)
s->_raw_size += PLT_ENTRY_SIZE;
- /* Set the symbol to this location in the .plt. */
- h->root.u.def.section = s;
- h->root.u.def.value = s->_raw_size;
+ /* If this symbol is not defined in a regular file, and we are
+ not generating a shared library, then set the symbol to this
+ location in the .plt. This is required to make function
+ pointers compare as equal between the normal executable and
+ the shared library. */
+ if (! info->shared
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ {
+ h->root.u.def.section = s;
+ h->root.u.def.value = s->_raw_size;
+ }
h->plt_offset = s->_raw_size;
for (; rel < relend; rel++)
{
int r_type;
- const reloc_howto_type *howto;
+ reloc_howto_type *howto;
long r_symndx;
struct elf_link_hash_entry *h;
Elf_Internal_Sym *sym;
if (h->root.type == bfd_link_hash_defined)
{
sec = h->root.u.def.section;
- relocation = (h->root.u.def.value
- + sec->output_section->vma
- + sec->output_offset);
+ if (r_type == R_386_GOTPC
+ || (r_type == R_386_PLT32
+ && h->plt_offset != (bfd_vma) -1)
+ || (r_type == R_386_GOT32
+ && elf_hash_table (info)->dynamic_sections_created)
+ || (info->shared
+ && (r_type == R_386_32
+ || r_type == R_386_PC32)
+ && (input_section->flags & SEC_ALLOC) != 0))
+ {
+ /* In these cases, we don't need the relocation
+ value. We check specially because in some
+ obscure cases sec->output_section will be NULL. */
+ relocation = 0;
+ }
+ else
+ relocation = (h->root.u.def.value
+ + sec->output_section->vma
+ + sec->output_offset);
}
else if (h->root.type == bfd_link_hash_weak)
relocation = 0;