mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-24 04:00:07 +08:00
* elfxx-mips.c (mips_elf_create_dynamic_relocation): Return early
for discard relocations; don't add an R_MIPS_NONE to the main body of .rel.dyn.
This commit is contained in:
@ -1,3 +1,9 @@
|
|||||||
|
2004-11-16 Richard Sandiford <rsandifo@redhat.com>
|
||||||
|
|
||||||
|
* elfxx-mips.c (mips_elf_create_dynamic_relocation): Return early
|
||||||
|
for discard relocations; don't add an R_MIPS_NONE to the main body
|
||||||
|
of .rel.dyn.
|
||||||
|
|
||||||
2004-11-04 Paul Brook <paul@codesourcery.com>
|
2004-11-04 Paul Brook <paul@codesourcery.com>
|
||||||
|
|
||||||
* elf-bfd.h (_bfd_elf_slurp_version_tables): Update prototype.
|
* elf-bfd.h (_bfd_elf_slurp_version_tables): Update prototype.
|
||||||
|
188
bfd/elfxx-mips.c
188
bfd/elfxx-mips.c
@ -3783,10 +3783,11 @@ mips_elf_create_dynamic_relocation (bfd *output_bfd,
|
|||||||
bfd_vma *addendp, asection *input_section)
|
bfd_vma *addendp, asection *input_section)
|
||||||
{
|
{
|
||||||
Elf_Internal_Rela outrel[3];
|
Elf_Internal_Rela outrel[3];
|
||||||
bfd_boolean skip;
|
|
||||||
asection *sreloc;
|
asection *sreloc;
|
||||||
bfd *dynobj;
|
bfd *dynobj;
|
||||||
int r_type;
|
int r_type;
|
||||||
|
long indx;
|
||||||
|
bfd_boolean defined_p;
|
||||||
|
|
||||||
r_type = ELF_R_TYPE (output_bfd, rel->r_info);
|
r_type = ELF_R_TYPE (output_bfd, rel->r_info);
|
||||||
dynobj = elf_hash_table (info)->dynobj;
|
dynobj = elf_hash_table (info)->dynobj;
|
||||||
@ -3796,7 +3797,6 @@ mips_elf_create_dynamic_relocation (bfd *output_bfd,
|
|||||||
BFD_ASSERT (sreloc->reloc_count * MIPS_ELF_REL_SIZE (output_bfd)
|
BFD_ASSERT (sreloc->reloc_count * MIPS_ELF_REL_SIZE (output_bfd)
|
||||||
< sreloc->size);
|
< sreloc->size);
|
||||||
|
|
||||||
skip = FALSE;
|
|
||||||
outrel[0].r_offset =
|
outrel[0].r_offset =
|
||||||
_bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset);
|
_bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset);
|
||||||
outrel[1].r_offset =
|
outrel[1].r_offset =
|
||||||
@ -3830,119 +3830,109 @@ mips_elf_create_dynamic_relocation (bfd *output_bfd,
|
|||||||
|
|
||||||
if (outrel[0].r_offset == MINUS_ONE)
|
if (outrel[0].r_offset == MINUS_ONE)
|
||||||
/* The relocation field has been deleted. */
|
/* The relocation field has been deleted. */
|
||||||
skip = TRUE;
|
return TRUE;
|
||||||
else if (outrel[0].r_offset == MINUS_TWO)
|
|
||||||
|
if (outrel[0].r_offset == MINUS_TWO)
|
||||||
{
|
{
|
||||||
/* The relocation field has been converted into a relative value of
|
/* The relocation field has been converted into a relative value of
|
||||||
some sort. Functions like _bfd_elf_write_section_eh_frame expect
|
some sort. Functions like _bfd_elf_write_section_eh_frame expect
|
||||||
the field to be fully relocated, so add in the symbol's value. */
|
the field to be fully relocated, so add in the symbol's value. */
|
||||||
skip = TRUE;
|
|
||||||
*addendp += symbol;
|
*addendp += symbol;
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we've decided to skip this relocation, just output an empty
|
/* We must now calculate the dynamic symbol table index to use
|
||||||
record. Note that R_MIPS_NONE == 0, so that this call to memset
|
in the relocation. */
|
||||||
is a way of setting R_TYPE to R_MIPS_NONE. */
|
if (h != NULL
|
||||||
if (skip)
|
&& (! info->symbolic || !h->root.def_regular)
|
||||||
memset (outrel, 0, sizeof (Elf_Internal_Rela) * 3);
|
/* h->root.dynindx may be -1 if this symbol was marked to
|
||||||
|
become local. */
|
||||||
|
&& h->root.dynindx != -1)
|
||||||
|
{
|
||||||
|
indx = h->root.dynindx;
|
||||||
|
if (SGI_COMPAT (output_bfd))
|
||||||
|
defined_p = h->root.def_regular;
|
||||||
|
else
|
||||||
|
/* ??? glibc's ld.so just adds the final GOT entry to the
|
||||||
|
relocation field. It therefore treats relocs against
|
||||||
|
defined symbols in the same way as relocs against
|
||||||
|
undefined symbols. */
|
||||||
|
defined_p = FALSE;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
long indx;
|
if (sec != NULL && bfd_is_abs_section (sec))
|
||||||
bfd_boolean defined_p;
|
indx = 0;
|
||||||
|
else if (sec == NULL || sec->owner == NULL)
|
||||||
/* We must now calculate the dynamic symbol table index to use
|
|
||||||
in the relocation. */
|
|
||||||
if (h != NULL
|
|
||||||
&& (! info->symbolic || !h->root.def_regular)
|
|
||||||
/* h->root.dynindx may be -1 if this symbol was marked to
|
|
||||||
become local. */
|
|
||||||
&& h->root.dynindx != -1)
|
|
||||||
{
|
{
|
||||||
indx = h->root.dynindx;
|
bfd_set_error (bfd_error_bad_value);
|
||||||
if (SGI_COMPAT (output_bfd))
|
return FALSE;
|
||||||
defined_p = h->root.def_regular;
|
|
||||||
else
|
|
||||||
/* ??? glibc's ld.so just adds the final GOT entry to the
|
|
||||||
relocation field. It therefore treats relocs against
|
|
||||||
defined symbols in the same way as relocs against
|
|
||||||
undefined symbols. */
|
|
||||||
defined_p = FALSE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (sec != NULL && bfd_is_abs_section (sec))
|
indx = elf_section_data (sec->output_section)->dynindx;
|
||||||
indx = 0;
|
if (indx == 0)
|
||||||
else if (sec == NULL || sec->owner == NULL)
|
abort ();
|
||||||
{
|
|
||||||
bfd_set_error (bfd_error_bad_value);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
indx = elf_section_data (sec->output_section)->dynindx;
|
|
||||||
if (indx == 0)
|
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Instead of generating a relocation using the section
|
|
||||||
symbol, we may as well make it a fully relative
|
|
||||||
relocation. We want to avoid generating relocations to
|
|
||||||
local symbols because we used to generate them
|
|
||||||
incorrectly, without adding the original symbol value,
|
|
||||||
which is mandated by the ABI for section symbols. In
|
|
||||||
order to give dynamic loaders and applications time to
|
|
||||||
phase out the incorrect use, we refrain from emitting
|
|
||||||
section-relative relocations. It's not like they're
|
|
||||||
useful, after all. This should be a bit more efficient
|
|
||||||
as well. */
|
|
||||||
/* ??? Although this behavior is compatible with glibc's ld.so,
|
|
||||||
the ABI says that relocations against STN_UNDEF should have
|
|
||||||
a symbol value of 0. Irix rld honors this, so relocations
|
|
||||||
against STN_UNDEF have no effect. */
|
|
||||||
if (!SGI_COMPAT (output_bfd))
|
|
||||||
indx = 0;
|
|
||||||
defined_p = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the relocation was previously an absolute relocation and
|
/* Instead of generating a relocation using the section
|
||||||
this symbol will not be referred to by the relocation, we must
|
symbol, we may as well make it a fully relative
|
||||||
adjust it by the value we give it in the dynamic symbol table.
|
relocation. We want to avoid generating relocations to
|
||||||
Otherwise leave the job up to the dynamic linker. */
|
local symbols because we used to generate them
|
||||||
if (defined_p && r_type != R_MIPS_REL32)
|
incorrectly, without adding the original symbol value,
|
||||||
*addendp += symbol;
|
which is mandated by the ABI for section symbols. In
|
||||||
|
order to give dynamic loaders and applications time to
|
||||||
/* The relocation is always an REL32 relocation because we don't
|
phase out the incorrect use, we refrain from emitting
|
||||||
know where the shared library will wind up at load-time. */
|
section-relative relocations. It's not like they're
|
||||||
outrel[0].r_info = ELF_R_INFO (output_bfd, (unsigned long) indx,
|
useful, after all. This should be a bit more efficient
|
||||||
R_MIPS_REL32);
|
as well. */
|
||||||
/* For strict adherence to the ABI specification, we should
|
/* ??? Although this behavior is compatible with glibc's ld.so,
|
||||||
generate a R_MIPS_64 relocation record by itself before the
|
the ABI says that relocations against STN_UNDEF should have
|
||||||
_REL32/_64 record as well, such that the addend is read in as
|
a symbol value of 0. Irix rld honors this, so relocations
|
||||||
a 64-bit value (REL32 is a 32-bit relocation, after all).
|
against STN_UNDEF have no effect. */
|
||||||
However, since none of the existing ELF64 MIPS dynamic
|
if (!SGI_COMPAT (output_bfd))
|
||||||
loaders seems to care, we don't waste space with these
|
indx = 0;
|
||||||
artificial relocations. If this turns out to not be true,
|
defined_p = TRUE;
|
||||||
mips_elf_allocate_dynamic_relocation() should be tweaked so
|
|
||||||
as to make room for a pair of dynamic relocations per
|
|
||||||
invocation if ABI_64_P, and here we should generate an
|
|
||||||
additional relocation record with R_MIPS_64 by itself for a
|
|
||||||
NULL symbol before this relocation record. */
|
|
||||||
outrel[1].r_info = ELF_R_INFO (output_bfd, 0,
|
|
||||||
ABI_64_P (output_bfd)
|
|
||||||
? R_MIPS_64
|
|
||||||
: R_MIPS_NONE);
|
|
||||||
outrel[2].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_NONE);
|
|
||||||
|
|
||||||
/* Adjust the output offset of the relocation to reference the
|
|
||||||
correct location in the output file. */
|
|
||||||
outrel[0].r_offset += (input_section->output_section->vma
|
|
||||||
+ input_section->output_offset);
|
|
||||||
outrel[1].r_offset += (input_section->output_section->vma
|
|
||||||
+ input_section->output_offset);
|
|
||||||
outrel[2].r_offset += (input_section->output_section->vma
|
|
||||||
+ input_section->output_offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the relocation was previously an absolute relocation and
|
||||||
|
this symbol will not be referred to by the relocation, we must
|
||||||
|
adjust it by the value we give it in the dynamic symbol table.
|
||||||
|
Otherwise leave the job up to the dynamic linker. */
|
||||||
|
if (defined_p && r_type != R_MIPS_REL32)
|
||||||
|
*addendp += symbol;
|
||||||
|
|
||||||
|
/* The relocation is always an REL32 relocation because we don't
|
||||||
|
know where the shared library will wind up at load-time. */
|
||||||
|
outrel[0].r_info = ELF_R_INFO (output_bfd, (unsigned long) indx,
|
||||||
|
R_MIPS_REL32);
|
||||||
|
/* For strict adherence to the ABI specification, we should
|
||||||
|
generate a R_MIPS_64 relocation record by itself before the
|
||||||
|
_REL32/_64 record as well, such that the addend is read in as
|
||||||
|
a 64-bit value (REL32 is a 32-bit relocation, after all).
|
||||||
|
However, since none of the existing ELF64 MIPS dynamic
|
||||||
|
loaders seems to care, we don't waste space with these
|
||||||
|
artificial relocations. If this turns out to not be true,
|
||||||
|
mips_elf_allocate_dynamic_relocation() should be tweaked so
|
||||||
|
as to make room for a pair of dynamic relocations per
|
||||||
|
invocation if ABI_64_P, and here we should generate an
|
||||||
|
additional relocation record with R_MIPS_64 by itself for a
|
||||||
|
NULL symbol before this relocation record. */
|
||||||
|
outrel[1].r_info = ELF_R_INFO (output_bfd, 0,
|
||||||
|
ABI_64_P (output_bfd)
|
||||||
|
? R_MIPS_64
|
||||||
|
: R_MIPS_NONE);
|
||||||
|
outrel[2].r_info = ELF_R_INFO (output_bfd, 0, R_MIPS_NONE);
|
||||||
|
|
||||||
|
/* Adjust the output offset of the relocation to reference the
|
||||||
|
correct location in the output file. */
|
||||||
|
outrel[0].r_offset += (input_section->output_section->vma
|
||||||
|
+ input_section->output_offset);
|
||||||
|
outrel[1].r_offset += (input_section->output_section->vma
|
||||||
|
+ input_section->output_offset);
|
||||||
|
outrel[2].r_offset += (input_section->output_section->vma
|
||||||
|
+ input_section->output_offset);
|
||||||
|
|
||||||
/* Put the relocation back out. We have to use the special
|
/* Put the relocation back out. We have to use the special
|
||||||
relocation outputter in the 64-bit case since the 64-bit
|
relocation outputter in the 64-bit case since the 64-bit
|
||||||
relocation format is non-standard. */
|
relocation format is non-standard. */
|
||||||
@ -3967,7 +3957,7 @@ mips_elf_create_dynamic_relocation (bfd *output_bfd,
|
|||||||
|= SHF_WRITE;
|
|= SHF_WRITE;
|
||||||
|
|
||||||
/* On IRIX5, make an entry of compact relocation info. */
|
/* On IRIX5, make an entry of compact relocation info. */
|
||||||
if (! skip && IRIX_COMPAT (output_bfd) == ict_irix5)
|
if (IRIX_COMPAT (output_bfd) == ict_irix5)
|
||||||
{
|
{
|
||||||
asection *scpt = bfd_get_section_by_name (dynobj, ".compact_rel");
|
asection *scpt = bfd_get_section_by_name (dynobj, ".compact_rel");
|
||||||
bfd_byte *cr;
|
bfd_byte *cr;
|
||||||
|
Reference in New Issue
Block a user