(elf_i386_relocate_section): Don't fail relocations in debug sections
for symbol defined externally.
This commit is contained in:
parent
4770ff087a
commit
5f49173db3
305
bfd/elf32-i386.c
305
bfd/elf32-i386.c
@ -1,5 +1,5 @@
|
||||
/* Intel 80386/80486-specific support for 32-bit ELF
|
||||
Copyright 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||
Copyright 1993-1997, 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
|
||||
@ -52,45 +52,7 @@ static boolean elf_i386_finish_dynamic_sections
|
||||
|
||||
#define USE_REL 1 /* 386 uses REL relocations instead of RELA */
|
||||
|
||||
enum reloc_type
|
||||
{
|
||||
R_386_NONE = 0,
|
||||
R_386_32,
|
||||
R_386_PC32,
|
||||
R_386_GOT32,
|
||||
R_386_PLT32,
|
||||
R_386_COPY,
|
||||
R_386_GLOB_DAT,
|
||||
R_386_JUMP_SLOT,
|
||||
R_386_RELATIVE,
|
||||
R_386_GOTOFF,
|
||||
R_386_GOTPC,
|
||||
FIRST_INVALID_RELOC,
|
||||
LAST_INVALID_RELOC = 19,
|
||||
/* The remaining relocs are a GNU extension. */
|
||||
R_386_16 = 20,
|
||||
R_386_PC16,
|
||||
R_386_8,
|
||||
R_386_PC8,
|
||||
R_386_max
|
||||
};
|
||||
|
||||
#if 0
|
||||
static CONST char *CONST reloc_type_names[] =
|
||||
{
|
||||
"R_386_NONE",
|
||||
"R_386_32",
|
||||
"R_386_PC32",
|
||||
"R_386_GOT32",
|
||||
"R_386_PLT32",
|
||||
"R_386_COPY",
|
||||
"R_386_GLOB_DAT",
|
||||
"R_386_JUMP_SLOT",
|
||||
"R_386_RELATIVE",
|
||||
"R_386_GOTOFF",
|
||||
"R_386_GOTPC",
|
||||
};
|
||||
#endif
|
||||
#include "elf/i386.h"
|
||||
|
||||
static reloc_howto_type elf_howto_table[]=
|
||||
{
|
||||
@ -121,6 +83,38 @@ static reloc_howto_type elf_howto_table[]=
|
||||
HOWTO(R_386_PC8, 0,0,8,true, 0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_PC8", true,0xff,0xff,true),
|
||||
};
|
||||
|
||||
/* GNU extension to record C++ vtable hierarchy. */
|
||||
static reloc_howto_type elf32_i386_vtinherit_howto =
|
||||
HOWTO (R_386_GNU_VTINHERIT, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
0, /* bitsize */
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
NULL, /* special_function */
|
||||
"R_386_GNU_VTINHERIT", /* name */
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
false);
|
||||
|
||||
/* GNU extension to record C++ vtable member usage. */
|
||||
static reloc_howto_type elf32_i386_vtentry_howto =
|
||||
HOWTO (R_386_GNU_VTENTRY, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
0, /* bitsize */
|
||||
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 */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
false);
|
||||
|
||||
#ifdef DEBUG_GEN_RELOC
|
||||
#define TRACE(str) fprintf (stderr, "i386 bfd reloc lookup %d (%s)\n", code, str)
|
||||
#else
|
||||
@ -195,6 +189,14 @@ elf_i386_reloc_type_lookup (abfd, code)
|
||||
TRACE ("BFD_RELOC_8_PCREL");
|
||||
return &elf_howto_table[(int) R_386_PC8];
|
||||
|
||||
case BFD_RELOC_VTABLE_INHERIT:
|
||||
TRACE ("BFD_RELOC_VTABLE_INHERIT");
|
||||
return &elf32_i386_vtinherit_howto;
|
||||
|
||||
case BFD_RELOC_VTABLE_ENTRY:
|
||||
TRACE ("BFD_RELOC_VTABLE_ENTRY");
|
||||
return &elf32_i386_vtentry_howto;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -218,13 +220,19 @@ elf_i386_info_to_howto_rel (abfd, cache_ptr, dst)
|
||||
arelent *cache_ptr;
|
||||
Elf32_Internal_Rel *dst;
|
||||
{
|
||||
enum reloc_type type;
|
||||
enum elf_i386_reloc_type type;
|
||||
|
||||
type = (enum reloc_type) ELF32_R_TYPE (dst->r_info);
|
||||
BFD_ASSERT (type < R_386_max);
|
||||
BFD_ASSERT (type < FIRST_INVALID_RELOC || type > LAST_INVALID_RELOC);
|
||||
|
||||
cache_ptr->howto = &elf_howto_table[(int) type];
|
||||
type = (enum elf_i386_reloc_type) ELF32_R_TYPE (dst->r_info);
|
||||
if (type == R_386_GNU_VTINHERIT)
|
||||
cache_ptr->howto = &elf32_i386_vtinherit_howto;
|
||||
else if (type == R_386_GNU_VTENTRY)
|
||||
cache_ptr->howto = &elf32_i386_vtentry_howto;
|
||||
else
|
||||
{
|
||||
BFD_ASSERT (type < R_386_max);
|
||||
BFD_ASSERT (type < FIRST_INVALID_RELOC || type > LAST_INVALID_RELOC);
|
||||
cache_ptr->howto = &elf_howto_table[(int) type];
|
||||
}
|
||||
}
|
||||
|
||||
/* Return whether a symbol name implies a local label. The UnixWare
|
||||
@ -488,10 +496,14 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
|
||||
if (srelgot == NULL
|
||||
&& (h != NULL || info->shared))
|
||||
{
|
||||
srelgot = bfd_get_section_by_name (dynobj, ".rel.got");
|
||||
const char *srelgot_name;
|
||||
|
||||
srelgot_name = info->combine_reloc ? ".gnu.reloc" : ".rel.got";
|
||||
|
||||
srelgot = bfd_get_section_by_name (dynobj, srelgot_name);
|
||||
if (srelgot == NULL)
|
||||
{
|
||||
srelgot = bfd_make_section (dynobj, ".rel.got");
|
||||
srelgot = bfd_make_section (dynobj, srelgot_name);
|
||||
if (srelgot == NULL
|
||||
|| ! bfd_set_section_flags (dynobj, srelgot,
|
||||
(SEC_ALLOC
|
||||
@ -507,12 +519,12 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
|
||||
|
||||
if (h != NULL)
|
||||
{
|
||||
if (h->got_offset != (bfd_vma) -1)
|
||||
if (h->got.offset != (bfd_vma) -1)
|
||||
{
|
||||
/* We have already allocated space in the .got. */
|
||||
break;
|
||||
}
|
||||
h->got_offset = sgot->_raw_size;
|
||||
h->got.offset = sgot->_raw_size;
|
||||
|
||||
/* Make sure this symbol is output as a dynamic symbol. */
|
||||
if (h->dynindx == -1)
|
||||
@ -592,6 +604,7 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
|
||||
possibility below by storing information in the
|
||||
pcrel_relocs_copied field of the hash table entry. */
|
||||
if (info->shared
|
||||
&& (sec->flags & SEC_ALLOC) != 0
|
||||
&& (ELF32_R_TYPE (rel->r_info) != R_386_PC32
|
||||
|| (h != NULL
|
||||
&& (! info->symbolic
|
||||
@ -616,6 +629,11 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
|
||||
&& strcmp (bfd_get_section_name (abfd, sec),
|
||||
name + 4) == 0);
|
||||
|
||||
if (info->combine_reloc)
|
||||
/* If we combine the relocation sections use change
|
||||
the name here. */
|
||||
name = ".gnu.reloc";
|
||||
|
||||
sreloc = bfd_get_section_by_name (dynobj, name);
|
||||
if (sreloc == NULL)
|
||||
{
|
||||
@ -673,6 +691,20 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
|
||||
|
||||
break;
|
||||
|
||||
/* This relocation describes the C++ object vtable hierarchy.
|
||||
Reconstruct it for later use during GC. */
|
||||
case R_386_GNU_VTINHERIT:
|
||||
if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
|
||||
return false;
|
||||
break;
|
||||
|
||||
/* This relocation describes which C++ vtable entries are actually
|
||||
used. Record for later use during GC. */
|
||||
case R_386_GNU_VTENTRY:
|
||||
if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_offset))
|
||||
return false;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -681,6 +713,67 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Return the section that should be marked against GC for a given
|
||||
relocation. */
|
||||
|
||||
static asection *
|
||||
elf_i386_gc_mark_hook (abfd, info, rel, h, sym)
|
||||
bfd *abfd;
|
||||
struct bfd_link_info *info;
|
||||
Elf_Internal_Rela *rel;
|
||||
struct elf_link_hash_entry *h;
|
||||
Elf_Internal_Sym *sym;
|
||||
{
|
||||
if (h != NULL)
|
||||
{
|
||||
switch (ELF32_R_TYPE (rel->r_info))
|
||||
{
|
||||
case R_386_GNU_VTINHERIT:
|
||||
case R_386_GNU_VTENTRY:
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (h->root.type)
|
||||
{
|
||||
case bfd_link_hash_defined:
|
||||
case bfd_link_hash_defweak:
|
||||
return h->root.u.def.section;
|
||||
|
||||
case bfd_link_hash_common:
|
||||
return h->root.u.c.p->section;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(elf_bad_symtab (abfd)
|
||||
&& ELF_ST_BIND (sym->st_info) != STB_LOCAL)
|
||||
&& ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
|
||||
&& sym->st_shndx != SHN_COMMON))
|
||||
{
|
||||
return bfd_section_from_elf_index (abfd, sym->st_shndx);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Update the got entry reference counts for the section being removed. */
|
||||
|
||||
static boolean
|
||||
elf_i386_gc_sweep_hook (abfd, info, sec, relocs)
|
||||
bfd *abfd;
|
||||
struct bfd_link_info *info;
|
||||
asection *sec;
|
||||
const Elf_Internal_Rela *relocs;
|
||||
{
|
||||
/* ??? It would seem that the existing i386 code does no sort
|
||||
of reference counting or whatnot on its GOT and PLT entries,
|
||||
so it is not possible to garbage collect them at this time. */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Adjust a symbol defined by a dynamic object and referenced by a
|
||||
regular object. The current definition is in some section of the
|
||||
dynamic object, but we're not including those sections. We have to
|
||||
@ -755,7 +848,7 @@ elf_i386_adjust_dynamic_symbol (info, h)
|
||||
h->root.u.def.value = s->_raw_size;
|
||||
}
|
||||
|
||||
h->plt_offset = s->_raw_size;
|
||||
h->plt.offset = s->_raw_size;
|
||||
|
||||
/* Make room for this entry. */
|
||||
s->_raw_size += PLT_ENTRY_SIZE;
|
||||
@ -818,8 +911,9 @@ elf_i386_adjust_dynamic_symbol (info, h)
|
||||
if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
|
||||
{
|
||||
asection *srel;
|
||||
const char *srel_name = info->combine_reloc ? ".gnu.reloc" : ".rel.bss";
|
||||
|
||||
srel = bfd_get_section_by_name (dynobj, ".rel.bss");
|
||||
srel = bfd_get_section_by_name (dynobj, srel_name);
|
||||
BFD_ASSERT (srel != NULL);
|
||||
srel->_raw_size += sizeof (Elf32_External_Rel);
|
||||
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
|
||||
@ -884,7 +978,9 @@ elf_i386_size_dynamic_sections (output_bfd, info)
|
||||
not actually use these entries. Reset the size of .rel.got,
|
||||
which will cause it to get stripped from the output file
|
||||
below. */
|
||||
s = bfd_get_section_by_name (dynobj, ".rel.got");
|
||||
const char *s_name = info->combine_reloc ? ".gnu.reloc" : ".rel.got";
|
||||
|
||||
s = bfd_get_section_by_name (dynobj, s_name);
|
||||
if (s != NULL)
|
||||
s->_raw_size = 0;
|
||||
}
|
||||
@ -932,7 +1028,8 @@ elf_i386_size_dynamic_sections (output_bfd, info)
|
||||
plt = true;
|
||||
}
|
||||
}
|
||||
else if (strncmp (name, ".rel", 4) == 0)
|
||||
else if (strncmp (name, ".rel", 4) == 0
|
||||
|| strcmp (name, ".gnu.reloc") == 0)
|
||||
{
|
||||
if (s->_raw_size == 0)
|
||||
{
|
||||
@ -968,7 +1065,8 @@ elf_i386_size_dynamic_sections (output_bfd, info)
|
||||
s->output_section);
|
||||
target = bfd_get_section_by_name (output_bfd, outname + 4);
|
||||
if (target != NULL
|
||||
&& (target->flags & SEC_READONLY) != 0)
|
||||
&& (target->flags & SEC_READONLY) != 0
|
||||
&& (target->flags & SEC_ALLOC) != 0)
|
||||
reltext = true;
|
||||
}
|
||||
|
||||
@ -1116,6 +1214,9 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
bfd_reloc_status_type r;
|
||||
|
||||
r_type = ELF32_R_TYPE (rel->r_info);
|
||||
if (r_type == R_386_GNU_VTINHERIT
|
||||
|| r_type == R_386_GNU_VTENTRY)
|
||||
continue;
|
||||
if (r_type < 0
|
||||
|| r_type >= (int) R_386_max
|
||||
|| (r_type >= (int) FIRST_INVALID_RELOC
|
||||
@ -1175,7 +1276,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
sec = h->root.u.def.section;
|
||||
if (r_type == R_386_GOTPC
|
||||
|| (r_type == R_386_PLT32
|
||||
&& h->plt_offset != (bfd_vma) -1)
|
||||
&& h->plt.offset != (bfd_vma) -1)
|
||||
|| (r_type == R_386_GOT32
|
||||
&& elf_hash_table (info)->dynamic_sections_created
|
||||
&& (! info->shared
|
||||
@ -1188,7 +1289,12 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
& ELF_LINK_HASH_DEF_REGULAR) == 0)
|
||||
&& (r_type == R_386_32
|
||||
|| r_type == R_386_PC32)
|
||||
&& (input_section->flags & SEC_ALLOC) != 0))
|
||||
&& ((input_section->flags & SEC_ALLOC) != 0
|
||||
/* DWARF will emit R_386_32 relocations in its
|
||||
sections against symbols defined externally
|
||||
in shared libraries. We can't do anything
|
||||
with them here. */
|
||||
|| (input_section->flags & SEC_DEBUGGING) != 0)))
|
||||
{
|
||||
/* In these cases, we don't need the relocation
|
||||
value. We check specially because in some
|
||||
@ -1198,7 +1304,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
else if (sec->output_section == NULL)
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
("%s: warning: unresolvable relocation against symbol `%s' from %s section",
|
||||
(_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
|
||||
bfd_get_filename (input_bfd), h->root.root.string,
|
||||
bfd_get_section_name (input_bfd, input_section));
|
||||
relocation = 0;
|
||||
@ -1237,7 +1343,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
{
|
||||
bfd_vma off;
|
||||
|
||||
off = h->got_offset;
|
||||
off = h->got.offset;
|
||||
BFD_ASSERT (off != (bfd_vma) -1);
|
||||
|
||||
if (! elf_hash_table (info)->dynamic_sections_created
|
||||
@ -1263,7 +1369,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
{
|
||||
bfd_put_32 (output_bfd, relocation,
|
||||
sgot->contents + off);
|
||||
h->got_offset |= 1;
|
||||
h->got.offset |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1291,8 +1397,12 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
{
|
||||
asection *srelgot;
|
||||
Elf_Internal_Rel outrel;
|
||||
const char *srelgot_name;
|
||||
|
||||
srelgot = bfd_get_section_by_name (dynobj, ".rel.got");
|
||||
srelgot_name = (info->combine_reloc
|
||||
? ".gnu.reloc" : ".rel.got");
|
||||
|
||||
srelgot = bfd_get_section_by_name (dynobj, srelgot_name);
|
||||
BFD_ASSERT (srelgot != NULL);
|
||||
|
||||
outrel.r_offset = (sgot->output_section->vma
|
||||
@ -1355,7 +1465,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
if (h == NULL)
|
||||
break;
|
||||
|
||||
if (h->plt_offset == (bfd_vma) -1)
|
||||
if (h->plt.offset == (bfd_vma) -1)
|
||||
{
|
||||
/* We didn't make a PLT entry for this symbol. This
|
||||
happens when statically linking PIC code, or when
|
||||
@ -1371,15 +1481,17 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
|
||||
relocation = (splt->output_section->vma
|
||||
+ splt->output_offset
|
||||
+ h->plt_offset);
|
||||
+ h->plt.offset);
|
||||
|
||||
break;
|
||||
|
||||
case R_386_32:
|
||||
case R_386_PC32:
|
||||
if (info->shared
|
||||
&& (input_section->flags & SEC_ALLOC) != 0
|
||||
&& (r_type != R_386_PC32
|
||||
|| (h != NULL
|
||||
&& h->dynindx != -1
|
||||
&& (! info->symbolic
|
||||
|| (h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_REGULAR) == 0))))
|
||||
@ -1402,10 +1514,14 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
if (name == NULL)
|
||||
return false;
|
||||
|
||||
BFD_ASSERT (strncmp (name, ".rel", 4) == 0
|
||||
&& strcmp (bfd_get_section_name (input_bfd,
|
||||
input_section),
|
||||
name + 4) == 0);
|
||||
if (info->combine_reloc)
|
||||
name = ".gnu.reloc";
|
||||
|
||||
BFD_ASSERT ((strncmp (name, ".rel", 4) == 0
|
||||
&& strcmp (bfd_get_section_name (input_bfd,
|
||||
input_section),
|
||||
name + 4) == 0)
|
||||
|| strcmp (name, ".gnu.reloc") == 0);
|
||||
|
||||
sreloc = bfd_get_section_by_name (dynobj, name);
|
||||
BFD_ASSERT (sreloc != NULL);
|
||||
@ -1440,10 +1556,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
else if (r_type == R_386_PC32)
|
||||
{
|
||||
BFD_ASSERT (h != NULL && h->dynindx != -1);
|
||||
if ((input_section->flags & SEC_ALLOC) != 0)
|
||||
relocate = false;
|
||||
else
|
||||
relocate = true;
|
||||
relocate = false;
|
||||
outrel.r_info = ELF32_R_INFO (h->dynindx, R_386_PC32);
|
||||
}
|
||||
else
|
||||
@ -1461,10 +1574,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
else
|
||||
{
|
||||
BFD_ASSERT (h->dynindx != -1);
|
||||
if ((input_section->flags & SEC_ALLOC) != 0)
|
||||
relocate = false;
|
||||
else
|
||||
relocate = true;
|
||||
relocate = false;
|
||||
outrel.r_info = ELF32_R_INFO (h->dynindx, R_386_32);
|
||||
}
|
||||
}
|
||||
@ -1543,7 +1653,7 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||
|
||||
dynobj = elf_hash_table (info)->dynobj;
|
||||
|
||||
if (h->plt_offset != (bfd_vma) -1)
|
||||
if (h->plt.offset != (bfd_vma) -1)
|
||||
{
|
||||
asection *splt;
|
||||
asection *sgot;
|
||||
@ -1566,7 +1676,7 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||
corresponds to this symbol. This is the index of this symbol
|
||||
in all the symbols for which we are making plt entries. The
|
||||
first entry in the procedure linkage table is reserved. */
|
||||
plt_index = h->plt_offset / PLT_ENTRY_SIZE - 1;
|
||||
plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
|
||||
|
||||
/* Get the offset into the .got table of the entry that
|
||||
corresponds to this function. Each .got entry is 4 bytes.
|
||||
@ -1576,32 +1686,32 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||
/* Fill in the entry in the procedure linkage table. */
|
||||
if (! info->shared)
|
||||
{
|
||||
memcpy (splt->contents + h->plt_offset, elf_i386_plt_entry,
|
||||
memcpy (splt->contents + h->plt.offset, elf_i386_plt_entry,
|
||||
PLT_ENTRY_SIZE);
|
||||
bfd_put_32 (output_bfd,
|
||||
(sgot->output_section->vma
|
||||
+ sgot->output_offset
|
||||
+ got_offset),
|
||||
splt->contents + h->plt_offset + 2);
|
||||
splt->contents + h->plt.offset + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (splt->contents + h->plt_offset, elf_i386_pic_plt_entry,
|
||||
memcpy (splt->contents + h->plt.offset, elf_i386_pic_plt_entry,
|
||||
PLT_ENTRY_SIZE);
|
||||
bfd_put_32 (output_bfd, got_offset,
|
||||
splt->contents + h->plt_offset + 2);
|
||||
splt->contents + h->plt.offset + 2);
|
||||
}
|
||||
|
||||
bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rel),
|
||||
splt->contents + h->plt_offset + 7);
|
||||
bfd_put_32 (output_bfd, - (h->plt_offset + PLT_ENTRY_SIZE),
|
||||
splt->contents + h->plt_offset + 12);
|
||||
splt->contents + h->plt.offset + 7);
|
||||
bfd_put_32 (output_bfd, - (h->plt.offset + PLT_ENTRY_SIZE),
|
||||
splt->contents + h->plt.offset + 12);
|
||||
|
||||
/* Fill in the entry in the global offset table. */
|
||||
bfd_put_32 (output_bfd,
|
||||
(splt->output_section->vma
|
||||
+ splt->output_offset
|
||||
+ h->plt_offset
|
||||
+ h->plt.offset
|
||||
+ 6),
|
||||
sgot->contents + got_offset);
|
||||
|
||||
@ -1622,22 +1732,23 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||
}
|
||||
}
|
||||
|
||||
if (h->got_offset != (bfd_vma) -1)
|
||||
if (h->got.offset != (bfd_vma) -1)
|
||||
{
|
||||
asection *sgot;
|
||||
asection *srel;
|
||||
Elf_Internal_Rel rel;
|
||||
const char *srel_name = info->combine_reloc ? ".gnu.reloc" : ".rel.got";
|
||||
|
||||
/* This symbol has an entry in the global offset table. Set it
|
||||
up. */
|
||||
|
||||
sgot = bfd_get_section_by_name (dynobj, ".got");
|
||||
srel = bfd_get_section_by_name (dynobj, ".rel.got");
|
||||
srel = bfd_get_section_by_name (dynobj, srel_name);
|
||||
BFD_ASSERT (sgot != NULL && srel != NULL);
|
||||
|
||||
rel.r_offset = (sgot->output_section->vma
|
||||
+ sgot->output_offset
|
||||
+ (h->got_offset &~ 1));
|
||||
+ (h->got.offset &~ 1));
|
||||
|
||||
/* If this is a -Bsymbolic link, and the symbol is defined
|
||||
locally, we just want to emit a RELATIVE reloc. Likewise if
|
||||
@ -1650,7 +1761,7 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||
rel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
|
||||
else
|
||||
{
|
||||
bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got_offset);
|
||||
bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
|
||||
rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT);
|
||||
}
|
||||
|
||||
@ -1664,6 +1775,7 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||
{
|
||||
asection *s;
|
||||
Elf_Internal_Rel rel;
|
||||
const char *s_name = info->combine_reloc ? ".gnu.reloc" : ".rel.bss";
|
||||
|
||||
/* This symbol needs a copy reloc. Set it up. */
|
||||
|
||||
@ -1671,8 +1783,7 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||
&& (h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak));
|
||||
|
||||
s = bfd_get_section_by_name (h->root.u.def.section->owner,
|
||||
".rel.bss");
|
||||
s = bfd_get_section_by_name (h->root.u.def.section->owner, s_name);
|
||||
BFD_ASSERT (s != NULL);
|
||||
|
||||
rel.r_offset = (h->root.u.def.value
|
||||
@ -1842,8 +1953,14 @@ elf_i386_finish_dynamic_sections (output_bfd, info)
|
||||
elf_i386_finish_dynamic_symbol
|
||||
#define elf_backend_finish_dynamic_sections \
|
||||
elf_i386_finish_dynamic_sections
|
||||
#define elf_backend_want_got_plt 1
|
||||
#define elf_backend_plt_readonly 1
|
||||
#define elf_backend_want_plt_sym 0
|
||||
#define elf_backend_gc_mark_hook elf_i386_gc_mark_hook
|
||||
#define elf_backend_gc_sweep_hook elf_i386_gc_sweep_hook
|
||||
|
||||
#define elf_backend_can_gc_sections 1
|
||||
#define elf_backend_want_got_plt 1
|
||||
#define elf_backend_plt_readonly 1
|
||||
#define elf_backend_want_plt_sym 0
|
||||
#define elf_backend_got_header_size 12
|
||||
#define elf_backend_plt_header_size PLT_ENTRY_SIZE
|
||||
|
||||
#include "elf32-target.h"
|
||||
|
Loading…
Reference in New Issue
Block a user