mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-27 22:48:57 +08:00
* elf32-mips.c (mips_elf_create_dynamic_relocation): Change
prototype. Handle local symbols. Add commentary. (mips_elf_calculate_relocation): Adjust accordingly. (_bfd_mips_elf_check_relocs): Handle local symbols in R_MIPS_32 relocations.
This commit is contained in:
@ -1,5 +1,11 @@
|
|||||||
Tue Aug 10 00:21:08 1999 Mark P. Mitchell <mark@codesourcery.com>
|
Tue Aug 10 00:21:08 1999 Mark P. Mitchell <mark@codesourcery.com>
|
||||||
|
|
||||||
|
* elf32-mips.c (mips_elf_create_dynamic_relocation): Change
|
||||||
|
prototype. Handle local symbols. Add commentary.
|
||||||
|
(mips_elf_calculate_relocation): Adjust accordingly.
|
||||||
|
(_bfd_mips_elf_check_relocs): Handle local symbols in R_MIPS_32
|
||||||
|
relocations.
|
||||||
|
|
||||||
* elflink.h (elf_bfd_final_link): Tweak last change.
|
* elflink.h (elf_bfd_final_link): Tweak last change.
|
||||||
|
|
||||||
1999-08-09 Mark Mitchell <mark@codesourcery.com>
|
1999-08-09 Mark Mitchell <mark@codesourcery.com>
|
||||||
|
180
bfd/elf32-mips.c
180
bfd/elf32-mips.c
@ -192,9 +192,10 @@ static bfd_vma mips_elf_create_local_got_entry
|
|||||||
PARAMS ((bfd *, struct mips_got_info *, asection *, bfd_vma));
|
PARAMS ((bfd *, struct mips_got_info *, asection *, bfd_vma));
|
||||||
static bfd_vma mips_elf_got16_entry
|
static bfd_vma mips_elf_got16_entry
|
||||||
PARAMS ((bfd *, struct bfd_link_info *, bfd_vma));
|
PARAMS ((bfd *, struct bfd_link_info *, bfd_vma));
|
||||||
static unsigned int mips_elf_create_dynamic_relocation
|
static boolean mips_elf_create_dynamic_relocation
|
||||||
PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Rela *,
|
PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Rela *,
|
||||||
long, bfd_vma, asection *));
|
struct mips_elf_link_hash_entry *, asection *,
|
||||||
|
bfd_vma, bfd_vma *, asection *));
|
||||||
static void mips_elf_allocate_dynamic_relocations
|
static void mips_elf_allocate_dynamic_relocations
|
||||||
PARAMS ((bfd *, unsigned int));
|
PARAMS ((bfd *, unsigned int));
|
||||||
static boolean mips_elf_stub_section_p
|
static boolean mips_elf_stub_section_p
|
||||||
@ -5541,7 +5542,7 @@ mips_elf_got16_entry (abfd, info, value)
|
|||||||
want, it is really the %high value. The complete value is
|
want, it is really the %high value. The complete value is
|
||||||
calculated with a `addiu' of a LO16 relocation, just as with a
|
calculated with a `addiu' of a LO16 relocation, just as with a
|
||||||
HI16/LO16 pair. */
|
HI16/LO16 pair. */
|
||||||
value = mips_elf_high (value);
|
value = mips_elf_high (value) << 16;
|
||||||
g = mips_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
|
g = mips_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
|
||||||
|
|
||||||
/* Look to see if we already have an appropriate entry. */
|
/* Look to see if we already have an appropriate entry. */
|
||||||
@ -5594,19 +5595,21 @@ mips_elf_next_lo16_relocation (relocation, relend)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a rel.dyn relocation for the dynamic linker to resolve. The
|
/* Create a rel.dyn relocation for the dynamic linker to resolve. REL
|
||||||
relocatin is against the symbol with the dynamic symbol table index
|
is the original relocation, which is now being transformed into a
|
||||||
DYNINDX. REL is the original relocation, which is now being made
|
dyanmic relocation. The ADDENDP is adjusted if necessary; the
|
||||||
dynamic. */
|
caller should store the result in place of the original addend. */
|
||||||
|
|
||||||
static unsigned int
|
static boolean
|
||||||
mips_elf_create_dynamic_relocation (output_bfd, info, rel, dynindx,
|
mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
|
||||||
addend, input_section)
|
symbol, addendp, input_section)
|
||||||
bfd *output_bfd;
|
bfd *output_bfd;
|
||||||
struct bfd_link_info *info;
|
struct bfd_link_info *info;
|
||||||
const Elf_Internal_Rela *rel;
|
const Elf_Internal_Rela *rel;
|
||||||
long dynindx;
|
struct mips_elf_link_hash_entry *h;
|
||||||
bfd_vma addend;
|
asection *sec;
|
||||||
|
bfd_vma symbol;
|
||||||
|
bfd_vma *addendp;
|
||||||
asection *input_section;
|
asection *input_section;
|
||||||
{
|
{
|
||||||
Elf_Internal_Rel outrel;
|
Elf_Internal_Rel outrel;
|
||||||
@ -5624,36 +5627,94 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, dynindx,
|
|||||||
|
|
||||||
skip = false;
|
skip = false;
|
||||||
|
|
||||||
/* The symbol for the relocation is the same as it was for the
|
/* We begin by assuming that the offset for the dynamic relocation
|
||||||
original relocation. */
|
is the same as for the original relocation. We'll adjust this
|
||||||
outrel.r_info = ELF32_R_INFO (dynindx, R_MIPS_REL32);
|
later to reflect the correct output offsets. */
|
||||||
|
|
||||||
/* The offset for the dynamic relocation is the same as for the
|
|
||||||
original relocation, adjusted by the offset at which the original
|
|
||||||
section is output. */
|
|
||||||
if (elf_section_data (input_section)->stab_info == NULL)
|
if (elf_section_data (input_section)->stab_info == NULL)
|
||||||
outrel.r_offset = rel->r_offset;
|
outrel.r_offset = rel->r_offset;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bfd_vma off;
|
/* Except that in a stab section things are more complex.
|
||||||
|
Because we compress stab information, the offset given in the
|
||||||
off = (_bfd_stab_section_offset
|
relocation may not be the one we want; we must let the stabs
|
||||||
(output_bfd, &elf_hash_table (info)->stab_info,
|
machinery tell us the offset. */
|
||||||
input_section,
|
outrel.r_offset
|
||||||
&elf_section_data (input_section)->stab_info,
|
= (_bfd_stab_section_offset
|
||||||
rel->r_offset));
|
(output_bfd, &elf_hash_table (info)->stab_info,
|
||||||
if (off == (bfd_vma) -1)
|
input_section,
|
||||||
|
&elf_section_data (input_section)->stab_info,
|
||||||
|
rel->r_offset));
|
||||||
|
/* If we didn't need the relocation at all, this value will be
|
||||||
|
-1. */
|
||||||
|
if (outrel.r_offset == (bfd_vma) -1)
|
||||||
skip = true;
|
skip = true;
|
||||||
outrel.r_offset = off;
|
|
||||||
}
|
}
|
||||||
outrel.r_offset += (input_section->output_section->vma
|
|
||||||
+ input_section->output_offset);
|
|
||||||
|
|
||||||
/* If we've decided to skip this relocation, just output an emtpy
|
/* If we've decided to skip this relocation, just output an emtpy
|
||||||
record. */
|
record. Note that R_MIPS_NONE == 0, so that this call to memset
|
||||||
|
is a way of setting R_TYPE to R_MIPS_NONE. */
|
||||||
if (skip)
|
if (skip)
|
||||||
memset (&outrel, 0, sizeof (outrel));
|
memset (&outrel, 0, sizeof (outrel));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
long indx;
|
||||||
|
bfd_vma section_offset;
|
||||||
|
|
||||||
|
/* We must now calculate the dynamic symbol table index to use
|
||||||
|
in the relocation. */
|
||||||
|
if (h != NULL
|
||||||
|
&& (! info->symbolic || (h->root.elf_link_hash_flags
|
||||||
|
& ELF_LINK_HASH_DEF_REGULAR) == 0))
|
||||||
|
{
|
||||||
|
indx = h->root.dynindx;
|
||||||
|
BFD_ASSERT (indx != -1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (sec != NULL && bfd_is_abs_section (sec))
|
||||||
|
indx = 0;
|
||||||
|
else if (sec == NULL || sec->owner == NULL)
|
||||||
|
{
|
||||||
|
bfd_set_error (bfd_error_bad_value);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
indx = elf_section_data (sec->output_section)->dynindx;
|
||||||
|
if (indx == 0)
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Figure out how far the target of the relocation is from
|
||||||
|
the beginning of its section. */
|
||||||
|
section_offset = symbol - sec->output_section->vma;
|
||||||
|
/* The relocation we're building is section-relative.
|
||||||
|
Therefore, the original addend must be adjusted by the
|
||||||
|
section offset. */
|
||||||
|
*addendp += symbol - sec->output_section->vma;
|
||||||
|
/* Now, the relocation is just against the section. */
|
||||||
|
symbol = sec->output_section->vma;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the relocation was previously an absolute relocation, we
|
||||||
|
must adjust it by the value we give it in the dynamic symbol
|
||||||
|
table. */
|
||||||
|
if (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.r_info = ELF32_R_INFO (indx, R_MIPS_REL32);
|
||||||
|
|
||||||
|
/* Adjust the output offset of the relocation to reference the
|
||||||
|
correct location in the output file. */
|
||||||
|
outrel.r_offset += (input_section->output_section->vma
|
||||||
|
+ input_section->output_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put the relocation back out. We have to use the special
|
||||||
|
relocation outputter in the 64-bit case since the 64-bit
|
||||||
|
relocation format is non-standard. */
|
||||||
if (ABI_64_P (output_bfd))
|
if (ABI_64_P (output_bfd))
|
||||||
{
|
{
|
||||||
(*get_elf_backend_data (output_bfd)->s->swap_reloc_out)
|
(*get_elf_backend_data (output_bfd)->s->swap_reloc_out)
|
||||||
@ -5666,6 +5727,15 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, dynindx,
|
|||||||
(((Elf32_External_Rel *)
|
(((Elf32_External_Rel *)
|
||||||
sreloc->contents)
|
sreloc->contents)
|
||||||
+ sreloc->reloc_count));
|
+ sreloc->reloc_count));
|
||||||
|
|
||||||
|
/* Record the index of the first relocation referencing H. This
|
||||||
|
information is later emitted in the .msym section. */
|
||||||
|
if (h != NULL
|
||||||
|
&& (h->min_dyn_reloc_index == 0
|
||||||
|
|| sreloc->reloc_count < h->min_dyn_reloc_index))
|
||||||
|
h->min_dyn_reloc_index = sreloc->reloc_count;
|
||||||
|
|
||||||
|
/* We've now added another relocation. */
|
||||||
++sreloc->reloc_count;
|
++sreloc->reloc_count;
|
||||||
|
|
||||||
/* Make sure the output section is writable. The dynamic linker
|
/* Make sure the output section is writable. The dynamic linker
|
||||||
@ -5692,7 +5762,7 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, dynindx,
|
|||||||
else
|
else
|
||||||
mips_elf_set_cr_type (cptrel, CRT_MIPS_WORD);
|
mips_elf_set_cr_type (cptrel, CRT_MIPS_WORD);
|
||||||
mips_elf_set_cr_dist2to (cptrel, 0);
|
mips_elf_set_cr_dist2to (cptrel, 0);
|
||||||
cptrel.konst = addend;
|
cptrel.konst = *addendp;
|
||||||
|
|
||||||
cr = (scpt->contents
|
cr = (scpt->contents
|
||||||
+ sizeof (Elf32_External_compact_rel));
|
+ sizeof (Elf32_External_compact_rel));
|
||||||
@ -5703,7 +5773,7 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, dynindx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sreloc->reloc_count - 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the value produced by the RELOCATION (which comes from
|
/* Calculate the value produced by the RELOCATION (which comes from
|
||||||
@ -6024,27 +6094,28 @@ mips_elf_calculate_relocation (abfd,
|
|||||||
case R_MIPS_32:
|
case R_MIPS_32:
|
||||||
case R_MIPS_REL32:
|
case R_MIPS_REL32:
|
||||||
case R_MIPS_64:
|
case R_MIPS_64:
|
||||||
/* If we're creating a shared library, or this relocation is
|
if ((info->shared
|
||||||
against a symbol in a shared library, then we can't know
|
|| (elf_hash_table (info)->dynamic_sections_created
|
||||||
where the symbol will end up. So, we create a relocation
|
&& h != NULL
|
||||||
record in the output, and leave the job up to the dynamic
|
&& ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
|
||||||
linker. */
|
== 0)))
|
||||||
if (info->shared || !sec->output_section)
|
&& (input_section->flags & SEC_ALLOC) != 0)
|
||||||
{
|
{
|
||||||
unsigned int reloc_index;
|
/* If we're creating a shared library, or this relocation is
|
||||||
|
against a symbol in a shared library, then we can't know
|
||||||
BFD_ASSERT (h != NULL);
|
where the symbol will end up. So, we create a relocation
|
||||||
reloc_index
|
record in the output, and leave the job up to the dynamic
|
||||||
= mips_elf_create_dynamic_relocation (abfd,
|
linker. */
|
||||||
info,
|
value = addend;
|
||||||
relocation,
|
if (!mips_elf_create_dynamic_relocation (abfd,
|
||||||
h->root.dynindx,
|
info,
|
||||||
addend,
|
relocation,
|
||||||
input_section);
|
h,
|
||||||
if (h->min_dyn_reloc_index == 0
|
sec,
|
||||||
|| reloc_index < h->min_dyn_reloc_index)
|
symbol,
|
||||||
h->min_dyn_reloc_index = reloc_index;
|
&value,
|
||||||
value = symbol + addend;
|
input_section))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -7488,7 +7559,8 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
|
|||||||
this symbol, a symbol must have a dynamic symbol
|
this symbol, a symbol must have a dynamic symbol
|
||||||
table index greater that DT_GOTSYM if there are
|
table index greater that DT_GOTSYM if there are
|
||||||
dynamic relocations against it. */
|
dynamic relocations against it. */
|
||||||
if (!mips_elf_record_global_got_symbol (h, info, g))
|
if (h != NULL
|
||||||
|
&& !mips_elf_record_global_got_symbol (h, info, g))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user