From: "Mark P. Mitchell" <mark@codesourcery.com>
To: binutils@sourceware.cygnus.com
Subject: elf32-mips.c patch
Date: Mon, 09 Aug 1999 23:29:00 -0000 [thread overview]
Message-ID: <199908100629.AAA770945@n02.acl.lanl.gov> (raw)
This patch is the result of an audit of the changes in the rel.dyn
generation from the pre-N32 code to the present, as well as
conversation with Ian. Checked in after verification on IRIX6.
-- Mark
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.
Index: elf32-mips.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf32-mips.c,v
retrieving revision 1.46
diff -c -p -r1.46 elf32-mips.c
*** elf32-mips.c 1999/08/09 22:45:38 1.46
--- elf32-mips.c 1999/08/10 06:23:15
*************** static bfd_vma mips_elf_create_local_got
*** 192,200 ****
PARAMS ((bfd *, struct mips_got_info *, asection *, bfd_vma));
static bfd_vma mips_elf_got16_entry
PARAMS ((bfd *, struct bfd_link_info *, bfd_vma));
! static unsigned int mips_elf_create_dynamic_relocation
PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Rela *,
! long, bfd_vma, asection *));
static void mips_elf_allocate_dynamic_relocations
PARAMS ((bfd *, unsigned int));
static boolean mips_elf_stub_section_p
--- 192,201 ----
PARAMS ((bfd *, struct mips_got_info *, asection *, bfd_vma));
static bfd_vma mips_elf_got16_entry
PARAMS ((bfd *, struct bfd_link_info *, bfd_vma));
! static boolean mips_elf_create_dynamic_relocation
PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Rela *,
! struct mips_elf_link_hash_entry *, asection *,
! bfd_vma, bfd_vma *, asection *));
static void mips_elf_allocate_dynamic_relocations
PARAMS ((bfd *, unsigned int));
static boolean mips_elf_stub_section_p
*************** mips_elf_got16_entry (abfd, info, value)
*** 5541,5547 ****
want, it is really the %high value. The complete value is
calculated with a `addiu' of a LO16 relocation, just as with a
HI16/LO16 pair. */
! value = mips_elf_high (value);
g = mips_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
/* Look to see if we already have an appropriate entry. */
--- 5542,5548 ----
want, it is really the %high value. The complete value is
calculated with a `addiu' of a LO16 relocation, just as with a
HI16/LO16 pair. */
! value = mips_elf_high (value) << 16;
g = mips_elf_got_info (elf_hash_table (info)->dynobj, &sgot);
/* Look to see if we already have an appropriate entry. */
*************** mips_elf_next_lo16_relocation (relocatio
*** 5594,5612 ****
return NULL;
}
! /* Create a rel.dyn relocation for the dynamic linker to resolve. The
! relocatin is against the symbol with the dynamic symbol table index
! DYNINDX. REL is the original relocation, which is now being made
! dynamic. */
!
! static unsigned int
! mips_elf_create_dynamic_relocation (output_bfd, info, rel, dynindx,
! addend, input_section)
bfd *output_bfd;
struct bfd_link_info *info;
const Elf_Internal_Rela *rel;
! long dynindx;
! bfd_vma addend;
asection *input_section;
{
Elf_Internal_Rel outrel;
--- 5595,5615 ----
return NULL;
}
! /* Create a rel.dyn relocation for the dynamic linker to resolve. REL
! is the original relocation, which is now being transformed into a
! dyanmic relocation. The ADDENDP is adjusted if necessary; the
! caller should store the result in place of the original addend. */
!
! static boolean
! mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
! symbol, addendp, input_section)
bfd *output_bfd;
struct bfd_link_info *info;
const Elf_Internal_Rela *rel;
! struct mips_elf_link_hash_entry *h;
! asection *sec;
! bfd_vma symbol;
! bfd_vma *addendp;
asection *input_section;
{
Elf_Internal_Rel outrel;
*************** mips_elf_create_dynamic_relocation (outp
*** 5624,5659 ****
skip = false;
! /* The symbol for the relocation is the same as it was for the
! original relocation. */
! outrel.r_info = ELF32_R_INFO (dynindx, R_MIPS_REL32);
!
! /* 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)
outrel.r_offset = rel->r_offset;
else
{
! bfd_vma off;
!
! off = (_bfd_stab_section_offset
! (output_bfd, &elf_hash_table (info)->stab_info,
! input_section,
! &elf_section_data (input_section)->stab_info,
! rel->r_offset));
! if (off == (bfd_vma) -1)
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
! record. */
if (skip)
memset (&outrel, 0, sizeof (outrel));
if (ABI_64_P (output_bfd))
{
(*get_elf_backend_data (output_bfd)->s->swap_reloc_out)
--- 5627,5720 ----
skip = false;
! /* We begin by assuming that the offset for the dynamic relocation
! is the same as for the original relocation. We'll adjust this
! later to reflect the correct output offsets. */
if (elf_section_data (input_section)->stab_info == NULL)
outrel.r_offset = rel->r_offset;
else
{
! /* Except that in a stab section things are more complex.
! Because we compress stab information, the offset given in the
! relocation may not be the one we want; we must let the stabs
! machinery tell us the offset. */
! outrel.r_offset
! = (_bfd_stab_section_offset
! (output_bfd, &elf_hash_table (info)->stab_info,
! 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;
}
/* If we've decided to skip this relocation, just output an emtpy
! 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)
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))
{
(*get_elf_backend_data (output_bfd)->s->swap_reloc_out)
*************** mips_elf_create_dynamic_relocation (outp
*** 5666,5671 ****
--- 5727,5741 ----
(((Elf32_External_Rel *)
sreloc->contents)
+ 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;
/* Make sure the output section is writable. The dynamic linker
*************** mips_elf_create_dynamic_relocation (outp
*** 5692,5698 ****
else
mips_elf_set_cr_type (cptrel, CRT_MIPS_WORD);
mips_elf_set_cr_dist2to (cptrel, 0);
! cptrel.konst = addend;
cr = (scpt->contents
+ sizeof (Elf32_External_compact_rel));
--- 5762,5768 ----
else
mips_elf_set_cr_type (cptrel, CRT_MIPS_WORD);
mips_elf_set_cr_dist2to (cptrel, 0);
! cptrel.konst = *addendp;
cr = (scpt->contents
+ sizeof (Elf32_External_compact_rel));
*************** mips_elf_create_dynamic_relocation (outp
*** 5703,5709 ****
}
}
! return sreloc->reloc_count - 1;
}
/* Calculate the value produced by the RELOCATION (which comes from
--- 5773,5779 ----
}
}
! return true;
}
/* Calculate the value produced by the RELOCATION (which comes from
*************** mips_elf_calculate_relocation (abfd,
*** 6024,6050 ****
case R_MIPS_32:
case R_MIPS_REL32:
case R_MIPS_64:
! /* If we're creating a shared library, or this relocation is
! against a symbol in a shared library, then we can't know
! where the symbol will end up. So, we create a relocation
! record in the output, and leave the job up to the dynamic
! linker. */
! if (info->shared || !sec->output_section)
! {
! unsigned int reloc_index;
!
! BFD_ASSERT (h != NULL);
! reloc_index
! = mips_elf_create_dynamic_relocation (abfd,
! info,
! relocation,
! h->root.dynindx,
! addend,
! input_section);
! if (h->min_dyn_reloc_index == 0
! || reloc_index < h->min_dyn_reloc_index)
! h->min_dyn_reloc_index = reloc_index;
! value = symbol + addend;
}
else
{
--- 6094,6121 ----
case R_MIPS_32:
case R_MIPS_REL32:
case R_MIPS_64:
! if ((info->shared
! || (elf_hash_table (info)->dynamic_sections_created
! && h != NULL
! && ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
! == 0)))
! && (input_section->flags & SEC_ALLOC) != 0)
! {
! /* If we're creating a shared library, or this relocation is
! against a symbol in a shared library, then we can't know
! where the symbol will end up. So, we create a relocation
! record in the output, and leave the job up to the dynamic
! linker. */
! value = addend;
! if (!mips_elf_create_dynamic_relocation (abfd,
! info,
! relocation,
! h,
! sec,
! symbol,
! &value,
! input_section))
! return false;
}
else
{
*************** _bfd_mips_elf_check_relocs (abfd, info,
*** 7488,7494 ****
this symbol, a symbol must have a dynamic symbol
table index greater that DT_GOTSYM if there are
dynamic relocations against it. */
! if (!mips_elf_record_global_got_symbol (h, info, g))
return false;
}
--- 7559,7566 ----
this symbol, a symbol must have a dynamic symbol
table index greater that DT_GOTSYM if there are
dynamic relocations against it. */
! if (h != NULL
! && !mips_elf_record_global_got_symbol (h, info, g))
return false;
}
reply other threads:[~1999-08-09 23:29 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=199908100629.AAA770945@n02.acl.lanl.gov \
--to=mark@codesourcery.com \
--cc=binutils@sourceware.cygnus.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).