* elf32-i386.c (struct elf_i386_pcrel_relocs_copied): Rename to
elf_i386_dyn_relocs. Update comment. (struct elf_i386_link_hash_entry): Rename pcrel_relocs_copied to dyn_relocs. (elf_i386_adjust_dynamic_symbol): Remove a BFD_ASSERT, change others to aborts. (allocate_plt_and_got_and_discard_relocs): Replace BFD_ASSERT with abort. (elf_i386_size_dynamic_sections): Likewise. (elf_i386_finish_dynamic_symbol): Likewise. (elf_i386_finish_dynamic_sections): Likewise. (elf_i386_relocate_section): Likewise. Tidy R_386_GOT32 and error handling code.
This commit is contained in:
parent
12d0ee4aca
commit
ffb2e45bfb
@ -1,5 +1,19 @@
|
||||
2001-06-23 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf32-i386.c (struct elf_i386_pcrel_relocs_copied): Rename to
|
||||
elf_i386_dyn_relocs. Update comment.
|
||||
(struct elf_i386_link_hash_entry): Rename pcrel_relocs_copied to
|
||||
dyn_relocs.
|
||||
(elf_i386_adjust_dynamic_symbol): Remove a BFD_ASSERT, change
|
||||
others to aborts.
|
||||
(allocate_plt_and_got_and_discard_relocs): Replace BFD_ASSERT with
|
||||
abort.
|
||||
(elf_i386_size_dynamic_sections): Likewise.
|
||||
(elf_i386_finish_dynamic_symbol): Likewise.
|
||||
(elf_i386_finish_dynamic_sections): Likewise.
|
||||
(elf_i386_relocate_section): Likewise. Tidy R_386_GOT32 and error
|
||||
handling code.
|
||||
|
||||
Avoid creating COPY relocs if possible.
|
||||
* elf32-i386.c (elf_i386_check_relocs): Tweak condition under
|
||||
which .got created. Mark symbols used by R_386_32 and R_386_PC32
|
||||
|
189
bfd/elf32-i386.c
189
bfd/elf32-i386.c
@ -357,18 +357,15 @@ static const bfd_byte elf_i386_pic_plt_entry[PLT_ENTRY_SIZE] =
|
||||
};
|
||||
|
||||
/* The i386 linker needs to keep track of the number of relocs that it
|
||||
decides to copy in check_relocs for each symbol. This is so that
|
||||
it can discard PC relative relocs if it doesn't need them when
|
||||
linking with -Bsymbolic. We store the information in a field
|
||||
extending the regular ELF linker hash table. */
|
||||
decides to copy as dynamic relocs in check_relocs for each symbol.
|
||||
This is so that it can later discard them if they are found to be
|
||||
unnecessary. We store the information in a field extending the
|
||||
regular ELF linker hash table. */
|
||||
|
||||
/* This structure keeps track of the number of PC relative relocs we
|
||||
have copied for a given symbol. */
|
||||
|
||||
struct elf_i386_pcrel_relocs_copied
|
||||
struct elf_i386_dyn_relocs
|
||||
{
|
||||
/* Next section. */
|
||||
struct elf_i386_pcrel_relocs_copied *next;
|
||||
struct elf_i386_dyn_relocs *next;
|
||||
/* A section in dynobj. */
|
||||
asection *section;
|
||||
/* Number of relocs copied in this section. */
|
||||
@ -382,7 +379,7 @@ struct elf_i386_link_hash_entry
|
||||
struct elf_link_hash_entry root;
|
||||
|
||||
/* Number of PC relative relocs copied for this symbol. */
|
||||
struct elf_i386_pcrel_relocs_copied *pcrel_relocs_copied;
|
||||
struct elf_i386_dyn_relocs *dyn_relocs;
|
||||
};
|
||||
|
||||
/* i386 ELF linker hash table. */
|
||||
@ -432,7 +429,7 @@ elf_i386_link_hash_newfunc (entry, table, string)
|
||||
table, string));
|
||||
if (ret != (struct elf_i386_link_hash_entry *) NULL)
|
||||
{
|
||||
ret->pcrel_relocs_copied = NULL;
|
||||
ret->dyn_relocs = NULL;
|
||||
}
|
||||
|
||||
return (struct bfd_hash_entry *) ret;
|
||||
@ -784,22 +781,22 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
|
||||
&& ELF32_R_TYPE (rel->r_info) == R_386_PC32))
|
||||
{
|
||||
struct elf_i386_link_hash_entry *eh;
|
||||
struct elf_i386_pcrel_relocs_copied *p;
|
||||
struct elf_i386_dyn_relocs *p;
|
||||
|
||||
eh = (struct elf_i386_link_hash_entry *) h;
|
||||
|
||||
for (p = eh->pcrel_relocs_copied; p != NULL; p = p->next)
|
||||
for (p = eh->dyn_relocs; p != NULL; p = p->next)
|
||||
if (p->section == sreloc)
|
||||
break;
|
||||
|
||||
if (p == NULL)
|
||||
{
|
||||
p = ((struct elf_i386_pcrel_relocs_copied *)
|
||||
p = ((struct elf_i386_dyn_relocs *)
|
||||
bfd_alloc (dynobj, sizeof *p));
|
||||
if (p == NULL)
|
||||
return false;
|
||||
p->next = eh->pcrel_relocs_copied;
|
||||
eh->pcrel_relocs_copied = p;
|
||||
p->next = eh->dyn_relocs;
|
||||
eh->dyn_relocs = p;
|
||||
p->section = sreloc;
|
||||
p->count = 0;
|
||||
}
|
||||
@ -968,17 +965,6 @@ elf_i386_adjust_dynamic_symbol (info, h)
|
||||
htab = elf_i386_hash_table (info);
|
||||
dynobj = htab->root.dynobj;
|
||||
|
||||
/* Make sure we know what is going on here. */
|
||||
BFD_ASSERT (dynobj != NULL
|
||||
&& ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
|
||||
|| h->weakdef != NULL
|
||||
|| ((h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_DYNAMIC) != 0
|
||||
&& (h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_REF_REGULAR) != 0
|
||||
&& (h->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_DEF_REGULAR) == 0)));
|
||||
|
||||
/* If this is a function, put it in the procedure linkage table. We
|
||||
will fill in the contents of the procedure linkage table later,
|
||||
when we know the address of the .got section. */
|
||||
@ -1055,7 +1041,8 @@ elf_i386_adjust_dynamic_symbol (info, h)
|
||||
same memory location for the variable. */
|
||||
|
||||
s = htab->sdynbss;
|
||||
BFD_ASSERT (s != NULL);
|
||||
if (s == NULL)
|
||||
abort ();
|
||||
|
||||
/* We must generate a R_386_COPY reloc to tell the dynamic linker to
|
||||
copy the initial value out of the dynamic object and into the
|
||||
@ -1066,7 +1053,8 @@ elf_i386_adjust_dynamic_symbol (info, h)
|
||||
asection *srel;
|
||||
|
||||
srel = htab->srelbss;
|
||||
BFD_ASSERT (srel != NULL);
|
||||
if (srel == NULL)
|
||||
abort ();
|
||||
srel->_raw_size += sizeof (Elf32_External_Rel);
|
||||
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;
|
||||
}
|
||||
@ -1132,7 +1120,8 @@ allocate_plt_and_got_and_discard_relocs (h, inf)
|
||||
&& h->plt.refcount > 0)
|
||||
{
|
||||
s = htab->splt;
|
||||
BFD_ASSERT (s != NULL);
|
||||
if (s == NULL)
|
||||
abort ();
|
||||
|
||||
/* If this is the first .plt entry, make room for the special
|
||||
first entry. */
|
||||
@ -1159,14 +1148,16 @@ allocate_plt_and_got_and_discard_relocs (h, inf)
|
||||
/* We also need to make an entry in the .got.plt section, which
|
||||
will be placed in the .got section by the linker script. */
|
||||
s = htab->sgotplt;
|
||||
BFD_ASSERT (s != NULL);
|
||||
if (s == NULL)
|
||||
abort ();
|
||||
s->_raw_size += 4;
|
||||
|
||||
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h))
|
||||
{
|
||||
/* We also need to make an entry in the .rel.plt section. */
|
||||
s = htab->srelplt;
|
||||
BFD_ASSERT (s != NULL);
|
||||
if (s == NULL)
|
||||
abort ();
|
||||
s->_raw_size += sizeof (Elf32_External_Rel);
|
||||
}
|
||||
}
|
||||
@ -1206,10 +1197,10 @@ allocate_plt_and_got_and_discard_relocs (h, inf)
|
||||
|| h->dynindx == -1)))
|
||||
{
|
||||
struct elf_i386_link_hash_entry *eh;
|
||||
struct elf_i386_pcrel_relocs_copied *c;
|
||||
struct elf_i386_dyn_relocs *c;
|
||||
|
||||
eh = (struct elf_i386_link_hash_entry *) h;
|
||||
for (c = eh->pcrel_relocs_copied; c != NULL; c = c->next)
|
||||
for (c = eh->dyn_relocs; c != NULL; c = c->next)
|
||||
c->section->_raw_size -= c->count * sizeof (Elf32_External_Rel);
|
||||
}
|
||||
|
||||
@ -1232,7 +1223,8 @@ elf_i386_size_dynamic_sections (output_bfd, info)
|
||||
|
||||
htab = elf_i386_hash_table (info);
|
||||
dynobj = htab->root.dynobj;
|
||||
BFD_ASSERT (dynobj != NULL);
|
||||
if (dynobj == NULL)
|
||||
abort ();
|
||||
|
||||
if (htab->root.dynamic_sections_created)
|
||||
{
|
||||
@ -1240,7 +1232,8 @@ elf_i386_size_dynamic_sections (output_bfd, info)
|
||||
if (! info->shared)
|
||||
{
|
||||
s = bfd_get_section_by_name (dynobj, ".interp");
|
||||
BFD_ASSERT (s != NULL);
|
||||
if (s == NULL)
|
||||
abort ();
|
||||
s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
|
||||
s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
|
||||
}
|
||||
@ -1453,6 +1446,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
struct elf_link_hash_entry *h;
|
||||
Elf_Internal_Sym *sym;
|
||||
asection *sec;
|
||||
bfd_vma off;
|
||||
bfd_vma relocation;
|
||||
bfd_reloc_status_type r;
|
||||
unsigned int indx;
|
||||
@ -1514,6 +1508,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
while (h->root.type == bfd_link_hash_indirect
|
||||
|| h->root.type == bfd_link_hash_warning)
|
||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||||
|
||||
relocation = 0;
|
||||
if (h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak)
|
||||
@ -1591,16 +1586,14 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
case R_386_GOT32:
|
||||
/* Relocation is to the entry for this symbol in the global
|
||||
offset table. */
|
||||
BFD_ASSERT (htab->sgot != NULL);
|
||||
if (htab->sgot == NULL)
|
||||
abort ();
|
||||
|
||||
if (h != NULL)
|
||||
{
|
||||
bfd_vma off;
|
||||
boolean dyn;
|
||||
|
||||
off = h->got.offset;
|
||||
BFD_ASSERT (off != (bfd_vma) -1);
|
||||
|
||||
dyn = htab->root.dynamic_sections_created;
|
||||
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h)
|
||||
|| (info->shared
|
||||
@ -1630,15 +1623,11 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
h->got.offset |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
relocation = htab->sgot->output_offset + off;
|
||||
}
|
||||
else
|
||||
{
|
||||
bfd_vma off;
|
||||
|
||||
BFD_ASSERT (local_got_offsets != NULL
|
||||
&& local_got_offsets[r_symndx] != (bfd_vma) -1);
|
||||
if (local_got_offsets == NULL)
|
||||
abort ();
|
||||
|
||||
off = local_got_offsets[r_symndx];
|
||||
|
||||
@ -1658,7 +1647,8 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
Elf_Internal_Rel outrel;
|
||||
|
||||
srelgot = htab->srelgot;
|
||||
BFD_ASSERT (srelgot != NULL);
|
||||
if (srelgot == NULL)
|
||||
abort ();
|
||||
|
||||
outrel.r_offset = (htab->sgot->output_section->vma
|
||||
+ htab->sgot->output_offset
|
||||
@ -1673,10 +1663,12 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
|
||||
local_got_offsets[r_symndx] |= 1;
|
||||
}
|
||||
|
||||
relocation = htab->sgot->output_offset + off;
|
||||
}
|
||||
|
||||
if (off >= (bfd_vma) -2)
|
||||
abort ();
|
||||
|
||||
relocation = htab->sgot->output_offset + off;
|
||||
break;
|
||||
|
||||
case R_386_GOTOFF:
|
||||
@ -1689,7 +1681,6 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
permitted by the ABI, we might have to change this
|
||||
calculation. */
|
||||
relocation -= htab->sgot->output_section->vma;
|
||||
|
||||
break;
|
||||
|
||||
case R_386_GOTPC:
|
||||
@ -1718,7 +1709,6 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
relocation = (htab->splt->output_section->vma
|
||||
+ htab->splt->output_offset
|
||||
+ h->plt.offset);
|
||||
|
||||
break;
|
||||
|
||||
case R_386_32:
|
||||
@ -1764,19 +1754,22 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
name + 4) != 0)
|
||||
{
|
||||
if (input_bfd->my_archive)
|
||||
(*_bfd_error_handler) (_("%s(%s): bad relocation section name `%s\'"),
|
||||
bfd_get_filename (input_bfd->my_archive),
|
||||
bfd_get_filename (input_bfd),
|
||||
name);
|
||||
(*_bfd_error_handler)\
|
||||
(_("%s(%s): bad relocation section name `%s\'"),
|
||||
bfd_get_filename (input_bfd->my_archive),
|
||||
bfd_get_filename (input_bfd),
|
||||
name);
|
||||
else
|
||||
(*_bfd_error_handler) (_("%s: bad relocation section name `%s\'"),
|
||||
bfd_get_filename (input_bfd),
|
||||
name);
|
||||
(*_bfd_error_handler)
|
||||
(_("%s: bad relocation section name `%s\'"),
|
||||
bfd_get_filename (input_bfd),
|
||||
name);
|
||||
return false;
|
||||
}
|
||||
|
||||
sreloc = bfd_get_section_by_name (dynobj, name);
|
||||
BFD_ASSERT (sreloc != NULL);
|
||||
if (sreloc == NULL)
|
||||
abort ();
|
||||
}
|
||||
|
||||
skip = false;
|
||||
@ -1855,36 +1848,38 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
contents, rel->r_offset,
|
||||
relocation, (bfd_vma) 0);
|
||||
|
||||
if (r != bfd_reloc_ok)
|
||||
switch (r)
|
||||
{
|
||||
switch (r)
|
||||
{
|
||||
default:
|
||||
case bfd_reloc_outofrange:
|
||||
abort ();
|
||||
case bfd_reloc_overflow:
|
||||
{
|
||||
const char *name;
|
||||
case bfd_reloc_ok:
|
||||
break;
|
||||
|
||||
if (h != NULL)
|
||||
name = h->root.root.string;
|
||||
else
|
||||
{
|
||||
name = bfd_elf_string_from_elf_section (input_bfd,
|
||||
symtab_hdr->sh_link,
|
||||
sym->st_name);
|
||||
if (name == NULL)
|
||||
return false;
|
||||
if (*name == '\0')
|
||||
name = bfd_section_name (input_bfd, sec);
|
||||
}
|
||||
if (! ((*info->callbacks->reloc_overflow)
|
||||
(info, name, howto->name, (bfd_vma) 0,
|
||||
input_bfd, input_section, rel->r_offset)))
|
||||
case bfd_reloc_overflow:
|
||||
{
|
||||
const char *name;
|
||||
|
||||
if (h != NULL)
|
||||
name = h->root.root.string;
|
||||
else
|
||||
{
|
||||
name = bfd_elf_string_from_elf_section (input_bfd,
|
||||
symtab_hdr->sh_link,
|
||||
sym->st_name);
|
||||
if (name == NULL)
|
||||
return false;
|
||||
if (*name == '\0')
|
||||
name = bfd_section_name (input_bfd, sec);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (! ((*info->callbacks->reloc_overflow)
|
||||
(info, name, howto->name, (bfd_vma) 0,
|
||||
input_bfd, input_section, rel->r_offset)))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case bfd_reloc_outofrange:
|
||||
abort ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1916,10 +1911,11 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||
/* This symbol has an entry in the procedure linkage table. Set
|
||||
it up. */
|
||||
|
||||
BFD_ASSERT (h->dynindx != -1
|
||||
&& htab->splt != NULL
|
||||
&& htab->sgotplt != NULL
|
||||
&& htab->srelplt != NULL);
|
||||
if (h->dynindx == -1
|
||||
|| htab->splt == NULL
|
||||
|| htab->sgotplt == NULL
|
||||
|| htab->srelplt == NULL)
|
||||
abort ();
|
||||
|
||||
/* Get the index in the procedure linkage table which
|
||||
corresponds to this symbol. This is the index of this symbol
|
||||
@ -1988,7 +1984,8 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||
/* This symbol has an entry in the global offset table. Set it
|
||||
up. */
|
||||
|
||||
BFD_ASSERT (htab->sgot != NULL && htab->srelgot != NULL);
|
||||
if (htab->sgot == NULL || htab->srelgot == NULL)
|
||||
abort ();
|
||||
|
||||
rel.r_offset = (htab->sgot->output_section->vma
|
||||
+ htab->sgot->output_offset
|
||||
@ -2028,10 +2025,11 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||
|
||||
/* This symbol needs a copy reloc. Set it up. */
|
||||
|
||||
BFD_ASSERT (h->dynindx != -1
|
||||
&& (h->root.type == bfd_link_hash_defined
|
||||
|| h->root.type == bfd_link_hash_defweak)
|
||||
&& htab->srelbss != NULL);
|
||||
if (h->dynindx == -1
|
||||
|| (h->root.type != bfd_link_hash_defined
|
||||
&& h->root.type != bfd_link_hash_defweak)
|
||||
|| htab->srelbss == NULL)
|
||||
abort ();
|
||||
|
||||
rel.r_offset = (h->root.u.def.value
|
||||
+ h->root.u.def.section->output_section->vma
|
||||
@ -2070,7 +2068,8 @@ elf_i386_finish_dynamic_sections (output_bfd, info)
|
||||
{
|
||||
Elf32_External_Dyn *dyncon, *dynconend;
|
||||
|
||||
BFD_ASSERT (sdyn != NULL && htab->sgot != NULL);
|
||||
if (sdyn == NULL || htab->sgot == NULL)
|
||||
abort ();
|
||||
|
||||
dyncon = (Elf32_External_Dyn *) sdyn->contents;
|
||||
dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
|
||||
|
Loading…
Reference in New Issue
Block a user